summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt4
-rw-r--r--README.md65
-rw-r--r--cmake/FindDesignerComponents.cmake2
-rw-r--r--cmake/Findyaml-cpp.cmake113
-rw-r--r--cmake/QtCreatorAPI.cmake155
-rw-r--r--cmake/QtCreatorIDEBranding.cmake7
-rw-r--r--doc/images/qtcreator-cpp-class-wizard.pngbin31457 -> 14636 bytes
-rw-r--r--doc/images/qtcreator-editortoolbar-symbols.pngbin52123 -> 24161 bytes
-rw-r--r--doc/images/qtcreator-kit-webassembly.pngbin0 -> 26213 bytes
-rw-r--r--doc/images/qtcreator-new-subproject.pngbin0 -> 20751 bytes
-rw-r--r--doc/images/qtcreator-options-cpp-files.pngbin7939 -> 9277 bytes
-rw-r--r--doc/images/qtcreator-options-environment-system.pngbin0 -> 10529 bytes
-rw-r--r--doc/images/qtcreator-settings-run-webassembly.pngbin0 -> 7298 bytes
-rw-r--r--doc/src/editors/creator-coding-edit-mode.qdoc5
-rw-r--r--doc/src/editors/creator-only/creator-language-server.qdoc3
-rw-r--r--doc/src/editors/creator-semantic-highlighting.qdoc4
-rw-r--r--doc/src/howto/creator-sidebar-views.qdoc27
-rw-r--r--doc/src/overview/creator-acknowledgements.qdoc67
-rw-r--r--doc/src/overview/creator-only/creator-mobile-targets.qdoc11
-rw-r--r--doc/src/overview/creator-only/creator-overview.qdoc3
-rw-r--r--doc/src/overview/creator-only/creator-supported-platforms.qdoc3
-rw-r--r--doc/src/overview/creator-only/creator-target-platforms.qdocinc7
-rw-r--r--doc/src/projects/creator-only/creator-projects-building.qdoc15
-rw-r--r--doc/src/projects/creator-only/creator-projects-builds-customizing.qdoc4
-rw-r--r--doc/src/projects/creator-only/creator-projects-creating.qdoc12
-rw-r--r--doc/src/projects/creator-only/creator-projects-generic.qdoc6
-rw-r--r--doc/src/projects/creator-only/creator-projects-settings-build.qdoc5
-rw-r--r--doc/src/qnx/creator-developing-qnx.qdoc2
-rw-r--r--doc/src/qtcreator-toc.qdoc1
-rw-r--r--doc/src/qtcreator.qdoc7
-rw-r--r--doc/src/webassembly/creator-webassembly.qdoc116
-rw-r--r--qbs/modules/qtc/qtc.qbs6
-rw-r--r--qtcreator.pri1
-rw-r--r--qtcreator_ide_branding.pri8
-rwxr-xr-xscripts/deployqt.py4
-rwxr-xr-xscripts/deployqtHelper_mac.sh4
-rw-r--r--share/qtcreator/CMakeLists.txt4
-rw-r--r--share/qtcreator/cplusplus/examples/CMakeLists.txt22
-rw-r--r--share/qtcreator/debugger/.pylintrc11
-rw-r--r--share/qtcreator/debugger/dumper.py8
-rw-r--r--share/qtcreator/debugger/lldbbridge.py10
-rw-r--r--share/qtcreator/debugger/misctypes.py1
-rw-r--r--share/qtcreator/debugger/pdbbridge.py368
-rw-r--r--share/qtcreator/debugger/qttypes.py5
-rw-r--r--share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp2
-rw-r--r--share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp2
-rw-r--r--share/qtcreator/qml/qmlpuppet/container/sharedmemory.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp34
-rw-r--r--share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp9
-rw-r--r--share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp3
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp11
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp16
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp6
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp16
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h4
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml72
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml203
-rw-r--r--share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml34
-rwxr-xr-xshare/qtcreator/scripts/openTerminal.py3
-rw-r--r--share/qtcreator/templates/wizards/autotest/files/googlecommon.js9
-rw-r--r--share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri36
-rw-r--r--share/qtcreator/templates/wizards/autotest/files/tst.qbs8
-rw-r--r--share/qtcreator/templates/wizards/autotest/files/tst.txt21
-rw-r--r--share/qtcreator/templates/wizards/autotest/wizard.json5
-rw-r--r--share/qtcreator/templates/wizards/classes/cpp/file.h7
-rw-r--r--share/qtcreator/templates/wizards/classes/cpp/wizard.json14
-rw-r--r--share/qtcreator/templates/wizards/classes/python/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/files/python/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt17
-rw-r--r--share/qtcreator/templates/wizards/projects/consoleapp/file.pro5
-rw-r--r--share/qtcreator/templates/wizards/projects/consoleapp/file.qbs7
-rw-r--r--share/qtcreator/templates/wizards/projects/consoleapp/wizard.json11
-rw-r--r--share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt13
-rw-r--r--share/qtcreator/templates/wizards/projects/cpplibrary/project.pro5
-rw-r--r--share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs3
-rw-r--r--share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json12
-rw-r--r--share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/lib.png (renamed from share/qtcreator/templates/wizards/qtquick2-extension/lib.png)bin1789 -> 1789 bytes
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/lib@2x.png (renamed from share/qtcreator/templates/wizards/qtquick2-extension/lib@2x.png)bin3717 -> 3717 bytes
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/object.cpp (renamed from share/qtcreator/templates/wizards/qtquick2-extension/object.cpp)8
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h23
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp12
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.h (renamed from share/qtcreator/templates/wizards/qtquick2-extension/plugin.h)9
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/project.pro (renamed from share/qtcreator/templates/wizards/qtquick2-extension/project.pro)18
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir2
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json109
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt32
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro5
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs3
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json11
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json11
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json11
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json11
-rw-r--r--share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt13
-rw-r--r--share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro5
-rw-r--r--share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs7
-rw-r--r--share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json11
-rw-r--r--share/qtcreator/templates/wizards/projects/translation.ts3
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json4
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/cvs/icon.pngbin1167 -> 2012 bytes
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.pngbin1977 -> 4868 bytes
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json4
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/git/icon.pngbin1100 -> 1781 bytes
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.pngbin1805 -> 4251 bytes
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/git/wizard.json4
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json4
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json4
-rw-r--r--share/qtcreator/templates/wizards/qtquick2-extension/object.h22
-rw-r--r--share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp11
-rw-r--r--share/qtcreator/templates/wizards/qtquick2-extension/qmldir2
-rw-r--r--share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml66
-rw-r--r--share/qtcreator/translations/CMakeLists.txt214
-rw-r--r--share/qtcreator/translations/extract-customwizards.py67
-rw-r--r--share/qtcreator/translations/extract-externaltools.py64
-rw-r--r--share/qtcreator/translations/extract-jsonwizards.py81
-rw-r--r--share/qtcreator/translations/extract-snippets.py65
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/app/CMakeLists.txt6
-rw-r--r--src/app/main.cpp10
-rw-r--r--src/libs/3rdparty/cplusplus/AST.cpp1542
-rw-r--r--src/libs/3rdparty/cplusplus/AST.h3228
-rw-r--r--src/libs/3rdparty/cplusplus/ASTClone.cpp156
-rw-r--r--src/libs/3rdparty/cplusplus/ASTPatternBuilder.h308
-rw-r--r--src/libs/3rdparty/cplusplus/ASTVisitor.cpp30
-rw-r--r--src/libs/3rdparty/cplusplus/ASTVisitor.h36
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.cpp568
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.h16
-rw-r--r--src/libs/3rdparty/cplusplus/Control.cpp108
-rw-r--r--src/libs/3rdparty/cplusplus/Control.h68
-rw-r--r--src/libs/3rdparty/cplusplus/DiagnosticClient.h2
-rw-r--r--src/libs/3rdparty/cplusplus/FullySpecifiedType.h4
-rw-r--r--src/libs/3rdparty/cplusplus/Lexer.cpp20
-rw-r--r--src/libs/3rdparty/cplusplus/LiteralTable.h18
-rw-r--r--src/libs/3rdparty/cplusplus/Literals.cpp6
-rw-r--r--src/libs/3rdparty/cplusplus/Literals.h10
-rw-r--r--src/libs/3rdparty/cplusplus/Matcher.cpp6
-rw-r--r--src/libs/3rdparty/cplusplus/Matcher.h4
-rw-r--r--src/libs/3rdparty/cplusplus/MemoryPool.cpp10
-rw-r--r--src/libs/3rdparty/cplusplus/Name.cpp28
-rw-r--r--src/libs/3rdparty/cplusplus/Name.h18
-rw-r--r--src/libs/3rdparty/cplusplus/Names.cpp38
-rw-r--r--src/libs/3rdparty/cplusplus/Names.h14
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.cpp594
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.h48
-rw-r--r--src/libs/3rdparty/cplusplus/Scope.cpp50
-rw-r--r--src/libs/3rdparty/cplusplus/Scope.h18
-rw-r--r--src/libs/3rdparty/cplusplus/Symbol.cpp98
-rw-r--r--src/libs/3rdparty/cplusplus/Symbol.h122
-rw-r--r--src/libs/3rdparty/cplusplus/Symbols.cpp172
-rw-r--r--src/libs/3rdparty/cplusplus/Symbols.h84
-rw-r--r--src/libs/3rdparty/cplusplus/Templates.cpp50
-rw-r--r--src/libs/3rdparty/cplusplus/Templates.h6
-rw-r--r--src/libs/3rdparty/cplusplus/Token.cpp2
-rw-r--r--src/libs/3rdparty/cplusplus/Token.h17
-rw-r--r--src/libs/3rdparty/cplusplus/TranslationUnit.cpp146
-rw-r--r--src/libs/3rdparty/cplusplus/TranslationUnit.h94
-rw-r--r--src/libs/3rdparty/cplusplus/Type.cpp38
-rw-r--r--src/libs/3rdparty/cplusplus/Type.h82
-rw-r--r--src/libs/3rdparty/json/json.hpp20842
-rw-r--r--src/libs/3rdparty/syntax-highlighting/CMakeLists.txt2
-rw-r--r--src/libs/3rdparty/yaml-cpp/.clang-format47
-rw-r--r--src/libs/3rdparty/yaml-cpp/LICENSE19
-rw-r--r--src/libs/3rdparty/yaml-cpp/README.md51
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h17
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h67
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h42
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h57
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h254
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterdef.h16
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h137
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterstyle.h16
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h40
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h261
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/mark.h29
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h331
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h26
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h185
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h92
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h27
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h46
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h169
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h127
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h180
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h98
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/emit.h32
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h448
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h31
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h145
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/parse.h78
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h29
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/type.h16
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h25
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/null.h26
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h72
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h86
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h51
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h103
-rw-r--r--src/libs/3rdparty/yaml-cpp/include/yaml-cpp/yaml.h24
-rw-r--r--src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch1667
-rw-r--r--src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch42
-rw-r--r--src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch52
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/binary.cpp93
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/collectionstack.h39
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/convert.cpp75
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/directives.cpp22
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/directives.h29
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emit.cpp25
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp119
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitter.cpp911
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp365
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterstate.h203
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp483
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/emitterutils.h50
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/exceptions.cpp25
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/exp.cpp136
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/exp.h222
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/indentation.h41
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/memory.cpp26
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/node.cpp12
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/node_data.cpp300
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp130
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodebuilder.h70
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp101
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/nodeevents.h64
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/null.cpp10
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp57
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/parse.cpp72
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/parser.cpp129
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/ptr_vector.h43
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp45
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/regex_yaml.h87
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/regeximpl.h186
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanner.cpp386
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanner.h190
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp250
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scanscalar.h63
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scantag.cpp81
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scantag.h19
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/scantoken.cpp437
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/setting.h95
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/simplekey.cpp128
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp414
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/singledocparser.h65
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/stream.cpp448
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/stream.h76
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/streamcharsource.h48
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/stringsource.h48
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/tag.cpp49
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/tag.h33
-rw-r--r--src/libs/3rdparty/yaml-cpp/src/token.h69
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake11
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp.pri89
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp.pro5
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs105
-rw-r--r--src/libs/3rdparty/yaml-cpp/yaml-cpp_dependencies.pri2
-rw-r--r--src/libs/clangsupport/CMakeLists.txt1
-rw-r--r--src/libs/clangsupport/clangpathwatcher.h6
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri2
-rw-r--r--src/libs/clangsupport/clangsupport_global.h9
-rw-r--r--src/libs/clangsupport/clangsupportdebugutils.h2
-rw-r--r--src/libs/clangsupport/filecontainerv2.h20
-rw-r--r--src/libs/clangsupport/filepathcache.h144
-rw-r--r--src/libs/clangsupport/filepathcaching.cpp45
-rw-r--r--src/libs/clangsupport/filepathcaching.h27
-rw-r--r--src/libs/clangsupport/filepathcachinginterface.h4
-rw-r--r--src/libs/clangsupport/filepathstorage.h33
-rw-r--r--src/libs/clangsupport/filepathstoragesources.h85
-rw-r--r--src/libs/clangsupport/filepathstoragesqlitestatementfactory.h14
-rw-r--r--src/libs/clangsupport/filesystem.cpp5
-rw-r--r--src/libs/clangsupport/generatedfiles.cpp19
-rw-r--r--src/libs/clangsupport/generatedfiles.h1
-rw-r--r--src/libs/clangsupport/generatedfilesinterface.h1
-rw-r--r--src/libs/clangsupport/idpaths.h14
-rw-r--r--src/libs/clangsupport/modifiedtimechecker.h44
-rw-r--r--src/libs/clangsupport/processcreator.cpp6
-rw-r--r--src/libs/clangsupport/projectpartcontainer.h19
-rw-r--r--src/libs/clangsupport/projectpartid.h18
-rw-r--r--src/libs/clangsupport/projectpartsstorage.h100
-rw-r--r--src/libs/clangsupport/projectpartsstorageinterface.h5
-rw-r--r--src/libs/clangsupport/projectpartstoragestructs.h55
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h4
-rw-r--r--src/libs/clangsupport/set_algorithm.h24
-rw-r--r--src/libs/clangsupport/sourceentry.h13
-rw-r--r--src/libs/clangsupport/sourcelocationcontainer.h8
-rw-r--r--src/libs/clangsupport/sourcerangecontainer.h2
-rw-r--r--src/libs/clangsupport/stringcache.h203
-rw-r--r--src/libs/clangsupport/stringcacheentry.h50
-rw-r--r--src/libs/clangsupport/stringcachefwd.h7
-rw-r--r--src/libs/clangsupport/tokeninfocontainer.h10
-rw-r--r--src/libs/cplusplus/ASTPath.cpp4
-rw-r--r--src/libs/cplusplus/ASTPath.h4
-rw-r--r--src/libs/cplusplus/AlreadyConsideredClassContainer.h2
-rw-r--r--src/libs/cplusplus/CppDocument.cpp84
-rw-r--r--src/libs/cplusplus/CppDocument.h90
-rw-r--r--src/libs/cplusplus/CppRewriter.cpp16
-rw-r--r--src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp12
-rw-r--r--src/libs/cplusplus/FastPreprocessor.cpp16
-rw-r--r--src/libs/cplusplus/FastPreprocessor.h20
-rw-r--r--src/libs/cplusplus/FindUsages.cpp12
-rw-r--r--src/libs/cplusplus/FindUsages.h8
-rw-r--r--src/libs/cplusplus/LookupContext.cpp144
-rw-r--r--src/libs/cplusplus/LookupContext.h12
-rw-r--r--src/libs/cplusplus/LookupItem.cpp2
-rw-r--r--src/libs/cplusplus/Macro.cpp2
-rw-r--r--src/libs/cplusplus/Macro.h6
-rw-r--r--src/libs/cplusplus/MatchingText.cpp9
-rw-r--r--src/libs/cplusplus/MatchingText.h2
-rw-r--r--src/libs/cplusplus/NamePrettyPrinter.cpp4
-rw-r--r--src/libs/cplusplus/Overview.h6
-rw-r--r--src/libs/cplusplus/PreprocessorClient.cpp8
-rw-r--r--src/libs/cplusplus/PreprocessorClient.h42
-rw-r--r--src/libs/cplusplus/PreprocessorEnvironment.cpp12
-rw-r--r--src/libs/cplusplus/PreprocessorEnvironment.h2
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp58
-rw-r--r--src/libs/cplusplus/ResolveExpression.h6
-rw-r--r--src/libs/cplusplus/SimpleLexer.cpp6
-rw-r--r--src/libs/cplusplus/SimpleLexer.h6
-rw-r--r--src/libs/cplusplus/SymbolNameVisitor.cpp2
-rw-r--r--src/libs/cplusplus/TypeOfExpression.cpp12
-rw-r--r--src/libs/cplusplus/TypePrettyPrinter.cpp8
-rw-r--r--src/libs/cplusplus/cppmodelmanagerbase.cpp10
-rw-r--r--src/libs/cplusplus/cppmodelmanagerbase.h2
-rw-r--r--src/libs/cplusplus/findcdbbreakpoint.cpp10
-rw-r--r--src/libs/cplusplus/findcdbbreakpoint.h15
-rw-r--r--src/libs/cplusplus/pp-engine.cpp30
-rw-r--r--src/libs/cplusplus/pp-engine.h6
-rw-r--r--src/libs/extensionsystem/CMakeLists.txt4
-rw-r--r--src/libs/extensionsystem/pluginmanager.cpp41
-rw-r--r--src/libs/extensionsystem/pluginmanager.h1
-rw-r--r--src/libs/extensionsystem/pluginspec.cpp4
-rw-r--r--src/libs/glsl/glslast.cpp4
-rw-r--r--src/libs/glsl/glslastdump.cpp2
-rw-r--r--src/libs/glsl/glslengine.h6
-rw-r--r--src/libs/glsl/glsllexer.cpp4
-rw-r--r--src/libs/glsl/glsllexer.h2
-rw-r--r--src/libs/glsl/glslmemorypool.cpp10
-rw-r--r--src/libs/glsl/glslparser.cpp52
-rw-r--r--src/libs/glsl/glslparser.h4
-rw-r--r--src/libs/glsl/glslsemantic.cpp70
-rw-r--r--src/libs/glsl/glslsemantic.h4
-rw-r--r--src/libs/glsl/glslsymbol.cpp2
-rw-r--r--src/libs/glsl/glslsymbol.h20
-rw-r--r--src/libs/glsl/glslsymbols.cpp8
-rw-r--r--src/libs/glsl/glslsymbols.h2
-rw-r--r--src/libs/glsl/glsltype.h34
-rw-r--r--src/libs/glsl/glsltypes.cpp106
-rw-r--r--src/libs/glsl/glsltypes.h6
-rw-r--r--src/libs/languageserverprotocol/clientcapabilities.cpp35
-rw-r--r--src/libs/languageserverprotocol/clientcapabilities.h20
-rw-r--r--src/libs/languageserverprotocol/jsonkeys.h5
-rw-r--r--src/libs/languageserverprotocol/languagefeatures.cpp56
-rw-r--r--src/libs/languageserverprotocol/languagefeatures.h56
-rw-r--r--src/libs/languageserverprotocol/lsptypes.cpp4
-rw-r--r--src/libs/languageserverprotocol/lsptypes.h4
-rw-r--r--src/libs/languageserverprotocol/servercapabilities.cpp43
-rw-r--r--src/libs/languageserverprotocol/servercapabilities.h17
-rw-r--r--src/libs/libs.pro3
-rw-r--r--src/libs/libs.qbs1
-rw-r--r--src/libs/modelinglib/qmt/config/textscanner.cpp2
-rw-r--r--src/libs/modelinglib/qmt/controller/undocommand.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp4
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp28
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp18
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp12
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp14
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp18
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp10
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp10
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp2
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp12
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.cpp6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp12
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.cpp4
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp6
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp8
-rw-r--r--src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp6
-rw-r--r--src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp2
-rw-r--r--src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp4
-rw-r--r--src/libs/modelinglib/qmt/model/melement.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp4
-rw-r--r--src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp4
-rw-r--r--src/libs/modelinglib/qmt/model_ui/sortedtreemodel.cpp6
-rw-r--r--src/libs/modelinglib/qmt/model_ui/treemodel.cpp38
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp4
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp2
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp60
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp9
-rw-r--r--src/libs/modelinglib/qmt/style/defaultstyleengine.cpp28
-rw-r--r--src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp4
-rw-r--r--src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp4
-rw-r--r--src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h4
-rw-r--r--src/libs/qmldebug/qmldebugcommandlinearguments.h29
-rw-r--r--src/libs/qmldebug/qmldebugconnection.cpp2
-rw-r--r--src/libs/qmldebug/qmldebugconnectionmanager.cpp2
-rw-r--r--src/libs/qmldebug/qmldebugconnectionmanager.h2
-rw-r--r--src/libs/qmldebug/qmloutputparser.h2
-rw-r--r--src/libs/qmldebug/qpacketprotocol.cpp2
-rw-r--r--src/libs/qmldebug/qpacketprotocol.h2
-rw-r--r--src/libs/qmleditorwidgets/colorbox.h2
-rw-r--r--src/libs/qmleditorwidgets/colorbutton.h2
-rw-r--r--src/libs/qmleditorwidgets/contextpanetextwidget.h2
-rw-r--r--src/libs/qmleditorwidgets/contextpanewidget.cpp5
-rw-r--r--src/libs/qmleditorwidgets/contextpanewidget.h4
-rw-r--r--src/libs/qmleditorwidgets/contextpanewidgetimage.cpp3
-rw-r--r--src/libs/qmleditorwidgets/contextpanewidgetimage.h10
-rw-r--r--src/libs/qmleditorwidgets/contextpanewidgetrectangle.h2
-rw-r--r--src/libs/qmleditorwidgets/customcolordialog.cpp9
-rw-r--r--src/libs/qmleditorwidgets/customcolordialog.h2
-rw-r--r--src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp4
-rw-r--r--src/libs/qmleditorwidgets/easingpane/easingcontextpane.h2
-rw-r--r--src/libs/qmleditorwidgets/easingpane/easinggraph.h2
-rw-r--r--src/libs/qmleditorwidgets/filewidget.h2
-rw-r--r--src/libs/qmleditorwidgets/fontsizespinbox.cpp2
-rw-r--r--src/libs/qmleditorwidgets/fontsizespinbox.h2
-rw-r--r--src/libs/qmleditorwidgets/gradientline.h2
-rw-r--r--src/libs/qmleditorwidgets/huecontrol.h2
-rw-r--r--src/libs/qmljs/jsoncheck.cpp2
-rw-r--r--src/libs/qmljs/parser/qmljsengine_p.h18
-rw-r--r--src/libs/qmljs/persistenttrie.cpp15
-rw-r--r--src/libs/qmljs/qmljsbind.cpp22
-rw-r--r--src/libs/qmljs/qmljsbundle.cpp14
-rw-r--r--src/libs/qmljs/qmljscheck.cpp74
-rw-r--r--src/libs/qmljs/qmljscontext.cpp18
-rw-r--r--src/libs/qmljs/qmljscontext.h2
-rw-r--r--src/libs/qmljs/qmljsdocument.cpp46
-rw-r--r--src/libs/qmljs/qmljsdocument.h3
-rw-r--r--src/libs/qmljs/qmljsevaluate.cpp8
-rw-r--r--src/libs/qmljs/qmljsevaluate.h2
-rw-r--r--src/libs/qmljs/qmljsfindexportedcpptypes.cpp75
-rw-r--r--src/libs/qmljs/qmljsicons.cpp4
-rw-r--r--src/libs/qmljs/qmljsicontextpane.h2
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.cpp30
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp176
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h74
-rw-r--r--src/libs/qmljs/qmljslineinfo.cpp6
-rw-r--r--src/libs/qmljs/qmljslink.cpp35
-rw-r--r--src/libs/qmljs/qmljslink.h2
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp35
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.h1
-rw-r--r--src/libs/qmljs/qmljsplugindumper.cpp4
-rw-r--r--src/libs/qmljs/qmljsrewriter.cpp26
-rw-r--r--src/libs/qmljs/qmljsscopebuilder.cpp12
-rw-r--r--src/libs/qmljs/qmljsscopechain.cpp18
-rw-r--r--src/libs/qmljs/qmljsscopechain.h2
-rw-r--r--src/libs/qmljs/qmljstypedescriptionreader.cpp2
-rw-r--r--src/libs/qmljs/qmljsutils.cpp6
-rw-r--r--src/libs/qmljs/qmljsutils.h2
-rw-r--r--src/libs/qmljs/qmljsvalueowner.cpp24
-rw-r--r--src/libs/qmljs/qmljsvalueowner.h2
-rw-r--r--src/libs/sqlite/CMakeLists.txt2
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.cpp2
-rw-r--r--src/libs/ssh/sftpfilesystemmodel.cpp18
-rw-r--r--src/libs/ssh/sftpfilesystemmodel.h2
-rw-r--r--src/libs/ssh/sshconnection.h2
-rw-r--r--src/libs/ssh/sshconnectionmanager.cpp10
-rw-r--r--src/libs/ssh/sshkeycreationdialog.h2
-rw-r--r--src/libs/ssh/sshremoteprocess.cpp28
-rw-r--r--src/libs/ssh/sshremoteprocess.h4
-rw-r--r--src/libs/ssh/sshremoteprocessrunner.cpp4
-rw-r--r--src/libs/ssh/sshremoteprocessrunner.h2
-rw-r--r--src/libs/tracing/CMakeLists.txt1
-rw-r--r--src/libs/tracing/flamegraph.cpp6
-rw-r--r--src/libs/tracing/qml/ButtonsBar.qml30
-rw-r--r--src/libs/tracing/qml/CategoryLabel.qml15
-rw-r--r--src/libs/tracing/qml/FlameGraphView.qml28
-rw-r--r--src/libs/tracing/qml/ImageToolButton.qml20
-rw-r--r--src/libs/tracing/qml/MainView.qml42
-rw-r--r--src/libs/tracing/qml/RangeDetails.qml5
-rw-r--r--src/libs/tracing/qml/RowLabel.qml36
-rw-r--r--src/libs/tracing/qml/SelectionRangeDetails.qml3
-rw-r--r--src/libs/tracing/qml/TimelineContent.qml240
-rw-r--r--src/libs/tracing/qml/TimelineLabels.qml6
-rw-r--r--src/libs/tracing/timelineabstractrenderer.cpp2
-rw-r--r--src/libs/tracing/timelineformattime.cpp10
-rw-r--r--src/libs/tracing/timelineitemsrenderpass.cpp10
-rw-r--r--src/libs/tracing/timelinemodel.cpp83
-rw-r--r--src/libs/tracing/timelinemodel.h17
-rw-r--r--src/libs/tracing/timelinemodel_p.h3
-rw-r--r--src/libs/tracing/timelinenotesrenderpass.cpp10
-rw-r--r--src/libs/tracing/timelineoverviewrenderer.cpp10
-rw-r--r--src/libs/tracing/timelinerenderer.cpp17
-rw-r--r--src/libs/tracing/timelinerenderpass.cpp4
-rw-r--r--src/libs/tracing/timelinerenderstate.cpp2
-rw-r--r--src/libs/tracing/timelineselectionrenderpass.cpp6
-rw-r--r--src/libs/tracing/timelinetheme.cpp6
-rw-r--r--src/libs/utils/CMakeLists.txt25
-rw-r--r--src/libs/utils/algorithm.h32
-rw-r--r--src/libs/utils/basetreeview.cpp2
-rw-r--r--src/libs/utils/buildablehelperlibrary.cpp4
-rw-r--r--src/libs/utils/camelcasecursor.cpp341
-rw-r--r--src/libs/utils/camelcasecursor.h45
-rw-r--r--src/libs/utils/changeset.cpp10
-rw-r--r--src/libs/utils/changeset.h2
-rw-r--r--src/libs/utils/consoleprocess.cpp840
-rw-r--r--src/libs/utils/consoleprocess.h45
-rw-r--r--src/libs/utils/consoleprocess_p.h80
-rw-r--r--src/libs/utils/consoleprocess_unix.cpp449
-rw-r--r--src/libs/utils/consoleprocess_win.cpp400
-rw-r--r--src/libs/utils/cpplanguage_details.h2
-rw-r--r--src/libs/utils/delegates.cpp12
-rw-r--r--src/libs/utils/detailsbutton.cpp58
-rw-r--r--src/libs/utils/detailsbutton.h18
-rw-r--r--src/libs/utils/displayname.cpp76
-rw-r--r--src/libs/utils/displayname.h (renamed from src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h)46
-rw-r--r--src/libs/utils/environment.cpp450
-rw-r--r--src/libs/utils/environment.h82
-rw-r--r--src/libs/utils/environmentdialog.cpp152
-rw-r--r--src/libs/utils/environmentdialog.h30
-rw-r--r--src/libs/utils/environmentfwd.h51
-rw-r--r--src/libs/utils/environmentmodel.cpp354
-rw-r--r--src/libs/utils/environmentmodel.h44
-rw-r--r--src/libs/utils/fadingindicator.cpp4
-rw-r--r--src/libs/utils/fancylineedit.cpp69
-rw-r--r--src/libs/utils/fancylineedit.h7
-rw-r--r--src/libs/utils/fancymainwindow.cpp9
-rw-r--r--src/libs/utils/fileutils.cpp54
-rw-r--r--src/libs/utils/fileutils.h28
-rw-r--r--src/libs/utils/flowlayout.cpp4
-rw-r--r--src/libs/utils/fuzzymatcher.cpp19
-rw-r--r--src/libs/utils/fuzzymatcher.h2
-rw-r--r--src/libs/utils/images/download_arrow.pngbin0 -> 150 bytes
-rw-r--r--src/libs/utils/images/download_arrow@2x.pngbin0 -> 181 bytes
-rw-r--r--src/libs/utils/images/download_base.pngbin0 -> 96 bytes
-rw-r--r--src/libs/utils/images/download_base@2x.pngbin0 -> 104 bytes
-rw-r--r--src/libs/utils/images/online.pngbin0 -> 214 bytes
-rw-r--r--src/libs/utils/images/online@2x.pngbin0 -> 440 bytes
-rw-r--r--src/libs/utils/images/run_file.png (renamed from src/plugins/autotest/images/run_file.png)bin102 -> 102 bytes
-rw-r--r--src/libs/utils/images/run_file@2x.png (renamed from src/plugins/autotest/images/run_file@2x.png)bin132 -> 132 bytes
-rw-r--r--src/libs/utils/images/runselected_boxes.png (renamed from src/plugins/autotest/images/runselected_boxes.png)bin99 -> 99 bytes
-rw-r--r--src/libs/utils/images/runselected_boxes@2x.png (renamed from src/plugins/autotest/images/runselected_boxes@2x.png)bin104 -> 104 bytes
-rw-r--r--src/libs/utils/images/runselected_tickmarks.png (renamed from src/plugins/autotest/images/runselected_tickmarks.png)bin151 -> 151 bytes
-rw-r--r--src/libs/utils/images/runselected_tickmarks@2x.png (renamed from src/plugins/autotest/images/runselected_tickmarks@2x.png)bin162 -> 162 bytes
-rw-r--r--src/libs/utils/listmodel.h6
-rw-r--r--src/libs/utils/macroexpander.cpp5
-rw-r--r--src/libs/utils/mimetypes/mimeglobpattern.cpp7
-rw-r--r--src/libs/utils/mimetypes/mimeglobpattern_p.h9
-rw-r--r--src/libs/utils/mimetypes/mimeprovider.cpp14
-rw-r--r--src/libs/utils/namevaluedictionary.cpp202
-rw-r--r--src/libs/utils/namevaluedictionary.h105
-rw-r--r--src/libs/utils/namevalueitem.cpp213
-rw-r--r--src/libs/utils/namevalueitem.h80
-rw-r--r--src/libs/utils/namevaluemodel.cpp437
-rw-r--r--src/libs/utils/namevaluemodel.h85
-rw-r--r--src/libs/utils/namevaluesdialog.cpp147
-rw-r--r--src/libs/utils/namevaluesdialog.h86
-rw-r--r--src/libs/utils/namevaluevalidator.cpp72
-rw-r--r--src/libs/utils/namevaluevalidator.h58
-rw-r--r--src/libs/utils/osspecificaspects.h5
-rw-r--r--src/libs/utils/outputformatter.cpp2
-rw-r--r--src/libs/utils/pathchooser.cpp13
-rw-r--r--src/libs/utils/pathlisteditor.cpp2
-rw-r--r--src/libs/utils/process_ctrlc_stub.cpp16
-rw-r--r--src/libs/utils/qrcparser.cpp18
-rw-r--r--src/libs/utils/qrcparser.h8
-rw-r--r--src/libs/utils/qtcprocess.cpp38
-rw-r--r--src/libs/utils/qtcprocess.h4
-rw-r--r--src/libs/utils/savefile.cpp18
-rw-r--r--src/libs/utils/settingsaccessor.cpp15
-rw-r--r--src/libs/utils/shellcommand.cpp55
-rw-r--r--src/libs/utils/shellcommand.h21
-rw-r--r--src/libs/utils/smallstring.h10
-rw-r--r--src/libs/utils/smallstringio.h4
-rw-r--r--src/libs/utils/smallstringvector.h11
-rw-r--r--src/libs/utils/stringutils.cpp8
-rw-r--r--src/libs/utils/synchronousprocess.cpp27
-rw-r--r--src/libs/utils/synchronousprocess.h9
-rw-r--r--src/libs/utils/textutils.cpp27
-rw-r--r--src/libs/utils/textutils.h3
-rw-r--r--src/libs/utils/tooltip/tips.cpp2
-rw-r--r--src/libs/utils/treemodel.cpp16
-rw-r--r--src/libs/utils/treeviewcombobox.cpp4
-rw-r--r--src/libs/utils/utils-lib.pri24
-rw-r--r--src/libs/utils/utils.qbs35
-rw-r--r--src/libs/utils/utils.qrc12
-rw-r--r--src/libs/utils/utilsicons.cpp5
-rw-r--r--src/libs/utils/utilsicons.h2
-rw-r--r--src/libs/utils/winutils.cpp8
-rw-r--r--src/libs/utils/wizard.cpp2
-rw-r--r--src/plugins/CMakeLists.txt5
-rw-r--r--src/plugins/android/CMakeLists.txt1
-rw-r--r--src/plugins/android/android.pro2
-rw-r--r--src/plugins/android/android.qbs2
-rw-r--r--src/plugins/android/android.qrc1
-rw-r--r--src/plugins/android/androidavdmanager.cpp16
-rw-r--r--src/plugins/android/androidbuildapkstep.cpp82
-rw-r--r--src/plugins/android/androidbuildapkstep.h6
-rw-r--r--src/plugins/android/androidbuildapkwidget.cpp7
-rw-r--r--src/plugins/android/androidconfigurations.cpp135
-rw-r--r--src/plugins/android/androidconfigurations.h17
-rw-r--r--src/plugins/android/androidconstants.h12
-rw-r--r--src/plugins/android/androidcreatekeystorecertificate.cpp29
-rw-r--r--src/plugins/android/androiddebugsupport.cpp47
-rw-r--r--src/plugins/android/androiddeployqtstep.cpp61
-rw-r--r--src/plugins/android/androiddeployqtstep.h4
-rw-r--r--src/plugins/android/androiddevice.cpp16
-rw-r--r--src/plugins/android/androiddevice.h4
-rw-r--r--src/plugins/android/androiddevicedialog.cpp26
-rw-r--r--src/plugins/android/androiddevicedialog.h4
-rw-r--r--src/plugins/android/androiderrormessage.cpp2
-rw-r--r--src/plugins/android/androidextralibrarylistmodel.cpp8
-rw-r--r--src/plugins/android/androidgdbserverkitinformation.cpp217
-rw-r--r--src/plugins/android/androidmanager.cpp180
-rw-r--r--src/plugins/android/androidmanager.h19
-rw-r--r--src/plugins/android/androidmanifesteditorwidget.cpp2
-rw-r--r--src/plugins/android/androidpackageinstallationstep.cpp11
-rw-r--r--src/plugins/android/androidpackageinstallationstep.h2
-rw-r--r--src/plugins/android/androidplugin.cpp59
-rw-r--r--src/plugins/android/androidpotentialkit.cpp2
-rw-r--r--src/plugins/android/androidqmltoolingsupport.cpp8
-rw-r--r--src/plugins/android/androidqtversion.cpp55
-rw-r--r--src/plugins/android/androidqtversion.h4
-rw-r--r--src/plugins/android/androidrunconfiguration.cpp2
-rw-r--r--src/plugins/android/androidrunner.cpp6
-rw-r--r--src/plugins/android/androidrunnerworker.cpp8
-rw-r--r--src/plugins/android/androidrunnerworker.h2
-rw-r--r--src/plugins/android/androidsdkmanager.cpp18
-rw-r--r--src/plugins/android/androidsdkmanager.h2
-rw-r--r--src/plugins/android/androidsettingspage.cpp3
-rw-r--r--src/plugins/android/androidsettingspage.h2
-rw-r--r--src/plugins/android/androidsettingswidget.cpp21
-rw-r--r--src/plugins/android/androidsettingswidget.ui12
-rw-r--r--src/plugins/android/androidsignaloperation.cpp4
-rw-r--r--src/plugins/android/androidtoolchain.cpp44
-rw-r--r--src/plugins/android/androidtoolchain.h8
-rw-r--r--src/plugins/android/androidtoolmanager.cpp6
-rw-r--r--src/plugins/android/avddialog.cpp10
-rw-r--r--src/plugins/android/avddialog.h4
-rw-r--r--src/plugins/android/images/download.pngbin262 -> 0 bytes
-rw-r--r--src/plugins/autotest/CMakeLists.txt2
-rw-r--r--src/plugins/autotest/autotest.pro73
-rw-r--r--src/plugins/autotest/autotest.qbs4
-rw-r--r--src/plugins/autotest/autotest.qrc6
-rw-r--r--src/plugins/autotest/autotestconstants.h7
-rw-r--r--src/plugins/autotest/autotesticons.h8
-rw-r--r--src/plugins/autotest/autotestplugin.cpp143
-rw-r--r--src/plugins/autotest/autotestplugin.h23
-rw-r--r--src/plugins/autotest/autotestunittests.h3
-rw-r--r--src/plugins/autotest/boost/boostcodeparser.cpp2
-rw-r--r--src/plugins/autotest/boost/boostcodeparser.h2
-rw-r--r--src/plugins/autotest/boost/boosttestoutputreader.h1
-rw-r--r--src/plugins/autotest/boost/boosttestsettingspage.h4
-rw-r--r--src/plugins/autotest/boost/boosttesttreeitem.h2
-rw-r--r--src/plugins/autotest/gtest/gtestoutputreader.h1
-rw-r--r--src/plugins/autotest/gtest/gtestsettingspage.cpp3
-rw-r--r--src/plugins/autotest/gtest/gtestsettingspage.h7
-rw-r--r--src/plugins/autotest/gtest/gtesttreeitem.cpp2
-rw-r--r--src/plugins/autotest/gtest/gtestvisitors.cpp4
-rw-r--r--src/plugins/autotest/iframeworksettings.h2
-rw-r--r--src/plugins/autotest/itestframework.h4
-rw-r--r--src/plugins/autotest/itestparser.cpp6
-rw-r--r--src/plugins/autotest/itestparser.h8
-rw-r--r--src/plugins/autotest/itestsettingspage.h2
-rw-r--r--src/plugins/autotest/projectsettingswidget.cpp129
-rw-r--r--src/plugins/autotest/projectsettingswidget.h (renamed from src/plugins/qmakeprojectmanager/wizards/modulespage.h)45
-rw-r--r--src/plugins/autotest/qtest/qttestparser.cpp8
-rw-r--r--src/plugins/autotest/qtest/qttestsettingspage.cpp3
-rw-r--r--src/plugins/autotest/qtest/qttestsettingspage.h7
-rw-r--r--src/plugins/autotest/qtest/qttestvisitors.cpp66
-rw-r--r--src/plugins/autotest/quick/quicktestparser.cpp50
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.cpp4
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.h2
-rw-r--r--src/plugins/autotest/testcodeparser.cpp88
-rw-r--r--src/plugins/autotest/testcodeparser.h12
-rw-r--r--src/plugins/autotest/testconfiguration.cpp35
-rw-r--r--src/plugins/autotest/testconfiguration.h9
-rw-r--r--src/plugins/autotest/testframeworkmanager.cpp55
-rw-r--r--src/plugins/autotest/testframeworkmanager.h22
-rw-r--r--src/plugins/autotest/testnavigationwidget.cpp2
-rw-r--r--src/plugins/autotest/testnavigationwidget.h4
-rw-r--r--src/plugins/autotest/testoutputreader.cpp2
-rw-r--r--src/plugins/autotest/testoutputreader.h2
-rw-r--r--src/plugins/autotest/testprojectsettings.cpp107
-rw-r--r--src/plugins/autotest/testprojectsettings.h61
-rw-r--r--src/plugins/autotest/testresult.cpp2
-rw-r--r--src/plugins/autotest/testresult.h6
-rw-r--r--src/plugins/autotest/testresultspane.cpp30
-rw-r--r--src/plugins/autotest/testresultspane.h4
-rw-r--r--src/plugins/autotest/testrunconfiguration.h2
-rw-r--r--src/plugins/autotest/testrunner.cpp131
-rw-r--r--src/plugins/autotest/testrunner.h6
-rw-r--r--src/plugins/autotest/testsettings.cpp4
-rw-r--r--src/plugins/autotest/testsettings.h8
-rw-r--r--src/plugins/autotest/testsettingspage.cpp8
-rw-r--r--src/plugins/autotest/testsettingspage.ui46
-rw-r--r--src/plugins/autotest/testtreeitem.cpp6
-rw-r--r--src/plugins/autotest/testtreeitem.h24
-rw-r--r--src/plugins/autotest/testtreemodel.cpp50
-rw-r--r--src/plugins/autotest/testtreemodel.h16
-rw-r--r--src/plugins/autotoolsprojectmanager/CMakeLists.txt2
-rw-r--r--src/plugins/autotoolsprojectmanager/autogenstep.cpp69
-rw-r--r--src/plugins/autotoolsprojectmanager/autogenstep.h2
-rw-r--r--src/plugins/autotoolsprojectmanager/autoreconfstep.cpp64
-rw-r--r--src/plugins/autotoolsprojectmanager/autoreconfstep.h1
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp70
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h13
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp (renamed from src/plugins/autotoolsprojectmanager/autotoolsproject.cpp)180
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h (renamed from src/plugins/autotoolsprojectmanager/autotoolsproject.h)47
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp3
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h12
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro8
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs4
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp24
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h16
-rw-r--r--src/plugins/autotoolsprojectmanager/configurestep.cpp89
-rw-r--r--src/plugins/autotoolsprojectmanager/configurestep.h6
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparser.cpp7
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparserthread.cpp10
-rw-r--r--src/plugins/autotoolsprojectmanager/makefileparserthread.h6
-rw-r--r--src/plugins/autotoolsprojectmanager/makestep.cpp7
-rw-r--r--src/plugins/baremetal/CMakeLists.txt1
-rw-r--r--src/plugins/baremetal/baremetal.pro2
-rw-r--r--src/plugins/baremetal/baremetal.qbs1
-rw-r--r--src/plugins/baremetal/baremetaldebugsupport.cpp46
-rw-r--r--src/plugins/baremetal/baremetaldebugsupport.h2
-rw-r--r--src/plugins/baremetal/baremetaldevice.cpp27
-rw-r--r--src/plugins/baremetal/baremetaldevice.h6
-rw-r--r--src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp25
-rw-r--r--src/plugins/baremetal/baremetaldeviceconfigurationwidget.h7
-rw-r--r--src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp7
-rw-r--r--src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h2
-rw-r--r--src/plugins/baremetal/baremetalplugin.cpp19
-rw-r--r--src/plugins/baremetal/defaultgdbserverprovider.cpp87
-rw-r--r--src/plugins/baremetal/defaultgdbserverprovider.h21
-rw-r--r--src/plugins/baremetal/gdbserverprovider.cpp73
-rw-r--r--src/plugins/baremetal/gdbserverprovider.h20
-rw-r--r--src/plugins/baremetal/gdbserverproviderchooser.cpp2
-rw-r--r--src/plugins/baremetal/gdbserverproviderssettingspage.cpp3
-rw-r--r--src/plugins/baremetal/gdbserverproviderssettingspage.h2
-rw-r--r--src/plugins/baremetal/iarewtoolchain.cpp59
-rw-r--r--src/plugins/baremetal/iarewtoolchain.h7
-rw-r--r--src/plugins/baremetal/keiltoolchain.cpp28
-rw-r--r--src/plugins/baremetal/keiltoolchain.h8
-rw-r--r--src/plugins/baremetal/openocdgdbserverprovider.cpp39
-rw-r--r--src/plugins/baremetal/openocdgdbserverprovider.h7
-rw-r--r--src/plugins/baremetal/sdcctoolchain.cpp98
-rw-r--r--src/plugins/baremetal/sdcctoolchain.h8
-rw-r--r--src/plugins/baremetal/stlinkutilgdbserverprovider.cpp36
-rw-r--r--src/plugins/baremetal/stlinkutilgdbserverprovider.h5
-rw-r--r--src/plugins/bazaar/bazaarclient.cpp2
-rw-r--r--src/plugins/bazaar/bazaarcontrol.cpp2
-rw-r--r--src/plugins/bazaar/bazaarplugin.cpp4
-rw-r--r--src/plugins/beautifier/abstractsettings.cpp4
-rw-r--r--src/plugins/beautifier/abstractsettings.h3
-rw-r--r--src/plugins/beautifier/artisticstyle/artisticstyle.cpp12
-rw-r--r--src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp9
-rw-r--r--src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.h3
-rw-r--r--src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp8
-rw-r--r--src/plugins/beautifier/beautifierplugin.cpp10
-rw-r--r--src/plugins/beautifier/clangformat/clangformat.cpp2
-rw-r--r--src/plugins/beautifier/clangformat/clangformatoptionspage.cpp2
-rw-r--r--src/plugins/beautifier/configurationdialog.cpp2
-rw-r--r--src/plugins/beautifier/generaloptionspage.cpp3
-rw-r--r--src/plugins/beautifier/generaloptionspage.h2
-rw-r--r--src/plugins/beautifier/uncrustify/uncrustify.cpp10
-rw-r--r--src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp2
-rw-r--r--src/plugins/beautifier/uncrustify/uncrustifysettings.cpp4
-rw-r--r--src/plugins/bineditor/bineditorplugin.cpp1
-rw-r--r--src/plugins/bineditor/bineditorwidget.cpp2
-rw-r--r--src/plugins/bookmarks/bookmarkfilter.cpp10
-rw-r--r--src/plugins/boot2qt/Boot2Qt.json.in22
-rw-r--r--src/plugins/boot2qt/CMakeLists.txt31
-rw-r--r--src/plugins/boot2qt/boot2qt.pro40
-rw-r--r--src/plugins/boot2qt/boot2qt.qbs65
-rw-r--r--src/plugins/boot2qt/boot2qt_dependencies.pri8
-rw-r--r--src/plugins/boot2qt/device-detection/device-detection.pri13
-rw-r--r--src/plugins/boot2qt/device-detection/devicedetector.cpp149
-rw-r--r--src/plugins/boot2qt/device-detection/devicedetector.h (renamed from src/plugins/clangtools/clangtidyclazyruncontrol.h)36
-rw-r--r--src/plugins/boot2qt/device-detection/hostmessages.cpp147
-rw-r--r--src/plugins/boot2qt/device-detection/hostmessages.h65
-rw-r--r--src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp87
-rw-r--r--src/plugins/boot2qt/device-detection/qdbdevicetracker.h61
-rw-r--r--src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp88
-rw-r--r--src/plugins/boot2qt/device-detection/qdbmessagetracker.h55
-rw-r--r--src/plugins/boot2qt/device-detection/qdbwatcher.cpp165
-rw-r--r--src/plugins/boot2qt/device-detection/qdbwatcher.h76
-rw-r--r--src/plugins/boot2qt/images/qdbdevice.pngbin0 -> 378 bytes
-rw-r--r--src/plugins/boot2qt/images/qdbdevice@2x.pngbin0 -> 706 bytes
-rw-r--r--src/plugins/boot2qt/images/qdbdevicesmall.pngbin0 -> 260 bytes
-rw-r--r--src/plugins/boot2qt/images/qdbdevicesmall@2x.pngbin0 -> 442 bytes
-rw-r--r--src/plugins/boot2qt/qdb.qrc8
-rw-r--r--src/plugins/boot2qt/qdb_global.h34
-rw-r--r--src/plugins/boot2qt/qdbconstants.h47
-rw-r--r--src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp (renamed from src/plugins/android/androidgdbserverkitinformation.h)47
-rw-r--r--src/plugins/boot2qt/qdbdeployconfigurationfactory.h40
-rw-r--r--src/plugins/boot2qt/qdbdeploystepfactory.cpp (renamed from src/plugins/cpptools/cppkitinfo.cpp)48
-rw-r--r--src/plugins/boot2qt/qdbdeploystepfactory.h46
-rw-r--r--src/plugins/boot2qt/qdbdevice.cpp302
-rw-r--r--src/plugins/boot2qt/qdbdevice.h72
-rw-r--r--src/plugins/boot2qt/qdbdevicedebugsupport.cpp216
-rw-r--r--src/plugins/boot2qt/qdbdevicedebugsupport.h70
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappservice.cpp126
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappservice.h (renamed from src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h)40
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappstep.cpp66
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappstep.h45
-rw-r--r--src/plugins/boot2qt/qdbplugin.cpp256
-rw-r--r--src/plugins/boot2qt/qdbplugin.h51
-rw-r--r--src/plugins/boot2qt/qdbqtversion.cpp (renamed from src/plugins/clangtools/clangtoolsbasicsettings.cpp)27
-rw-r--r--src/plugins/boot2qt/qdbqtversion.h44
-rw-r--r--src/plugins/boot2qt/qdbrunconfiguration.cpp137
-rw-r--r--src/plugins/boot2qt/qdbrunconfiguration.h (renamed from src/plugins/qbsprojectmanager/qbsrunconfiguration.h)36
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationservice.cpp123
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationservice.h60
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationstep.cpp55
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationstep.h44
-rw-r--r--src/plugins/boot2qt/qdbutils.cpp112
-rw-r--r--src/plugins/boot2qt/qdbutils.h47
-rw-r--r--src/plugins/clangcodemodel/clangassistproposalmodel.cpp6
-rw-r--r--src/plugins/clangcodemodel/clangbackendreceiver.cpp21
-rw-r--r--src/plugins/clangcodemodel/clangcodemodelplugin.cpp9
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp2
-rw-r--r--src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp2
-rw-r--r--src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp1
-rw-r--r--src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp1
-rw-r--r--src/plugins/clangcodemodel/clangfixitoperation.cpp5
-rw-r--r--src/plugins/clangcodemodel/clangfixitoperationsextractor.cpp2
-rw-r--r--src/plugins/clangcodemodel/clangfollowsymbol.cpp4
-rw-r--r--src/plugins/clangcodemodel/clanghighlightingresultreporter.h2
-rw-r--r--src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h12
-rw-r--r--src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp2
-rw-r--r--src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp2
-rw-r--r--src/plugins/clangformat/clangformatplugin.cpp6
-rw-r--r--src/plugins/clangpchmanager/CMakeLists.txt5
-rw-r--r--src/plugins/clangpchmanager/clangindexingprojectsettings.cpp96
-rw-r--r--src/plugins/clangpchmanager/clangindexingprojectsettings.h50
-rw-r--r--src/plugins/clangpchmanager/clangindexingprojectsettingswidget.cpp74
-rw-r--r--src/plugins/clangpchmanager/clangindexingprojectsettingswidget.h66
-rw-r--r--src/plugins/clangpchmanager/clangindexingprojectsettingswidget.ui75
-rw-r--r--src/plugins/clangpchmanager/clangindexingsettingsmanager.cpp55
-rw-r--r--src/plugins/clangpchmanager/clangindexingsettingsmanager.h (renamed from src/plugins/projectexplorer/deploymentdatamodel.h)37
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager-source.pri6
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager.pro7
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager.qbs11
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.cpp46
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.h2
-rw-r--r--src/plugins/clangpchmanager/pchmanagerprojectupdater.h5
-rw-r--r--src/plugins/clangpchmanager/preprocessormacrocollector.cpp68
-rw-r--r--src/plugins/clangpchmanager/preprocessormacrocollector.h51
-rw-r--r--src/plugins/clangpchmanager/preprocessormacrowidget.cpp282
-rw-r--r--src/plugins/clangpchmanager/preprocessormacrowidget.h79
-rw-r--r--src/plugins/clangpchmanager/projectupdater.cpp141
-rw-r--r--src/plugins/clangpchmanager/projectupdater.h39
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp17
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.h30
-rw-r--r--src/plugins/clangrefactoring/clangqueryhoverhandler.cpp4
-rw-r--r--src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp14
-rw-r--r--src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h2
-rw-r--r--src/plugins/clangrefactoring/clangrefactoringplugin.cpp17
-rw-r--r--src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp10
-rw-r--r--src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h2
-rw-r--r--src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.cpp30
-rw-r--r--src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.h10
-rw-r--r--src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp2
-rw-r--r--src/plugins/clangrefactoring/querysqlitestatementfactory.h15
-rw-r--r--src/plugins/clangrefactoring/refactoringengine.cpp38
-rw-r--r--src/plugins/clangrefactoring/refactoringengine.h1
-rw-r--r--src/plugins/clangrefactoring/refactoringprojectupdater.h5
-rw-r--r--src/plugins/clangrefactoring/symbolquery.h30
-rw-r--r--src/plugins/clangrefactoring/symbolqueryinterface.h7
-rw-r--r--src/plugins/clangtools/CMakeLists.txt10
-rw-r--r--src/plugins/clangtools/clangselectablefilesdialog.cpp54
-rw-r--r--src/plugins/clangtools/clangselectablefilesdialog.h1
-rw-r--r--src/plugins/clangtools/clangselectablefilesdialog.ui8
-rw-r--r--src/plugins/clangtools/clangtidyclazyruncontrol.cpp71
-rw-r--r--src/plugins/clangtools/clangtidyclazyrunner.cpp136
-rw-r--r--src/plugins/clangtools/clangtidyclazyrunner.h26
-rw-r--r--src/plugins/clangtools/clangtidyclazytool.cpp128
-rw-r--r--src/plugins/clangtools/clangtidyclazytool.h15
-rw-r--r--src/plugins/clangtools/clangtool.cpp50
-rw-r--r--src/plugins/clangtools/clangtool.h26
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.cpp258
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.h45
-rw-r--r--src/plugins/clangtools/clangtoolrunner.cpp96
-rw-r--r--src/plugins/clangtools/clangtoolrunner.h60
-rw-r--r--src/plugins/clangtools/clangtools.pro22
-rw-r--r--src/plugins/clangtools/clangtools.qbs12
-rw-r--r--src/plugins/clangtools/clangtools_dependencies.pri4
-rw-r--r--src/plugins/clangtools/clangtools_global.h2
-rw-r--r--src/plugins/clangtools/clangtoolsbasicsettings.ui47
-rw-r--r--src/plugins/clangtools/clangtoolsconfigwidget.cpp89
-rw-r--r--src/plugins/clangtools/clangtoolsconstants.h6
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnostic.cpp20
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnostic.h8
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp19
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.h2
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticview.cpp3
-rw-r--r--src/plugins/clangtools/clangtoolslogfilereader.cpp276
-rw-r--r--src/plugins/clangtools/clangtoolslogfilereader.h33
-rw-r--r--src/plugins/clangtools/clangtoolsplugin.cpp20
-rw-r--r--src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp2
-rw-r--r--src/plugins/clangtools/clangtoolsprojectsettings.cpp28
-rw-r--r--src/plugins/clangtools/clangtoolsprojectsettings.h17
-rw-r--r--src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp9
-rw-r--r--src/plugins/clangtools/clangtoolssettings.cpp41
-rw-r--r--src/plugins/clangtools/clangtoolssettings.h13
-rw-r--r--src/plugins/clangtools/clangtoolsunittestfiles.pri13
-rw-r--r--src/plugins/clangtools/clangtoolsunittests.cpp2
-rw-r--r--src/plugins/clangtools/clangtoolsutils.cpp84
-rw-r--r--src/plugins/clangtools/clangtoolsutils.h8
-rw-r--r--src/plugins/clangtools/settingswidget.cpp156
-rw-r--r--src/plugins/clangtools/settingswidget.h (renamed from src/plugins/clangtools/clangtoolsconfigwidget.h)12
-rw-r--r--src/plugins/clangtools/settingswidget.ui (renamed from src/plugins/clangtools/clangtoolsconfigwidget.ui)54
-rw-r--r--src/plugins/classview/classviewparser.cpp4
-rw-r--r--src/plugins/clearcase/clearcasecontrol.cpp2
-rw-r--r--src/plugins/clearcase/clearcaseplugin.cpp13
-rw-r--r--src/plugins/cmakeprojectmanager/CMakeLists.txt7
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.cpp246
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.h59
-rw-r--r--src/plugins/cmakeprojectmanager/builddirreader.cpp22
-rw-r--r--src/plugins/cmakeprojectmanager/builddirreader.h22
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp286
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h28
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp10
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.cpp63
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.h11
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp380
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildsystem.h89
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildtarget.h21
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp24
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeconfigitem.h5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeeditor.cpp24
-rw-r--r--src/plugins/cmakeprojectmanager/cmakekitinformation.cpp10
-rw-r--r--src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp129
-rw-r--r--src/plugins/cmakeprojectmanager/cmakelocatorfilter.h36
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeparser.cpp16
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeparser.h3
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprocess.cpp258
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprocess.h81
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp510
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.h48
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp54
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp7
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro14
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs14
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp13
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.h4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp121
-rw-r--r--src/plugins/cmakeprojectmanager/cmakesettingspage.cpp120
-rw-r--r--src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp3
-rw-r--r--src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h3
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketool.cpp175
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketool.h18
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp14
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketoolmanager.h1
-rw-r--r--src/plugins/cmakeprojectmanager/cmaketoolsettingsaccessor.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/configmodel.cpp13
-rw-r--r--src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/fileapidataextractor.cpp617
-rw-r--r--src/plugins/cmakeprojectmanager/fileapidataextractor.h (renamed from src/plugins/cmakeprojectmanager/cmakerunconfiguration.h)39
-rw-r--r--src/plugins/cmakeprojectmanager/fileapiparser.cpp956
-rw-r--r--src/plugins/cmakeprojectmanager/fileapiparser.h275
-rw-r--r--src/plugins/cmakeprojectmanager/fileapireader.cpp301
-rw-r--r--src/plugins/cmakeprojectmanager/fileapireader.h97
-rw-r--r--src/plugins/cmakeprojectmanager/projecttreehelper.cpp211
-rw-r--r--src/plugins/cmakeprojectmanager/projecttreehelper.h74
-rw-r--r--src/plugins/cmakeprojectmanager/servermode.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.cpp421
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.h35
-rw-r--r--src/plugins/cmakeprojectmanager/tealeafreader.cpp283
-rw-r--r--src/plugins/cmakeprojectmanager/tealeafreader.h29
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp112
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h13
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp4
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp19
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h17
-rw-r--r--src/plugins/coreplugin/CMakeLists.txt1
-rw-r--r--src/plugins/coreplugin/actionmanager/actioncontainer.cpp16
-rw-r--r--src/plugins/coreplugin/actionmanager/command.cpp13
-rw-r--r--src/plugins/coreplugin/coreplugin.cpp47
-rw-r--r--src/plugins/coreplugin/coreplugin.h1
-rw-r--r--src/plugins/coreplugin/dialogs/externaltoolconfig.cpp42
-rw-r--r--src/plugins/coreplugin/dialogs/externaltoolconfig.h10
-rw-r--r--src/plugins/coreplugin/dialogs/settingsdialog.cpp2
-rw-r--r--src/plugins/coreplugin/dialogs/shortcutsettings.cpp3
-rw-r--r--src/plugins/coreplugin/dialogs/shortcutsettings.h2
-rw-r--r--src/plugins/coreplugin/documentmanager.cpp38
-rw-r--r--src/plugins/coreplugin/editmode.cpp2
-rw-r--r--src/plugins/coreplugin/editormanager/documentmodel.cpp3
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.cpp20
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager_p.h3
-rw-r--r--src/plugins/coreplugin/editormanager/editorview.cpp2
-rw-r--r--src/plugins/coreplugin/editormanager/editorwindow.cpp2
-rw-r--r--src/plugins/coreplugin/editormanager/openeditorswindow.cpp2
-rw-r--r--src/plugins/coreplugin/editortoolbar.cpp4
-rw-r--r--src/plugins/coreplugin/externaltool.cpp22
-rw-r--r--src/plugins/coreplugin/externaltool.h6
-rw-r--r--src/plugins/coreplugin/externaltoolmanager.cpp22
-rw-r--r--src/plugins/coreplugin/fancyactionbar.cpp2
-rw-r--r--src/plugins/coreplugin/fancytabwidget.cpp20
-rw-r--r--src/plugins/coreplugin/fancytabwidget.h5
-rw-r--r--src/plugins/coreplugin/find/findtoolwindow.cpp2
-rw-r--r--src/plugins/coreplugin/find/itemviewfind.cpp2
-rw-r--r--src/plugins/coreplugin/find/searchresulttreemodel.cpp2
-rw-r--r--src/plugins/coreplugin/find/searchresultwidget.cpp12
-rw-r--r--src/plugins/coreplugin/findplaceholder.cpp2
-rw-r--r--src/plugins/coreplugin/generalsettings.cpp33
-rw-r--r--src/plugins/coreplugin/generalsettings.h5
-rw-r--r--src/plugins/coreplugin/generalsettings.ui87
-rw-r--r--src/plugins/coreplugin/helpitem.cpp5
-rw-r--r--src/plugins/coreplugin/icore.cpp26
-rw-r--r--src/plugins/coreplugin/icore.h7
-rw-r--r--src/plugins/coreplugin/infobar.cpp22
-rw-r--r--src/plugins/coreplugin/infobar.h15
-rw-r--r--src/plugins/coreplugin/iversioncontrol.cpp57
-rw-r--r--src/plugins/coreplugin/iversioncontrol.h15
-rw-r--r--src/plugins/coreplugin/iwelcomepage.cpp21
-rw-r--r--src/plugins/coreplugin/locator/basefilefilter.cpp95
-rw-r--r--src/plugins/coreplugin/locator/basefilefilter.h23
-rw-r--r--src/plugins/coreplugin/locator/directoryfilter.cpp10
-rw-r--r--src/plugins/coreplugin/locator/directoryfilter.h2
-rw-r--r--src/plugins/coreplugin/locator/executefilter.cpp2
-rw-r--r--src/plugins/coreplugin/locator/filesystemfilter.cpp77
-rw-r--r--src/plugins/coreplugin/locator/filesystemfilter.h2
-rw-r--r--src/plugins/coreplugin/locator/ilocatorfilter.cpp4
-rw-r--r--src/plugins/coreplugin/locator/ilocatorfilter.h11
-rw-r--r--src/plugins/coreplugin/locator/javascriptfilter.cpp12
-rw-r--r--src/plugins/coreplugin/locator/locator_test.cpp4
-rw-r--r--src/plugins/coreplugin/locator/locatorfiltertest.cpp27
-rw-r--r--src/plugins/coreplugin/locator/locatorfiltertest.h8
-rw-r--r--src/plugins/coreplugin/locator/locatorsettingspage.cpp4
-rw-r--r--src/plugins/coreplugin/locator/locatorwidget.cpp2
-rw-r--r--src/plugins/coreplugin/locator/spotlightlocatorfilter.mm31
-rw-r--r--src/plugins/coreplugin/mainwindow.cpp7
-rw-r--r--src/plugins/coreplugin/mainwindow.h2
-rw-r--r--src/plugins/coreplugin/manhattanstyle.cpp6
-rw-r--r--src/plugins/coreplugin/menubarfilter.cpp14
-rw-r--r--src/plugins/coreplugin/mimetypesettings.cpp6
-rw-r--r--src/plugins/coreplugin/mimetypesettings.h2
-rw-r--r--src/plugins/coreplugin/minisplitter.cpp4
-rw-r--r--src/plugins/coreplugin/minisplitter.h2
-rw-r--r--src/plugins/coreplugin/navigationsubwidget.cpp4
-rw-r--r--src/plugins/coreplugin/navigationwidget.cpp4
-rw-r--r--src/plugins/coreplugin/outputpane.cpp2
-rw-r--r--src/plugins/coreplugin/outputpanemanager.cpp6
-rw-r--r--src/plugins/coreplugin/progressmanager/futureprogress.cpp2
-rw-r--r--src/plugins/coreplugin/progressmanager/progressmanager.cpp4
-rw-r--r--src/plugins/coreplugin/rightpane.cpp4
-rw-r--r--src/plugins/coreplugin/settingsdatabase.cpp5
-rw-r--r--src/plugins/coreplugin/sidebar.cpp11
-rw-r--r--src/plugins/coreplugin/sidebarwidget.cpp2
-rw-r--r--src/plugins/coreplugin/statusbarmanager.cpp2
-rw-r--r--src/plugins/coreplugin/systemsettings.cpp4
-rw-r--r--src/plugins/coreplugin/systemsettings.ui279
-rw-r--r--src/plugins/coreplugin/textdocument.cpp10
-rw-r--r--src/plugins/coreplugin/textdocument.h2
-rw-r--r--src/plugins/coreplugin/themechooser.cpp2
-rw-r--r--src/plugins/coreplugin/toolsettings.cpp11
-rw-r--r--src/plugins/coreplugin/toolsettings.h2
-rw-r--r--src/plugins/coreplugin/variablechooser.cpp2
-rw-r--r--src/plugins/coreplugin/vcsmanager.cpp2
-rw-r--r--src/plugins/cpaster/columnindicatortextedit.cpp5
-rw-r--r--src/plugins/cpaster/fileshareprotocolsettingspage.cpp8
-rw-r--r--src/plugins/cpaster/fileshareprotocolsettingspage.h9
-rw-r--r--src/plugins/cpaster/pastebindotcomprotocol.cpp4
-rw-r--r--src/plugins/cpaster/pastecodedotxyzprotocol.cpp2
-rw-r--r--src/plugins/cpaster/stickynotespasteprotocol.cpp2
-rw-r--r--src/plugins/cppcheck/cppcheckplugin.cpp4
-rw-r--r--src/plugins/cppcheck/cppcheckrunner.cpp2
-rw-r--r--src/plugins/cppcheck/cppchecktool.cpp3
-rw-r--r--src/plugins/cppeditor/cppcodemodelinspectordialog.cpp11
-rw-r--r--src/plugins/cppeditor/cppeditordocument.cpp15
-rw-r--r--src/plugins/cppeditor/cppeditorwidget.cpp67
-rw-r--r--src/plugins/cppeditor/cppfunctiondecldeflink.cpp5
-rw-r--r--src/plugins/cppeditor/cppfunctiondecldeflink.h4
-rw-r--r--src/plugins/cppeditor/cpphighlighter.cpp4
-rw-r--r--src/plugins/cppeditor/cppincludehierarchy.cpp4
-rw-r--r--src/plugins/cppeditor/cppinsertvirtualmethods.cpp6
-rw-r--r--src/plugins/cppeditor/cppoutline.cpp2
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp24
-rw-r--r--src/plugins/cppeditor/cpptypehierarchy.cpp2
-rw-r--r--src/plugins/cppeditor/cppuseselections_test.cpp2
-rw-r--r--src/plugins/cppeditor/fileandtokenactions_test.cpp4
-rw-r--r--src/plugins/cppeditor/resourcepreviewhoverhandler.cpp16
-rw-r--r--src/plugins/cpptools/CMakeLists.txt4
-rw-r--r--src/plugins/cpptools/baseeditordocumentparser.cpp2
-rw-r--r--src/plugins/cpptools/builtincursorinfo.cpp41
-rw-r--r--src/plugins/cpptools/builtineditordocumentprocessor.cpp2
-rw-r--r--src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp4
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp2
-rw-r--r--src/plugins/cpptools/cppchecksymbols.cpp24
-rw-r--r--src/plugins/cpptools/cppchecksymbols.h4
-rw-r--r--src/plugins/cpptools/cppcodeformatter.cpp2
-rw-r--r--src/plugins/cpptools/cppcodegen_test.cpp182
-rw-r--r--src/plugins/cpptools/cppcodemodelinspectordumper.cpp32
-rw-r--r--src/plugins/cpptools/cppcodemodelinspectordumper.h5
-rw-r--r--src/plugins/cpptools/cppcodemodelsettingspage.cpp16
-rw-r--r--src/plugins/cpptools/cppcodemodelsettingspage.h5
-rw-r--r--src/plugins/cpptools/cppcodestylepreferencesfactory.cpp2
-rw-r--r--src/plugins/cpptools/cppcompletionassist.cpp22
-rw-r--r--src/plugins/cpptools/cppcompletionassist.h2
-rw-r--r--src/plugins/cpptools/cppcursorinfo.h8
-rw-r--r--src/plugins/cpptools/cppelementevaluator.cpp6
-rw-r--r--src/plugins/cpptools/cppelementevaluator.h4
-rw-r--r--src/plugins/cpptools/cppfilesettingspage.cpp8
-rw-r--r--src/plugins/cpptools/cppfilesettingspage.h5
-rw-r--r--src/plugins/cpptools/cppfollowsymbolundercursor.cpp19
-rw-r--r--src/plugins/cpptools/cpphoverhandler.cpp2
-rw-r--r--src/plugins/cpptools/cppincludesfilter.cpp34
-rw-r--r--src/plugins/cpptools/cpplocalsymbols.cpp8
-rw-r--r--src/plugins/cpptools/cpplocalsymbols_test.cpp4
-rw-r--r--src/plugins/cpptools/cpplocatordata.cpp19
-rw-r--r--src/plugins/cpptools/cpplocatorfilter.cpp35
-rw-r--r--src/plugins/cpptools/cpplocatorfilter_test.cpp379
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp102
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h3
-rw-r--r--src/plugins/cpptools/cppmodelmanager_test.cpp49
-rw-r--r--src/plugins/cpptools/cppoverviewmodel.cpp20
-rw-r--r--src/plugins/cpptools/cppoverviewmodel.h4
-rw-r--r--src/plugins/cpptools/cpppointerdeclarationformatter.cpp4
-rw-r--r--src/plugins/cpptools/cpppointerdeclarationformatter.h6
-rw-r--r--src/plugins/cpptools/cppprojectfile.cpp34
-rw-r--r--src/plugins/cpptools/cppprojectfile.h1
-rw-r--r--src/plugins/cpptools/cppprojectfilecategorizer.cpp16
-rw-r--r--src/plugins/cpptools/cppprojectfilecategorizer.h13
-rw-r--r--src/plugins/cpptools/cppprojectinfogenerator.cpp22
-rw-r--r--src/plugins/cpptools/cppprojectinfogenerator.h9
-rw-r--r--src/plugins/cpptools/cppprojectupdater.cpp12
-rw-r--r--src/plugins/cpptools/cppprojectupdater.h21
-rw-r--r--src/plugins/cpptools/cppprojectupdaterinterface.h41
-rw-r--r--src/plugins/cpptools/cpprawprojectpart.cpp140
-rw-r--r--src/plugins/cpptools/cpprawprojectpart.h109
-rw-r--r--src/plugins/cpptools/cpprefactoringchanges.cpp14
-rw-r--r--src/plugins/cpptools/cppselectionchanger.cpp20
-rw-r--r--src/plugins/cpptools/cppsemanticinfo.h1
-rw-r--r--src/plugins/cpptools/cppsourceprocessor.cpp22
-rw-r--r--src/plugins/cpptools/cppsourceprocessor.h22
-rw-r--r--src/plugins/cpptools/cppsourceprocessor_test.cpp10
-rw-r--r--src/plugins/cpptools/cpptools.pro10
-rw-r--r--src/plugins/cpptools/cpptools.qbs6
-rw-r--r--src/plugins/cpptools/cpptools.qrc6
-rw-r--r--src/plugins/cpptools/cpptoolsconstants.h1
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.cpp19
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.h2
-rw-r--r--src/plugins/cpptools/cpptoolstestcase.cpp2
-rw-r--r--src/plugins/cpptools/cppworkingcopy.h6
-rw-r--r--src/plugins/cpptools/doxygengenerator.cpp4
-rw-r--r--src/plugins/cpptools/headerpathfilter.cpp4
-rw-r--r--src/plugins/cpptools/includeutils.cpp2
-rw-r--r--src/plugins/cpptools/insertionpointlocator.cpp24
-rw-r--r--src/plugins/cpptools/insertionpointlocator.h10
-rw-r--r--src/plugins/cpptools/projectinfo.cpp37
-rw-r--r--src/plugins/cpptools/projectinfo.h45
-rw-r--r--src/plugins/cpptools/projectpart.cpp3
-rw-r--r--src/plugins/cpptools/projectpart.h19
-rw-r--r--src/plugins/cpptools/searchsymbols.cpp8
-rw-r--r--src/plugins/cpptools/symbolsfindfilter.cpp2
-rw-r--r--src/plugins/cpptools/typehierarchybuilder.cpp4
-rw-r--r--src/plugins/cpptools/usages.h6
-rw-r--r--src/plugins/ctfvisualizer/CMakeLists.txt22
-rw-r--r--src/plugins/ctfvisualizer/CtfVisualizer.json.in20
-rw-r--r--src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp189
-rw-r--r--src/plugins/ctfvisualizer/ctfstatisticsmodel.h84
-rw-r--r--src/plugins/ctfvisualizer/ctfstatisticsview.cpp84
-rw-r--r--src/plugins/ctfvisualizer/ctfstatisticsview.h52
-rw-r--r--src/plugins/ctfvisualizer/ctftimelinemodel.cpp383
-rw-r--r--src/plugins/ctfvisualizer/ctftimelinemodel.h115
-rw-r--r--src/plugins/ctfvisualizer/ctftracemanager.cpp256
-rw-r--r--src/plugins/ctfvisualizer/ctftracemanager.h92
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizer.pro34
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizer.qbs28
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizer_dependencies.pri9
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizerconstants.h58
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizerplugin.cpp58
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizerplugin.h49
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertool.cpp186
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertool.h83
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertraceview.cpp85
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertraceview.h (renamed from src/plugins/clangtools/clangtoolsbasicsettings.h)26
-rw-r--r--src/plugins/cvs/cvscontrol.cpp10
-rw-r--r--src/plugins/cvs/cvsplugin.cpp2
-rw-r--r--src/plugins/debugger/CMakeLists.txt1
-rw-r--r--src/plugins/debugger/analyzer/analyzermanager.h1
-rw-r--r--src/plugins/debugger/analyzer/startremotedialog.cpp2
-rw-r--r--src/plugins/debugger/breakpoint.cpp2
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp141
-rw-r--r--src/plugins/debugger/cdb/cdbengine.h2
-rw-r--r--src/plugins/debugger/cdb/cdboptionspage.cpp16
-rw-r--r--src/plugins/debugger/cdb/cdboptionspage.h7
-rw-r--r--src/plugins/debugger/cdb/cdbparsehelpers.cpp3
-rw-r--r--src/plugins/debugger/commonoptionspage.cpp2
-rw-r--r--src/plugins/debugger/console/console.cpp17
-rw-r--r--src/plugins/debugger/console/console.h1
-rw-r--r--src/plugins/debugger/console/consoleview.cpp2
-rw-r--r--src/plugins/debugger/debugger.pro58
-rw-r--r--src/plugins/debugger/debugger.qbs1
-rw-r--r--src/plugins/debugger/debugger_global.h2
-rw-r--r--src/plugins/debugger/debuggeractions.cpp10
-rw-r--r--src/plugins/debugger/debuggercore.h11
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp43
-rw-r--r--src/plugins/debugger/debuggerdialogs.h17
-rw-r--r--src/plugins/debugger/debuggerengine.cpp105
-rw-r--r--src/plugins/debugger/debuggerengine.h10
-rw-r--r--src/plugins/debugger/debuggeritem.cpp16
-rw-r--r--src/plugins/debugger/debuggeritemmanager.cpp57
-rw-r--r--src/plugins/debugger/debuggerkitinformation.cpp4
-rw-r--r--src/plugins/debugger/debuggermainwindow.cpp10
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp659
-rw-r--r--src/plugins/debugger/debuggerplugin.h2
-rw-r--r--src/plugins/debugger/debuggerprotocol.cpp8
-rw-r--r--src/plugins/debugger/debuggerrunconfigurationaspect.cpp4
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp162
-rw-r--r--src/plugins/debugger/debuggerruncontrol.h18
-rw-r--r--src/plugins/debugger/debuggertooltipmanager.cpp3
-rw-r--r--src/plugins/debugger/debuggerunittestfiles.pri11
-rw-r--r--src/plugins/debugger/disassemblerlines.cpp4
-rw-r--r--src/plugins/debugger/disassemblerlines.h4
-rw-r--r--src/plugins/debugger/enginemanager.cpp4
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp106
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h4
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp16
-rw-r--r--src/plugins/debugger/loadcoredialog.cpp7
-rw-r--r--src/plugins/debugger/loadcoredialog.h3
-rw-r--r--src/plugins/debugger/localsandexpressionswindow.cpp2
-rw-r--r--src/plugins/debugger/logwindow.cpp8
-rw-r--r--src/plugins/debugger/pdb/pdbengine.cpp2
-rw-r--r--src/plugins/debugger/peripheralregisterhandler.cpp957
-rw-r--r--src/plugins/debugger/peripheralregisterhandler.h185
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp45
-rw-r--r--src/plugins/debugger/qml/qmlengine.h1
-rw-r--r--src/plugins/debugger/registerhandler.cpp2
-rw-r--r--src/plugins/debugger/registerpostmortemaction.cpp2
-rw-r--r--src/plugins/debugger/shared/backtrace.cpp2
-rw-r--r--src/plugins/debugger/sourceutils.cpp2
-rw-r--r--src/plugins/debugger/stackhandler.cpp185
-rw-r--r--src/plugins/debugger/stackhandler.h70
-rw-r--r--src/plugins/debugger/stackwindow.cpp4
-rw-r--r--src/plugins/debugger/terminal.cpp7
-rw-r--r--src/plugins/debugger/unstartedappwatcherdialog.cpp10
-rw-r--r--src/plugins/debugger/watchhandler.cpp63
-rw-r--r--src/plugins/debugger/watchhandler.h5
-rw-r--r--src/plugins/designer/codemodelhelpers.cpp10
-rw-r--r--src/plugins/designer/editordata.h2
-rw-r--r--src/plugins/designer/formeditorstack.cpp6
-rw-r--r--src/plugins/designer/formeditorw.cpp32
-rw-r--r--src/plugins/designer/formtemplatewizardpage.cpp6
-rw-r--r--src/plugins/designer/formwindoweditor.cpp2
-rw-r--r--src/plugins/designer/formwindowfile.cpp2
-rw-r--r--src/plugins/designer/qtcreatorintegration.cpp28
-rw-r--r--src/plugins/designer/resourcehandler.cpp6
-rw-r--r--src/plugins/designer/settingspage.cpp5
-rw-r--r--src/plugins/designer/settingspage.h2
-rw-r--r--src/plugins/diffeditor/diffeditor.cpp2
-rw-r--r--src/plugins/diffeditor/diffeditordocument.cpp2
-rw-r--r--src/plugins/diffeditor/diffview.cpp2
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.cpp2
-rw-r--r--src/plugins/fakevim/fakevimhandler.cpp14
-rw-r--r--src/plugins/fakevim/fakevimplugin.cpp4
-rw-r--r--src/plugins/genericprojectmanager/CMakeLists.txt8
-rw-r--r--src/plugins/genericprojectmanager/genericbuildconfiguration.cpp40
-rw-r--r--src/plugins/genericprojectmanager/genericbuildconfiguration.h12
-rw-r--r--src/plugins/genericprojectmanager/genericmakestep.cpp50
-rw-r--r--src/plugins/genericprojectmanager/genericmakestep.h12
-rw-r--r--src/plugins/genericprojectmanager/genericproject.cpp159
-rw-r--r--src/plugins/genericprojectmanager/genericproject.h20
-rw-r--r--src/plugins/genericprojectmanager/genericprojectconstants.h2
-rw-r--r--src/plugins/genericprojectmanager/genericprojectmanager.pro5
-rw-r--r--src/plugins/genericprojectmanager/genericprojectmanager.qbs13
-rw-r--r--src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri3
-rw-r--r--src/plugins/genericprojectmanager/genericprojectplugin.cpp34
-rw-r--r--src/plugins/genericprojectmanager/genericprojectplugin.h7
-rw-r--r--src/plugins/genericprojectmanager/genericprojectplugin_test.cpp168
-rw-r--r--src/plugins/genericprojectmanager/genericprojectwizard.cpp2
-rw-r--r--src/plugins/genericprojectmanager/images/genericprojectmanager.pngbin512 -> 895 bytes
-rw-r--r--src/plugins/genericprojectmanager/images/genericprojectmanager@2x.pngbin837 -> 1725 bytes
-rw-r--r--src/plugins/git/branchmodel.cpp2
-rw-r--r--src/plugins/git/changeselectiondialog.cpp36
-rw-r--r--src/plugins/git/changeselectiondialog.h6
-rw-r--r--src/plugins/git/changeselectiondialog.ui7
-rw-r--r--src/plugins/git/gerrit/gerritmodel.cpp3
-rw-r--r--src/plugins/git/gerrit/gerritplugin.cpp2
-rw-r--r--src/plugins/git/gerrit/gerritpushdialog.cpp2
-rw-r--r--src/plugins/git/gerrit/gerritremotechooser.cpp8
-rw-r--r--src/plugins/git/gerrit/gerritserver.cpp6
-rw-r--r--src/plugins/git/gitclient.cpp99
-rw-r--r--src/plugins/git/gitclient.h14
-rw-r--r--src/plugins/git/giteditor.cpp2
-rw-r--r--src/plugins/git/gitgrep.cpp4
-rw-r--r--src/plugins/git/gitplugin.cpp6
-rw-r--r--src/plugins/git/gitsettings.cpp2
-rw-r--r--src/plugins/git/gitsettings.h1
-rw-r--r--src/plugins/git/gitversioncontrol.cpp9
-rw-r--r--src/plugins/git/gitversioncontrol.h2
-rw-r--r--src/plugins/git/mergetool.cpp2
-rw-r--r--src/plugins/git/remotemodel.cpp6
-rw-r--r--src/plugins/glsleditor/glslcompletionassist.cpp1
-rw-r--r--src/plugins/helloworld/CMakeLists.txt1
-rw-r--r--src/plugins/help/CMakeLists.txt22
-rw-r--r--src/plugins/help/generalsettingspage.cpp19
-rw-r--r--src/plugins/help/generalsettingspage.ui27
-rw-r--r--src/plugins/help/help.pro8
-rw-r--r--src/plugins/help/help.qbs1
-rw-r--r--src/plugins/help/helpconstants.h1
-rw-r--r--src/plugins/help/helpplugin.cpp62
-rw-r--r--src/plugins/help/helpviewer.cpp2
-rw-r--r--src/plugins/help/helpwidget.cpp157
-rw-r--r--src/plugins/help/helpwidget.h35
-rw-r--r--src/plugins/help/litehtmlhelpviewer.cpp362
-rw-r--r--src/plugins/help/litehtmlhelpviewer.h102
-rw-r--r--src/plugins/help/localhelpmanager.cpp123
-rw-r--r--src/plugins/help/localhelpmanager.h20
-rw-r--r--src/plugins/help/macwebkithelpviewer.mm1
-rw-r--r--src/plugins/help/openpagesmanager.cpp179
-rw-r--r--src/plugins/help/openpagesmanager.h32
-rw-r--r--src/plugins/help/openpagesmodel.cpp104
-rw-r--r--src/plugins/help/openpagesmodel.h60
-rw-r--r--src/plugins/help/openpagesswitcher.cpp9
-rw-r--r--src/plugins/help/openpagesswitcher.h12
-rw-r--r--src/plugins/help/openpageswidget.cpp11
-rw-r--r--src/plugins/help/openpageswidget.h6
-rw-r--r--src/plugins/help/qlitehtml/CMakeLists.txt38
-rw-r--r--src/plugins/help/qlitehtml/README.md24
-rw-r--r--src/plugins/help/qlitehtml/container_qpainter.cpp1272
-rw-r--r--src/plugins/help/qlitehtml/container_qpainter.h213
m---------src/plugins/help/qlitehtml/litehtml0
-rw-r--r--src/plugins/help/qlitehtml/qlitehtml.pri56
-rw-r--r--src/plugins/help/qlitehtml/qlitehtmlwidget.cpp687
-rw-r--r--src/plugins/help/qlitehtml/qlitehtmlwidget.h91
-rw-r--r--src/plugins/help/searchwidget.cpp6
-rw-r--r--src/plugins/help/textbrowserhelpviewer.cpp2
-rw-r--r--src/plugins/help/webenginehelpviewer.cpp53
-rw-r--r--src/plugins/help/webenginehelpviewer.h13
-rw-r--r--src/plugins/imageviewer/imageview.cpp2
-rw-r--r--src/plugins/ios/CMakeLists.txt2
-rw-r--r--src/plugins/ios/ios.pro1
-rw-r--r--src/plugins/ios/ios.qbs1
-rw-r--r--src/plugins/ios/iosbuildconfiguration.cpp2
-rw-r--r--src/plugins/ios/iosbuildstep.cpp198
-rw-r--r--src/plugins/ios/iosbuildstep.h21
-rw-r--r--src/plugins/ios/iosbuildstep.ui65
-rw-r--r--src/plugins/ios/iosconfigurations.cpp43
-rw-r--r--src/plugins/ios/iosdeploystep.cpp6
-rw-r--r--src/plugins/ios/iosdevice.cpp48
-rw-r--r--src/plugins/ios/iosdevice.h5
-rw-r--r--src/plugins/ios/iosdsymbuildstep.cpp44
-rw-r--r--src/plugins/ios/iosdsymbuildstep.h10
-rw-r--r--src/plugins/ios/iosplugin.cpp25
-rw-r--r--src/plugins/ios/iosprobe.cpp6
-rw-r--r--src/plugins/ios/iosqtversion.cpp4
-rw-r--r--src/plugins/ios/iosrunconfiguration.cpp9
-rw-r--r--src/plugins/ios/iosrunconfiguration.h1
-rw-r--r--src/plugins/ios/iosrunner.cpp47
-rw-r--r--src/plugins/ios/iosrunner.h1
-rw-r--r--src/plugins/ios/iossettingspage.cpp3
-rw-r--r--src/plugins/ios/iossettingspage.h2
-rw-r--r--src/plugins/ios/iossettingswidget.cpp5
-rw-r--r--src/plugins/ios/iossettingswidget.h4
-rw-r--r--src/plugins/ios/iossimulator.cpp25
-rw-r--r--src/plugins/ios/iossimulator.h2
-rw-r--r--src/plugins/ios/iostoolhandler.cpp12
-rw-r--r--src/plugins/ios/simulatorcontrol.cpp15
-rw-r--r--src/plugins/languageclient/CMakeLists.txt1
-rw-r--r--src/plugins/languageclient/client.cpp420
-rw-r--r--src/plugins/languageclient/client.h42
-rw-r--r--src/plugins/languageclient/documentsymbolcache.cpp2
-rw-r--r--src/plugins/languageclient/languageclient.pro6
-rw-r--r--src/plugins/languageclient/languageclient.qbs2
-rw-r--r--src/plugins/languageclient/languageclient_global.h6
-rw-r--r--src/plugins/languageclient/languageclientcompletionassist.cpp5
-rw-r--r--src/plugins/languageclient/languageclientcompletionassist.h2
-rw-r--r--src/plugins/languageclient/languageclientfunctionhint.cpp5
-rw-r--r--src/plugins/languageclient/languageclientfunctionhint.h2
-rw-r--r--src/plugins/languageclient/languageclienthoverhandler.cpp2
-rw-r--r--src/plugins/languageclient/languageclientmanager.cpp197
-rw-r--r--src/plugins/languageclient/languageclientmanager.h17
-rw-r--r--src/plugins/languageclient/languageclientoutline.cpp21
-rw-r--r--src/plugins/languageclient/languageclientquickfix.cpp6
-rw-r--r--src/plugins/languageclient/languageclientsettings.cpp95
-rw-r--r--src/plugins/languageclient/languageclientsettings.h11
-rw-r--r--src/plugins/languageclient/languageclientutils.cpp43
-rw-r--r--src/plugins/languageclient/locatorfilter.cpp20
-rw-r--r--src/plugins/languageclient/semantichighlightsupport.cpp161
-rw-r--r--src/plugins/languageclient/semantichighlightsupport.h46
-rw-r--r--src/plugins/macros/macroevent.cpp5
-rw-r--r--src/plugins/macros/macrolocatorfilter.cpp4
-rw-r--r--src/plugins/macros/macrooptionswidget.cpp10
-rw-r--r--src/plugins/macros/macrosplugin.cpp4
-rw-r--r--src/plugins/macros/texteditormacrohandler.cpp2
-rw-r--r--src/plugins/mercurial/mercurialclient.cpp10
-rw-r--r--src/plugins/mercurial/mercurialcontrol.cpp2
-rw-r--r--src/plugins/modeleditor/classviewcontroller.cpp12
-rw-r--r--src/plugins/modeleditor/dragtool.cpp10
-rw-r--r--src/plugins/modeleditor/editordiagramview.cpp9
-rw-r--r--src/plugins/modeleditor/elementtasks.cpp42
-rw-r--r--src/plugins/modeleditor/modeldocument.cpp2
-rw-r--r--src/plugins/modeleditor/modeleditor.cpp26
-rw-r--r--src/plugins/modeleditor/modeleditor_plugin.cpp4
-rw-r--r--src/plugins/modeleditor/modelindexer.cpp9
-rw-r--r--src/plugins/modeleditor/modelsmanager.cpp2
-rw-r--r--src/plugins/modeleditor/openelementvisitor.cpp20
-rw-r--r--src/plugins/nim/CMakeLists.txt2
-rw-r--r--src/plugins/nim/editor/nimindenter.cpp4
-rw-r--r--src/plugins/nim/nim.pro5
-rw-r--r--src/plugins/nim/nim.qbs2
-rw-r--r--src/plugins/nim/nimconstants.h5
-rw-r--r--src/plugins/nim/nimplugin.cpp6
-rw-r--r--src/plugins/nim/project/nimbuildconfiguration.cpp89
-rw-r--r--src/plugins/nim/project/nimbuildconfiguration.h15
-rw-r--r--src/plugins/nim/project/nimbuildsystem.cpp179
-rw-r--r--src/plugins/nim/project/nimbuildsystem.h (renamed from src/plugins/nim/project/nimcompilercleanstepconfigwidget.h)40
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstep.cpp66
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstep.h1
-rw-r--r--src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp35
-rw-r--r--src/plugins/nim/project/nimcompilercleanstep.cpp16
-rw-r--r--src/plugins/nim/project/nimcompilercleanstep.h2
-rw-r--r--src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp59
-rw-r--r--src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui39
-rw-r--r--src/plugins/nim/project/nimproject.cpp126
-rw-r--r--src/plugins/nim/project/nimproject.h22
-rw-r--r--src/plugins/nim/project/nimprojectnode.cpp25
-rw-r--r--src/plugins/nim/project/nimprojectnode.h9
-rw-r--r--src/plugins/nim/project/nimrunconfiguration.cpp3
-rw-r--r--src/plugins/nim/project/nimtoolchain.cpp20
-rw-r--r--src/plugins/nim/project/nimtoolchain.h9
-rw-r--r--src/plugins/nim/project/nimtoolchainfactory.cpp6
-rw-r--r--src/plugins/nim/project/nimtoolchainfactory.h2
-rw-r--r--src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp2
-rw-r--r--src/plugins/nim/settings/nimcodestylesettingspage.cpp5
-rw-r--r--src/plugins/nim/settings/nimcodestylesettingspage.h2
-rw-r--r--src/plugins/nim/suggest/server.cpp2
-rw-r--r--src/plugins/perforce/perforceplugin.cpp4
-rw-r--r--src/plugins/perforce/perforcesubmiteditor.cpp5
-rw-r--r--src/plugins/perforce/perforceversioncontrol.cpp4
-rw-r--r--src/plugins/perfprofiler/PerfProfilerFlameGraphView.qml1
-rw-r--r--src/plugins/perfprofiler/perfconfigwidget.cpp6
-rw-r--r--src/plugins/perfprofiler/perfprofilerconstants.h1
-rw-r--r--src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp4
-rw-r--r--src/plugins/perfprofiler/perfprofilerplugin.cpp12
-rw-r--r--src/plugins/perfprofiler/perfprofilerruncontrol.cpp9
-rw-r--r--src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp8
-rw-r--r--src/plugins/perfprofiler/perfprofilerstatisticsview.cpp2
-rw-r--r--src/plugins/perfprofiler/perfprofilertool.cpp1
-rw-r--r--src/plugins/perfprofiler/perfprofilertool.h3
-rw-r--r--src/plugins/perfprofiler/perfprofilertracefile.cpp2
-rw-r--r--src/plugins/perfprofiler/perfsettings.cpp8
-rw-r--r--src/plugins/perfprofiler/perftimelinemodelmanager.cpp2
-rw-r--r--src/plugins/perfprofiler/perftimelineresourcesrenderpass.cpp4
-rw-r--r--src/plugins/perfprofiler/perftracepointdialog.cpp4
-rw-r--r--src/plugins/plugins.pro10
-rw-r--r--src/plugins/plugins.qbs5
-rw-r--r--src/plugins/projectexplorer/CMakeLists.txt9
-rw-r--r--src/plugins/projectexplorer/abi.cpp64
-rw-r--r--src/plugins/projectexplorer/abi.h8
-rw-r--r--src/plugins/projectexplorer/abiwidget.cpp2
-rw-r--r--src/plugins/projectexplorer/abstractprocessstep.cpp12
-rw-r--r--src/plugins/projectexplorer/abstractprocessstep.h1
-rw-r--r--src/plugins/projectexplorer/allprojectsfilter.cpp4
-rw-r--r--src/plugins/projectexplorer/allprojectsfind.cpp5
-rw-r--r--src/plugins/projectexplorer/applicationlauncher.cpp3
-rw-r--r--src/plugins/projectexplorer/appoutputpane.cpp63
-rw-r--r--src/plugins/projectexplorer/appoutputpane.h9
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp87
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h33
-rw-r--r--src/plugins/projectexplorer/buildenvironmentwidget.cpp2
-rw-r--r--src/plugins/projectexplorer/buildmanager.cpp74
-rw-r--r--src/plugins/projectexplorer/buildmanager.h5
-rw-r--r--src/plugins/projectexplorer/buildsettingspropertiespage.cpp23
-rw-r--r--src/plugins/projectexplorer/buildstep.cpp56
-rw-r--r--src/plugins/projectexplorer/buildstep.h16
-rw-r--r--src/plugins/projectexplorer/buildsteplist.cpp82
-rw-r--r--src/plugins/projectexplorer/buildsteplist.h31
-rw-r--r--src/plugins/projectexplorer/buildstepspage.cpp21
-rw-r--r--src/plugins/projectexplorer/buildstepspage.h14
-rw-r--r--src/plugins/projectexplorer/buildsystem.cpp102
-rw-r--r--src/plugins/projectexplorer/buildsystem.h111
-rw-r--r--src/plugins/projectexplorer/buildtargettype.h (renamed from src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.h)23
-rw-r--r--src/plugins/projectexplorer/codestylesettingspropertiespage.cpp7
-rw-r--r--src/plugins/projectexplorer/configtaskhandler.cpp2
-rw-r--r--src/plugins/projectexplorer/currentprojectfilter.cpp4
-rw-r--r--src/plugins/projectexplorer/currentprojectfind.cpp4
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.cpp9
-rw-r--r--src/plugins/projectexplorer/customtoolchain.cpp15
-rw-r--r--src/plugins/projectexplorer/customtoolchain.h7
-rw-r--r--src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp9
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.cpp26
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.h12
-rw-r--r--src/plugins/projectexplorer/deploymentdata.cpp7
-rw-r--r--src/plugins/projectexplorer/deploymentdata.h2
-rw-r--r--src/plugins/projectexplorer/deploymentdatamodel.cpp71
-rw-r--r--src/plugins/projectexplorer/deploymentdataview.cpp89
-rw-r--r--src/plugins/projectexplorer/deploymentdataview.h21
-rw-r--r--src/plugins/projectexplorer/deploymentdataview.ui50
-rw-r--r--src/plugins/projectexplorer/desktoprunconfiguration.cpp261
-rw-r--r--src/plugins/projectexplorer/desktoprunconfiguration.h77
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdevice.cpp22
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdevice.h2
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp86
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui69
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp2
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.cpp6
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp2
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp3
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicesettingspage.h2
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp5
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicesettingswidget.h2
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp28
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h2
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.cpp58
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h15
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevicewidget.h2
-rw-r--r--src/plugins/projectexplorer/devicesupport/localprocesslist.cpp2
-rw-r--r--src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp14
-rw-r--r--src/plugins/projectexplorer/devicesupport/sshsettingspage.cpp2
-rw-r--r--src/plugins/projectexplorer/devicesupport/sshsettingspage.h2
-rw-r--r--src/plugins/projectexplorer/editorconfiguration.cpp12
-rw-r--r--src/plugins/projectexplorer/environmentaspect.cpp2
-rw-r--r--src/plugins/projectexplorer/environmentaspect.h8
-rw-r--r--src/plugins/projectexplorer/environmentaspectwidget.cpp6
-rw-r--r--src/plugins/projectexplorer/environmentaspectwidget.h2
-rw-r--r--src/plugins/projectexplorer/environmentwidget.cpp97
-rw-r--r--src/plugins/projectexplorer/environmentwidget.h11
-rw-r--r--src/plugins/projectexplorer/extracompiler.cpp6
-rw-r--r--src/plugins/projectexplorer/extracompiler.h4
-rw-r--r--src/plugins/projectexplorer/fileinsessionfinder.cpp2
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.cpp9
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp127
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp276
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.h16
-rw-r--r--src/plugins/projectexplorer/gcctoolchainfactories.h10
-rw-r--r--src/plugins/projectexplorer/images/settingscategory_cpp.png (renamed from src/plugins/cpptools/images/settingscategory_cpp.png)bin159 -> 159 bytes
-rw-r--r--src/plugins/projectexplorer/images/settingscategory_cpp@2x.png (renamed from src/plugins/cpptools/images/settingscategory_cpp@2x.png)bin278 -> 278 bytes
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp20
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h6
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp2
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp21
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp2
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp38
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardpagefactory_p.cpp18
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardscannergenerator.cpp2
-rw-r--r--src/plugins/projectexplorer/kit.cpp25
-rw-r--r--src/plugins/projectexplorer/kit.h6
-rw-r--r--src/plugins/projectexplorer/kitinformation.cpp46
-rw-r--r--src/plugins/projectexplorer/kitinformation.h4
-rw-r--r--src/plugins/projectexplorer/kitmanager.cpp56
-rw-r--r--src/plugins/projectexplorer/kitmanager.h5
-rw-r--r--src/plugins/projectexplorer/kitmanagerconfigwidget.cpp4
-rw-r--r--src/plugins/projectexplorer/ldparser.cpp2
-rw-r--r--src/plugins/projectexplorer/linuxiccparser.cpp2
-rw-r--r--src/plugins/projectexplorer/lldparser.cpp76
-rw-r--r--src/plugins/projectexplorer/lldparser.h (renamed from src/plugins/cpptools/cppkitinfo.h)29
-rw-r--r--src/plugins/projectexplorer/localenvironmentaspect.cpp13
-rw-r--r--src/plugins/projectexplorer/localenvironmentaspect.h2
-rw-r--r--src/plugins/projectexplorer/makestep.cpp79
-rw-r--r--src/plugins/projectexplorer/makestep.h11
-rw-r--r--src/plugins/projectexplorer/miniprojecttargetselector.cpp215
-rw-r--r--src/plugins/projectexplorer/miniprojecttargetselector.h20
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp295
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.h42
-rw-r--r--src/plugins/projectexplorer/outputparser_test.cpp6
-rw-r--r--src/plugins/projectexplorer/panelswidget.cpp8
-rw-r--r--src/plugins/projectexplorer/processparameters.cpp32
-rw-r--r--src/plugins/projectexplorer/processparameters.h11
-rw-r--r--src/plugins/projectexplorer/processstep.cpp51
-rw-r--r--src/plugins/projectexplorer/processstep.h2
-rw-r--r--src/plugins/projectexplorer/project.cpp317
-rw-r--r--src/plugins/projectexplorer/project.h132
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.cpp62
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.h14
-rw-r--r--src/plugins/projectexplorer/projectconfigurationaspects.cpp112
-rw-r--r--src/plugins/projectexplorer/projectconfigurationaspects.h32
-rw-r--r--src/plugins/projectexplorer/projectconfigurationmodel.cpp99
-rw-r--r--src/plugins/projectexplorer/projectconfigurationmodel.h35
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp309
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h6
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro19
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs11
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qrc2
-rw-r--r--src/plugins/projectexplorer/projectexplorerconstants.h10
-rw-r--r--src/plugins/projectexplorer/projectexplorersettings.h7
-rw-r--r--src/plugins/projectexplorer/projectexplorersettingspage.cpp2
-rw-r--r--src/plugins/projectexplorer/projectexplorersettingspage.ui8
-rw-r--r--src/plugins/projectexplorer/projectimporter.cpp14
-rw-r--r--src/plugins/projectexplorer/projectimporter.h6
-rw-r--r--src/plugins/projectexplorer/projectmacroexpander.cpp4
-rw-r--r--src/plugins/projectexplorer/projectmacroexpander.h7
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp59
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp98
-rw-r--r--src/plugins/projectexplorer/projectnodes.h50
-rw-r--r--src/plugins/projectexplorer/projecttree.cpp2
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.cpp20
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.h2
-rw-r--r--src/plugins/projectexplorer/projectwelcomepage.cpp26
-rw-r--r--src/plugins/projectexplorer/projectwindow.cpp8
-rw-r--r--src/plugins/projectexplorer/projectwizardpage.cpp7
-rw-r--r--src/plugins/projectexplorer/rawprojectpart.cpp213
-rw-r--r--src/plugins/projectexplorer/rawprojectpart.h183
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp111
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h44
-rw-r--r--src/plugins/projectexplorer/runconfigurationaspects.cpp87
-rw-r--r--src/plugins/projectexplorer/runconfigurationaspects.h11
-rw-r--r--src/plugins/projectexplorer/runcontrol.cpp326
-rw-r--r--src/plugins/projectexplorer/runcontrol.h127
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.cpp64
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.h6
-rw-r--r--src/plugins/projectexplorer/selectablefilesmodel.cpp4
-rw-r--r--src/plugins/projectexplorer/subscription.cpp42
-rw-r--r--src/plugins/projectexplorer/subscription.h9
-rw-r--r--src/plugins/projectexplorer/target.cpp125
-rw-r--r--src/plugins/projectexplorer/target.h46
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.cpp19
-rw-r--r--src/plugins/projectexplorer/targetsetuppage.cpp228
-rw-r--r--src/plugins/projectexplorer/targetsetuppage.h30
-rw-r--r--src/plugins/projectexplorer/targetsetupwidget.cpp68
-rw-r--r--src/plugins/projectexplorer/targetsetupwidget.h18
-rw-r--r--src/plugins/projectexplorer/taskhub.cpp10
-rw-r--r--src/plugins/projectexplorer/taskmodel.cpp2
-rw-r--r--src/plugins/projectexplorer/toolchain.cpp40
-rw-r--r--src/plugins/projectexplorer/toolchain.h32
-rw-r--r--src/plugins/projectexplorer/toolchaincache.h20
-rw-r--r--src/plugins/projectexplorer/toolchainmanager.cpp6
-rw-r--r--src/plugins/projectexplorer/toolchainmanager.h2
-rw-r--r--src/plugins/projectexplorer/toolchainsettingsaccessor.cpp20
-rw-r--r--src/plugins/projectexplorer/userfileaccessor.cpp4
-rw-r--r--src/plugins/python/CMakeLists.txt (renamed from src/plugins/pythoneditor/CMakeLists.txt)10
-rw-r--r--src/plugins/python/Python.json.in (renamed from src/plugins/pythoneditor/PythonEditor.json.in)4
-rw-r--r--src/plugins/python/images/settingscategory_python.pngbin0 -> 227 bytes
-rw-r--r--src/plugins/python/images/settingscategory_python@2x.pngbin0 -> 446 bytes
-rw-r--r--src/plugins/python/python.pro29
-rw-r--r--src/plugins/python/python.qbs37
-rw-r--r--src/plugins/python/python.qrc6
-rw-r--r--src/plugins/python/python_dependencies.pri (renamed from src/plugins/pythoneditor/pythoneditor_dependencies.pri)2
-rw-r--r--src/plugins/python/pythonconstants.h (renamed from src/plugins/pythoneditor/pythoneditorconstants.h)7
-rw-r--r--src/plugins/python/pythoneditor.cpp (renamed from src/plugins/pythoneditor/pythoneditor.cpp)8
-rw-r--r--src/plugins/python/pythoneditor.h (renamed from src/plugins/pythoneditor/pythoneditor.h)4
-rw-r--r--src/plugins/python/pythonformattoken.h (renamed from src/plugins/pythoneditor/pythonformattoken.h)4
-rw-r--r--src/plugins/python/pythonhighlighter.cpp (renamed from src/plugins/pythoneditor/pythonhighlighter.cpp)4
-rw-r--r--src/plugins/python/pythonhighlighter.h (renamed from src/plugins/pythoneditor/pythonhighlighter.h)4
-rw-r--r--src/plugins/python/pythonindenter.cpp (renamed from src/plugins/pythoneditor/pythonindenter.cpp)4
-rw-r--r--src/plugins/python/pythonindenter.h (renamed from src/plugins/pythoneditor/pythonindenter.h)4
-rw-r--r--src/plugins/python/pythonplugin.cpp98
-rw-r--r--src/plugins/python/pythonplugin.h (renamed from src/plugins/pythoneditor/pythoneditorplugin.h)14
-rw-r--r--src/plugins/python/pythonproject.cpp444
-rw-r--r--src/plugins/python/pythonproject.h69
-rw-r--r--src/plugins/python/pythonrunconfiguration.cpp332
-rw-r--r--src/plugins/python/pythonrunconfiguration.h70
-rw-r--r--src/plugins/python/pythonscanner.cpp (renamed from src/plugins/pythoneditor/pythonscanner.cpp)8
-rw-r--r--src/plugins/python/pythonscanner.h (renamed from src/plugins/pythoneditor/pythonscanner.h)4
-rw-r--r--src/plugins/python/pythonsettings.cpp487
-rw-r--r--src/plugins/python/pythonsettings.h62
-rw-r--r--src/plugins/pythoneditor/pythoneditor.pro20
-rw-r--r--src/plugins/pythoneditor/pythoneditor.qbs25
-rw-r--r--src/plugins/pythoneditor/pythoneditorplugin.cpp763
-rw-r--r--src/plugins/qbsprojectmanager/CMakeLists.txt3
-rw-r--r--src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp18
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp122
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildconfiguration.h13
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildstep.cpp233
-rw-r--r--src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui319
-rw-r--r--src/plugins/qbsprojectmanager/qbscleanstep.cpp41
-rw-r--r--src/plugins/qbsprojectmanager/qbscleanstep.h6
-rw-r--r--src/plugins/qbsprojectmanager/qbsinstallstep.cpp128
-rw-r--r--src/plugins/qbsprojectmanager/qbsinstallstep.h25
-rw-r--r--src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui118
-rw-r--r--src/plugins/qbsprojectmanager/qbslogsink.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.cpp32
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.h8
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp4
-rw-r--r--src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp13
-rw-r--r--src/plugins/qbsprojectmanager/qbsprofilessettingspage.h2
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp283
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.h13
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectimporter.cpp15
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanager.pro8
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanager.qbs4
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp15
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h8
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectparser.cpp3
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectparser.h2
-rw-r--r--src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp169
-rw-r--r--src/plugins/qmakeprojectmanager/CMakeLists.txt3
-rw-r--r--src/plugins/qmakeprojectmanager/addlibrarywizard.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizarddialog.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp153
-rw-r--r--src/plugins/qmakeprojectmanager/images/qmakeprojectmanager.pngbin512 -> 895 bytes
-rw-r--r--src/plugins/qmakeprojectmanager/images/qmakeprojectmanager@2x.pngbin837 -> 1725 bytes
-rw-r--r--src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp104
-rw-r--r--src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h27
-rw-r--r--src/plugins/qmakeprojectmanager/qmakemakestep.cpp41
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.cpp43
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodes.h6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp27
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp170
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeparsernodes.h26
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp85
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.h8
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp31
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp5
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.h4
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs3
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp4
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.cpp113
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.h21
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.ui32
-rw-r--r--src/plugins/qmakeprojectmanager/qtmodulesinfo.cpp191
-rw-r--r--src/plugins/qmakeprojectmanager/wizards/modulespage.cpp119
-rw-r--r--src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp101
-rw-r--r--src/plugins/qmakeprojectmanager/wizards/qtwizard.h20
-rw-r--r--src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizarddialog.cpp2
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt8
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp324
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h132
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri3
-rw-r--r--src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp4
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp4
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp5
-rw-r--r--src/plugins/qmldesigner/components/componentcore/theme.cpp2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp4
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp4
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp4
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp2
-rw-r--r--src/plugins/qmldesigner/components/curveeditor/treeitem.cpp2
-rw-r--r--src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp8
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp7
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp4
-rw-r--r--src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp12
-rw-r--r--src/plugins/qmldesigner/components/formeditor/movetool.cpp28
-rw-r--r--src/plugins/qmldesigner/components/formeditor/onedimensionalcluster.cpp15
-rw-r--r--src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp11
-rw-r--r--src/plugins/qmldesigner/components/formeditor/selectiontool.h3
-rw-r--r--src/plugins/qmldesigner/components/formeditor/snapper.cpp48
-rw-r--r--src/plugins/qmldesigner/components/formeditor/snappinglinecreator.h1
-rw-r--r--src/plugins/qmldesigner/components/formeditor/toolbox.cpp2
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp6
-rw-r--r--src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp4
-rw-r--r--src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp2
-rw-r--r--src/plugins/qmldesigner/components/pathtool/pathitem.cpp8
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp2
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp2
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp40
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h2
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp2
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp18
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp8
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp18
-rw-r--r--src/plugins/qmldesigner/designercore/include/abstractproperty.h1
-rw-r--r--src/plugins/qmldesigner/designercore/include/abstractview.h1
-rw-r--r--src/plugins/qmldesigner/designercore/include/modelnode.h1
-rw-r--r--src/plugins/qmldesigner/designercore/include/nodeinstanceview.h3
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp11
-rw-r--r--src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/model/internalnode_p.h1
-rw-r--r--src/plugins/qmldesigner/designercore/model/internalproperty.h6
-rw-r--r--src/plugins/qmldesigner/designercore/model/model.cpp22
-rw-r--r--src/plugins/qmldesigner/designercore/model/modelnodepositionstorage.cpp4
-rw-r--r--src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp46
-rw-r--r--src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp6
-rw-r--r--src/plugins/qmldesigner/designercore/model/viewmanager.cpp8
-rw-r--r--src/plugins/qmldesigner/designercore/rewritertransaction.cpp2
-rw-r--r--src/plugins/qmldesigner/designmodewidget.cpp6
-rw-r--r--src/plugins/qmldesigner/documentmanager.cpp6
-rw-r--r--src/plugins/qmldesigner/documentwarningwidget.cpp2
-rw-r--r--src/plugins/qmldesigner/generateresource.cpp156
-rw-r--r--src/plugins/qmldesigner/generateresource.h33
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.cpp38
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.pri2
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.pro1
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.qbs4
-rw-r--r--src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.cpp1
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.h5
-rw-r--r--src/plugins/qmljseditor/qmljscompletionassist.h28
-rw-r--r--src/plugins/qmljseditor/qmljseditingsettingspage.cpp40
-rw-r--r--src/plugins/qmljseditor/qmljseditingsettingspage.h2
-rw-r--r--src/plugins/qmljseditor/qmljseditor.cpp68
-rw-r--r--src/plugins/qmljseditor/qmljseditor.h11
-rw-r--r--src/plugins/qmljseditor/qmljseditorconstants.h21
-rw-r--r--src/plugins/qmljseditor/qmljseditordocument.cpp41
-rw-r--r--src/plugins/qmljseditor/qmljseditordocument.h5
-rw-r--r--src/plugins/qmljseditor/qmljseditordocument_p.h7
-rw-r--r--src/plugins/qmljseditor/qmljseditorplugin.cpp26
-rw-r--r--src/plugins/qmljseditor/qmljsfindreferences.cpp11
-rw-r--r--src/plugins/qmljseditor/qmljshoverhandler.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljshoverhandler.h5
-rw-r--r--src/plugins/qmljseditor/qmljsoutline.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljsoutline.h4
-rw-r--r--src/plugins/qmljseditor/qmljsquickfixassist.h3
-rw-r--r--src/plugins/qmljseditor/qmljssemantichighlighter.cpp4
-rw-r--r--src/plugins/qmljseditor/qmljssemantichighlighter.h6
-rw-r--r--src/plugins/qmljseditor/qmljswrapinloader.cpp4
-rw-r--r--src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp2
-rw-r--r--src/plugins/qmljstools/qmljscodestylesettingspage.cpp4
-rw-r--r--src/plugins/qmljstools/qmljscodestylesettingspage.h2
-rw-r--r--src/plugins/qmljstools/qmljsfunctionfilter.cpp35
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.cpp2
-rw-r--r--src/plugins/qmlpreview/qmlpreviewfileontargetfinder.cpp2
-rw-r--r--src/plugins/qmlpreview/qmlpreviewfileontargetfinder.h4
-rw-r--r--src/plugins/qmlpreview/qmlpreviewplugin.cpp244
-rw-r--r--src/plugins/qmlpreview/qmlpreviewplugin.h24
-rw-r--r--src/plugins/qmlpreview/qmlpreviewruncontrol.cpp14
-rw-r--r--src/plugins/qmlprofiler/debugmessagesmodel.cpp2
-rw-r--r--src/plugins/qmlprofiler/flamegraphmodel.cpp2
-rw-r--r--src/plugins/qmlprofiler/memoryusagemodel.cpp4
-rw-r--r--src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml1
-rw-r--r--src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp6
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerconfigwidget.cpp4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerconfigwidget.h2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerplugin.cpp46
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp44
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.h8
-rw-r--r--src/plugins/qmlprofiler/qmlprofilersettings.cpp3
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp10
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.cpp43
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.h4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceclient.cpp30
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertracefile.cpp4
-rw-r--r--src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp13
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp4
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp34
-rw-r--r--src/plugins/qmlprofiler/tests/qmlprofilertool_test.cpp4
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp45
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/filefilteritems.h54
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp39
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp29
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h6
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.cpp38
-rw-r--r--src/plugins/qmlprojectmanager/qmlproject.h6
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.cpp2
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectplugin.cpp7
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp29
-rw-r--r--src/plugins/qnx/qnxanalyzesupport.cpp43
-rw-r--r--src/plugins/qnx/qnxanalyzesupport.h11
-rw-r--r--src/plugins/qnx/qnxconfiguration.cpp2
-rw-r--r--src/plugins/qnx/qnxconfiguration.h4
-rw-r--r--src/plugins/qnx/qnxdebugsupport.cpp72
-rw-r--r--src/plugins/qnx/qnxdevice.cpp20
-rw-r--r--src/plugins/qnx/qnxdevice.h3
-rw-r--r--src/plugins/qnx/qnxdeviceprocess.cpp10
-rw-r--r--src/plugins/qnx/qnxdevicetester.cpp1
-rw-r--r--src/plugins/qnx/qnxdevicewizard.cpp1
-rw-r--r--src/plugins/qnx/qnxplugin.cpp21
-rw-r--r--src/plugins/qnx/qnxqtversion.cpp2
-rw-r--r--src/plugins/qnx/qnxqtversion.h4
-rw-r--r--src/plugins/qnx/qnxrunconfiguration.cpp46
-rw-r--r--src/plugins/qnx/qnxrunconfiguration.h4
-rw-r--r--src/plugins/qnx/qnxsettingspage.cpp3
-rw-r--r--src/plugins/qnx/qnxsettingspage.h4
-rw-r--r--src/plugins/qnx/qnxtoolchain.cpp15
-rw-r--r--src/plugins/qnx/qnxtoolchain.h2
-rw-r--r--src/plugins/qnx/qnxutils.cpp6
-rw-r--r--src/plugins/qnx/qnxutils.h4
-rw-r--r--src/plugins/qnx/slog2inforunner.cpp6
-rw-r--r--src/plugins/qtsupport/CMakeLists.txt7
-rw-r--r--src/plugins/qtsupport/baseqtversion.cpp690
-rw-r--r--src/plugins/qtsupport/baseqtversion.h131
-rw-r--r--src/plugins/qtsupport/codegensettingspage.cpp11
-rw-r--r--src/plugins/qtsupport/codegensettingspage.h4
-rw-r--r--src/plugins/qtsupport/gettingstartedwelcomepage.cpp1
-rw-r--r--src/plugins/qtsupport/qscxmlcgenerator.cpp2
-rw-r--r--src/plugins/qtsupport/qscxmlcgenerator.h4
-rw-r--r--src/plugins/qtsupport/qtcppkitinfo.cpp8
-rw-r--r--src/plugins/qtsupport/qtcppkitinfo.h4
-rw-r--r--src/plugins/qtsupport/qtkitinformation.cpp4
-rw-r--r--src/plugins/qtsupport/qtoptionspage.cpp26
-rw-r--r--src/plugins/qtsupport/qtoptionspage.h2
-rw-r--r--src/plugins/qtsupport/qtoutputformatter.cpp75
-rw-r--r--src/plugins/qtsupport/qtoutputformatter.h46
-rw-r--r--src/plugins/qtsupport/qtprojectimporter.cpp4
-rw-r--r--src/plugins/qtsupport/qtsupport.pro11
-rw-r--r--src/plugins/qtsupport/qtsupport.qbs8
-rw-r--r--src/plugins/qtsupport/qtsupport_dependencies.pri1
-rw-r--r--src/plugins/qtsupport/qtsupportplugin.cpp29
-rw-r--r--src/plugins/qtsupport/qtversionfactory.cpp171
-rw-r--r--src/plugins/qtsupport/qtversionfactory.h5
-rw-r--r--src/plugins/qtsupport/qtversionmanager.cpp11
-rw-r--r--src/plugins/qtsupport/qtversionmanager.h5
-rw-r--r--src/plugins/qtsupport/qtversions.cpp (renamed from src/plugins/qtsupport/desktopqtversion.cpp)82
-rw-r--r--src/plugins/qtsupport/qtversions.h (renamed from src/plugins/qmakeprojectmanager/qtmodulesinfo.h)21
-rw-r--r--src/plugins/qtsupport/screenshotcropper.cpp4
-rw-r--r--src/plugins/qtsupport/translationwizardpage.cpp173
-rw-r--r--src/plugins/qtsupport/translationwizardpage.h45
-rw-r--r--src/plugins/qtsupport/uicgenerator.h4
-rw-r--r--src/plugins/remotelinux/CMakeLists.txt3
-rw-r--r--src/plugins/remotelinux/abstractpackagingstep.cpp19
-rw-r--r--src/plugins/remotelinux/abstractpackagingstep.h2
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp6
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp50
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxdeploystep.h16
-rw-r--r--src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp5
-rw-r--r--src/plugins/remotelinux/abstractuploadandinstallpackageservice.h2
-rw-r--r--src/plugins/remotelinux/deploymenttimeinfo.cpp20
-rw-r--r--src/plugins/remotelinux/embeddedlinuxqtversion.cpp69
-rw-r--r--src/plugins/remotelinux/genericdirectuploadstep.cpp63
-rw-r--r--src/plugins/remotelinux/genericdirectuploadstep.h10
-rw-r--r--src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.cpp4
-rw-r--r--src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.h2
-rw-r--r--src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp1
-rw-r--r--src/plugins/remotelinux/linuxdevice.cpp19
-rw-r--r--src/plugins/remotelinux/linuxdevice.h2
-rw-r--r--src/plugins/remotelinux/linuxdeviceprocess.cpp14
-rw-r--r--src/plugins/remotelinux/makeinstallstep.cpp20
-rw-r--r--src/plugins/remotelinux/remotelinux.pro2
-rw-r--r--src/plugins/remotelinux/remotelinux.qbs3
-rw-r--r--src/plugins/remotelinux/remotelinux_constants.h2
-rw-r--r--src/plugins/remotelinux/remotelinux_dependencies.pri3
-rw-r--r--src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.cpp49
-rw-r--r--src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.h9
-rw-r--r--src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.cpp41
-rw-r--r--src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.h8
-rw-r--r--src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp3
-rw-r--r--src/plugins/remotelinux/remotelinuxenvironmentaspect.cpp2
-rw-r--r--src/plugins/remotelinux/remotelinuxenvironmentreader.cpp3
-rw-r--r--src/plugins/remotelinux/remotelinuxkillappservice.cpp5
-rw-r--r--src/plugins/remotelinux/remotelinuxkillappservice.h2
-rw-r--r--src/plugins/remotelinux/remotelinuxkillappstep.cpp28
-rw-r--r--src/plugins/remotelinux/remotelinuxkillappstep.h7
-rw-r--r--src/plugins/remotelinux/remotelinuxplugin.cpp47
-rw-r--r--src/plugins/remotelinux/remotelinuxqmltoolingsupport.cpp50
-rw-r--r--src/plugins/remotelinux/remotelinuxqmltoolingsupport.h30
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfiguration.cpp12
-rw-r--r--src/plugins/remotelinux/remotelinuxrunconfiguration.h6
-rw-r--r--src/plugins/remotelinux/rsyncdeploystep.cpp62
-rw-r--r--src/plugins/remotelinux/rsyncdeploystep.h9
-rw-r--r--src/plugins/remotelinux/tarpackagecreationstep.cpp33
-rw-r--r--src/plugins/remotelinux/tarpackagecreationstep.h1
-rw-r--r--src/plugins/remotelinux/uploadandinstalltarpackagestep.cpp39
-rw-r--r--src/plugins/remotelinux/uploadandinstalltarpackagestep.h9
-rw-r--r--src/plugins/resourceeditor/qrceditor/qrceditor.cpp25
-rw-r--r--src/plugins/resourceeditor/qrceditor/qrceditor.h5
-rw-r--r--src/plugins/resourceeditor/qrceditor/qrceditor.ui225
-rw-r--r--src/plugins/resourceeditor/qrceditor/resourceview.cpp2
-rw-r--r--src/plugins/resourceeditor/resourceeditorplugin.cpp2
-rw-r--r--src/plugins/resourceeditor/resourceeditorw.cpp18
-rw-r--r--src/plugins/resourceeditor/resourceeditorw.h2
-rw-r--r--src/plugins/resourceeditor/resourcenode.cpp20
-rw-r--r--src/plugins/resourceeditor/resourcenode.h6
-rw-r--r--src/plugins/scxmleditor/common/colorpicker.cpp2
-rw-r--r--src/plugins/scxmleditor/common/graphicsview.cpp2
-rw-r--r--src/plugins/scxmleditor/common/magnifier.cpp2
-rw-r--r--src/plugins/scxmleditor/common/mainwidget.cpp4
-rw-r--r--src/plugins/scxmleditor/common/navigator.cpp2
-rw-r--r--src/plugins/scxmleditor/common/navigatorgraphicsview.cpp6
-rw-r--r--src/plugins/scxmleditor/common/shapegroupwidget.cpp2
-rw-r--r--src/plugins/scxmleditor/common/stateproperties.cpp2
-rw-r--r--src/plugins/scxmleditor/common/structure.cpp8
-rw-r--r--src/plugins/scxmleditor/outputpane/errorwidget.cpp2
-rw-r--r--src/plugins/scxmleditor/outputpane/outputtabwidget.cpp2
-rw-r--r--src/plugins/scxmleditor/plugin_interface/sceneutils.cpp4
-rw-r--r--src/plugins/scxmleditor/plugin_interface/scxmldocument.cpp20
-rw-r--r--src/plugins/scxmleditor/plugin_interface/scxmltag.cpp5
-rw-r--r--src/plugins/scxmleditor/plugin_interface/transitionitem.cpp20
-rw-r--r--src/plugins/scxmleditor/scxmleditordata.cpp2
-rw-r--r--src/plugins/serialterminal/serialoutputpane.cpp10
-rw-r--r--src/plugins/serialterminal/serialoutputpane.h9
-rw-r--r--src/plugins/silversearcher/findinfilessilversearcher.cpp2
-rw-r--r--src/plugins/studiowelcome/CMakeLists.txt2
-rw-r--r--src/plugins/studiowelcome/studiowelcomeplugin.cpp4
-rw-r--r--src/plugins/subversion/subversionclient.cpp4
-rw-r--r--src/plugins/subversion/subversioncontrol.cpp2
-rw-r--r--src/plugins/subversion/subversionplugin.cpp3
-rw-r--r--src/plugins/tasklist/stopmonitoringhandler.cpp2
-rw-r--r--src/plugins/tasklist/taskfile.cpp6
-rw-r--r--src/plugins/texteditor/autocompleter.cpp34
-rw-r--r--src/plugins/texteditor/basefilefind.cpp8
-rw-r--r--src/plugins/texteditor/basehoverhandler.cpp7
-rw-r--r--src/plugins/texteditor/basehoverhandler.h2
-rw-r--r--src/plugins/texteditor/codeassist/assistproposalitem.cpp2
-rw-r--r--src/plugins/texteditor/codeassist/assistproposaliteminterface.h13
-rw-r--r--src/plugins/texteditor/codeassist/codeassistant.cpp2
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp6
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalmodel.cpp31
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalwidget.cpp6
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposal.cpp4
-rw-r--r--src/plugins/texteditor/codeassist/keywordscompletionassist.cpp2
-rw-r--r--src/plugins/texteditor/colorscheme.cpp5
-rw-r--r--src/plugins/texteditor/extraencodingsettings.cpp7
-rw-r--r--src/plugins/texteditor/extraencodingsettings.h2
-rw-r--r--src/plugins/texteditor/findinfiles.cpp2
-rw-r--r--src/plugins/texteditor/formattexteditor.cpp2
-rw-r--r--src/plugins/texteditor/highlighter.cpp72
-rw-r--r--src/plugins/texteditor/highlightersettings.cpp6
-rw-r--r--src/plugins/texteditor/normalindenter.cpp4
-rw-r--r--src/plugins/texteditor/refactoringchanges.cpp6
-rw-r--r--src/plugins/texteditor/refactoringchanges.h4
-rw-r--r--src/plugins/texteditor/refactoroverlay.cpp3
-rw-r--r--src/plugins/texteditor/semantichighlighter.cpp69
-rw-r--r--src/plugins/texteditor/semantichighlighter.h24
-rw-r--r--src/plugins/texteditor/syntaxhighlighter.cpp69
-rw-r--r--src/plugins/texteditor/syntaxhighlighter.h4
-rw-r--r--src/plugins/texteditor/texteditor.cpp327
-rw-r--r--src/plugins/texteditor/texteditor.h2
-rw-r--r--src/plugins/texteditor/texteditorconstants.h4
-rw-r--r--src/plugins/texteditor/texteditoroverlay.cpp4
-rw-r--r--src/plugins/texteditor/texteditorplugin.cpp5
-rw-r--r--src/plugins/texteditor/texteditorsettings.cpp10
-rw-r--r--src/plugins/texteditor/texteditorsettings.h2
-rw-r--r--src/plugins/texteditor/textindenter.cpp2
-rw-r--r--src/plugins/texteditor/textmark.cpp2
-rw-r--r--src/plugins/todo/cpptodoitemsscanner.cpp4
-rw-r--r--src/plugins/todo/lineparser.cpp16
-rw-r--r--src/plugins/todo/optionsdialog.cpp3
-rw-r--r--src/plugins/todo/optionsdialog.h2
-rw-r--r--src/plugins/todo/todoitemsmodel.cpp2
-rw-r--r--src/plugins/todo/todoitemsprovider.cpp10
-rw-r--r--src/plugins/todo/todooutputpane.cpp2
-rw-r--r--src/plugins/todo/todooutputtreeview.cpp2
-rw-r--r--src/plugins/todo/todoplugin.cpp4
-rw-r--r--src/plugins/updateinfo/updateinfoplugin.cpp46
-rw-r--r--src/plugins/valgrind/callgrind/callgrindcontroller.cpp4
-rw-r--r--src/plugins/valgrind/callgrind/callgrinddatamodel.cpp2
-rw-r--r--src/plugins/valgrind/callgrind/callgrindparser.cpp2
-rw-r--r--src/plugins/valgrind/callgrindengine.cpp12
-rw-r--r--src/plugins/valgrind/callgrindtool.cpp20
-rw-r--r--src/plugins/valgrind/memchecktool.cpp32
-rw-r--r--src/plugins/valgrind/suppressiondialog.cpp2
-rw-r--r--src/plugins/valgrind/valgrindengine.cpp21
-rw-r--r--src/plugins/valgrind/valgrindengine.h7
-rw-r--r--src/plugins/valgrind/valgrindmemcheckparsertest.cpp16
-rw-r--r--src/plugins/valgrind/valgrindmemcheckparsertest.h2
-rw-r--r--src/plugins/valgrind/valgrindrunner.cpp48
-rw-r--r--src/plugins/valgrind/valgrindrunner.h3
-rw-r--r--src/plugins/valgrind/valgrindsettings.cpp12
-rw-r--r--src/plugins/valgrind/valgrindsettings.h2
-rw-r--r--src/plugins/valgrind/valgrindtestrunnertest.cpp18
-rw-r--r--src/plugins/vcsbase/CMakeLists.txt4
-rw-r--r--src/plugins/vcsbase/submitfieldwidget.cpp4
-rw-r--r--src/plugins/vcsbase/vcsbase.qbs4
-rw-r--r--src/plugins/vcsbase/vcsbase_dependencies.pri4
-rw-r--r--src/plugins/vcsbase/vcsbaseclient.cpp13
-rw-r--r--src/plugins/vcsbase/vcsbaseclient.h2
-rw-r--r--src/plugins/vcsbase/vcsbaseclientsettings.cpp5
-rw-r--r--src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp2
-rw-r--r--src/plugins/vcsbase/vcsbaseeditor.cpp26
-rw-r--r--src/plugins/vcsbase/vcsbaseplugin.cpp5
-rw-r--r--src/plugins/vcsbase/vcsbaseplugin.h5
-rw-r--r--src/plugins/vcsbase/vcsbasesubmiteditor.cpp92
-rw-r--r--src/plugins/vcsbase/vcscommand.cpp10
-rw-r--r--src/plugins/vcsbase/vcscommand.h4
-rw-r--r--src/plugins/vcsbase/vcsoutputwindow.cpp14
-rw-r--r--src/plugins/vcsbase/vcsoutputwindow.h8
-rw-r--r--src/plugins/vcsbase/wizard/vcscommandpage.cpp8
-rw-r--r--src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp10
-rw-r--r--src/plugins/vcsbase/wizard/vcsjsextension.cpp6
-rw-r--r--src/plugins/vcsbase/wizard/vcsjsextension.h1
-rw-r--r--src/plugins/webassembly/CMakeLists.txt14
-rw-r--r--src/plugins/webassembly/WebAssembly.json.in20
-rw-r--r--src/plugins/webassembly/images/webassemblydevice.pngbin0 -> 273 bytes
-rw-r--r--src/plugins/webassembly/images/webassemblydevice@2x.pngbin0 -> 553 bytes
-rw-r--r--src/plugins/webassembly/images/webassemblydevicesmall.pngbin0 -> 159 bytes
-rw-r--r--src/plugins/webassembly/images/webassemblydevicesmall@2x.pngbin0 -> 255 bytes
-rw-r--r--src/plugins/webassembly/webassembly.pro22
-rw-r--r--src/plugins/webassembly/webassembly.qbs31
-rw-r--r--src/plugins/webassembly/webassembly.qrc8
-rw-r--r--src/plugins/webassembly/webassembly_dependencies.pri10
-rw-r--r--src/plugins/webassembly/webassembly_global.h34
-rw-r--r--src/plugins/webassembly/webassemblyconstants.h38
-rw-r--r--src/plugins/webassembly/webassemblydevice.cpp72
-rw-r--r--src/plugins/webassembly/webassemblydevice.h57
-rw-r--r--src/plugins/webassembly/webassemblyplugin.cpp87
-rw-r--r--src/plugins/webassembly/webassemblyplugin.h49
-rw-r--r--src/plugins/webassembly/webassemblyqtversion.cpp65
-rw-r--r--src/plugins/webassembly/webassemblyqtversion.h (renamed from src/plugins/remotelinux/embeddedlinuxqtversion.h)16
-rw-r--r--src/plugins/webassembly/webassemblyrunconfiguration.cpp123
-rw-r--r--src/plugins/webassembly/webassemblyrunconfiguration.h43
-rw-r--r--src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp107
-rw-r--r--src/plugins/webassembly/webassemblyrunconfigurationaspects.h (renamed from src/plugins/qtsupport/desktopqtversion.h)41
-rw-r--r--src/plugins/webassembly/webassemblytoolchain.cpp158
-rw-r--r--src/plugins/webassembly/webassemblytoolchain.h56
-rw-r--r--src/plugins/welcome/introductionwidget.cpp41
-rw-r--r--src/plugins/welcome/welcomeplugin.cpp9
-rw-r--r--src/plugins/winrt/winrtdebugsupport.cpp2
-rw-r--r--src/plugins/winrt/winrtdevice.cpp28
-rw-r--r--src/plugins/winrt/winrtdevice.h2
-rw-r--r--src/plugins/winrt/winrtpackagedeploymentstep.cpp18
-rw-r--r--src/plugins/winrt/winrtplugin.cpp34
-rw-r--r--src/plugins/winrt/winrtrunnerhelper.cpp25
-rw-r--r--src/plugins/winrt/winrtrunnerhelper.h2
-rw-r--r--src/shared/designerintegrationv2/CMakeLists.txt10
-rw-r--r--src/shared/designerintegrationv2/formresizer.cpp5
-rw-r--r--src/shared/designerintegrationv2/widgethost.cpp2
-rw-r--r--src/shared/help/CMakeLists.txt8
-rw-r--r--src/shared/help/bookmarkmanager.cpp4
-rw-r--r--src/shared/help/contentwindow.cpp2
-rw-r--r--src/shared/help/indexwindow.cpp4
-rw-r--r--src/shared/modeltest/modeltest.cpp2
-rw-r--r--src/shared/proparser/registry.cpp4
-rw-r--r--src/shared/qtcreator_gui_pch.h1
-rw-r--r--src/shared/registryaccess/registryaccess.cpp2
-rw-r--r--src/shared/yaml-cpp/yaml-cpp_installation.pri7
-rw-r--r--src/tools/clangbackend/clangbackendmain.cpp24
-rw-r--r--src/tools/clangbackend/source/clangfollowsymbol.cpp2
-rw-r--r--src/tools/clangbackend/source/clangjobqueue.cpp7
-rw-r--r--src/tools/clangbackend/source/clangreferencescollector.cpp8
-rw-r--r--src/tools/clangbackend/source/clangtooltipinfocollector.cpp2
-rw-r--r--src/tools/clangbackend/source/clangtranslationunitupdater.cpp2
-rw-r--r--src/tools/clangbackend/source/codecompleter.cpp2
-rw-r--r--src/tools/clangbackend/source/codecompleter.h2
-rw-r--r--src/tools/clangbackend/source/sourcelocation.cpp21
-rw-r--r--src/tools/clangbackend/source/sourcelocation.h12
-rw-r--r--src/tools/clangbackend/source/sourcerange.cpp2
-rw-r--r--src/tools/clangbackend/source/sourcerange.h2
-rw-r--r--src/tools/clangbackend/source/token.cpp4
-rw-r--r--src/tools/clangbackend/source/token.h6
-rw-r--r--src/tools/clangbackend/source/unsavedfile.cpp6
-rw-r--r--src/tools/clangbackend/source/unsavedfile.h6
-rw-r--r--src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp30
-rw-r--r--src/tools/clangbackend/source/utf8positionfromlinecolumn.h12
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp22
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp21
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h7
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h3
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h12
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp23
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.h18
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp72
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.h5
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp3
-rw-r--r--src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h71
-rw-r--r--src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h9
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp287
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsmanager.h28
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h8
-rw-r--r--src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp2
-rw-r--r--src/tools/clangrefactoringbackend/source/CMakeLists.txt1
-rw-r--r--src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri2
-rw-r--r--src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp59
-rw-r--r--src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp23
-rw-r--r--src/tools/clangrefactoringbackend/source/indexdataconsumer.h7
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.cpp1
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp56
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.h14
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.cpp11
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h1
-rw-r--r--src/tools/cplusplus-ast2png/cplusplus-ast2png.cpp8
-rw-r--r--src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor.cpp2
-rw-r--r--src/tools/cplusplus-update-frontend/cplusplus-update-frontend.cpp234
-rw-r--r--src/tools/icons/qtcreatoricons.svg284
-rw-r--r--src/tools/iostool/iosdevicemanager.cpp4
-rw-r--r--src/tools/iostool/main.cpp19
m---------src/tools/perfparser0
-rw-r--r--src/tools/qtcdebugger/main.cpp3
-rw-r--r--src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp6
-rw-r--r--src/tools/sdktool/CMakeLists.txt9
-rw-r--r--src/tools/sdktool/addtoolchainoperation.cpp2
-rw-r--r--src/tools/sdktool/addvalueoperation.cpp194
-rw-r--r--src/tools/sdktool/addvalueoperation.h52
-rw-r--r--src/tools/sdktool/main.cpp2
-rw-r--r--src/tools/sdktool/sdktool.pro6
-rw-r--r--src/tools/sdktool/sdktool.qbs4
-rw-r--r--src/tools/sdktool/settings.cpp4
-rw-r--r--src/tools/valgrindfake/outputgenerator.cpp4
-rw-r--r--tests/auto/cplusplus/ast/tst_ast.cpp118
-rw-r--r--tests/auto/cplusplus/c99/tst_c99.cpp2
-rw-r--r--tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp6
-rw-r--r--tests/auto/cplusplus/cxx11/tst_cxx11.cpp4
-rw-r--r--tests/auto/cplusplus/findusages/tst_findusages.cpp106
-rw-r--r--tests/auto/cplusplus/lexer/tst_lexer.cpp11
-rw-r--r--tests/auto/cplusplus/lookup/tst_lookup.cpp34
-rw-r--r--tests/auto/cplusplus/misc/tst_misc.cpp44
-rw-r--r--tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp152
-rw-r--r--tests/auto/cplusplus/semantic/tst_semantic.cpp114
-rw-r--r--tests/auto/cplusplus/translationunit/tst_translationunit.cpp28
-rw-r--r--tests/auto/debugger/CMakeLists.txt2
-rw-r--r--tests/auto/debugger/tst_dumpers.cpp33
-rw-r--r--tests/auto/environment/tst_environment.cpp28
-rw-r--r--tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/CMakeLists.txt3
-rw-r--r--tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/CMakeLists.txt3
-rw-r--r--tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/CMakeLists.txt3
-rw-r--r--tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/CMakeLists.txt1
-rw-r--r--tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/CMakeLists.txt1
-rw-r--r--tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/CMakeLists.txt1
-rw-r--r--tests/auto/extensionsystem/pluginspec/testplugin/CMakeLists.txt1
-rw-r--r--tests/auto/json/tst_json.cpp4
-rw-r--r--tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp6
-rw-r--r--tests/auto/qml/codemodel/check/tst_check.cpp2
-rw-r--r--tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp2
-rw-r--r--tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp4
-rw-r--r--tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp10
-rw-r--r--tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp36
-rw-r--r--tests/auto/ssh/tst_ssh.cpp12
-rw-r--r--tests/auto/toolchaincache/CMakeLists.txt2
-rw-r--r--tests/auto/toolchaincache/tst_toolchaincache.cpp10
-rw-r--r--tests/auto/tracing/flamegraphview/TestFlameGraphView.qml1
-rw-r--r--tests/auto/tracing/flamegraphview/tst_flamegraphview.cpp6
-rw-r--r--tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp12
-rw-r--r--tests/auto/utils/fileutils/tst_fileutils.cpp2
-rw-r--r--tests/auto/utils/fuzzymatcher/tst_fuzzymatcher.cpp24
-rw-r--r--tests/auto/utils/settings/tst_settings.cpp14
-rw-r--r--tests/auto/utils/stringutils/tst_stringutils.cpp2
-rw-r--r--tests/auto/valgrind/memcheck/modeldemo.cpp4
-rw-r--r--tests/manual/debugger/simple/simple_test_app.cpp10
-rw-r--r--tests/manual/process/mainwindow.cpp3
-rw-r--r--tests/unit/mockup/projectexplorer/buildconfiguration.h2
-rw-r--r--tests/unit/mockup/projectexplorer/kitinformation.h2
-rw-r--r--tests/unit/mockup/projectexplorer/project.h6
-rw-r--r--tests/unit/mockup/projectexplorer/toolchain.h6
-rw-r--r--tests/unit/mockup/texteditor/semantichighlighter.h10
-rw-r--r--tests/unit/unittest/CMakeLists.txt9
-rw-r--r--tests/unit/unittest/builddependenciesprovider-test.cpp69
-rw-r--r--tests/unit/unittest/builddependenciesstorage-test.cpp44
-rw-r--r--tests/unit/unittest/builddependencycollector-test.cpp15
-rw-r--r--tests/unit/unittest/clangindexingsettingsmanager-test.cpp83
-rw-r--r--tests/unit/unittest/clangquery-test.cpp9
-rw-r--r--tests/unit/unittest/clangquerygatherer-test.cpp22
-rw-r--r--tests/unit/unittest/clangqueryprojectfindfilter-test.cpp21
-rw-r--r--tests/unit/unittest/clangtranslationunit-test.cpp8
-rw-r--r--tests/unit/unittest/compileroptionsbuilder-test.cpp2
-rw-r--r--tests/unit/unittest/cppprojectinfogenerator-test.cpp4
-rw-r--r--tests/unit/unittest/creator_dependency.pri3
-rw-r--r--tests/unit/unittest/data/clangtools/CMakeLists.txt26
-rw-r--r--tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.cpp5
-rw-r--r--tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.yaml23
-rw-r--r--tests/unit/unittest/data/clangtools/clang.unused-parameter.cpp5
-rw-r--r--tests/unit/unittest/data/clangtools/clang.unused-parameter.h1
-rw-r--r--tests/unit/unittest/data/clangtools/clang.unused-parameter.yaml10
-rw-r--r--tests/unit/unittest/data/clangtools/clazy.qgetenv.cpp8
-rw-r--r--tests/unit/unittest/data/clangtools/clazy.qgetenv.yaml17
-rw-r--r--tests/unit/unittest/data/clangtools/empty.yaml0
-rw-r--r--tests/unit/unittest/data/clangtools/main.cpp4
-rw-r--r--tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.cpp2
-rw-r--r--tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.yaml14
-rw-r--r--tests/unit/unittest/data/symbolscollector/class.cpp14
-rw-r--r--tests/unit/unittest/filepathcache-test.cpp179
-rw-r--r--tests/unit/unittest/filepathstorage-test.cpp87
-rw-r--r--tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp12
-rw-r--r--tests/unit/unittest/fixit-test.cpp12
-rw-r--r--tests/unit/unittest/generatedfiles-test.cpp27
-rw-r--r--tests/unit/unittest/gtest-creator-printing.cpp45
-rw-r--r--tests/unit/unittest/gtest-creator-printing.h18
-rw-r--r--tests/unit/unittest/mockbuilddependenciesprovider.h11
-rw-r--r--tests/unit/unittest/mockbuilddependenciesstorage.h3
-rw-r--r--tests/unit/unittest/mockfilepathcaching.h3
-rw-r--r--tests/unit/unittest/mockfilepathstorage.h17
-rw-r--r--tests/unit/unittest/mockgeneratedfiles.h1
-rw-r--r--tests/unit/unittest/mockmutex.h13
-rw-r--r--tests/unit/unittest/mockprecompiledheaderstorage.h12
-rw-r--r--tests/unit/unittest/mockprojectpartsmanager.h13
-rw-r--r--tests/unit/unittest/mockprojectpartsstorage.h3
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.cpp27
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.h45
-rw-r--r--tests/unit/unittest/mocksqlitewritestatement.h2
-rw-r--r--tests/unit/unittest/mocksymbolindexertaskqueue.h3
-rw-r--r--tests/unit/unittest/mocksymbolquery.h7
-rw-r--r--tests/unit/unittest/mocksymbolscollector.h3
-rw-r--r--tests/unit/unittest/modifiedtimechecker-test.cpp80
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp114
-rw-r--r--tests/unit/unittest/pchmanagerclient-test.cpp7
-rw-r--r--tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp2
-rw-r--r--tests/unit/unittest/pchmanagerserver-test.cpp72
-rw-r--r--tests/unit/unittest/pchtaskqueue-test.cpp10
-rw-r--r--tests/unit/unittest/precompiledheaderstorage-test.cpp151
-rw-r--r--tests/unit/unittest/preprocessormacrocollector-test.cpp71
-rw-r--r--tests/unit/unittest/processevents-utilities.cpp4
-rw-r--r--tests/unit/unittest/projectpartsmanager-test.cpp582
-rw-r--r--tests/unit/unittest/projectpartsstorage-test.cpp178
-rw-r--r--tests/unit/unittest/projectupdater-test.cpp130
-rw-r--r--tests/unit/unittest/readexporteddiagnostics-test.cpp352
-rw-r--r--tests/unit/unittest/refactoringclientserverinprocess-test.cpp9
-rw-r--r--tests/unit/unittest/refactoringdatabaseinitializer-test.cpp7
-rw-r--r--tests/unit/unittest/refactoringengine-test.cpp91
-rw-r--r--tests/unit/unittest/refactoringprojectupdater-test.cpp13
-rw-r--r--tests/unit/unittest/refactoringserver-test.cpp29
-rw-r--r--tests/unit/unittest/skippedsourceranges-test.cpp6
-rw-r--r--tests/unit/unittest/sourcerange-test.cpp12
-rw-r--r--tests/unit/unittest/stringcache-test.cpp529
-rw-r--r--tests/unit/unittest/symbolindexer-test.cpp10
-rw-r--r--tests/unit/unittest/symbolquery-test.cpp57
-rw-r--r--tests/unit/unittest/symbolscollector-test.cpp83
-rw-r--r--tests/unit/unittest/unittest.pro7
-rw-r--r--tests/unit/unittest/usedmacrocollector-test.cpp2
2292 files changed, 84715 insertions, 28934 deletions
diff --git a/.gitignore b/.gitignore
index 956f30769f..fa9097edfc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,6 +102,9 @@ phony.c
# Squish generated files
/tests/system/suite_*/config.xml
+# Clang tooling files
+compile_commands.json
+
# Directories to ignore
# ---------------------
diff --git a/.gitmodules b/.gitmodules
index 6fdaf4283f..d6d89e9ce4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,3 +6,6 @@
path = src/tools/perfparser
url = ../perfparser.git
ignore = dirty
+[submodule "litehtml"]
+ path = src/plugins/help/qlitehtml/litehtml
+ url = https://github.com/litehtml/litehtml.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41278e8d93..c047ca59d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,8 +35,8 @@ if (WITH_TESTS)
endif()
find_package(Qt5
- COMPONENTS Concurrent Core Network PrintSupport Qml Quick QuickWidgets
- Sql Widgets ${_TEST_QT_COMPONENT}
+ COMPONENTS Concurrent Core LinguistTools Network PrintSupport Qml Quick
+ QuickWidgets Sql Widgets ${_TEST_QT_COMPONENT}
REQUIRED
)
diff --git a/README.md b/README.md
index 94738e5fae..7ff6307201 100644
--- a/README.md
+++ b/README.md
@@ -287,6 +287,32 @@ Note that the plugin is disabled by default.
Qt Creator includes the following third-party components,
we thank the authors who made this possible:
+### YAML Parser yaml-cpp (MIT License)
+
+ https://github.com/jbeder/yaml-cpp
+
+ QtCreator/src/libs/3rdparty/yaml-cpp
+
+ Copyright (c) 2008-2015 Jesse Beder.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
### KSyntaxHighlighting
Syntax highlighting engine for Kate syntax definitions
@@ -475,3 +501,42 @@ SQLite (https://www.sqlite.org) is in the Public Domain.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
The font and license files can be found in QtCreator/src/libs/3rdparty/fonts.
+
+### JSON Library by Niels Lohmann
+
+ Used by the Chrome Trace Format Visualizer plugin instead of QJson
+ because of QJson's current hard limit of 128 Mb object size and
+ trace files often being much larger.
+
+ The sources can be found in `QtCreator/src/libs/3rdparty/json`.
+
+ The class is licensed under the MIT License:
+
+ Copyright © 2013-2019 Niels Lohmann
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the “Software”), to
+ deal in the Software without restriction, including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is furnished
+ to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ \endcode
+
+ The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is
+ licensed under the MIT License (see above). Copyright © 2008-2009 Björn
+ Hoehrmann bjoern@hoehrmann.de
+
+ The class contains a slightly modified version of the Grisu2 algorithm
+ from Florian Loitsch which is licensed under the MIT License (see above).
+ Copyright © 2009 Florian Loitsch
diff --git a/cmake/FindDesignerComponents.cmake b/cmake/FindDesignerComponents.cmake
index 58f957b468..3d2b0255de 100644
--- a/cmake/FindDesignerComponents.cmake
+++ b/cmake/FindDesignerComponents.cmake
@@ -35,7 +35,7 @@ if (NOT _designer_location)
endif()
get_target_property(_designer_is_framework Qt5::Designer FRAMEWORK)
find_library(DesignerComponents_LIBRARIES NAMES Qt5DesignerComponents QtDesignerComponents
- NO_DEFAULT_PATH PATHS "${_designer_location}/.." "${_designer_location}/../..")
+ HINTS "${_designer_location}/.." "${_designer_location}/../..")
if (_designer_is_framework)
if (DesignerComponents_LIBRARIES)
diff --git a/cmake/Findyaml-cpp.cmake b/cmake/Findyaml-cpp.cmake
new file mode 100644
index 0000000000..bcdcfd104b
--- /dev/null
+++ b/cmake/Findyaml-cpp.cmake
@@ -0,0 +1,113 @@
+#.rst:
+# Findyaml-cpp
+# -----------------
+#
+# Try to find a yaml-cpp config/package.
+# If that fails, build and use our copy of it.
+#
+
+find_package(yaml-cpp 0.5 QUIET NO_MODULE)
+if (yaml-cpp_FOUND)
+ # target doesn't set include directory for some reason
+ get_filename_component(yaml_cpp_include_dir ${YAML_CPP_INCLUDE_DIR} ABSOLUTE)
+ target_include_directories(yaml-cpp INTERFACE ${yaml_cpp_include_dir})
+else()
+ set(yaml-cpp_FOUND 1)
+ set_package_properties(yaml-cpp PROPERTIES DESCRIPTION "using internal src/libs/3rdparty/yaml-cpp")
+ set(YAML_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src/libs/3rdparty/yaml-cpp)
+ add_qtc_library(yaml-cpp
+ DEFINES YAML_CPP_DLL yaml_cpp_EXPORTS
+ INCLUDES ${YAML_SOURCE_DIR}/include
+ PUBLIC_DEFINES YAML_CPP_DLL
+ PUBLIC_INCLUDES ${YAML_SOURCE_DIR}/include
+ SOURCES
+ ${YAML_SOURCE_DIR}/include/yaml-cpp
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/anchor.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/binary.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/dll.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/emitfromevents.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/emitter.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/emitterdef.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/emittermanip.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/emitterstyle.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/eventhandler.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/exceptions.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/mark.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/convert.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/bool_type.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/impl.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/iterator.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/iterator_fwd.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/memory.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/node.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/node_data.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/node_iterator.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/detail/node_ref.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/emit.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/impl.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/iterator.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/node.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/parse.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/ptr.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/node/type.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/noncopyable.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/null.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/ostream_wrapper.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/parser.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/stlemitter.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/traits.h
+ ${YAML_SOURCE_DIR}/include/yaml-cpp/yaml.h
+ ${YAML_SOURCE_DIR}/src/binary.cpp
+ ${YAML_SOURCE_DIR}/src/collectionstack.h
+ ${YAML_SOURCE_DIR}/src/convert.cpp
+ ${YAML_SOURCE_DIR}/src/directives.cpp
+ ${YAML_SOURCE_DIR}/src/directives.h
+ ${YAML_SOURCE_DIR}/src/emit.cpp
+ ${YAML_SOURCE_DIR}/src/emitfromevents.cpp
+ ${YAML_SOURCE_DIR}/src/emitter.cpp
+ ${YAML_SOURCE_DIR}/src/emitterstate.cpp
+ ${YAML_SOURCE_DIR}/src/emitterstate.h
+ ${YAML_SOURCE_DIR}/src/emitterutils.cpp
+ ${YAML_SOURCE_DIR}/src/emitterutils.h
+ ${YAML_SOURCE_DIR}/src/exceptions.cpp
+ ${YAML_SOURCE_DIR}/src/exp.cpp
+ ${YAML_SOURCE_DIR}/src/exp.h
+ ${YAML_SOURCE_DIR}/src/indentation.h
+ ${YAML_SOURCE_DIR}/src/memory.cpp
+ ${YAML_SOURCE_DIR}/src/node.cpp
+ ${YAML_SOURCE_DIR}/src/node_data.cpp
+ ${YAML_SOURCE_DIR}/src/nodebuilder.cpp
+ ${YAML_SOURCE_DIR}/src/nodebuilder.h
+ ${YAML_SOURCE_DIR}/src/nodeevents.cpp
+ ${YAML_SOURCE_DIR}/src/nodeevents.h
+ ${YAML_SOURCE_DIR}/src/null.cpp
+ ${YAML_SOURCE_DIR}/src/ostream_wrapper.cpp
+ ${YAML_SOURCE_DIR}/src/parse.cpp
+ ${YAML_SOURCE_DIR}/src/parser.cpp
+ ${YAML_SOURCE_DIR}/src/ptr_vector.h
+ ${YAML_SOURCE_DIR}/src/regex_yaml.cpp
+ ${YAML_SOURCE_DIR}/src/regex_yaml.h
+ ${YAML_SOURCE_DIR}/src/regeximpl.h
+ ${YAML_SOURCE_DIR}/src/scanner.cpp
+ ${YAML_SOURCE_DIR}/src/scanner.h
+ ${YAML_SOURCE_DIR}/src/scanscalar.cpp
+ ${YAML_SOURCE_DIR}/src/scanscalar.h
+ ${YAML_SOURCE_DIR}/src/scantag.cpp
+ ${YAML_SOURCE_DIR}/src/scantag.h
+ ${YAML_SOURCE_DIR}/src/scantoken.cpp
+ ${YAML_SOURCE_DIR}/src/setting.h
+ ${YAML_SOURCE_DIR}/src/simplekey.cpp
+ ${YAML_SOURCE_DIR}/src/singledocparser.cpp
+ ${YAML_SOURCE_DIR}/src/singledocparser.h
+ ${YAML_SOURCE_DIR}/src/stream.cpp
+ ${YAML_SOURCE_DIR}/src/stream.h
+ ${YAML_SOURCE_DIR}/src/streamcharsource.h
+ ${YAML_SOURCE_DIR}/src/stringsource.h
+ ${YAML_SOURCE_DIR}/src/tag.cpp
+ ${YAML_SOURCE_DIR}/src/tag.h
+ ${YAML_SOURCE_DIR}/src/token.h
+ )
+ unset(YAML_SOURCE_DIR)
+endif()
diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake
index 13ff1970d9..f6bade8d26 100644
--- a/cmake/QtCreatorAPI.cmake
+++ b/cmake/QtCreatorAPI.cmake
@@ -1,6 +1,23 @@
include(FeatureSummary)
#
+# Default Qt compilation defines
+#
+
+list(APPEND DEFAULT_DEFINES
+ QT_CREATOR
+ QT_NO_JAVA_STYLE_ITERATORS
+ QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII
+ QT_DISABLE_DEPRECATED_BEFORE=0x050900
+ QT_USE_FAST_OPERATOR_PLUS
+ QT_USE_FAST_CONCATENATION
+)
+
+if (WIN32)
+ list(APPEND DEFAULT_DEFINES UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS)
+endif()
+
+#
# Setup path handling
#
@@ -81,6 +98,22 @@ set(__QTC_TESTS "" CACHE INTERNAL "*** Internal ***")
# Internal functions
#
+function(append_extra_translations target_name)
+ if(NOT ARGN)
+ return()
+ endif()
+
+ if(TARGET "${target_name}")
+ get_target_property(_input "${target_name}" QT_EXTRA_TRANSLATIONS)
+ if (_input)
+ set(_output "${_input}" "${ARGN}")
+ else()
+ set(_output "${ARGN}")
+ endif()
+ set_target_properties("${target_name}" PROPERTIES QT_EXTRA_TRANSLATIONS "${_output}")
+ endif()
+endfunction()
+
function(update_cached_list name value)
set(_tmp_list "${${name}}")
list(APPEND _tmp_list "${value}")
@@ -172,7 +205,10 @@ function(set_public_includes target includes)
endforeach()
endfunction()
-function(fix_test_environment test_name)
+function(finalize_test_setup test_name)
+ # Never translate tests:
+ set_tests_properties(${name} PROPERTIES QT_SKIP_TRANSLATION ON)
+
if (WIN32)
list(APPEND env_path $ENV{PATH})
list(APPEND env_path ${CMAKE_BINARY_DIR}/${IDE_PLUGIN_PATH})
@@ -252,11 +288,8 @@ endfunction()
function(enable_pch target)
if (BUILD_WITH_PCH)
- get_target_property(target_sources ${target} SOURCES)
- list(LENGTH target_sources target_sources_number)
- if (${target_sources_number} GREATER "3")
- set(PCH_FILE "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_pch.h")
-
+ get_target_property(target_type ${target} TYPE)
+ if (NOT ${target_type} STREQUAL "OBJECT_LIBRARY")
function(_recursively_collect_dependencies input_target)
get_target_property(input_type ${input_target} TYPE)
if (${input_type} STREQUAL "INTERFACE_LIBRARY")
@@ -273,15 +306,38 @@ function(enable_pch target)
endfunction()
_recursively_collect_dependencies(${target})
+ function(_add_pch_target pch_target pch_file pch_dependency)
+ if (EXISTS ${pch_file})
+ add_library(${pch_target} STATIC
+ ${CMAKE_BINARY_DIR}/empty_pch.cpp)
+ target_compile_definitions(${pch_target} PRIVATE ${DEFAULT_DEFINES})
+ set_target_properties(${pch_target} PROPERTIES
+ PRECOMPILE_HEADERS ${pch_file})
+ target_link_libraries(${pch_target} PRIVATE ${pch_dependency})
+ endif()
+ endfunction()
+
+ if (NOT TARGET QtCreatorPchGui AND NOT TARGET QtCreatorPchConsole)
+ file(WRITE ${CMAKE_BINARY_DIR}/empty_pch.cpp.in "/*empty file*/")
+ configure_file(
+ ${CMAKE_BINARY_DIR}/empty_pch.cpp.in
+ ${CMAKE_BINARY_DIR}/empty_pch.cpp)
+
+ _add_pch_target(QtCreatorPchGui
+ "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h" Qt5::Widgets)
+ _add_pch_target(QtCreatorPchConsole
+ "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_pch.h" Qt5::Core)
+ endif()
+
+ set(PCH_TARGET QtCreatorPchConsole)
if ("Qt5::Widgets" IN_LIST dependencies)
- set(PCH_FILE "${PROJECT_SOURCE_DIR}/src/shared/qtcreator_gui_pch.h")
+ set(PCH_TARGET QtCreatorPchGui)
endif()
- if (EXISTS ${PCH_FILE})
- set_target_properties(${target} PROPERTIES PRECOMPILE_HEADERS ${PCH_FILE})
+ if (TARGET ${PCH_TARGET})
+ set_target_properties(${target} PROPERTIES
+ PRECOMPILE_HEADERS_REUSE_FROM ${PCH_TARGET})
endif()
- elseif(WITH_DEBUG_CMAKE)
- message(STATUS "Skipped PCH for ${target}")
endif()
endif()
endfunction()
@@ -294,13 +350,22 @@ function(qtc_output_binary_dir varName)
endif()
endfunction()
+function(condition_info varName condition)
+ if (NOT ${condition})
+ set(${varName} "" PARENT_SCOPE)
+ else()
+ string(REPLACE ";" " " _contents "${${condition}}")
+ set(${varName} "with CONDITION ${_contents}" PARENT_SCOPE)
+ endif()
+endfunction()
+
#
# Public API functions
#
function(add_qtc_library name)
- cmake_parse_arguments(_arg "STATIC;OBJECT" ""
- "DEFINES;DEPENDS;INCLUDES;PUBLIC_DEFINES;PUBLIC_DEPENDS;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;PROPERTIES" ${ARGN}
+ cmake_parse_arguments(_arg "STATIC;OBJECT;SKIP_TRANSLATION" ""
+ "DEFINES;DEPENDS;EXTRA_TRANSLATIONS;INCLUDES;PUBLIC_DEFINES;PUBLIC_DEPENDS;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;PROPERTIES" ${ARGN}
)
if (${_arg_UNPARSED_ARGUMENTS})
@@ -324,7 +389,7 @@ function(add_qtc_library name)
add_library(${IDE_CASED_ID}::${name} ALIAS ${name})
set_public_headers(${name} "${_arg_SOURCES}")
- if (${name} MATCHES "^[^0-9]+")
+ if (${name} MATCHES "^[^0-9-]+$")
string(TOUPPER "${name}_LIBRARY" EXPORT_SYMBOL)
endif()
@@ -362,6 +427,11 @@ function(add_qtc_library name)
set_property(SOURCE ${file} PROPERTY SKIP_AUTOMOC ON)
endforeach()
+ set(skip_translation OFF)
+ if (_arg_SKIP_TRANSLATION)
+ set(skip_translation ON)
+ endif()
+
qtc_output_binary_dir(_output_binary_dir)
set_target_properties(${name} PROPERTIES
SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
@@ -404,13 +474,15 @@ function(add_qtc_library name)
COMPONENT Devel EXCLUDE_FROM_ALL
)
endif()
+
+ append_extra_translations("${name}" "${_arg_EXTRA_TRANSLATIONS}")
endfunction(add_qtc_library)
function(add_qtc_plugin target_name)
cmake_parse_arguments(_arg
- "EXPERIMENTAL;SKIP_DEBUG_CMAKE_FILE_CHECK;SKIP_INSTALL"
+ "EXPERIMENTAL;SKIP_DEBUG_CMAKE_FILE_CHECK;SKIP_INSTALL;INTERNAL_ONLY;SKIP_TRANSLATION"
"VERSION;COMPAT_VERSION;PLUGIN_JSON_IN;PLUGIN_PATH;PLUGIN_NAME;OUTPUT_NAME"
- "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;SOURCES;EXPLICIT_MOC"
+ "CONDITION;DEPENDS;EXTRA_TRANSLATIONS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;SOURCES;EXPLICIT_MOC"
${ARGN}
)
@@ -425,12 +497,9 @@ function(add_qtc_plugin target_name)
set(name ${_arg_PLUGIN_NAME})
endif()
+ condition_info(_extra_text _arg_CONDITION)
if (NOT _arg_CONDITION)
set(_arg_CONDITION ON)
- set(_extra_text "")
- else()
- string(REPLACE ";" " " _contents "${_arg_CONDITION}")
- set(_extra_text "with CONDITION ${_contents}")
endif()
string(TOUPPER "BUILD_PLUGIN_${target_name}" _build_plugin_var)
@@ -438,7 +507,11 @@ function(add_qtc_plugin target_name)
if (DEFINED ENV{QTC_${_build_plugin_var}})
set(_build_plugin_default "$ENV{QTC_${_build_plugin_var}}")
endif()
- set(${_build_plugin_var} "${_build_plugin_default}" CACHE BOOL "Build plugin ${name}.")
+ if (_arg_INTERNAL_ONLY)
+ set(${_build_plugin_var} "${_build_plugin_default}")
+ else()
+ set(${_build_plugin_var} "${_build_plugin_default}" CACHE BOOL "Build plugin ${name}.")
+ endif()
if ((${_arg_CONDITION}) AND ${_build_plugin_var})
set(_plugin_enabled ON)
@@ -446,7 +519,9 @@ function(add_qtc_plugin target_name)
set(_plugin_enabled OFF)
endif()
- add_feature_info("Plugin ${name}" _plugin_enabled "${_extra_text}")
+ if (NOT _arg_INTERNAL_ONLY)
+ add_feature_info("Plugin ${name}" _plugin_enabled "${_extra_text}")
+ endif()
if (NOT _plugin_enabled)
return()
endif()
@@ -560,6 +635,11 @@ function(add_qtc_plugin target_name)
set(plugin_dir "${_arg_PLUGIN_PATH}")
endif()
+ set(skip_translation OFF)
+ if (_arg_SKIP_TRANSLATION)
+ set(skip_translation ON)
+ endif()
+
qtc_output_binary_dir(_output_binary_dir)
set_target_properties(${target_name} PROPERTIES
SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
@@ -573,8 +653,10 @@ function(add_qtc_plugin target_name)
ARCHIVE_OUTPUT_DIRECTORY "${_output_binary_dir}/${plugin_dir}"
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${plugin_dir}"
OUTPUT_NAME "${name}"
+ QT_SKIP_TRANSLATION "${skip_translation}"
${_arg_PROPERTIES}
)
+ append_extra_translations("${target_name}" "${_arg_EXTRA_TRANSLATIONS}")
enable_pch(${target_name})
foreach(file IN LISTS _arg_EXPLICIT_MOC)
@@ -596,7 +678,7 @@ endfunction()
function(extend_qtc_target target_name)
cmake_parse_arguments(_arg
""
- "SOURCES_PREFIX"
+ "SOURCES_PREFIX;FEATURE_INFO"
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC"
${ARGN}
)
@@ -605,10 +687,19 @@ function(extend_qtc_target target_name)
message(FATAL_ERROR "extend_qtc_target had unparsed arguments")
endif()
+ condition_info(_extra_text _arg_CONDITION)
if (NOT _arg_CONDITION)
set(_arg_CONDITION ON)
endif()
- if (NOT (${_arg_CONDITION}))
+ if (${_arg_CONDITION})
+ set(_feature_enabled ON)
+ else()
+ set(_feature_enabled OFF)
+ endif()
+ if (_arg_FEATURE_INFO)
+ add_feature_info(${_arg_FEATURE_INFO} _feature_enabled "${_extra_text}")
+ endif()
+ if (NOT _feature_enabled)
return()
endif()
@@ -664,7 +755,9 @@ function(extend_qtc_plugin target_name)
endfunction()
function(add_qtc_executable name)
- cmake_parse_arguments(_arg "SKIP_INSTALL" "DESTINATION" "DEFINES;DEPENDS;INCLUDES;SOURCES;PROPERTIES" ${ARGN})
+ cmake_parse_arguments(_arg "SKIP_INSTALL;SKIP_TRANSLATION"
+ "DESTINATION"
+ "DEFINES;DEPENDS;EXTRA_TRANSLATIONS;INCLUDES;SOURCES;PROPERTIES" ${ARGN})
if ($_arg_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "add_qtc_executable had unparsed arguments!")
@@ -707,13 +800,21 @@ function(add_qtc_executable name)
target_include_directories("${name}" PRIVATE "${CMAKE_BINARY_DIR}/src" ${_arg_INCLUDES})
target_compile_definitions("${name}" PRIVATE ${_arg_DEFINES} ${TEST_DEFINES} ${DEFAULT_DEFINES})
target_link_libraries("${name}" PRIVATE ${_arg_DEPENDS} ${_TEST_DEPENDS})
+
+ set(skip_translation OFF)
+ if (_arg_SKIP_TRANSLATION)
+ set(skip_translation ON)
+ endif()
+
qtc_output_binary_dir(_output_binary_dir)
set_target_properties("${name}" PROPERTIES
BUILD_RPATH "${_RPATH_BASE}/${_RELATIVE_LIB_PATH}"
INSTALL_RPATH "${_RPATH_BASE}/${_RELATIVE_LIB_PATH}"
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}"
+ QT_SKIP_TRANSLATION "${skip_translation}"
${_arg_PROPERTIES}
)
+ append_extra_translations("${name}" "${_arg_EXTRA_TRANSLATIONS}")
enable_pch(${name})
if (NOT _arg_SKIP_INSTALL)
@@ -759,7 +860,7 @@ function(add_qtc_test name)
if (NOT _arg_GTEST)
add_test(NAME ${name} COMMAND ${name})
- fix_test_environment(${name})
+ finalize_test_setup(${name})
endif()
endfunction()
@@ -769,6 +870,6 @@ function(finalize_qtc_gtest test_name)
gtest_add_tests(TARGET ${test_name} SOURCES ${test_sources} TEST_LIST test_list)
foreach(test IN LISTS test_list)
- fix_test_environment(${test})
+ finalize_test_setup(${test})
endforeach()
endfunction()
diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake
index 5f8c164e7b..c973fa6f03 100644
--- a/cmake/QtCreatorIDEBranding.cmake
+++ b/cmake/QtCreatorIDEBranding.cmake
@@ -1,10 +1,9 @@
#BINARY_ARTIFACTS_BRANCH = master
#PROJECT_USER_FILE_EXTENSION = .user
-set(IDE_VERSION "4.10.1") # The IDE version.
-set(IDE_VERSION_COMPAT "4.10.0") # The IDE Compatibility version.
-set(IDE_VERSION_DISPLAY "4.10.1") # The IDE display version.
-set(IDE_COPYRIGHT_YEAR "2019") # The IDE copyright year.
+set(IDE_VERSION "4.10.82") # The IDE version.
+set(IDE_VERSION_COMPAT "4.10.82") # The IDE Compatibility version.
+set(IDE_VERSION_DISPLAY "4.11.0-beta1") # The IDE display version.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
set(IDE_COPY_SETTINGSVARIANT "Nokia") # The IDE settings to initially import.
diff --git a/doc/images/qtcreator-cpp-class-wizard.png b/doc/images/qtcreator-cpp-class-wizard.png
index c7e61301dc..02db85144b 100644
--- a/doc/images/qtcreator-cpp-class-wizard.png
+++ b/doc/images/qtcreator-cpp-class-wizard.png
Binary files differ
diff --git a/doc/images/qtcreator-editortoolbar-symbols.png b/doc/images/qtcreator-editortoolbar-symbols.png
index 7a5471181e..8128c7ae13 100644
--- a/doc/images/qtcreator-editortoolbar-symbols.png
+++ b/doc/images/qtcreator-editortoolbar-symbols.png
Binary files differ
diff --git a/doc/images/qtcreator-kit-webassembly.png b/doc/images/qtcreator-kit-webassembly.png
new file mode 100644
index 0000000000..d37450d245
--- /dev/null
+++ b/doc/images/qtcreator-kit-webassembly.png
Binary files differ
diff --git a/doc/images/qtcreator-new-subproject.png b/doc/images/qtcreator-new-subproject.png
new file mode 100644
index 0000000000..a55daead08
--- /dev/null
+++ b/doc/images/qtcreator-new-subproject.png
Binary files differ
diff --git a/doc/images/qtcreator-options-cpp-files.png b/doc/images/qtcreator-options-cpp-files.png
index 0a4b46022b..f373219e19 100644
--- a/doc/images/qtcreator-options-cpp-files.png
+++ b/doc/images/qtcreator-options-cpp-files.png
Binary files differ
diff --git a/doc/images/qtcreator-options-environment-system.png b/doc/images/qtcreator-options-environment-system.png
new file mode 100644
index 0000000000..e9d5b1dea4
--- /dev/null
+++ b/doc/images/qtcreator-options-environment-system.png
Binary files differ
diff --git a/doc/images/qtcreator-settings-run-webassembly.png b/doc/images/qtcreator-settings-run-webassembly.png
new file mode 100644
index 0000000000..e9396c30fc
--- /dev/null
+++ b/doc/images/qtcreator-settings-run-webassembly.png
Binary files differ
diff --git a/doc/src/editors/creator-coding-edit-mode.qdoc b/doc/src/editors/creator-coding-edit-mode.qdoc
index 51695520bc..7c458a7d4c 100644
--- a/doc/src/editors/creator-coding-edit-mode.qdoc
+++ b/doc/src/editors/creator-coding-edit-mode.qdoc
@@ -114,6 +114,11 @@
the new encoding, select \uicontrol {Save with Encoding}.
\endif
+ \section2 Selecting Line Ending Style
+
+ To switch between Windows line endings (CRLF) and Unix line endings (LF),
+ select the ending style on the editor toolbar (6).
+
\section1 Splitting the Editor View
Split the editor view or open the editor in a new window when you want to
diff --git a/doc/src/editors/creator-only/creator-language-server.qdoc b/doc/src/editors/creator-only/creator-language-server.qdoc
index 9dc5d1e84f..b354f762b4 100644
--- a/doc/src/editors/creator-only/creator-language-server.qdoc
+++ b/doc/src/editors/creator-only/creator-language-server.qdoc
@@ -39,6 +39,9 @@
\list
\li \l{Completing Code}{Code completion}
\li Highlighting the symbol under cursor
+ \li \l{Semantic Highlighting}{Semantic highlighting}, as defined in
+ \l{https://github.com/microsoft/vscode-languageserver-node/pull/367}
+ {Proposal of the semantic highlighting protocol extension}
\li Navigating in the code by using the \l{Searching with the Locator}
{locator} or \l{Moving to Symbol Definition or Declaration}
{moving to the symbol definition}
diff --git a/doc/src/editors/creator-semantic-highlighting.qdoc b/doc/src/editors/creator-semantic-highlighting.qdoc
index 28dc1a1763..ae6cb6a653 100644
--- a/doc/src/editors/creator-semantic-highlighting.qdoc
+++ b/doc/src/editors/creator-semantic-highlighting.qdoc
@@ -60,6 +60,10 @@
\l{https://docs.kde.org/stable5/en/applications/katepart/highlight.html}
{Working with Syntax Highlighting}.
+ Font attributes that a syntax definition file explicitly specifies, such as
+ bold, italic, underline, or strike through, are applied. Colors are applied
+ if they are readable with \QC themes.
+
If the editor cannot find the highlight definition for a file that you open
for editing, it prompts you to update the highlight definition files. Select
\uicontrol {Update Definitions} to update the files.
diff --git a/doc/src/howto/creator-sidebar-views.qdoc b/doc/src/howto/creator-sidebar-views.qdoc
index 9140af5f35..f6946423f5 100644
--- a/doc/src/howto/creator-sidebar-views.qdoc
+++ b/doc/src/howto/creator-sidebar-views.qdoc
@@ -287,6 +287,33 @@
closed when \uicontrol {Close All} is used.
\endlist
+ To specify settings for opening files and handling open files, select
+ \uicontrol Tools > \uicontrol Options > \uicontrol Environment >
+ \uicontrol System:
+
+ \image qtcreator-options-environment-system.png "Environment options System tab"
+
+ \list
+ \li In the \uicontrol {When files are externally modified} field,
+ select whether you want to be prompted to reload open files
+ that were modified externally. For example, when you pull
+ changes from a version control system.
+ \li Select the \uicontrol {Auto-save modified files} check box to
+ automatically save changed files at the intervals specified in
+ the \uicontrol Interval field.
+ \li Select the \uicontrol {Auto-suspend unmodified files} check
+ box to automatically free the resources of open files after
+ prolonged inactivity. The files are still listed in the
+ \uicontrol {Open Documents} view. Set the minimum number of files
+ that should be kept in memory in the \uicontrol {Files to keep open}
+ field.
+ \li Select the \uicontrol {Warn before opening text files greater than}
+ check box to receive warnings about opening big text files.
+ \li In the \uicontrol {Maximum number of entries in "Recent Files"}
+ field, set the number of recently opened files listed in
+ \uicontrol File > \uicontrol {Recent Files}.
+ \endlist
+
\section1 Viewing Defined Types and Symbols
The \uicontrol Outline view shows an overview of defined types and other
diff --git a/doc/src/overview/creator-acknowledgements.qdoc b/doc/src/overview/creator-acknowledgements.qdoc
index 43bac0ad4c..1364f75d39 100644
--- a/doc/src/overview/creator-acknowledgements.qdoc
+++ b/doc/src/overview/creator-acknowledgements.qdoc
@@ -51,6 +51,32 @@
\QC contains the following third-party components:
\list
+ \li \b{YAML Parser yaml-cpp (MIT License)}
+
+ \l {https://github.com/jbeder/yaml-cpp}
+
+ QtCreator/src/libs/3rdparty/yaml-cpp
+
+ Copyright (c) 2008-2015 Jesse Beder.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
\li \b{Syntax highlighting engine for Kate syntax definitions}
This is a stand-alone implementation of the Kate syntax highlighting engine.
@@ -508,5 +534,46 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\endcode
+ \li \b{JSON Library by Niels Lohmann}
+
+ Used by the Chrome Trace Format Visualizer plugin instead of QJson
+ because of QJson's current hard limit of 128 Mb object size and
+ trace files often being much larger.
+
+ The sources can be found in
+ \c QtCreator/src/libs/3rdparty/json.
+
+ The class is licensed under the MIT License:
+
+ Copyright (C) 2013-2019 Niels Lohmann
+
+ \code
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"), to
+ deal in the Software without restriction, including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is furnished
+ to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ \endcode
+
+ The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is
+ licensed under the MIT License (see above). Copyright (C) 2008-2009 Bjoern
+ Hoehrmann <bjoern@hoehrmann.de>
+
+ The class contains a slightly modified version of the Grisu2 algorithm
+ from Florian Loitsch which is licensed under the MIT License (see above).
+ Copyright (C) 2009 Florian Loitsch
+
\endlist
*/
diff --git a/doc/src/overview/creator-only/creator-mobile-targets.qdoc b/doc/src/overview/creator-only/creator-mobile-targets.qdoc
index 9cc5039656..4c5ff795a3 100644
--- a/doc/src/overview/creator-only/creator-mobile-targets.qdoc
+++ b/doc/src/overview/creator-only/creator-mobile-targets.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -47,6 +47,9 @@
Additionally, you can connect Linux-based devices by using a WLAN
connection.
+ The experimental WebAssembly plugin enables you to build your applications
+ in WebAssembly format, to deploy them, and to run them in a web browser.
+
\list
\li \l{Connecting Android Devices}
@@ -95,6 +98,12 @@
\list
+ \li \l{Building Applications for the Web}
+
+ You can use the experimental Qt WebAssembly plugin to build
+ applications in WebAssembly format, to deploy them, and to
+ run them in a web browser.
+
\li \l{http://doc.qt.io/qtcreator/creator-overview-qtasam.html}
{Qt Application Manager}
diff --git a/doc/src/overview/creator-only/creator-overview.qdoc b/doc/src/overview/creator-only/creator-overview.qdoc
index 09ef2766e4..4210894cdf 100644
--- a/doc/src/overview/creator-only/creator-overview.qdoc
+++ b/doc/src/overview/creator-only/creator-overview.qdoc
@@ -40,7 +40,8 @@
\QC is an integrated development environment (IDE) that provides you with
tools to design and develop applications with the Qt application framework.
Qt is designed for developing applications and user interfaces once and
- deploying them to several desktop, embedded, and mobile operating systems. \QC
+ deploying them to several desktop, embedded, and mobile operating systems or
+ web browsers (experimental). \QC
provides you with tools for accomplishing your tasks throughout the whole
application development life-cycle, from creating a project to deploying the
application to the target platforms.
diff --git a/doc/src/overview/creator-only/creator-supported-platforms.qdoc b/doc/src/overview/creator-only/creator-supported-platforms.qdoc
index a64947d802..55262c469e 100644
--- a/doc/src/overview/creator-only/creator-supported-platforms.qdoc
+++ b/doc/src/overview/creator-only/creator-supported-platforms.qdoc
@@ -39,7 +39,8 @@
\title Supported Platforms
You can install and run \QC on several operating systems to create
- applications for multiple desktop, embedded, and mobile device platforms.
+ applications for multiple desktop, embedded, and mobile device platforms,
+ as well as web browsers (experimental).
\QC automatically runs scheduled checks for updates based on the settings
specified in \uicontrol Tools > \uicontrol Options \uicontrol Environment >
diff --git a/doc/src/overview/creator-only/creator-target-platforms.qdocinc b/doc/src/overview/creator-only/creator-target-platforms.qdocinc
index a936ae7a9a..c269e61404 100644
--- a/doc/src/overview/creator-only/creator-target-platforms.qdocinc
+++ b/doc/src/overview/creator-only/creator-target-platforms.qdocinc
@@ -46,6 +46,8 @@
\li Universal Windows Platform (UWP)
+ \li WebAssembly
+
\endlist
\section2 Embedded Devices
@@ -104,6 +106,11 @@
\li
\li
\li \image ok
+ \row
+ \li WebAssembly
+ \li \image ok
+ \li \image ok
+ \li \image ok
\endtable
* See \l{Running on QNX Devices} for limitations.
diff --git a/doc/src/projects/creator-only/creator-projects-building.qdoc b/doc/src/projects/creator-only/creator-projects-building.qdoc
index ea9bc1d230..14f9770456 100644
--- a/doc/src/projects/creator-only/creator-projects-building.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-building.qdoc
@@ -69,15 +69,26 @@
While the application is being built, the \uicontrol Build button changes to
a \uicontrol {Cancel Build} button (3). To cancel the build, select the
- button or press \key {Alt+Backspace}.
+ button or press \key {Alt+Backspace}. If you selected a build command and
+ decide you would also like to run the application, you can select the
+ \uicontrol Run button to schedule running the project after building is done.
For more information on the options you have, see
\l{Specifying Build Settings}.
+ \section1 Additional Build Commands
+
+ To build all open projects, select \uicontrol Build > \uicontrol {Build All}.
+ If building one application fails, \QC displays an error message and
+ continues building the other applications.
+
To quickly check the compile output for changes that you made in one file or
subproject, you can use the \uicontrol Build menu commands to build a file or
subproject.
+ To build the executable that corresponds to the selected run configuration,
+ select \uicontrol Build > \uicontrol {Build for Run Configuration}.
+
To remove all build artifacts, select \uicontrol Build > \uicontrol {Clean All} or
\uicontrol {Clean Project}. To clean the build directory and then build
the project, select \uicontrol Build > \uicontrol {Rebuild All} or
@@ -90,7 +101,7 @@
\uicontrol {Clean Without Dependencies} options in the context menu in the
\uicontrol Projects view.
- \section1 Additional qmake Options
+ \section1 Additional qmake Commands
To run qmake to generate new Makefiles, select \uicontrol Build >
\uicontrol qmake. To prevent failures on incremental builds, it might make
diff --git a/doc/src/projects/creator-only/creator-projects-builds-customizing.qdoc b/doc/src/projects/creator-only/creator-projects-builds-customizing.qdoc
index 08e894f919..52b367cbf3 100644
--- a/doc/src/projects/creator-only/creator-projects-builds-customizing.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-builds-customizing.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -36,7 +36,7 @@
\previouspage creator-developing-generic-linux.html
\nextpage studio-advanced.html
\else
- \previouspage creator-developing-qnx.html
+ \previouspage creator-setup-webassembly.html
\nextpage creator-testing.html
\endif
diff --git a/doc/src/projects/creator-only/creator-projects-creating.qdoc b/doc/src/projects/creator-only/creator-projects-creating.qdoc
index ab35b3dd6a..557b2acfcb 100644
--- a/doc/src/projects/creator-only/creator-projects-creating.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-creating.qdoc
@@ -473,9 +473,15 @@
{SUBDIRS variable}. It also adds all the necessary files for the subproject.
To create more subprojects, right-click the project name in the
- \uicontrol Projects pane, and select \uicontrol {New Subproject} in the
- context menu. To add an existing project as a subproject, select
- \uicontrol {Add Existing Projects}.
+ \uicontrol Projects pane to open the context menu, and select
+ \uicontrol {New Subproject}. Follow the steps in the
+ \uicontrol {New Subproject} wizard to create a subproject.
+
+ \image qtcreator-new-subproject.png
+
+ To add an existing project as a subproject, select
+ \uicontrol {Add Existing Projects} in the context menu.
+ In the file browser dialog, locate your subproject.
To remove subprojects, right-click the project name in the \uicontrol Projects
pane, and select \uicontrol {Remove Subproject} in the context menu.
diff --git a/doc/src/projects/creator-only/creator-projects-generic.qdoc b/doc/src/projects/creator-only/creator-projects-generic.qdoc
index 7c1f06ec35..8ec7958d0e 100644
--- a/doc/src/projects/creator-only/creator-projects-generic.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-generic.qdoc
@@ -65,7 +65,7 @@
\li \l{Specifying Files}{.files}
- \li \l{Specifying Include Paths}{.includes}
+ \li \l{Specifying Include Paths and Framework Paths}{.includes}
\li \l{Specifying Defines}{.config}
@@ -114,12 +114,14 @@
git ls-files "*.cpp" "*.h" > MyProject.files
\endcode
- \section1 Specifying Include Paths
+ \section1 Specifying Include Paths and Framework Paths
The include paths are specified in the \tt{.includes} file, one include
path per line. The paths can be either absolute or relative to the
\tt{.includes} file.
+ Lines starting with "-F" are interpreted as framework paths.
+
\section1 Specifying Defines
The defines are specified in the \tt{.config} file. The \tt{.config} file is
diff --git a/doc/src/projects/creator-only/creator-projects-settings-build.qdoc b/doc/src/projects/creator-only/creator-projects-settings-build.qdoc
index e6f43c9998..1ca696f7c3 100644
--- a/doc/src/projects/creator-only/creator-projects-settings-build.qdoc
+++ b/doc/src/projects/creator-only/creator-projects-settings-build.qdoc
@@ -141,6 +141,11 @@
backreferences. For example, if \c %{variable} is \c my123var, then
\c %{variable/(..)(\d+)/\2\1} is expanded to \c {123myvar}.
+ Instead of the forward slash, you can also use the pound sign (\c #) as
+ the substitution character. This can be helpful if the value is supposed
+ to be a file path, in which case forward slashes might get translated
+ to backslashes on Windows hosts.
+
To use the default value if the variable is not set, use:
\badcode
diff --git a/doc/src/qnx/creator-developing-qnx.qdoc b/doc/src/qnx/creator-developing-qnx.qdoc
index 115e552bc9..7787437303 100644
--- a/doc/src/qnx/creator-developing-qnx.qdoc
+++ b/doc/src/qnx/creator-developing-qnx.qdoc
@@ -32,7 +32,7 @@
\contentspage index.html
\previouspage creator-developing-ios.html
\page creator-developing-qnx.html
- \nextpage creator-build-process-customizing.html
+ \nextpage creator-setup-webassembly.html
\title Connecting QNX Devices
diff --git a/doc/src/qtcreator-toc.qdoc b/doc/src/qtcreator-toc.qdoc
index 331a5a8091..2aab46319c 100644
--- a/doc/src/qtcreator-toc.qdoc
+++ b/doc/src/qtcreator-toc.qdoc
@@ -176,6 +176,7 @@
\li \l{Connecting Embedded Linux Devices}
\li \l{Connecting iOS Devices}
\li \l{Connecting QNX Devices}
+ \li \l{Building Applications for the Web}
\endlist
\li \l{Customizing the Build Process}
\endlist
diff --git a/doc/src/qtcreator.qdoc b/doc/src/qtcreator.qdoc
index 4d814582ec..5401ecc442 100644
--- a/doc/src/qtcreator.qdoc
+++ b/doc/src/qtcreator.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -45,6 +45,11 @@
Windows
operating systems. For more information, see \l{Supported Platforms}.
+ In addition, you can use the experimental
+ \l{Building Applications for the Web}{WebAssembly plugin}
+ to build applications in web format and run them in web
+ browsers.
+
This manual also describes features that are only available if you have the
appropriate \l{http://qt.io/licensing/}{Qt license}. For more information,
see \l{Commercial Features}.
diff --git a/doc/src/webassembly/creator-webassembly.qdoc b/doc/src/webassembly/creator-webassembly.qdoc
new file mode 100644
index 0000000000..37ca68ed5e
--- /dev/null
+++ b/doc/src/webassembly/creator-webassembly.qdoc
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Creator documentation.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+**
+****************************************************************************/
+
+ /*!
+ \contentspage index.html
+ \previouspage creator-developing-qnx.html
+ \page creator-setup-webassembly.html
+ \nextpage creator-build-process-customizing.html
+
+ \title Building Applications for the Web
+
+ WebAssembly is a binary format that allows sand-boxed executable code in
+ web pages. This format is nearly as fast as native machine code, and is
+ now supported by all major web browsers.
+
+ \l {Qt for WebAssembly} enables building Qt applications so that they can be
+ integrated into web pages. It doesn't require any client-side installations
+ and reduces the use of server-side resources.
+
+ The experimental WebAssembly plugin enables you to build your applications
+ in WebAssembly format and deploy and run them in the local web browser.
+ You can change the web browser in the project run settings.
+
+ To build applications for the web and run them in a web browser, you need to
+ install Qt for WebAssembly and the tool chain for compiling to WebAssembly,
+ as well as add a build and run kit in \QC.
+
+ \section1 Requirements
+
+ You need the following software to build Qt applications for the web and run
+ them in a browser:
+
+ \list
+ \li Qt for WebAssembly 5.13.1, or later
+ \li On Windows: \l{http://mingw.org/}{MinGW} 7.3.0, or later
+ \li \l{https://emscripten.org/docs/introducing_emscripten/index.html}
+ {emscripten} tool chain for compiling to WebAssembly
+ \li \c sed stream editor
+ \endlist
+
+ \note You need to add the location of the \MinGW and \c sed installation
+ folders to the system path, either globally or for the Qt for WebAssembly
+ kit.
+
+ \section1 Setting Up the Development Environment
+
+ To configure \QC for building Qt apps for the web and running them in a
+ web browser:
+
+ \list 1
+ \li Use the Qt maintenance tool to install Qt for WebAssembly and, on
+ Windows, \MinGW (found in \uicontrol {Developer and Designer Tools}).
+ \li Check out \c emsdk and install and activate \c emscripten, as
+ instructed in \l {Qt for WebAssembly}.
+ \li On Windows, you have to download and install \c sed, as instructed
+ in \l{http://gnuwin32.sourceforge.net/packages/sed.htm}
+ {sed for Windows}, and add its location to the system PATH.
+ \li In \QC, select \uicontrol Help > \uicontrol {About Plugins} >
+ \uicontrol {Device Support} > \uicontrol {WebAssembly} to enable
+ the plugin.
+ \li Restart \QC to be able to use the plugin.
+ \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Kits >
+ \uicontrol {Qt Versions} > \uicontrol Add to add Qt for WebAssembly
+ (wasm_32).
+ \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Kits >
+ \uicontrol Add to add a kit for building applications for the web:
+ \image qtcreator-kit-webassembly.png "Qt for WebAssembly kit"
+ \list 1
+ \li In the \uicontrol Name field, specify a name for the kit.
+ \li In the \uicontrol {Device type} field, select
+ \uicontrol {WebAssembly Runtime}.
+ The value of the \uicontrol Device field is automatically
+ set to \uicontrol {Web Browser}.
+ \li In the \uicontrol Compiler field, select
+ \uicontrol {Emscripten Compiler} for both C and C++.
+ \li Select \uicontrol Change next to the \uicontrol Environment
+ field to append the locations where you installed \MinGW and
+ \c sed to the PATH variable. For example, on Windows:
+ \c {PATH=C:\Qt\Tools\mingw730_64\bin;C:\Program Files (x86)\GnuWin32\bin;${PATH}}
+ \li Select \uicontrol Apply to add the kit.
+ \endlist
+ \li Open a project for an application you want to run in a web browser.
+ \li Select \uicontrol Projects > \uicontrol {Build & Run}, and then
+ select the WebAssembly kit as the build and run kit for the project.
+ \li Select \uicontrol Run to specify run settings.
+ \li In the \uicontrol Browser field, select the browser to run the
+ application in.
+ \image qtcreator-settings-run-webassembly.png "Selecting the browser to run in"
+ \endlist
+
+ You can now build Qt applications in WebAssembly format and run them in
+ a web browser as described in \l {Building for Multiple Platforms} and
+ \l{Running on Multiple Platforms}.
+*/
diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs
index 0a3d405edc..3269b43f78 100644
--- a/qbs/modules/qtc/qtc.qbs
+++ b/qbs/modules/qtc/qtc.qbs
@@ -4,16 +4,16 @@ import qbs.FileInfo
import "qtc.js" as HelperFunctions
Module {
- property string qtcreator_display_version: '4.10.1'
+ property string qtcreator_display_version: '4.11.0-beta1'
property string ide_version_major: '4'
property string ide_version_minor: '10'
- property string ide_version_release: '1'
+ property string ide_version_release: '82'
property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.'
+ ide_version_release
property string ide_compat_version_major: '4'
property string ide_compat_version_minor: '10'
- property string ide_compat_version_release: '0'
+ property string ide_compat_version_release: '82'
property string qtcreator_compat_version: ide_compat_version_major + '.'
+ ide_compat_version_minor + '.' + ide_compat_version_release
diff --git a/qtcreator.pri b/qtcreator.pri
index 9ed1bf1c8f..9a61746ddb 100644
--- a/qtcreator.pri
+++ b/qtcreator.pri
@@ -209,6 +209,7 @@ exists($$IDE_LIBRARY_PATH): LIBS *= -L$$IDE_LIBRARY_PATH # library path from ou
DEFINES += \
QT_CREATOR \
+ QT_NO_JAVA_STYLE_ITERATORS \
QT_NO_CAST_TO_ASCII \
QT_RESTRICTED_CAST_FROM_ASCII \
QT_DISABLE_DEPRECATED_BEFORE=0x050900 \
diff --git a/qtcreator_ide_branding.pri b/qtcreator_ide_branding.pri
index c4000309e4..f068254edc 100644
--- a/qtcreator_ide_branding.pri
+++ b/qtcreator_ide_branding.pri
@@ -1,8 +1,8 @@
-QTCREATOR_VERSION = 4.10.1
-QTCREATOR_COMPAT_VERSION = 4.10.0
-QTCREATOR_DISPLAY_VERSION = 4.10.1
+QTCREATOR_VERSION = 4.10.82
+QTCREATOR_COMPAT_VERSION = 4.10.82
+QTCREATOR_DISPLAY_VERSION = 4.11.0-beta1
QTCREATOR_COPYRIGHT_YEAR = 2019
-BINARY_ARTIFACTS_BRANCH = 4.10
+BINARY_ARTIFACTS_BRANCH = master
IDE_DISPLAY_NAME = Qt Creator
IDE_ID = qtcreator
diff --git a/scripts/deployqt.py b/scripts/deployqt.py
index 4efe99761c..5c22b6ac39 100755
--- a/scripts/deployqt.py
+++ b/scripts/deployqt.py
@@ -224,6 +224,8 @@ def deploy_libclang(install_dir, llvm_install_dir, chrpath_bin):
clangbindirtarget))
deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clangd.exe'),
clangbindirtarget))
+ deployinfo.append((os.path.join(llvm_install_dir, 'bin', 'clang-tidy.exe'),
+ clangbindirtarget))
resourcetarget = os.path.join(clanglibdirtarget, 'clang')
else:
libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*'))
@@ -231,11 +233,13 @@ def deploy_libclang(install_dir, llvm_install_dir, chrpath_bin):
deployinfo.append((libsource, os.path.join(install_dir, 'lib', 'qtcreator')))
clangbinary = os.path.join(llvm_install_dir, 'bin', 'clang')
clangdbinary = os.path.join(llvm_install_dir, 'bin', 'clangd')
+ clangtidybinary = os.path.join(llvm_install_dir, 'bin', 'clang-tidy')
clangbinary_targetdir = os.path.join(install_dir, 'libexec', 'qtcreator', 'clang', 'bin')
if not os.path.exists(clangbinary_targetdir):
os.makedirs(clangbinary_targetdir)
deployinfo.append((clangbinary, clangbinary_targetdir))
deployinfo.append((clangdbinary, clangbinary_targetdir))
+ deployinfo.append((clangtidybinary, clangbinary_targetdir))
# copy link target if clang is actually a symlink
if os.path.islink(clangbinary):
linktarget = os.readlink(clangbinary)
diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh
index 2ee40242f5..f2086ce2b9 100755
--- a/scripts/deployqtHelper_mac.sh
+++ b/scripts/deployqtHelper_mac.sh
@@ -117,6 +117,10 @@ if [ $LLVM_INSTALL_DIR ]; then
if [ $clanglinktarget ]; then
cp -Rf "$(dirname "$clangsource")/$clanglinktarget" "$resource_path/clang/bin/$clanglinktarget" || exit 1
fi
+ clangdsource="$LLVM_INSTALL_DIR"/bin/clangd
+ cp -Rf "$clangdsource" "$resource_path/clang/bin/" || exit 1
+ clangtidysource="$LLVM_INSTALL_DIR"/bin/clang-tidy
+ cp -Rf "$clangtidysource" "$resource_path/clang/bin/" || exit 1
fi
clangbackendArgument="-executable=$resource_path/clangbackend"
clangpchmanagerArgument="-executable=$resource_path/clangpchmanagerbackend"
diff --git a/share/qtcreator/CMakeLists.txt b/share/qtcreator/CMakeLists.txt
index 3fe6c60b4b..63393293c1 100644
--- a/share/qtcreator/CMakeLists.txt
+++ b/share/qtcreator/CMakeLists.txt
@@ -1,5 +1,5 @@
set(template_directories cplusplus debugger glsl modeleditor qml qmldesigner
- qmlicons qml-type-descriptions schemes snippets styles templates themes welcomescreen)
+ qmlicons qml-type-descriptions schemes scripts snippets styles templates themes welcomescreen)
add_custom_target(copy_share_to_builddir ALL
COMMENT Copy files into build directory
@@ -21,3 +21,5 @@ install(
FILES indexer_preincludes/qglobal.h indexer_preincludes/windows.h
DESTINATION "${IDE_DATA_PATH}/indexer_preincludes"
)
+
+add_subdirectory(translations)
diff --git a/share/qtcreator/cplusplus/examples/CMakeLists.txt b/share/qtcreator/cplusplus/examples/CMakeLists.txt
new file mode 100644
index 0000000000..2a5aeb6d78
--- /dev/null
+++ b/share/qtcreator/cplusplus/examples/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(examples LANGUAGES CXX)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt5 COMPONENTS Widgets REQUIRED)
+
+add_executable(examples
+ clazy_example.cpp
+ tidy_example.cpp
+ tidy_example.h
+)
+
+target_link_libraries(examples PRIVATE Qt5::Widgets)
diff --git a/share/qtcreator/debugger/.pylintrc b/share/qtcreator/debugger/.pylintrc
new file mode 100644
index 0000000000..dabd2ee07a
--- /dev/null
+++ b/share/qtcreator/debugger/.pylintrc
@@ -0,0 +1,11 @@
+[MESSAGES CONTROL]
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once).
+disable=invalid-name,missing-docstring
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index aa351b7e7e..04969d8e32 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -407,6 +407,8 @@ class DumperBase:
return xrange(min(self.currentMaxNumChild, self.currentNumChild))
def enterSubItem(self, item):
+ if self.useTimeStamps:
+ item.startTime = time.time()
if not item.iname:
item.iname = '%s.%s' % (self.currentIName, item.name)
if not self.isCli:
@@ -424,8 +426,6 @@ class DumperBase:
self.currentIName = item.iname
self.currentValue = ReportItem();
self.currentType = ReportItem();
- if self.useTimeStamps:
- item.startTime = time.time()
def exitSubItem(self, item, exType, exValue, exTraceBack):
#warn('CURRENT VALUE: %s: %s %s' %
@@ -435,8 +435,6 @@ class DumperBase:
showException('SUBITEM', exType, exValue, exTraceBack)
self.putSpecialValue('notaccessible')
self.putNumChild(0)
- if self.useTimeStamps:
- self.put('time="%s",' % (time.time() - item.startTime))
if not self.isCli:
try:
if self.currentType.value:
@@ -453,6 +451,8 @@ class DumperBase:
self.put('value="%s",' % self.currentValue.value)
except:
pass
+ if self.useTimeStamps:
+ self.put('time="%s",' % (time.time() - item.startTime))
self.put('},')
else:
self.indent -= 1
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index 27d33e3046..34589e0dd8 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -1910,7 +1910,7 @@ class LogMixin:
localz = frame.f_locals
instance = str(localz["self"]) + "." if 'self' in localz else ''
message = "%s%s(%s)%s" % (instance, fn, args, message)
- print message
+ print(message)
@staticmethod
def log_fn(arg_str = ''):
@@ -1945,7 +1945,7 @@ class SummaryDumper(Dumper, LogMixin):
@staticmethod
def warn(message):
- print "Qt summary warning: %s" % message
+ print("Qt summary warning: %s" % message)
@staticmethod
def showException(message, exType, exValue, exTraceback):
@@ -1979,9 +1979,9 @@ class SummaryDumper(Dumper, LogMixin):
try:
from pygdbmi import gdbmiparser
except ImportError:
- print "Qt summary provider requires the pygdbmi module, " \
- "please install using 'sudo /usr/bin/easy_install pygdbmi', " \
- "and then restart Xcode."
+ print("Qt summary provider requires the pygdbmi module, "
+ "please install using 'sudo /usr/bin/easy_install pygdbmi', "
+ "and then restart Xcode.")
lldb.debugger.HandleCommand('type category delete Qt')
return None
diff --git a/share/qtcreator/debugger/misctypes.py b/share/qtcreator/debugger/misctypes.py
index 97b2f6ef63..72e42e4510 100644
--- a/share/qtcreator/debugger/misctypes.py
+++ b/share/qtcreator/debugger/misctypes.py
@@ -181,6 +181,7 @@ def qdump__Eigen__Matrix(d, value):
def qdump__NimStringDesc(d, value):
size, reserved = value.split('pp')
data = value.address() + 2 * d.ptrSize()
+ d.putBetterType('string')
d.putCharArrayHelper(data, size, d.createType('char'), 'utf8')
def qdump__NimGenericSequence__(d, value, regex = '^TY[\d]+$'):
diff --git a/share/qtcreator/debugger/pdbbridge.py b/share/qtcreator/debugger/pdbbridge.py
index 76e213507d..fd9bef48cb 100644
--- a/share/qtcreator/debugger/pdbbridge.py
+++ b/share/qtcreator/debugger/pdbbridge.py
@@ -26,22 +26,22 @@
import os
import re
import sys
-import dis
import code
-import glob
import base64
+import linecache
import signal
import string
import inspect
import traceback
-import linecache
import fnmatch
import platform
+
class QuitException(Exception):
pass
-class Breakpoint:
+
+class QtcInternalBreakpoint:
"""Breakpoint class.
Breakpoints are indexed by number through bpbynumber and by
the file,line tuple using bplist. The former points to a
@@ -56,25 +56,25 @@ class Breakpoint:
# index 0 is unused, except for marking an
# effective break .... see effective()
- def __init__(self, file, line, temporary=False, cond=None, funcname=None):
+ def __init__(self, filepath, line, temporary=False, cond=None, funcname=None):
self.funcname = funcname
# Needed if funcname is not None.
self.func_first_executable_line = None
- self.file = file # This better be in canonical form!
+ self.file = filepath # This better be in canonical form!
self.line = line
self.temporary = temporary
self.cond = cond
self.enabled = True
self.ignore = 0
self.hits = 0
- self.number = Breakpoint.next
- Breakpoint.next += 1
+ self.number = QtcInternalBreakpoint.next
+ QtcInternalBreakpoint.next += 1
# Build the two lists
self.bpbynumber.append(self)
- if (file, line) in self.bplist:
- self.bplist[file, line].append(self)
+ if (filepath, line) in self.bplist:
+ self.bplist[filepath, line].append(self)
else:
- self.bplist[file, line] = [self]
+ self.bplist[filepath, line] = [self]
def deleteMe(self):
index = (self.file, self.line)
@@ -120,9 +120,10 @@ def checkfuncname(b, frame):
return False
return True
+
# Determines if there is an effective (active) breakpoint at this
# line of code. Returns breakpoint number or 0 if none
-def effective(file, line, frame):
+def effective(filename, line, frame):
"""Determine which breakpoint for this file:line is to be acted upon.
Called only if we know there is a bpt at this
@@ -130,7 +131,7 @@ def effective(file, line, frame):
that indicates if it is ok to delete a temporary bp.
"""
- possibles = Breakpoint.bplist[file, line]
+ possibles = QtcInternalBreakpoint.bplist[filename, line]
for b in possibles:
if not b.enabled:
continue
@@ -168,8 +169,8 @@ def effective(file, line, frame):
return (None, None)
+# __all__ = ['QtcInternalDumper']
-#__all__ = ['Dumper']
def find_function(funcname, filename):
cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname))
@@ -184,18 +185,21 @@ def find_function(funcname, filename):
return funcname, filename, lineno
return None
+
class _rstr(str):
"""String that doesn't quote its repr."""
+
def __repr__(self):
return self
-class Dumper:
+
+class QtcInternalDumper:
identchars = string.ascii_letters + string.digits + '_'
lastcmd = ''
use_rawinput = 1
def __init__(self, stdin=None, stdout=None):
- self.skip = None
+ self.skip = []
self.breaks = {}
self.fncache = {}
self.frame_returning = None
@@ -227,21 +231,47 @@ class Dumper:
self.allow_kbdint = False
self.nosigint = nosigint
- self.commands = {} # associates a command list to breakpoint numbers
+ self.commands = {} # associates a command list to breakpoint numbers
+ self.botframe = None
+ self.currentbp = -1
+ self.stopframe = None
+ self.returnframe = None
+ self.quitting = False
+ self.stoplineno = 0
+ self.mainpyfile = ''
+ self._user_requested_quit = False
+ self.stack = []
+ self.curindex = 0
+ self.curframe = None
+ self.curframe_locals = {}
+ self.typeformats = {}
+ self.formats = {}
+ self.output = ''
+ self.expandedINames = []
# Hex decoding operating on str, return str.
- def hexdecode(self, s):
+ @staticmethod
+ def hexdecode(s):
if sys.version_info[0] == 2:
return s.decode('hex')
return bytes.fromhex(s).decode('utf8')
# Hex encoding operating on str or bytes, return str.
- def hexencode(self, s):
+ @staticmethod
+ def hexencode(s):
if sys.version_info[0] == 2:
return s.encode('hex')
if isinstance(s, str):
s = s.encode('utf8')
return base64.b16encode(s).decode('utf8')
+
+ @staticmethod
+ def cleanAddress(addr):
+ if addr is None:
+ return '<no address>'
+ h = hex(addr)
+ return '0x%x' % (int(h, 16) if sys.version_info[0] >= 3 else long(h, 16))
+
def canonic(self, filename):
if filename == '<' + filename[1:-1] + '>':
return filename
@@ -255,7 +285,6 @@ class Dumper:
return canonic
def reset(self):
- import linecache
linecache.checkcache()
self.botframe = None
self._set_stopinfo(None, None)
@@ -263,7 +292,7 @@ class Dumper:
def trace_dispatch(self, frame, event, arg):
if self.quitting:
- return # None
+ return None
if event == 'line':
return self.dispatch_line(frame)
if event == 'call':
@@ -284,22 +313,24 @@ class Dumper:
def dispatch_line(self, frame):
if self.stop_here(frame) or self.break_here(frame):
self.user_line(frame)
- if self.quitting: raise QuitException
+ if self.quitting:
+ raise QuitException
return self.trace_dispatch
def dispatch_call(self, frame):
if self.botframe is None:
# First call of dispatch since reset()
- self.botframe = frame.f_back # (CT) Note that this may also be None!
+ self.botframe = frame.f_back # (CT) Note that this may also be None!
return self.trace_dispatch
if not (self.stop_here(frame) or self.break_anywhere(frame)):
# No need to trace this function
- return # None
+ return None
# Ignore call events in generator except when stepping.
if self.stopframe and frame.f_code.co_flags & inspect.CO_GENERATOR:
return self.trace_dispatch
self.user_call(frame)
- if self.quitting: raise QuitException
+ if self.quitting:
+ raise QuitException
return self.trace_dispatch
def dispatch_return(self, frame, arg):
@@ -312,7 +343,8 @@ class Dumper:
self.user_return(frame, arg)
finally:
self.frame_returning = None
- if self.quitting: raise QuitException
+ if self.quitting:
+ raise QuitException
# The user issued a 'next' or 'until' command.
if self.stopframe is frame and self.stoplineno != -1:
self._set_stopinfo(None, None)
@@ -326,16 +358,18 @@ class Dumper:
if not (frame.f_code.co_flags & inspect.CO_GENERATOR
and arg[0] is StopIteration and arg[2] is None):
self.user_exception(frame, arg)
- if self.quitting: raise QuitException
+ if self.quitting:
+ raise QuitException
# Stop at the StopIteration or GeneratorExit exception when the user
# has set stopframe in a generator by issuing a return command, or a
# next/until command at the last statement in the generator before the
# exception.
elif (self.stopframe and frame is not self.stopframe
- and self.stopframe.f_code.co_flags & inspect.CO_GENERATOR
- and arg[0] in (StopIteration, GeneratorExit)):
+ and self.stopframe.f_code.co_flags & inspect.CO_GENERATOR
+ and arg[0] in (StopIteration, GeneratorExit)):
self.user_exception(frame, arg)
- if self.quitting: raise QuitException
+ if self.quitting:
+ raise QuitException
return self.trace_dispatch
@@ -453,17 +487,17 @@ class Dumper:
def set_break(self, filename, lineno, temporary=False, cond=None,
funcname=None):
filename = self.canonic(filename)
- import linecache # Import as late as possible
line = linecache.getline(filename, lineno)
if not line:
return 'Line %s:%d does not exist' % (filename, lineno)
- list = self.breaks.setdefault(filename, [])
- if lineno not in list:
- list.append(lineno)
- bp = Breakpoint(filename, lineno, temporary, cond, funcname)
+ lines = self.breaks.setdefault(filename, [])
+ if lineno not in lines:
+ lines.append(lineno)
+ QtcInternalBreakpoint(filename, lineno, temporary, cond, funcname)
+ return None
def _prune_breaks(self, filename, lineno):
- if (filename, lineno) not in Breakpoint.bplist:
+ if (filename, lineno) not in QtcInternalBreakpoint.bplist:
self.breaks[filename].remove(lineno)
if not self.breaks[filename]:
del self.breaks[filename]
@@ -476,9 +510,10 @@ class Dumper:
return 'There is no breakpoint at %s:%d' % (filename, lineno)
# If there's only one bp in the list for that file,line
# pair, then remove the breaks entry
- for bp in Breakpoint.bplist[filename, lineno][:]:
+ for bp in QtcInternalBreakpoint.bplist[filename, lineno][:]:
bp.deleteMe()
self._prune_breaks(filename, lineno)
+ return None
def clear_bpbynumber(self, arg):
try:
@@ -487,26 +522,28 @@ class Dumper:
return str(err)
bp.deleteMe()
self._prune_breaks(bp.file, bp.line)
+ return None
def clear_all_file_breaks(self, filename):
filename = self.canonic(filename)
if filename not in self.breaks:
- return 'There are no breakpoints in %s' % filename
+ return
for line in self.breaks[filename]:
- blist = Breakpoint.bplist[filename, line]
+ blist = QtcInternalBreakpoint.bplist[filename, line]
for bp in blist:
bp.deleteMe()
del self.breaks[filename]
def clear_all_breaks(self):
if not self.breaks:
- return 'There are no breakpoints'
- for bp in Breakpoint.bpbynumber:
+ return
+ for bp in QtcInternalBreakpoint.bpbynumber:
if bp:
bp.deleteMe()
self.breaks = {}
- def get_bpbynumber(self, arg):
+ @staticmethod
+ def get_bpbynumber(arg):
if not arg:
raise ValueError('Breakpoint number expected')
try:
@@ -514,7 +551,7 @@ class Dumper:
except ValueError:
raise ValueError('Non-numeric breakpoint number %s' % arg)
try:
- bp = Breakpoint.bpbynumber[number]
+ bp = QtcInternalBreakpoint.bpbynumber[number]
except IndexError:
raise ValueError('Breakpoint number %d out of range' % number)
if bp is None:
@@ -528,16 +565,11 @@ class Dumper:
def get_breaks(self, filename, lineno):
filename = self.canonic(filename)
- return filename in self.breaks and \
- lineno in self.breaks[filename] and \
- Breakpoint.bplist[filename, lineno] or []
+ return QtcInternalBreakpoint.bplist.get((filename, lineno), [])
def get_file_breaks(self, filename):
filename = self.canonic(filename)
- if filename in self.breaks:
- return self.breaks[filename]
- else:
- return []
+ return self.breaks.get(filename, [])
def get_all_breaks(self):
return self.breaks
@@ -545,21 +577,21 @@ class Dumper:
# Derived classes and clients can call the following method
# to get a data structure representing a stack trace.
- def get_stack(self, f, t):
+ def get_stack(self, frame, tb):
stack = []
- if t and t.tb_frame is f:
- t = t.tb_next
- while f is not None:
- stack.append((f, f.f_lineno))
- if f is self.botframe:
+ if tb and tb.tb_frame is frame:
+ tb = tb.tb_next
+ while frame is not None:
+ stack.append((frame, frame.f_lineno))
+ if frame is self.botframe:
break
- f = f.f_back
+ frame = frame.f_back
stack.reverse()
i = max(0, len(stack) - 1)
- while t is not None:
- stack.append((t.tb_frame, t.tb_lineno))
- t = t.tb_next
- if f is None:
+ while tb is not None:
+ stack.append((tb.tb_frame, tb.tb_lineno))
+ tb = tb.tb_next
+ if frame is None:
i = max(0, len(stack) - 1)
return stack, i
@@ -567,41 +599,40 @@ class Dumper:
# a debugger to debug a statement or an expression.
# Both can be given as a string, or a code object.
- def run(self, cmd, globals=None, locals=None):
- if globals is None:
+ def run(self, cmd, pyGlobals=None, pyLocals=None):
+ if pyGlobals is None:
import __main__
- globals = __main__.__dict__
- if locals is None:
- locals = globals
+ pyGlobals = __main__.__dict__
+ if pyLocals is None:
+ pyLocals = pyGlobals
self.reset()
if isinstance(cmd, str):
cmd = compile(cmd, '<string>', 'exec')
sys.settrace(self.trace_dispatch)
try:
- exec(cmd, globals, locals)
+ exec(cmd, pyGlobals, pyLocals)
except QuitException:
pass
finally:
self.quitting = True
sys.settrace(None)
- def runeval(self, expr, globals=None, locals=None):
- if globals is None:
+ def runeval(self, expr, pyGlobals=None, pyLocals=None):
+ if pyGlobals is None:
import __main__
- globals = __main__.__dict__
- if locals is None:
- locals = globals
+ pyGlobals = __main__.__dict__
+ if pyLocals is None:
+ pyLocals = pyGlobals
self.reset()
sys.settrace(self.trace_dispatch)
try:
- return eval(expr, globals, locals)
+ return eval(expr, pyGlobals, pyLocals)
except QuitException:
pass
finally:
self.quitting = True
sys.settrace(None)
-
# This method is more useful to debug a single function call.
def runcall(self, func, *args, **kwds):
self.reset()
@@ -616,7 +647,6 @@ class Dumper:
sys.settrace(None)
return res
-
def cmdloop(self):
"""Repeatedly accept input, parse an initial prefix
off the received input, and dispatch to action methods, passing them
@@ -640,7 +670,7 @@ class Dumper:
self.stdout.write('')
self.stdout.flush()
line = self.stdin.readline()
- if not len(line):
+ if not line:
line = 'EOF'
else:
line = line.rstrip('\r\n')
@@ -664,8 +694,9 @@ class Dumper:
line = 'shell ' + line[1:]
else:
return None, None, line
- i, n = 0, len(line)
- while i < n and line[i] in self.identchars: i = i+1
+ i, length = 0, len(line)
+ while i < length and line[i] in self.identchars:
+ i = i+1
cmd, arg = line[:i], line[i:].strip()
return cmd, arg, line
@@ -683,7 +714,7 @@ class Dumper:
if cmd is None:
return self.default(line)
self.lastcmd = line
- if line == 'EOF' :
+ if line == 'EOF':
self.lastcmd = ''
if cmd == '':
return self.default(line)
@@ -691,11 +722,9 @@ class Dumper:
func = getattr(self, 'do_' + cmd, None)
if func:
return func(arg)
- else:
- return self.default(line)
+ return self.default(line)
def runit(self):
-
print('DIR: %s' % dir())
if sys.argv[0] == '-c':
sys.argv = sys.argv[2:]
@@ -714,12 +743,12 @@ class Dumper:
# So we clear up the __main__ and set several special variables
# (this gets rid of pdb's globals and cleans old variables on restarts).
- #import __main__
- #__main__.__dict__.clear()
- #__main__.__dict__.update({'__name__' : '__main__',
- # '__file__' : mainpyfile,
- # '__builtins__': __builtins__,
- # })
+ # import __main__
+ # __main__.__dict__.clear()
+ # __main__.__dict__.update({'__name__' : '__main__',
+ # '__file__' : mainpyfile,
+ # '__builtins__': __builtins__,
+ # })
# When bdb sets tracing, a number of call and line events happens
# BEFORE debugger even reaches user's code (and the exact sequence of
@@ -760,14 +789,13 @@ class Dumper:
signal.signal(signal.SIGINT, self._previous_sigint_handler)
def forget(self):
- self.lineno = None
self.stack = []
self.curindex = 0
self.curframe = None
- def setup(self, f, tb):
+ def setup(self, frame, tb):
self.forget()
- self.stack, self.curindex = self.get_stack(f, tb)
+ self.stack, self.curindex = self.get_stack(frame, tb)
self.curframe = self.stack[self.curindex][0]
# The f_locals dictionary is updated from the actual frame
# locals whenever the .f_locals accessor is called, so we
@@ -787,7 +815,7 @@ class Dumper:
"""This function is called when we stop or break at this line."""
if self._wait_for_mainpyfile:
if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
- or frame.f_lineno <= 0):
+ or frame.f_lineno <= 0):
return
self._wait_for_mainpyfile = False
if self.bp_commands(frame):
@@ -809,8 +837,8 @@ class Dumper:
self.onecmd(line)
self.lastcmd = lastcmd_back
self.forget()
- return
- return 1
+ return False
+ return True
def user_return(self, frame, return_value):
"""This function is called when a return trap is set here."""
@@ -834,13 +862,13 @@ class Dumper:
# actually occurred in this case. The debugger uses this debug event to
# stop when the debuggee is returning from such generators.
prefix = 'Internal ' if (not exc_traceback
- and exc_type is StopIteration) else ''
+ and exc_type is StopIteration) else ''
self.message('%s%s' % (prefix,
- traceback.format_exception_only(exc_type, exc_value)[-1].strip()))
+ traceback.format_exception_only(exc_type, exc_value)[-1].strip()))
self.interaction(frame, exc_traceback)
- def interaction(self, frame, traceback):
- if self.setup(frame, traceback):
+ def interaction(self, frame, tb):
+ if self.setup(frame, tb):
# no interaction desired at this time (happens if .pdbrc contains
# a command like 'continue')
self.forget()
@@ -871,9 +899,10 @@ class Dumper:
self.message(repr(obj))
def default(self, line):
- if line[:1] == '!': line = line[1:]
- locals = self.curframe_locals
- globals = self.curframe.f_globals
+ if line[:1] == '!':
+ line = line[1:]
+ pyLocals = self.curframe_locals
+ pyGlobals = self.curframe.f_globals
try:
code = compile(line + '\n', '<stdin>', 'single')
save_stdout = sys.stdout
@@ -883,7 +912,7 @@ class Dumper:
sys.stdin = self.stdin
sys.stdout = self.stdout
sys.displayhook = self.displayhook
- exec(code, globals, locals)
+ exec(code, pyGlobals, pyLocals)
finally:
sys.stdout = save_stdout
sys.stdin = save_stdin
@@ -892,15 +921,16 @@ class Dumper:
exc_info = sys.exc_info()[:2]
self.error(traceback.format_exception_only(*exc_info)[-1].strip())
- def message(self, msg):
+ @staticmethod
+ def message(msg):
print(msg)
- pass
- def error(self, msg):
- #print('***'+ msg)
+ @staticmethod
+ def error(msg):
+ # print('***'+ msg)
pass
- def do_break(self, arg, temporary = 0):
+ def do_break(self, arg, temporary=0):
"""b(reak) [ ([filename:]lineno | function) [, condition] ]
Without argument, list all breaks.
@@ -918,7 +948,7 @@ class Dumper:
if not arg:
if self.breaks: # There's at least one
self.message('Num Type Disp Enb Where')
- for bp in Breakpoint.bpbynumber:
+ for bp in QtcInternalBreakpoint.bpbynumber:
if bp:
self.message(bp.bpformat())
return
@@ -964,8 +994,8 @@ class Dumper:
if hasattr(func, '__func__'):
func = func.__func__
code = func.__code__
- #use co_name to identify the bkpt (function names
- #could be aliased, but co_name is invariant)
+ # use co_name to identify the bkpt (function names
+ # could be aliased, but co_name is invariant)
funcname = code.co_name
lineno = code.co_firstlineno
filename = code.co_filename
@@ -976,7 +1006,7 @@ class Dumper:
self.error('The specified object %r is not a function '
'or was not found along sys.path.' % arg)
return
- funcname = ok # ok contains a function name
+ funcname = ok # ok contains a function name
lineno = int(ln)
if not filename:
filename = self.defaultFile()
@@ -1013,18 +1043,19 @@ class Dumper:
idstring = identifier.split("'")
if len(idstring) == 1:
# not in single quotes
- id = idstring[0].strip()
+ tmp_id = idstring[0].strip()
elif len(idstring) == 3:
# quoted
- id = idstring[1].strip()
+ tmp_id = idstring[1].strip()
else:
return failed
- if id == '': return failed
- parts = id.split('.')
+ if tmp_id == '':
+ return failed
+ parts = tmp_id.split('.')
# Protection for derived debuggers
if parts[0] == 'self':
del parts[0]
- if len(parts) == 0:
+ if not parts:
return failed
# Best first guess at file to look at
fname = self.defaultFile()
@@ -1056,7 +1087,7 @@ class Dumper:
line = line.strip()
# Don't allow setting breakpoint at a blank line
if (not line or (line[0] == '#') or
- (line[:3] == '"""') or line[:3] == "'''"):
+ (line[:3] == '"""') or line[:3] == "'''"):
self.error('Blank or comment')
return 0
return lineno
@@ -1166,7 +1197,7 @@ class Dumper:
reply = 'no'
reply = reply.strip().lower()
if reply in ('y', 'yes'):
- bplist = [bp for bp in Breakpoint.bpbynumber if bp]
+ bplist = [bp for bp in QtcInternalBreakpoint.bpbynumber if bp]
self.clear_all_breaks()
for bp in bplist:
self.message('Deleted %s' % bp)
@@ -1212,11 +1243,11 @@ class Dumper:
lineno = int(arg)
except ValueError:
self.error('Error in argument: %r' % arg)
- return
+ return 0
if lineno <= self.curframe.f_lineno:
self.error('"until" line number is smaller than current '
'line number')
- return
+ return 0
else:
lineno = None
lineno = self.curframe.f_lineno + 1
@@ -1290,11 +1321,11 @@ class Dumper:
executed in the current environment).
"""
sys.settrace(None)
- globals = self.curframe.f_globals
- locals = self.curframe_locals
- p = Dumper(self.stdin, self.stdout)
+ pyGlobals = self.curframe.f_globals
+ pyLocals = self.curframe_locals
+ p = QtcInternalDumper(self.stdin, self.stdout)
self.message('ENTERING RECURSIVE DEBUGGER')
- sys.call_tracing(p.run, (arg, globals, locals))
+ sys.call_tracing(p.run, (arg, pyGlobals, pyLocals))
self.message('LEAVING RECURSIVE DEBUGGER')
sys.settrace(self.trace_dispatch)
self.lastcmd = p.lastcmd
@@ -1321,14 +1352,16 @@ class Dumper:
Print the argument list of the current function.
"""
co = self.curframe.f_code
- dict = self.curframe_locals
+ loc = self.curframe_locals
n = co.co_argcount
- if co.co_flags & 4: n = n+1
- if co.co_flags & 8: n = n+1
+ if co.co_flags & 4:
+ n = n + 1
+ if co.co_flags & 8:
+ n = n + 1
for i in range(n):
name = co.co_varnames[i]
- if name in dict:
- self.message('%s = %r' % (name, dict[name]))
+ if name in loc:
+ self.message('%s = %r' % (name, loc[name]))
else:
self.message('%s = *** undefined ***' % (name,))
@@ -1353,8 +1386,7 @@ class Dumper:
try:
if frame is None:
return eval(arg, self.curframe.f_globals, self.curframe_locals)
- else:
- return eval(arg, frame.f_globals, frame.f_locals)
+ return eval(arg, frame.f_globals, frame.f_locals)
except:
exc_info = sys.exc_info()[:2]
err = traceback.format_exception_only(*exc_info)[-1].strip()
@@ -1412,9 +1444,9 @@ class Dumper:
if os.path.isabs(filename) and os.path.exists(filename):
return filename
f = os.path.join(sys.path[0], filename)
- if os.path.exists(f) and self.canonic(f) == self.mainpyfile:
+ if os.path.exists(f) and self.canonic(f) == self.mainpyfile:
return f
- root, ext = os.path.splitext(filename)
+ ext = os.path.splitext(filename)[1]
if ext == '':
filename = filename + '.py'
if os.path.isabs(filename):
@@ -1440,14 +1472,14 @@ class Dumper:
if frameNr == -1:
frameNr = 0
- frame_lineno = self.stack[-1-frameNr]
- frame, lineno = frame_lineno
- filename = self.canonic(frame.f_code.co_filename)
+ frame_lineno = self.stack[-1 - frameNr]
+ frame = frame_lineno[0]
self.output += 'data={'
for var in frame.f_locals.keys():
if var in ('__file__', '__name__', '__package__', '__spec__',
- '__doc__', '__loader__', '__cached__', '__the_dumper__'):
+ '__doc__', '__loader__', '__cached__', '__the_dumper__',
+ '__annotations__', 'QtcInternalBreakpoint', 'QtcInternalDumper'):
continue
value = frame.f_locals[var]
# this applies only for anonymous arguments
@@ -1471,7 +1503,7 @@ class Dumper:
except:
self.putValue('<unavailable>')
self.put('}')
- #self.dumpValue(eval(value), escapedExp, iname)
+ # self.dumpValue(eval(value), escapedExp, iname)
self.output += '}'
self.output += '{frame="%s"}' % frameNr
@@ -1483,7 +1515,7 @@ class Dumper:
self.output = ''
def put(self, value):
- #sys.stdout.write(value)
+ # sys.stdout.write(value)
self.output += value
def putField(self, name, value):
@@ -1492,53 +1524,46 @@ class Dumper:
def putItemCount(self, count):
self.put('value="<%s items>",numchild="%s",' % (count, count))
- def cleanType(self, type):
- t = str(type)
+ @staticmethod
+ def cleanType(typename):
+ t = str(typename)
if t.startswith("<type '") and t.endswith("'>"):
t = t[7:-2]
if t.startswith("<class '") and t.endswith("'>"):
t = t[8:-2]
return t
- def putType(self, type, priority = 0):
- self.putField('type', self.cleanType(type))
+ def putType(self, typeName, priority=0):
+ self.putField('type', QtcInternalDumper.cleanType(typeName))
def putNumChild(self, numchild):
self.put('numchild="%s",' % numchild)
- def putValue(self, value, encoding = None, priority = 0):
+ def putValue(self, value, encoding=None, priority=0):
self.putField('value', value)
def putName(self, name):
self.put('name="%s",' % name)
def isExpanded(self, iname):
- #self.warn('IS EXPANDED: %s in %s' % (iname, self.expandedINames))
+ # self.warn('IS EXPANDED: %s in %s' % (iname, self.expandedINames))
if iname.startswith('None'):
raise "Illegal iname '%s'" % iname
- #self.warn(' --> %s' % (iname in self.expandedINames))
+ # self.warn(' --> %s' % (iname in self.expandedINames))
return iname in self.expandedINames
def isExpandedIName(self, iname):
return iname in self.expandedINames
def itemFormat(self, item):
- format = self.formats.get(str(cleanAddress(item.value.address)))
- if format is None:
- format = self.typeformats.get(str(item.value.type))
- return format
-
- # Hex encoding operating on str or bytes, return str.
- def hexencode(self, s):
- if sys.version_info[0] == 2:
- return s.encode('hex')
- if isinstance(s, str):
- s = s.encode('utf8')
- return base64.b16encode(s).decode('utf8')
+ form = self.formats.get(str(QtcInternalDumper.cleanAddress(item.value.address)))
+ if form is None:
+ form = self.typeformats.get(str(item.value.type))
+ return form
def dumpValue(self, value, name, iname):
t = type(value)
- tt = self.cleanType(t)
+ tt = QtcInternalDumper.cleanType(t)
if tt == 'module' or tt == 'function':
return
if str(value).startswith("<class '"):
@@ -1556,10 +1581,10 @@ class Dumper:
elif tt == 'list' or tt == 'tuple':
self.putType(tt)
self.putItemCount(len(value))
- #self.putValue(value)
+ # self.putValue(value)
self.put('children=[')
- for i in range(len(value)):
- self.dumpValue(value[i], str(i), '%s.%d' % (iname, i))
+ for i, val in enumerate(value):
+ self.dumpValue(val, str(i), '%s.%d' % (iname, i))
self.put(']')
elif tt == 'str':
v = value
@@ -1647,12 +1672,11 @@ class Dumper:
self.put('],')
self.put('},')
-
def warn(self, msg):
self.putField('warning', msg)
def listModules(self, args):
- self.put('modules=[');
+ self.put('modules=[')
for name in sys.modules:
self.put('{')
self.putName(name)
@@ -1665,19 +1689,19 @@ class Dumper:
moduleName = args['module']
module = sys.modules.get(moduleName, None)
self.put("symbols={module='%s',symbols='%s'}"
- % (module, dir(module) if module else []))
+ % (module, dir(module) if module else []))
self.flushOutput()
def assignValue(self, args):
exp = args['expression']
value = args['value']
- cmd = '%s=%s' % (exp, exp, value)
+ cmd = '%s=%s' % (exp, value)
eval(cmd, {})
self.put('CMD: "%s"' % cmd)
self.flushOutput()
def stackListFrames(self, args):
- #result = 'stack={current-thread="%s"' % thread.GetThreadID()
+ # result = 'stack={current-thread="%s"' % thread.GetThreadID()
result = 'stack={current-thread="%s"' % 1
result += ',frames=['
@@ -1698,12 +1722,13 @@ class Dumper:
pass
result += ']'
- #result += ',hasmore="%d"' % isLimited
- #result += ',limit="%d"' % limit
+ # result += ',hasmore="%d"' % isLimited
+ # result += ',limit="%d"' % limit
result += '}'
self.report(result)
- def report(self, stuff):
+ @staticmethod
+ def report(stuff):
sys.stdout.write('@\n' + stuff + '@\n')
sys.stdout.flush()
@@ -1713,5 +1738,6 @@ def qdebug(cmd, args):
method = getattr(__the_dumper__, cmd)
method(args)
-__the_dumper__=Dumper()
+
+__the_dumper__ = QtcInternalDumper()
__the_dumper__.runit()
diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index a584e24e84..65b0828cdb 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -1972,7 +1972,10 @@ def qdump__QWeakPointer(d, value):
qdump_QWeakPointerHelper(d, value, True)
def qdump__QPointer(d, value):
- qdump_QWeakPointerHelper(d, value['wp'], True, value.type[0])
+ # actually, we'd use value['wp'] instead of value, but since we
+ # only split() on the result and the (sub-)object address is the
+ # same it does not matter but saves some cycles.
+ qdump_QWeakPointerHelper(d, value, True, value.type[0])
def qdump_QWeakPointerHelper(d, value, isWeak, innerType = None):
if isWeak:
diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp
index 73e360122a..73c8138a43 100644
--- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp
+++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp
@@ -62,7 +62,7 @@ quint32 ValuesChangedCommand::keyNumber() const
void ValuesChangedCommand::removeSharedMemorys(const QVector<qint32> &keyNumberVector)
{
- foreach (qint32 keyNumber, keyNumberVector) {
+ for (qint32 keyNumber : keyNumberVector) {
SharedMemory *sharedMemory = globalSharedMemoryContainer()->take(keyNumber);
delete sharedMemory;
}
diff --git a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp
index 91b77e27a6..8348cbecb0 100644
--- a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp
+++ b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp
@@ -79,7 +79,7 @@ void ImageContainer::setImage(const QImage &image)
void ImageContainer::removeSharedMemorys(const QVector<qint32> &keyNumberVector)
{
- foreach (qint32 keyNumber, keyNumberVector) {
+ for (qint32 keyNumber : keyNumberVector) {
SharedMemory *sharedMemory = globalSharedMemoryContainer()->take(keyNumber);
delete sharedMemory;
}
diff --git a/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h b/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h
index 3266fa25ed..2b6466bbdb 100644
--- a/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h
+++ b/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h
@@ -62,7 +62,7 @@ protected:
#ifdef Q_OS_UNIX
bool initKeyInternal();
void cleanHandleInternal();
- bool createInternal(QSharedMemory::AccessMode mode, int size);
+ bool createInternal(QSharedMemory::AccessMode mode, size_t size);
bool attachInternal(QSharedMemory::AccessMode mode);
bool detachInternal();
int handle();
@@ -74,7 +74,7 @@ private:
QSharedMemory m_sharedMemory;
#else
void *m_memory;
- int m_size;
+ size_t m_size;
QString m_key;
QByteArray m_nativeKey;
QSharedMemory::SharedMemoryError m_error;
diff --git a/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp b/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp
index 9cd0e2a953..47857eaac7 100644
--- a/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp
+++ b/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp
@@ -45,10 +45,6 @@
#include <private/qcore_unix_p.h>
-#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
-#define QStringLiteral(str) QString::fromLatin1(str)
-#endif
-
namespace QmlDesigner {
class SharedMemoryLocker
@@ -74,7 +70,7 @@ public:
m_sharedMemory->m_errorString = QStringLiteral("%1: unable to lock").arg(function);
m_sharedMemory->m_error = QSharedMemory::LockError;
- m_sharedMemory = 0;
+ m_sharedMemory = nullptr;
return false;
}
@@ -98,7 +94,7 @@ static QByteArray makePlatformSafeKey(const QString &key)
SharedMemory::SharedMemory()
- : m_memory(0),
+ : m_memory(nullptr),
m_size(0),
m_error(QSharedMemory::NoError),
m_systemSemaphore(QString()),
@@ -109,7 +105,7 @@ SharedMemory::SharedMemory()
}
SharedMemory::SharedMemory(const QString &key)
- : m_memory(0),
+ : m_memory(nullptr),
m_size(0),
m_error(QSharedMemory::NoError),
m_systemSemaphore(QString()),
@@ -176,12 +172,12 @@ bool SharedMemory::create(int size, QSharedMemory::AccessMode mode)
return false;
}
- return createInternal(mode ,size);
+ return createInternal(mode, size_t(size));
}
int SharedMemory::size() const
{
- return m_size;
+ return int(m_size);
}
bool SharedMemory::attach(QSharedMemory::AccessMode mode)
@@ -202,7 +198,7 @@ bool SharedMemory::attach(QSharedMemory::AccessMode mode)
bool SharedMemory::isAttached() const
{
- return (0 != m_memory);
+ return m_memory != nullptr;
}
bool SharedMemory::detach()
@@ -348,7 +344,7 @@ void SharedMemory::cleanHandleInternal()
m_fileHandle = -1;
}
-bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size)
+bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, size_t size)
{
detachInternal();
@@ -390,10 +386,10 @@ bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size)
struct stat statBuffer;
if (fstat(m_fileHandle, &statBuffer) == -1)
return false;
- int fileSize = statBuffer.st_size;
+ size_t fileSize = size_t(statBuffer.st_size);
if (fileSize < size) {
- int returnValue = ftruncate(m_fileHandle, size);
+ int returnValue = ftruncate(m_fileHandle, ssize_t(size));
if (returnValue == -1) {
switch (errno) {
case EFBIG:
@@ -414,12 +410,12 @@ bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size)
}
int protection = mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_WRITE;
- m_memory = mmap(0, size, protection, MAP_SHARED, m_fileHandle, 0);
+ m_memory = mmap(nullptr, size, protection, MAP_SHARED, m_fileHandle, 0);
if (m_memory == MAP_FAILED) {
close(m_fileHandle);
shm_unlink(m_nativeKey.constData());
- m_memory = 0;
+ m_memory = nullptr;
m_fileHandle = -1;
m_size = 0;
@@ -460,13 +456,13 @@ bool SharedMemory::attachInternal(QSharedMemory::AccessMode mode)
struct stat statBuffer;
if (fstat(m_fileHandle, &statBuffer) == -1)
return false;
- int size = statBuffer.st_size;
+ size_t size = size_t(statBuffer.st_size);
int protection = mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_WRITE;
- m_memory = mmap(0, size, protection, MAP_SHARED, m_fileHandle, 0);
+ m_memory = mmap(nullptr, size, protection, MAP_SHARED, m_fileHandle, 0);
if (m_memory == MAP_FAILED) {
- m_memory = 0;
+ m_memory = nullptr;
return false;
}
@@ -480,7 +476,7 @@ bool SharedMemory::detachInternal()
{
if (m_memory) {
munmap(m_memory, m_size);
- m_memory = 0;
+ m_memory = nullptr;
m_size = 0;
}
diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp
index ca4792e7a0..5ac0e1057b 100644
--- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp
+++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp
@@ -72,9 +72,9 @@ namespace QmlDesigner {
NodeInstanceClientProxy::NodeInstanceClientProxy(QObject *parent)
: QObject(parent),
- m_inputIoDevice(0),
- m_outputIoDevice(0),
- m_nodeInstanceServer(0),
+ m_inputIoDevice(nullptr),
+ m_outputIoDevice(nullptr),
+ m_nodeInstanceServer(nullptr),
m_writeCommandCounter(0),
m_synchronizeId(-1)
{
@@ -303,9 +303,8 @@ void NodeInstanceClientProxy::readDataStream()
break;
}
- foreach (const QVariant &command, commandList) {
+ for (const QVariant &command : qAsConst(commandList))
dispatchCommand(command);
- }
}
void NodeInstanceClientProxy::sendPuppetAliveCommand()
diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h
index a14bbb3b45..2c53a77c90 100644
--- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h
+++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h
@@ -63,7 +63,7 @@ class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterfa
Q_OBJECT
public:
- NodeInstanceClientProxy(QObject *parent = 0);
+ NodeInstanceClientProxy(QObject *parent = nullptr);
void informationChanged(const InformationChangedCommand &command) override;
void valuesChanged(const ValuesChangedCommand &command) override;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp
index f546548b41..ad81fbdf6e 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp
@@ -72,7 +72,8 @@ void ComponentNodeInstance::setNodeSource(const QString &source)
setId(id());
if (component()->isError()) {
- foreach (const QQmlError &error, component()->errors())
+ const QList<QQmlError> errors = component()->errors();
+ for (const QQmlError &error : errors)
qWarning() << error;
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h
index a5257a2086..6afb5ad0ff 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h
@@ -38,7 +38,7 @@ class DummyContextObject : public QObject
Q_PROPERTY(bool runningInDesigner READ runningInDesigner FINAL)
public:
- explicit DummyContextObject(QObject *parent = 0);
+ explicit DummyContextObject(QObject *parent = nullptr);
QObject *parentDummy() const;
void setParentDummy(QObject *parentDummy);
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
index ad6867e930..5006281803 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
@@ -187,7 +187,7 @@ QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<Inst
{
Q_ASSERT(declarativeView() || quickView());
QList<ServerNodeInstance> instanceList;
- foreach (const InstanceContainer &instanceContainer, containerVector) {
+ for (const InstanceContainer &instanceContainer : containerVector) {
ServerNodeInstance instance;
if (instanceContainer.nodeSourceType() == InstanceContainer::ComponentSource) {
instance = ServerNodeInstance::create(this, instanceContainer, ServerNodeInstance::WrapAsComponent);
@@ -585,13 +585,8 @@ QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCo
setInstanceAuxiliaryData(container);
}
-
- QListIterator<ServerNodeInstance> instanceListIterator(instanceList);
- instanceListIterator.toBack();
- while (instanceListIterator.hasPrevious()) {
- ServerNodeInstance instance = instanceListIterator.previous();
- instance.doComponentComplete();
- }
+ for (int i = instanceList.size(); --i >= 0; )
+ instanceList[i].doComponentComplete();
return instanceList;
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
index 5f88683ffa..ec453956df 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp
@@ -137,7 +137,7 @@ void ObjectNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNod
void ObjectNodeInstance::setId(const QString &id)
{
if (!m_id.isEmpty() && context()) {
- context()->engine()->rootContext()->setContextProperty(m_id, 0);
+ context()->engine()->rootContext()->setContextProperty(m_id, nullptr);
}
if (!id.isEmpty() && context()) {
@@ -324,7 +324,7 @@ void ObjectNodeInstance::removeFromOldProperty(QObject *object, QObject *oldPare
}
if (object && object->parent())
- object->setParent(0);
+ object->setParent(nullptr);
}
void ObjectNodeInstance::addToNewProperty(QObject *object, QObject *newParent, const PropertyName &newParentProperty)
@@ -649,14 +649,14 @@ QObject *ObjectNodeInstance::createPrimitive(const QString &typeName, int majorN
QObject *ObjectNodeInstance::createPrimitiveFromSource(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context)
{
if (typeName.isEmpty())
- return 0;
+ return nullptr;
QStringList parts = typeName.split("/");
const QString unqualifiedTypeName = parts.last();
parts.removeLast();
if (parts.isEmpty())
- return 0;
+ return nullptr;
QString importString = parts.join(".") + " " + QString::number(majorNumber) + "." + QString::number(minorNumber);
if (importString == "QtQuick 1.0") /* Workaround for implicit QQml import */
@@ -772,12 +772,12 @@ QObject *ObjectNodeInstance::object() const
{
if (!m_object.isNull() && !QmlPrivateGate::objectWasDeleted(m_object.data()))
return m_object.data();
- return 0;
+ return nullptr;
}
QQuickItem *ObjectNodeInstance::contentItem() const
{
- return 0;
+ return nullptr;
}
bool ObjectNodeInstance::hasContent() const
@@ -819,7 +819,7 @@ QQmlContext *ObjectNodeInstance::context() const
return nodeInstanceServer()->context();
qWarning() << "Error: No NodeInstanceServer";
- return 0;
+ return nullptr;
}
QQmlEngine *ObjectNodeInstance::engine() const
@@ -867,7 +867,7 @@ QImage ObjectNodeInstance::renderPreviewImage(const QSize & /*previewImageSize*/
QObject *ObjectNodeInstance::parent() const
{
if (!object())
- return 0;
+ return nullptr;
return object()->parent();
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h
index b8efccc7ec..0b6b696e1a 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h
@@ -33,7 +33,7 @@ class Qt5NodeInstanceClientProxy : public NodeInstanceClientProxy
{
Q_OBJECT
public:
- explicit Qt5NodeInstanceClientProxy(QObject *parent = 0);
+ explicit Qt5NodeInstanceClientProxy(QObject *parent = nullptr);
};
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
index 2a9118625c..d8d45c4803 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp
@@ -77,7 +77,7 @@ void Qt5NodeInstanceServer::initializeView()
QQmlView *Qt5NodeInstanceServer::declarativeView() const
{
- return 0;
+ return nullptr;
}
QQmlEngine *Qt5NodeInstanceServer::engine() const
@@ -85,7 +85,7 @@ QQmlEngine *Qt5NodeInstanceServer::engine() const
if (quickView())
return quickView()->engine();
- return 0;
+ return nullptr;
}
void Qt5NodeInstanceServer::resizeCanvasSizeToRootItemSize()
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
index 761ad9cdfe..d061cdfc5d 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
@@ -95,7 +95,7 @@ QTransform QuickItemNodeInstance::transform() const
QObject *QuickItemNodeInstance::parent() const
{
if (!quickItem() || !quickItem()->parentItem())
- return 0;
+ return nullptr;
return quickItem()->parentItem();
}
@@ -799,8 +799,8 @@ bool QuickItemNodeInstance::isAnchoredBySibling() const
QQuickItem *QuickItemNodeInstance::quickItem() const
{
- if (object() == 0)
- return 0;
+ if (object() == nullptr)
+ return nullptr;
return static_cast<QQuickItem*>(object());
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
index 11234b9521..87aea97d8d 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp
@@ -160,7 +160,7 @@ Internal::ObjectNodeInstance::Pointer ServerNodeInstance::createInstance(QObject
{
Internal::ObjectNodeInstance::Pointer instance;
- if (objectToBeWrapped == 0)
+ if (objectToBeWrapped == nullptr)
instance = Internal::DummyNodeInstance::create();
else if (isSubclassOf(objectToBeWrapped, "Q3DSPresentationItem"))
instance = Internal::Qt3DPresentationNodeInstance::create(objectToBeWrapped);
@@ -198,28 +198,28 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe
Q_ASSERT(instanceContainer.instanceId() != -1);
Q_ASSERT(nodeInstanceServer);
- QObject *object = 0;
+ QObject *object = nullptr;
if (componentWrap == WrapAsComponent) {
object = Internal::ObjectNodeInstance::createComponentWrap(instanceContainer.nodeSource(), nodeInstanceServer->importCode(), nodeInstanceServer->context());
} else if (!instanceContainer.nodeSource().isEmpty()) {
object = Internal::ObjectNodeInstance::createCustomParserObject(instanceContainer.nodeSource(), nodeInstanceServer->importCode(), nodeInstanceServer->context());
- if (object == 0)
+ if (object == nullptr)
nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Custom parser object could not be created."), instanceContainer.instanceId());
} else if (!instanceContainer.componentPath().isEmpty()) {
object = Internal::ObjectNodeInstance::createComponent(instanceContainer.componentPath(), nodeInstanceServer->context());
- if (object == 0)
+ if (object == nullptr)
nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QString("Component with path %1 could not be created.").arg(instanceContainer.componentPath()), instanceContainer.instanceId());
} else {
object = Internal::ObjectNodeInstance::createPrimitive(QString::fromUtf8(instanceContainer.type()), instanceContainer.majorNumber(), instanceContainer.minorNumber(), nodeInstanceServer->context());
- if (object == 0)
+ if (object == nullptr)
nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Item could not be created."), instanceContainer.instanceId());
}
- if (object == 0) {
+ if (object == nullptr) {
if (instanceContainer.metaType() == InstanceContainer::ItemMetaType) { //If we cannot instanciate the object but we know it has to be an Ttem, we create an Item instead.
object = Internal::ObjectNodeInstance::createPrimitive("QtQuick/Item", 2, 0, nodeInstanceServer->context());
- if (object == 0)
+ if (object == nullptr)
object = new QQuickItem;
} else {
object = Internal::ObjectNodeInstance::createPrimitive("QtQml/QtObject", 2, 0, nodeInstanceServer->context());
@@ -549,7 +549,7 @@ void ServerNodeInstance::paintUpdate()
QObject *ServerNodeInstance::internalObject() const
{
if (m_nodeInstance.isNull())
- return 0;
+ return nullptr;
return m_nodeInstance->object();
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
index c0c3f87608..b37c153f65 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h
@@ -123,7 +123,7 @@ public:
PropertyNameList propertyNames() const;
- bool hasBindingForProperty(const PropertyName &name, bool *hasChanged = 0) const;
+ bool hasBindingForProperty(const PropertyName &name, bool *hasChanged = nullptr) const;
bool isValid() const;
void makeInvalid();
diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp b/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp
index 08caa70368..86049c9654 100644
--- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp
@@ -183,7 +183,7 @@ void MetaObject::createNewDynamicProperty(const QString &name)
copyTypeMetaObject();
setValue(id, QVariant());
Q_ASSERT(id >= 0);
- Q_UNUSED(id);
+ Q_UNUSED(id)
//Updating cache
QQmlPropertyCache *oldParent = m_cache->parent();
diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h
index 4e90bad1fc..b0b68907ed 100644
--- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h
+++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h
@@ -70,10 +70,10 @@ public:
bool isPropertyBlackListed(const QmlDesigner::PropertyName &propertyName);
PropertyNameList propertyNameListForWritableProperties(QObject *object,
const PropertyName &baseName = PropertyName(),
- QObjectList *inspectedObjects = 0);
+ QObjectList *inspectedObjects = nullptr);
PropertyNameList allPropertyNames(QObject *object,
const PropertyName &baseName = PropertyName(),
- QObjectList *inspectedObjects = 0);
+ QObjectList *inspectedObjects = nullptr);
bool hasFullImplementedListInterface(const QQmlListReference &list);
void registerCustomData(QObject *object);
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml
index e377dcdf33..80882ac213 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml
@@ -27,6 +27,7 @@ import QtQuick 2.1
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
import QtQuickDesignerTheme 1.0
+import HelperWidgets 2.0
Item {
id: extendedFunctionButton
@@ -143,62 +144,27 @@ Item {
function show() {
expressionDialogLoader.visible = true
}
+ sourceComponent: Item {
+ id: bindingEditorParent
+
+ Component.onCompleted: {
+ var x = extendedFunctionButton.mapToGlobal(0,0).x - 200
+ var y = extendedFunctionButton.mapToGlobal(0,0).y - 40
+ bindingEditor.showWidget(x, y)
+ bindingEditor.text = backendValue.expression
+ }
- sourceComponent: Component {
- Item {
- id: expressionDialog
- anchors.fill: parent
-
- Component.onCompleted: {
- textField.text = backendValue.expression
- textField.forceActiveFocus()
- }
-
- Rectangle {
- anchors.fill: parent
- color: Theme.qmlDesignerBackgroundColorDarker()
- opacity: 0.6
- }
+ BindingEditor {
+ id: bindingEditor
- MouseArea {
- anchors.fill: parent
- onDoubleClicked: expressionDialog.visible = false
+ onRejected: {
+ hideWidget()
+ expressionDialogLoader.visible = false
}
-
- Rectangle {
- x: 4
- Component.onCompleted: {
- var pos = itemPane.mapFromItem(
- extendedFunctionButton.parent, 0, 0)
- y = pos.y + 2
- }
-
- width: parent.width - 8
- height: 260
-
- radius: 2
- color: Theme.qmlDesignerBackgroundColorDarkAlternate()
- border.color: Theme.qmlDesignerBorderColor()
-
- Label {
- x: 8
- y: 6
- font.bold: true
- text: qsTr("Binding Editor")
- }
- ExpressionTextField {
- id: textField
- onRejected: expressionDialogLoader.visible = false
- onAccepted: {
- backendValue.expression = textField.text.trim()
- expressionDialogLoader.visible = false
- }
- anchors.fill: parent
- anchors.leftMargin: 8
- anchors.rightMargin: 8
- anchors.topMargin: 24
- anchors.bottomMargin: 32
- }
+ onAccepted: {
+ backendValue.expression = bindingEditor.text.trim()
+ hideWidget()
+ expressionDialogLoader.visible = false
}
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml
index ded679b624..c955cd8bc6 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml
@@ -31,6 +31,7 @@ import QtQuick.Dialogs 1.3
import HelperWidgets 2.0
import QtQuickDesignerTheme 1.0
+import QtQuick.Controls.Private 1.0 as PrivateControls
Rectangle {
@@ -45,9 +46,9 @@ Rectangle {
signal presetNameChanged(int id, string name)
signal deleteButtonClicked(int id)
- property int delegateWidth: 153;
- property int delegateHeight: 173;
- property int gridCellWidth: 160;
+ property real delegateWidth: 154;
+ property real delegateHeight: 178;
+ property real gridCellWidth: 160;
ScrollView {
@@ -66,7 +67,7 @@ Rectangle {
property int gridColumns: width / tabBackground.gridCellWidth;
cellWidth: width / gridColumns
- cellHeight: 180
+ cellHeight: 185
Component {
id: gradientDelegate
@@ -74,12 +75,13 @@ Rectangle {
Rectangle {
id: backgroundCard
color: "#404040"
- clip: false
+ clip: true
property real flexibleWidth: (gradientTable.width - gradientTable.cellWidth * gradientTable.gridColumns) / gradientTable.gridColumns
property bool isSelected: false
- width: gradientTable.cellWidth + flexibleWidth - 8; height: tabBackground.delegateHeight
+ width: gradientTable.cellWidth + flexibleWidth - 8
+ height: tabBackground.delegateHeight
radius: 16
MouseArea {
@@ -125,8 +127,6 @@ Rectangle {
PropertyChanges {
target: backgroundCard
color: "#606060"
- z: 5
- clip: true
border.width: 1
border.color: "#029de0"
}
@@ -136,8 +136,6 @@ Rectangle {
PropertyChanges {
target: backgroundCard
color:"#029de0"
- z: 4
- clip: true
border.width: 1
border.color: "#606060"
}
@@ -148,21 +146,22 @@ Rectangle {
{
target: backgroundCard
color: "#404040"
- scale: 1.0
border.width: 0
}
}
] //states
ColumnLayout {
+ spacing: 2
anchors.fill: parent
Rectangle {
width: 150; height: 150
id: gradientRect
radius: 16
- Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter //was top
Layout.topMargin: 2
+
gradient: Gradient {
id: showGr
}
@@ -184,54 +183,178 @@ Rectangle {
Rectangle {
id: removeItemRect
anchors.right: parent.right
- anchors.rightMargin: 2
+ anchors.rightMargin: 5
anchors.top: parent.top
- anchors.topMargin: 2
+ anchors.topMargin: 5
height: 16
width: 16
visible: editableName && rectMouseArea.containsMouse
color: "#804682b4"
-
MouseArea {
anchors.fill: parent;
onClicked: tabBackground.deleteButtonClicked(index);
}
Image {
- id: remoreItemImg
source: "image://icons/close"
fillMode: Image.PreserveAspectFit
anchors.fill: parent;
Layout.alignment: Qt.AlignCenter
- }
- }
+ } //image remove
+ } //rectangle remove
} //rectangle gradient
- TextInput {
+ Item {
id: presetNameBox
- readOnly: !editableName
- text: (presetName)
- Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
- Layout.preferredWidth: backgroundCard.width
- Layout.topMargin: -5
- padding: 5.0
- topPadding: -2.0
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.Wrap
- color: "#ffffff"
- activeFocusOnPress: true
-
- onEditingFinished: tabBackground.presetNameChanged(index, text);
-
- Keys.onPressed: {
- if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
- event.accepted = true;
- editingFinished();
- focus = false;
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.preferredWidth: backgroundCard.width - 2
+ Layout.preferredHeight: backgroundCard.height - gradientRect.height - 4
+ Layout.bottomMargin: 4
+
+ property bool readOnly : true;
+
+ onReadOnlyChanged: {
+ if (!readOnly) {
+ nameInput.visible = true;
+ nameInput.forceActiveFocus();
+
+ //have to select text like this, otherwise there is an issue with long names
+ nameInput.cursorPosition = 0;
+ nameInput.cursorPosition = nameInput.length;
+ nameInput.selectAll();
+ }
+ } //onReadOnlyChanged
+
+ Rectangle {
+ id: nameBackgroundColor
+ enabled: tabBackground.editableName
+ color: "transparent"
+ radius: 16
+ visible: true
+ anchors.fill: parent
+ } //rectangle
+
+ MouseArea {
+ id: nameMouseArea
+ visible: tabBackground.editableName
+ hoverEnabled: true
+ anchors.fill: parent
+
+ onClicked: presetNameBox.state = "Clicked";
+
+ onEntered: {
+ if (presetNameBox.state != "Clicked")
+ {
+ presetNameBox.state = "Hover";
+ }
+ }
+
+ onExited: {
+ if (presetNameBox.state != "Clicked")
+ {
+ presetNameBox.state = "Normal";
+ }
+ PrivateControls.Tooltip.hideText()
+ }
+
+ Timer {
+ interval: 1000
+ running: nameMouseArea.containsMouse && presetNameBox.readOnly
+ onTriggered: PrivateControls.Tooltip.showText(nameMouseArea, Qt.point(nameMouseArea.mouseX, nameMouseArea.mouseY), presetName)
+ }
+
+ onCanceled: Tooltip.hideText()
+
+ } //mouseArea
+
+ Text {
+ id: nameText
+ visible: presetNameBox.readOnly
+ text: presetName
+ anchors.fill: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "#ffffff"
+ elide: Text.ElideMiddle
+ maximumLineCount: 1
+ } //text
+
+
+ TextInput {
+ id: nameInput
+ visible: !presetNameBox.readOnly
+ text: presetName
+ anchors.fill: parent
+ anchors.leftMargin: 5
+ anchors.rightMargin: 5
+ horizontalAlignment: TextInput.AlignHCenter
+ verticalAlignment: TextInput.AlignVCenter
+ color: "#ffffff"
+ selectionColor: "#029de0"
+ activeFocusOnPress: true
+ wrapMode: TextInput.NoWrap
+ clip: true
+
+ onEditingFinished: {
+ nameText.text = text
+ tabBackground.presetNameChanged(index, text);
+ presetNameBox.state = "Normal";
+ }
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
+ event.accepted = true;
+ editingFinished();
+ focus = false;
+ } //if
+ } //Keys.onPressed
+ } //textInput
+
+ states: [
+ State {
+ name: "Normal"
+ PropertyChanges {
+ target: nameBackgroundColor
+ color: "transparent"
+ border.width: 0
+ }
+ PropertyChanges {
+ target: presetNameBox
+ readOnly: true
+ }
+ },
+ State {
+ name: "Hover"
+ PropertyChanges {
+ target: nameBackgroundColor
+ color: "#606060"
+ border.width: 0
+ }
+ PropertyChanges {
+ target: presetNameBox
+ readOnly: true
+ }
+ },
+ State {
+ name: "Clicked"
+ PropertyChanges {
+ target: nameBackgroundColor
+ color: "#606060"
+ border.color: "#029de0"
+ border.width: 1
+ }
+ PropertyChanges {
+ target: presetNameBox
+ readOnly: false
+ }
+ PropertyChanges {
+ target: nameInput
+ visible: true
+ }
}
- } //Keys.onPressed
- } //textInput
+ ] //states
+ } //gradient name Item
} //columnLayout
} //rectangle background
} //component delegate
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
index 26d4c21cc9..5f044b73f4 100644
--- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
+++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml
@@ -30,7 +30,6 @@ import HelperWidgets 2.0
import QtQuickDesignerTheme 1.0
Rectangle {
- z: expressionTextField.visible ? 5 : 0
border.width: 1
property bool isBaseState
property bool isCurrentState
@@ -111,9 +110,10 @@ Rectangle {
MenuItem {
text: qsTr("Set when Condition")
onTriggered: {
- expressionTextField.text = delegateWhenConditionString
- expressionTextField.visible = true
- expressionTextField.forceActiveFocus()
+ var x = whenButton.mapToGlobal(0,0).x + 4
+ var y = root.mapToGlobal(0,0).y - 32
+ bindingEditor.showWidget(x, y)
+ bindingEditor.text = delegateWhenConditionString
}
}
@@ -192,19 +192,27 @@ Rectangle {
}
}
- ExpressionTextField {
- id: expressionTextField
+ BindingEditor {
+ property string newWhenCondition
- parent: root
- visible: false
- onAccepted: {
- visible = false
- statesEditorModel.setWhenCondition(internalNodeId, expressionTextField.text.trim())
+ property Timer timer: Timer {
+ id: timer
+ running: false
+ interval: 50
+ repeat: false
+ onTriggered: statesEditorModel.setWhenCondition(internalNodeId, bindingEditor.newWhenCondition)
}
- onRejected: visible = false
+ id: bindingEditor
- anchors.fill: parent
+ onRejected: {
+ hideWidget()
+ }
+ onAccepted: {
+ bindingEditor.newWhenCondition = bindingEditor.text.trim()
+ timer.start()
+ hideWidget()
+ }
}
}
diff --git a/share/qtcreator/scripts/openTerminal.py b/share/qtcreator/scripts/openTerminal.py
index afcb94d632..e931c6bb26 100755
--- a/share/qtcreator/scripts/openTerminal.py
+++ b/share/qtcreator/scripts/openTerminal.py
@@ -105,7 +105,8 @@ def main():
login_script() +
'cd ' + quote_shell(os.getcwd()) + '\n' +
' '.join([quote_shell(arg) for arg in sys.argv[1:]]) + '\n' +
- 'rm ' + quoted_shell_script + '\n'
+ 'rm ' + quoted_shell_script + '\n' +
+ 'exit\n' if len(sys.argv) > 1 else ''
)
shell_script.write(commands)
shell_script.flush()
diff --git a/share/qtcreator/templates/wizards/autotest/files/googlecommon.js b/share/qtcreator/templates/wizards/autotest/files/googlecommon.js
index 1079ed5fdf..7f754cc9e8 100644
--- a/share/qtcreator/templates/wizards/autotest/files/googlecommon.js
+++ b/share/qtcreator/templates/wizards/autotest/files/googlecommon.js
@@ -13,12 +13,13 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
**/
+var File = require("qbs.File")
var FileInfo = require("qbs.FileInfo")
function getGTestDir(qbs, str) {
if (!str) {
- if (qbs.hostOS.contains("linux"))
- return "/usr/include/gtest";
+ if (qbs.hostOS.contains("linux") && File.exists("/usr/src/gtest"))
+ return "/usr/src/gtest";
} else {
return FileInfo.joinPaths(str, "googletest");
}
@@ -27,8 +28,8 @@ function getGTestDir(qbs, str) {
function getGMockDir(qbs, str) {
if (!str) {
- if (qbs.hostOS.contains("linux"))
- return "/usr/include/gmock";
+ if (qbs.hostOS.contains("linux") && File.exists("/usr/src/gmock"))
+ return "/usr/src/gmock";
} else {
return FileInfo.joinPaths(str, "googlemock");
}
diff --git a/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri b/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri
index c01bab677c..c064ef6242 100644
--- a/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri
+++ b/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri
@@ -1,31 +1,43 @@
isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR)
isEmpty(GOOGLETEST_DIR) {
- warning("Using googletest src dir specified at Qt Creator wizard")
- message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message")
GOOGLETEST_DIR = %{GTestRepository}
+ !isEmpty(GOOGLETEST_DIR) {
+ warning("Using googletest src dir specified at Qt Creator wizard")
+ message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message")
+ }
}
!isEmpty(GOOGLETEST_DIR): {
GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest
GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock
+} else: unix {
+ exists(/usr/src/gtest):GTEST_SRCDIR=/usr/src/gtest
+ exists(/usr/src/gmock):GMOCK_SRCDIR=/usr/src/gmock
+ !isEmpty(GTEST_SRCDIR): message("Using gtest from system")
}
requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR))
-!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.")
-
@if "%{GTestCXX11}" == "true"
DEFINES += \\
GTEST_LANG_CXX11
@endif
-INCLUDEPATH *= \\
- $$GTEST_SRCDIR \\
- $$GTEST_SRCDIR/include \\
- $$GMOCK_SRCDIR \\
- $$GMOCK_SRCDIR/include
+!isEmpty(GTEST_SRCDIR) {
+ INCLUDEPATH *= \\
+ $$GTEST_SRCDIR \\
+ $$GTEST_SRCDIR/include
+
+ SOURCES += \\
+ $$GTEST_SRCDIR/src/gtest-all.cc
+}
-SOURCES += \\
- $$GTEST_SRCDIR/src/gtest-all.cc \\
- $$GMOCK_SRCDIR/src/gmock-all.cc
+!isEmpty(GMOCK_SRCDIR) {
+ INCLUDEPATH *= \\
+ $$GMOCK_SRCDIR \\
+ $$GMOCK_SRCDIR/include
+
+ SOURCES += \\
+ $$GMOCK_SRCDIR/src/gmock-all.cc
+}
diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.qbs b/share/qtcreator/templates/wizards/autotest/files/tst.qbs
index 92a0656d65..e66605f0a5 100644
--- a/share/qtcreator/templates/wizards/autotest/files/tst.qbs
+++ b/share/qtcreator/templates/wizards/autotest/files/tst.qbs
@@ -26,8 +26,12 @@ CppApplication {
@if "%{TestFrameWork}" == "GTest"
property string googletestDir: {
if (typeof Environment.getEnv("GOOGLETEST_DIR") === 'undefined') {
- console.warn("Using googletest src dir specified at Qt Creator wizard")
- console.log("set GOOGLETEST_DIR as environment variable or Qbs property to get rid of this message")
+ if ("%{GTestRepository}" === "" && googleCommon.getGTestDir(qbs, undefined) !== "") {
+ console.warn("Using googletest from system")
+ } else {
+ console.warn("Using googletest src dir specified at Qt Creator wizard")
+ console.log("set GOOGLETEST_DIR as environment variable or Qbs property to get rid of this message")
+ }
return "%{GTestRepository}"
} else {
return Environment.getEnv("GOOGLETEST_DIR")
diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.txt b/share/qtcreator/templates/wizards/autotest/files/tst.txt
index bf5e75ff16..f1d57e97ab 100644
--- a/share/qtcreator/templates/wizards/autotest/files/tst.txt
+++ b/share/qtcreator/templates/wizards/autotest/files/tst.txt
@@ -62,22 +62,35 @@ find_package(Threads REQUIRED)
if ($ENV{GOOGLETEST_DIR})
set(GOOGLETEST_DIR $ENV{GOOGLETEST_DIR})
else ()
- message(WARNING "Using googletest src dir specified at Qt Creator wizard")
+ if (NOT "%{GTestRepository}" STREQUAL "")
+ message(WARNING "Using googletest src dir specified at Qt Creator wizard")
+ endif ()
set(GOOGLETEST_DIR "%{GTestRepository}")
endif ()
if (EXISTS ${GOOGLETEST_DIR})
set(GTestSrc ${GOOGLETEST_DIR}/googletest)
set(GMockSrc ${GOOGLETEST_DIR}/googlemock)
+elseif (UNIX AND EXISTS /usr/src/gtest)
+ set(GTestSrc /usr/src/gtest)
+ message(WARNING "Using gtest from system")
+ if (EXISTS /usr/src/gmock)
+ set(GMockSrc /usr/src/gmock)
+ endif ()
else ()
message( FATAL_ERROR "No googletest src dir found - set GOOGLETEST_DIR to enable!")
endif ()
+set(GTestFiles ${GTestSrc}/src/gtest-all.cc)
+set(GTestIncludes ${GTestSrc} ${GTestSrc}/include)
+if (NOT ${GMockSrc} STREQUAL "")
+ list(APPEND GTestFiles ${GMockSrc}/src/gmock-all.cc)
+ list(APPEND GTestIncludes ${GMockSrc} ${GMockSrc}/include)
+endif ()
-include_directories(${GTestSrc} ${GTestSrc}/include ${GMockSrc} ${GMockSrc}/include)
+include_directories(${GTestIncludes})
add_executable(%{TestCaseName} %{MainCppName} %{TestCaseFileWithHeaderSuffix}
- ${GTestSrc}/src/gtest-all.cc
- ${GMockSrc}/src/gmock-all.cc)
+ ${GTestFiles})
add_test(%{TestCaseName} COMMAND %{TestCaseName})
target_link_libraries(%{TestCaseName} PRIVATE Threads::Threads)
diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json
index 83a4be09a4..6744a14a8c 100644
--- a/share/qtcreator/templates/wizards/autotest/wizard.json
+++ b/share/qtcreator/templates/wizards/autotest/wizard.json
@@ -149,8 +149,9 @@
},
{
"name": "GTestRepository",
- "trDisplayName": "Googletest repository:",
+ "trDisplayName": "Googletest source directory (optional):",
"visible": "%{JS: value('TestFrameWork') === 'GTest'}",
+ "mandatory": false,
"type": "PathChooser",
"data": {
"kind": "existingDirectory"
@@ -158,7 +159,7 @@
},
{
"name": "BoostIncDir",
- "trDisplayName": "Boost include dir (optional):",
+ "trDisplayName": "Boost include directory (optional):",
"visible": "%{JS: value('TestFrameWork') == 'BoostTest'}",
"mandatory": false,
"type": "PathChooser",
diff --git a/share/qtcreator/templates/wizards/classes/cpp/file.h b/share/qtcreator/templates/wizards/classes/cpp/file.h
index 583c63dd30..aa2fa7faaf 100644
--- a/share/qtcreator/templates/wizards/classes/cpp/file.h
+++ b/share/qtcreator/templates/wizards/classes/cpp/file.h
@@ -28,7 +28,7 @@ class %{CN} : public %{Base}
class %{CN}
@endif
{
-@if %{isQObject}
+@if '%{AddQObjectMacro}'
Q_OBJECT
@endif
public:
@@ -46,9 +46,12 @@ public:
@endif
@if %{isQObject}
+@if %{QtKeywordsEnabled}
signals:
+@else
+Q_SIGNALS:
+@endif
-public slots:
@endif
@if '%{IncludeQSharedData}'
diff --git a/share/qtcreator/templates/wizards/classes/cpp/wizard.json b/share/qtcreator/templates/wizards/classes/cpp/wizard.json
index ae466ba7ed..bb8a1f9fef 100644
--- a/share/qtcreator/templates/wizards/classes/cpp/wizard.json
+++ b/share/qtcreator/templates/wizards/classes/cpp/wizard.json
@@ -18,7 +18,8 @@
{ "key": "Base", "value": "%{JS: value('BaseCB') === '' ? value('BaseEdit') : value('BaseCB')}" },
{ "key": "isQObject", "value": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QDeclarativeItem', 'QQuickItem'].indexOf(value('Base')) >= 0 }" },
{ "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" },
- { "key": "SharedDataInit", "value": "%{JS: (value('IncludeQSharedData')) ? 'data(new %{CN}Data)' : '' }" }
+ { "key": "SharedDataInit", "value": "%{JS: (value('IncludeQSharedData')) ? 'data(new %{CN}Data)' : '' }" },
+ { "key": "Dependencies", "value": "%{JS: '' + (value('IncludeQObject') || value('IncludeQSharedData') || value('BaseCB') === 'QObject' ? ':Qt.core' : '') + (value('IncludeQWidget') || value('IncludeQMainWindow') || value('BaseCB') === 'QWidget' || value('BaseCB') === 'QMainWindow' ? ':Qt.widgets' : '') + (value('IncludeQQuickItem') || value('BaseCB') === 'QQuickItem' ? ':Qt.quick' : '')}"}
],
"pages":
@@ -130,6 +131,17 @@
}
},
{
+ "name": "AddQObjectMacro",
+ "trDisplayName": "Add Q_OBJECT",
+ "type": "CheckBox",
+ "data":
+ {
+ "checkedValue": "AddQObjectMacro",
+ "uncheckedValue": "",
+ "checked": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QDeclarativeItem', 'QQuickItem'].indexOf(value('Base')) >= 0 }"
+ }
+ },
+ {
"name": "Sp2",
"type": "Spacer"
},
diff --git a/share/qtcreator/templates/wizards/classes/python/wizard.json b/share/qtcreator/templates/wizards/classes/python/wizard.json
index 233a8bac7a..552c3f15a0 100644
--- a/share/qtcreator/templates/wizards/classes/python/wizard.json
+++ b/share/qtcreator/templates/wizards/classes/python/wizard.json
@@ -7,7 +7,7 @@
"trDisplayName": "Python Class",
"trDisplayCategory": "Python",
"icon": "../../files/python/icon.png",
- "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}",
+ "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}",
"options":
[
diff --git a/share/qtcreator/templates/wizards/files/python/wizard.json b/share/qtcreator/templates/wizards/files/python/wizard.json
index 262de2d37b..f3bff037b5 100644
--- a/share/qtcreator/templates/wizards/files/python/wizard.json
+++ b/share/qtcreator/templates/wizards/files/python/wizard.json
@@ -7,7 +7,7 @@
"trDisplayName": "Python File",
"trDisplayCategory": "Python",
"icon": "icon.png",
- "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}",
+ "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}",
"pages" :
[
diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt
index ce63061d75..d7eda0b02d 100644
--- a/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt
+++ b/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt
@@ -11,7 +11,22 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
+@if %{HasTranslation}
+find_package(Qt5 COMPONENTS Core LinguistTools REQUIRED)
+
+set(TS_FILES %{TsFileName})
+@else
find_package(Qt5Core)
+@endif
-add_executable(%{ProjectName} %{CppFileName})
+add_executable(%{ProjectName}
+ %{CppFileName}
+@if %{HasTranslation}
+ ${TS_FILES}
+@endif
+)
target_link_libraries(%{ProjectName} Qt5::Core)
+@if %{HasTranslation}
+
+qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
+@endif
diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/file.pro b/share/qtcreator/templates/wizards/projects/consoleapp/file.pro
index d38289ce09..a8ed27c2ad 100644
--- a/share/qtcreator/templates/wizards/projects/consoleapp/file.pro
+++ b/share/qtcreator/templates/wizards/projects/consoleapp/file.pro
@@ -16,6 +16,11 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \\
%{CppFileName}
+@if %{HasTranslation}
+
+TRANSLATIONS += \\
+ %{TsFileName}
+@endif
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs b/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs
index 3587027384..dfdd823780 100644
--- a/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs
+++ b/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs
@@ -17,7 +17,12 @@ QtApplication {
]
consoleApplication: true
- files: "%{CppFileName}"
+ files: [
+ "%{CppFileName}",
+@if %{HasTranslation}
+ "%{TsFileName}",
+@endif
+ ]
Group { // Properties for the produced executable
fileTagsFilter: "application"
diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json b/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json
index bee602c87d..b500c9edf4 100644
--- a/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json
@@ -16,6 +16,7 @@
{ "key": "ProFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'pro')}" },
{ "key": "QbsFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'qbs')}" },
{ "key": "CMakeFile", "value": "%{ProjectDirectory}/CMakeLists.txt" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "CppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" }
],
@@ -64,6 +65,11 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -105,6 +111,11 @@
"openInEditor": true
},
{
+ "source": "../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt
index 243280b657..b69799a442 100644
--- a/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt
+++ b/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt
@@ -12,8 +12,14 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@if '%{QtModule}' != 'none'
+@if %{HasTranslation}
+find_package(Qt5 COMPONENTS %{QtModuleUpperCase} LinguistTools REQUIRED)
+
+set(TS_FILES %{TsFileName})
+@else
find_package(Qt5 COMPONENTS %{QtModuleUpperCase} REQUIRED)
@endif
+@endif
add_library(%{ProjectName} %{JS: %{IsStatic} ? 'STATIC' : 'SHARED'}
@if '%{Type}' === 'shared'
@@ -24,6 +30,9 @@ add_library(%{ProjectName} %{JS: %{IsStatic} ? 'STATIC' : 'SHARED'}
@if %{IsQtPlugin}
%{PluginJsonFile}
@endif
+@if %{HasTranslation}
+ ${TS_FILES}
+@endif
)
@if '%{QtModule}' != 'none'
@@ -33,3 +42,7 @@ target_link_libraries(%{ProjectName} PRIVATE Qt5::%{QtModuleUpperCase})
target_compile_definitions(%{ProjectName} PRIVATE %{LibraryDefine})
@endif
+@if %{HasTranslation}
+
+qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
+@endif
diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro b/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro
index 431667ada5..8eba894fe5 100644
--- a/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro
+++ b/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro
@@ -36,6 +36,11 @@ HEADERS += \\
%{GlobalHdrFileName} \\
@endif
%{HdrFileName}
+@if %{HasTranslation}
+
+TRANSLATIONS += \\
+ %{TsFileName}
+@endif
@if %{IsQtPlugin}
DISTFILES += %{PluginJsonFile}
diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs b/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs
index 0e5df73e84..2c51c9e116 100644
--- a/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs
+++ b/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs
@@ -41,6 +41,9 @@ DynamicLibrary {
@if %{IsQtPlugin}
"%{PluginJsonFile}",
@endif
+@if %{HasTranslation}
+ "%{TsFileName}",
+@endif
]
@if '%{TargetInstallPath}' != ''
diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json
index 8f4c264499..512ffdfe66 100644
--- a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json
@@ -31,6 +31,7 @@
{ "key": "TargetInstallPath", "value": "%{JS: value('IsShared') === 'true' ? '/usr/lib' : (value('IsQtPlugin') && value('PluginTargetPath') ? '$$[QT_INSTALL_PLUGINS]/' + value('PluginTargetPath') : '')}" },
{ "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" },
{ "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "GLOBAL_GUARD", "value": "%{JS: Cpp.headerGuard(value('GlobalHdrFileName'))}" }
],
@@ -272,6 +273,12 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "data": { "enabled": "%{JS: value('QtModule') === 'none' ? 'no' : 'yes'}" },
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -327,6 +334,11 @@
"condition": "%{JS: value('Type') === 'qtplugin'}"
},
{
+ "source": "../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
index 6d734cb0e8..87cc5c0979 100644
--- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
@@ -7,7 +7,7 @@
"trDisplayName": "Qt for Python - Empty",
"trDisplayCategory": "Application",
"icon": "icon.png",
- "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}",
+ "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.6" ],
"options":
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json
index c8e397d0d8..eedad020e3 100644
--- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json
@@ -7,7 +7,7 @@
"trDisplayName": "Qt for Python - Window",
"trDisplayCategory": "Application",
"icon": "icon.png",
- "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}",
+ "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.6" ],
"options":
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/lib.png b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib.png
index 0566f1d5f1..0566f1d5f1 100644
--- a/share/qtcreator/templates/wizards/qtquick2-extension/lib.png
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib.png
Binary files differ
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/lib@2x.png b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib@2x.png
index 90a842d6e8..90a842d6e8 100644
--- a/share/qtcreator/templates/wizards/qtquick2-extension/lib@2x.png
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib@2x.png
Binary files differ
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/object.cpp b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.cpp
index 15fe405242..a2288c47c1 100644
--- a/share/qtcreator/templates/wizards/qtquick2-extension/object.cpp
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.cpp
@@ -1,7 +1,7 @@
-#include "%ObjectName:l%.%CppHeaderSuffix%"
+#include "%{ObjectHdr}"
-%ObjectName%::%ObjectName%(QQuickItem *parent):
- QQuickItem(parent)
+%{ObjectName}::%{ObjectName}(QQuickItem *parent)
+ : QQuickItem(parent)
{
// By default, QQuickItem does not draw anything. If you subclass
// QQuickItem to create a visual item, you will need to uncomment the
@@ -10,6 +10,6 @@
// setFlag(ItemHasContents, true);
}
-%ObjectName%::~%ObjectName%()
+%{ObjectName}::~%{ObjectName}()
{
}
diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h
new file mode 100644
index 0000000000..e74c4233e8
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h
@@ -0,0 +1,23 @@
+%{Cpp:LicenseTemplate}\
+@if '%{Cpp:PragmaOnce}'
+#pragma once
+@else
+#ifndef %{OBJECTGUARD}
+#define %{OBJECTGUARD}
+@endif
+
+#include <QQuickItem>
+
+class %{ObjectName} : public QQuickItem
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(%{ObjectName})
+
+public:
+ explicit %{ObjectName}(QQuickItem *parent = nullptr);
+ ~%{ObjectName}() override;
+};
+
+@if ! '%{Cpp:PragmaOnce}'
+#endif // %{OBJECTGUARD}
+@endif
diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp
new file mode 100644
index 0000000000..69afb9badd
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp
@@ -0,0 +1,12 @@
+#include "%{PluginHdr}"
+
+#include "%{ObjectHdr}"
+
+#include <qqml.h>
+
+void %{PluginName}::registerTypes(const char *uri)
+{
+ // @uri %{Uri}
+ qmlRegisterType<%{ObjectName}>(uri, 1, 0, "%{ObjectName}");
+}
+
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.h b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.h
index a7a18893ef..539aee0d5d 100644
--- a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.h
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.h
@@ -1,13 +1,14 @@
+%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
-#ifndef %ProjectName:h%_PLUGIN_H
-#define %ProjectName:h%_PLUGIN_H
+#ifndef %{PLUGINGUARD}
+#define %{PLUGINGUARD}
@endif
#include <QQmlExtensionPlugin>
-class %ProjectName:s%Plugin : public QQmlExtensionPlugin
+class %{PluginName} : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
@@ -17,5 +18,5 @@ public:
};
@if ! '%{Cpp:PragmaOnce}'
-#endif // %ProjectName:h%_PLUGIN_H
+#endif // %{PLUGINGUARD}
@endif
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/project.pro b/share/qtcreator/templates/wizards/projects/qtquick2-extension/project.pro
index b9677739e4..78d4325d32 100644
--- a/share/qtcreator/templates/wizards/qtquick2-extension/project.pro
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/project.pro
@@ -1,26 +1,26 @@
TEMPLATE = lib
-TARGET = %ProjectName%
+TARGET = %{ProjectName}
QT += qml quick
CONFIG += plugin c++11
TARGET = $$qtLibraryTarget($$TARGET)
-uri = %Uri%
+uri = %{Uri}
# Input
-SOURCES += \
- %ProjectName:l%_plugin.%CppSourceSuffix% \
- %ObjectName:l%.%CppSourceSuffix%
+SOURCES += \\
+ %{PluginSrc} \\
+ %{ObjectSrc}
-HEADERS += \
- %ProjectName:l%_plugin.%CppHeaderSuffix% \
- %ObjectName:l%.%CppHeaderSuffix%
+HEADERS += \\
+ %{PluginHdr} \\
+ %{ObjectHdr}
DISTFILES = qmldir
!equals(_PRO_FILE_PWD_, $$OUT_PWD) {
copy_qmldir.target = $$OUT_PWD/qmldir
copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir
- copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\"
+ copy_qmldir.commands = $(COPY_FILE) "$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)" "$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)"
QMAKE_EXTRA_TARGETS += copy_qmldir
PRE_TARGETDEPS += $$copy_qmldir.target
}
diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir b/share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir
new file mode 100644
index 0000000000..8a3038ae48
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir
@@ -0,0 +1,2 @@
+module %{Uri}
+plugin %{ProjectName}
diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json b/share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json
new file mode 100644
index 0000000000..b0f9e33ae3
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json
@@ -0,0 +1,109 @@
+{
+ "version": 1,
+ "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ],
+ "id": "M.QtQuick2ExtensionPlugin",
+ "category": "G.Library",
+ "trDescription": "Creates a C++ plugin to load Qt Quick extensions dynamically into applications using the QQmlEngine class.",
+ "trDisplayName": "Qt Quick 2 Extension Plugin",
+ "trDisplayCategory": "Library",
+ "icon": "lib.png",
+ "featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick", "QtSupport.Wizards.FeatureQtQuick.2" ],
+ "enabled": "%{JS: value('Plugins').indexOf('QmakeProjectManager') >= 0}",
+
+ "options":
+ [
+ { "key": "ProjectFile", "value": "%{ProFile}" },
+ { "key": "ProFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'pro')}" },
+ { "key": "PluginBaseFileName", "value": "%{JS: value('ProjectName') + '_plugin'}" },
+ { "key": "PluginSrc", "value": "%{JS: Cpp.classToFileName(value('PluginBaseFileName'), Util.preferredSuffix('text/x-c++src'))}" },
+ { "key": "PluginHdr", "value": "%{JS: Cpp.classToFileName(value('PluginBaseFileName'), Util.preferredSuffix('text/x-c++hdr'))}" },
+ { "key": "ObjectSrc", "value": "%{JS: Cpp.classToFileName(value('ObjectName'), Util.preferredSuffix('text/x-c++src'))}" },
+ { "key": "ObjectHdr", "value": "%{JS: Cpp.classToFileName(value('ObjectName'), Util.preferredSuffix('text/x-c++hdr'))}" },
+ { "key": "PluginName", "value": "%{JS: value('ProjectName').charAt(0).toUpperCase() + value('ProjectName').slice(1) + 'Plugin' }" },
+ { "key": "PLUGINGUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('PluginBaseFileName'), Util.preferredSuffix('text/x-c++hdr'))}" },
+ { "key": "OBJECTGUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('ObjectName'), Util.preferredSuffix('text/x-c++hdr'))}" }
+ ],
+
+ "pages":
+ [
+ {
+ "trDisplayName": "Project Location",
+ "trShortTitle": "Location",
+ "typeId": "Project"
+ },
+ {
+ "trDisplayName": "Custom Parameters",
+ "trShortTitle": "Details",
+ "typeId": "Fields",
+ "data":
+ [
+ {
+ "name": "ObjectName",
+ "trDisplayName": "Object class-name:",
+ "mandatory": true,
+ "type": "LineEdit",
+ "data":
+ {
+ "validator": "^[A-Za-z0-9_]+$",
+ "trText": "MyItem"
+ }
+ },
+ {
+ "name": "Uri",
+ "trDisplayName": "URI:",
+ "mandatory": true,
+ "type": "LineEdit",
+ "data":
+ {
+ "validator": "^[A-Za-z0-9]+([A-Za-z0-9-]*[A-Za-z0-9]+)?(\\.[A-Za-z0-9]+([-A-Za-z0-9]*[A-Za-z0-9]+)?)*$",
+ "trText": "com.mycompany.qmlcomponents"
+ }
+ }
+ ]
+ },
+ {
+ "trDisplayName": "Project Management",
+ "trShortTitle": "Summary",
+ "typeId": "Summary"
+ }
+ ],
+ "generators":
+ [
+ {
+ "typeId": "File",
+ "data":
+ [
+ {
+ "source": "project.pro",
+ "target": "%{ProFile}",
+ "openAsProject": true
+ },
+ {
+ "source": "qmldir",
+ "target": "qmldir"
+ },
+ {
+ "source": "plugin.cpp",
+ "target": "%{PluginSrc}"
+ },
+ {
+ "source": "plugin.h",
+ "target": "%{PluginHdr}"
+ },
+ {
+ "source": "object.cpp",
+ "target": "%{ObjectSrc}"
+ },
+ {
+ "source": "object.h",
+ "target": "%{ObjectHdr}"
+ },
+ {
+ "source": "../git.ignore",
+ "target": ".gitignore",
+ "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
+ }
+ ]
+ }
+ ]
+}
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt
index 165a32be3d..3678b3dcdb 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt
@@ -11,18 +11,42 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
+@if %{HasTranslation}
+find_package(Qt5 COMPONENTS Core Quick LinguistTools REQUIRED)
+
+set(TS_FILES %{TsFileName})
+@else
find_package(Qt5 COMPONENTS Core Quick REQUIRED)
+@endif
if(ANDROID)
- add_library(%{ProjectName} SHARED %{MainCppFileName} qml.qrc)
+ set(TARGET %{ProjectName}_${ANDROID_ABI})
+ add_library(${TARGET} SHARED
+ %{MainCppFileName}
+ qml.qrc
+@if %{HasTranslation}
+ ${TS_FILES}
+@endif
+ )
else()
- add_executable(%{ProjectName} %{MainCppFileName} qml.qrc)
+ set(TARGET %{ProjectName})
+ add_executable(${TARGET}
+ %{MainCppFileName}
+ qml.qrc
+@if %{HasTranslation}
+ ${TS_FILES}
+@endif
+ )
endif()
-target_compile_definitions(%{ProjectName}
+target_compile_definitions(${TARGET}
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
-target_link_libraries(%{ProjectName}
+target_link_libraries(${TARGET}
PRIVATE Qt5::Core Qt5::Quick)
+@if %{HasTranslation}
+
+qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
+@endif
# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check http://doc.qt.io/qt-5/deployment-android.html for more information.
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro
index 0ac5682b11..908aaa3e07 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro
@@ -21,6 +21,11 @@ SOURCES += \\
%{MainCppFileName}
RESOURCES += qml.qrc
+@if %{HasTranslation}
+
+TRANSLATIONS += \\
+ %{TsFileName}
+@endif
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs
index 27a8b66c3c..f06fb39824 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs
@@ -29,6 +29,9 @@ Application {
"%{MainCppFileName}",
"main.qml",
"qml.qrc",
+@if %{HasTranslation}
+ "%{TsFileName}",
+@endif
]
Group { // Properties for the produced executable
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json
index fe284df679..412aa3f8f8 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json
@@ -22,6 +22,7 @@
{ "key": "QtQuickVirtualKeyboardImport", "value": "%{JS: value('QtVersion').QtQuickVirtualKeyboardImport}" },
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
{ "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" }
],
@@ -170,6 +171,11 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -222,6 +228,11 @@
"source": "qml.qrc"
},
{
+ "source": "../../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json
index f03b62635a..adfa7def75 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json
@@ -24,6 +24,7 @@
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: value('ControlsStyle').QtQuickControlsStyleTheme}" },
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
{ "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" }
],
@@ -221,6 +222,11 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -277,6 +283,11 @@
"source": "qml.qrc"
},
{
+ "source": "../../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json
index 6640901abe..a4593f8eb1 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json
@@ -24,6 +24,7 @@
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: value('ControlsStyle').QtQuickControlsStyleTheme}" },
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
{ "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" }
],
@@ -239,6 +240,11 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -307,6 +313,11 @@
"source": "qml.qrc"
},
{
+ "source": "../../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json
index 2b6ac53030..9f47b864e1 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json
@@ -24,6 +24,7 @@
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: value('ControlsStyle').QtQuickControlsStyleTheme}" },
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
{ "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" }
],
@@ -239,6 +240,11 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -303,6 +309,11 @@
"source": "qml.qrc"
},
{
+ "source": "../../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt
index 5fd51e9014..ea825062f4 100644
--- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt
+++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt
@@ -11,7 +11,13 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
+@if %{HasTranslation}
+find_package(Qt5 COMPONENTS Widgets LinguistTools REQUIRED)
+
+set(TS_FILES %{TsFileName})
+@else
find_package(Qt5 COMPONENTS Widgets REQUIRED)
+@endif
add_executable(%{ProjectName}
%{MainFileName}
@@ -20,6 +26,13 @@ add_executable(%{ProjectName}
@if %{GenerateForm}
%{FormFileName}
@endif
+@if %{HasTranslation}
+ ${TS_FILES}
+@endif
)
target_link_libraries(%{ProjectName} PRIVATE Qt5::Widgets)
+@if %{HasTranslation}
+
+qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
+@endif
diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro
index a5362aa9bc..a0a237bf20 100644
--- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro
+++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro
@@ -26,6 +26,11 @@ HEADERS += \\
FORMS += \\
%{FormFileName}
@endif
+@if %{HasTranslation}
+
+TRANSLATIONS += \\
+ %{TsFileName}
+@endif
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs
index 4a54380d6b..baa6326cb8 100644
--- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs
+++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs
@@ -19,9 +19,12 @@ QtApplication {
"%{MainFileName}",
"%{SrcFileName}",
"%{HdrFileName}",
- @if %{GenerateForm}
+@if %{GenerateForm}
"%{FormFileName}",
- @endif
+@endif
+@if %{HasTranslation}
+ "%{TsFileName}",
+@endif
]
install: true
diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json
index 9cce84a413..971ef3f88f 100644
--- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json
@@ -19,6 +19,7 @@
{ "key": "MainFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" },
{ "key": "UiHdrFileName", "value": "%{JS: (value('BuildSystem') === 'cmake' ? (Util.path(value('FormFileName')) + '/') : '') + 'ui_' + Util.completeBaseName(value('FormFileName')) + '.h'}" },
{ "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" },
+ { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" },
{ "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" }
],
@@ -140,6 +141,11 @@
]
},
{
+ "trDisplayName": "Translation File",
+ "trShortTitle": "Translation",
+ "typeId": "QtTranslation"
+ },
+ {
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
@@ -194,6 +200,11 @@
"condition": "%{GenerateForm}"
},
{
+ "source": "../translation.ts",
+ "target": "%{TsFileName}",
+ "condition": "%{HasTranslation}"
+ },
+ {
"source": "../git.ignore",
"target": ".gitignore",
"condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}"
diff --git a/share/qtcreator/templates/wizards/projects/translation.ts b/share/qtcreator/templates/wizards/projects/translation.ts
new file mode 100644
index 0000000000..ed21a4017e
--- /dev/null
+++ b/share/qtcreator/templates/wizards/projects/translation.ts
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="%{TsLanguage}"></TS>
diff --git a/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json
index f81509c4ed..060b55944a 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json
@@ -40,7 +40,9 @@
"name": "Repo",
"trDisplayName": "Repository:",
"mandatory": true,
- "type": "LineEdit"
+ "type": "LineEdit",
+ "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}",
+ "trIncompleteMessage": "Repository URL is not valid"
},
{
"name": "Sp1",
diff --git a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png
index bc452165a7..bd925b2e98 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png
+++ b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png
Binary files differ
diff --git a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png
index c29386c5e4..ec330c9f44 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png
+++ b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png
Binary files differ
diff --git a/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json
index 10969e3da8..075a69fdb1 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json
@@ -38,7 +38,9 @@
"name": "Repo",
"trDisplayName": "Module:",
"mandatory": true,
- "type": "LineEdit"
+ "type": "LineEdit",
+ "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}",
+ "trIncompleteMessage": "Repository URL is not valid"
},
{
"name": "Sp1",
diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/icon.png b/share/qtcreator/templates/wizards/projects/vcs/git/icon.png
index 46bcd4aab5..cfbd0c497f 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/git/icon.png
+++ b/share/qtcreator/templates/wizards/projects/vcs/git/icon.png
Binary files differ
diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png b/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png
index cca3e6ac0d..2edb04b5a0 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png
+++ b/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png
Binary files differ
diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json
index 0295468f6f..401be45a75 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json
@@ -39,7 +39,9 @@
{
"name": "Repo",
"trDisplayName": "Repository:",
- "type": "LineEdit"
+ "type": "LineEdit",
+ "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}",
+ "trIncompleteMessage": "Repository URL is not valid"
},
{
"name": "Branch",
diff --git a/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json
index 8e655e1eb6..81fa26da04 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json
@@ -39,7 +39,9 @@
"name": "Repo",
"trDisplayName": "Repository:",
"mandatory": true,
- "type": "LineEdit"
+ "type": "LineEdit",
+ "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}",
+ "trIncompleteMessage": "Repository URL is not valid"
},
{
"name": "Sp1",
diff --git a/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json
index cfeddbb532..2e63b12eb4 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json
@@ -39,7 +39,9 @@
"name": "Repo",
"trDisplayName": "Repository:",
"mandatory": true,
- "type": "LineEdit"
+ "type": "LineEdit",
+ "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}",
+ "trIncompleteMessage": "Repository URL is not valid"
},
{
"name": "Sp1",
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/object.h b/share/qtcreator/templates/wizards/qtquick2-extension/object.h
deleted file mode 100644
index cabd5229db..0000000000
--- a/share/qtcreator/templates/wizards/qtquick2-extension/object.h
+++ /dev/null
@@ -1,22 +0,0 @@
-@if '%{Cpp:PragmaOnce}'
-#pragma once
-@else
-#ifndef %ObjectName:u%_H
-#define %ObjectName:u%_H
-@endif
-
-#include <QQuickItem>
-
-class %ObjectName% : public QQuickItem
-{
- Q_OBJECT
- Q_DISABLE_COPY(%ObjectName%)
-
-public:
- explicit %ObjectName%(QQuickItem *parent = nullptr);
- ~%ObjectName%() override;
-};
-
-@if ! '%{Cpp:PragmaOnce}'
-#endif // %ObjectName:u%_H
-@endif
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp b/share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp
deleted file mode 100644
index c4ff1b1732..0000000000
--- a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "%ProjectName:l%_plugin.%CppHeaderSuffix%"
-#include "%ObjectName:l%.%CppHeaderSuffix%"
-
-#include <qqml.h>
-
-void %ProjectName:s%Plugin::registerTypes(const char *uri)
-{
- // @uri %Uri%
- qmlRegisterType<%ObjectName%>(uri, 1, 0, "%ObjectName:c%");
-}
-
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/qmldir b/share/qtcreator/templates/wizards/qtquick2-extension/qmldir
deleted file mode 100644
index f1f54802f3..0000000000
--- a/share/qtcreator/templates/wizards/qtquick2-extension/qmldir
+++ /dev/null
@@ -1,2 +0,0 @@
-module %Uri%
-plugin %ProjectName%
diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml b/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml
deleted file mode 100644
index 2c3a288c0c..0000000000
--- a/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-Custom project wizard configuration example file. Note that by convention,
-the project file goes last.
-The "class" and "firstpage" attributes specify that it is a Qt 4 wizard and
-leave room for the Qt 4 target page.
--->
-<wizard version="1" kind="project"
- class="qmakeproject" firstpage="10"
- id="QtQuick2ExtensionPlugin" category="G.Library"
- featuresRequired="QtSupport.Wizards.FeatureQtQuick,QtSupport.Wizards.FeatureQtQuick.2">
- <icon>lib.png</icon>
- <description>Creates a C++ plugin to load extensions dynamically into applications using the QQmlEngine class. Requires Qt 5.0 or newer.</description>
- <displayname>Qt Quick 2 Extension Plugin</displayname>
- <displaycategory>Library</displaycategory>
- <files>
- <file source="qmldir" target="qmldir"/>
- <file source="plugin.h" target="%ProjectName:l%_plugin.%CppHeaderSuffix%"/>
- <file source="plugin.cpp" target="%ProjectName:l%_plugin.%CppSourceSuffix%"/>
- <file source="object.h" target="%ObjectName:l%.%CppHeaderSuffix%"/>
- <file source="object.cpp" target="%ObjectName:l%.%CppSourceSuffix%" openeditor="true"/>
- <file source="project.pro" target="%ProjectName:l%.pro" openproject="true"/>
- </files>
- <!-- Create a 2nd wizard page with parameters -->
- <fieldpagetitle>Custom QML Extension Plugin Parameters</fieldpagetitle>
- <fields>
- <field mandatory="true" name="ObjectName">
- <fieldcontrol class="QLineEdit" validator='^[A-Za-z0-9_]+$' defaulttext="MyItem"/>
- <fielddescription>Object class-name:</fielddescription>
- </field>
- <field mandatory="true" name="Uri">
- <fieldcontrol class="QLineEdit" validator='^[A-Za-z0-9]+([A-Za-z0-9-]*[A-Za-z0-9]+)?(\.[A-Za-z0-9]+([-A-Za-z0-9]*[A-Za-z0-9]+)?)*$' defaulttext="com.mycompany.qmlcomponents"/>
- <fielddescription>URI:</fielddescription>
- </field>
- </fields>
- <validationrules>
- <validationrule condition='"%ObjectName%" != "%ProjectName%_plugin"'>
- <message>The project name and the object class-name cannot be the same.</message>
- </validationrule>
- </validationrules>
-</wizard>
diff --git a/share/qtcreator/translations/CMakeLists.txt b/share/qtcreator/translations/CMakeLists.txt
new file mode 100644
index 0000000000..dfa5da1238
--- /dev/null
+++ b/share/qtcreator/translations/CMakeLists.txt
@@ -0,0 +1,214 @@
+set(languages cs da de fr ja pl ru sl uk zh_CN zh_TW)
+set(bad_languages hu) # Fix these before including them in languages!
+
+find_package(PythonInterp)
+
+set(json_wizards_h "")
+set(custom_wizards_h "")
+set(externaltools_h "")
+set(snippets_h "")
+
+if (NOT PYTHONINTERP_FOUND OR NOT PYTHON_VERSION_STRING VERSION_GREATER_EQUAL "3.0.0")
+ message(WARNING "No python3 interpreter found, skipping extraction of data from XML and JSON files.\n *** Please pass -DPYTHON_EXECUTABLE=/path/to/python3 to cmake.")
+else()
+ set(json_wizards_h "${CMAKE_CURRENT_BINARY_DIR}/jsonwizards_tr.h")
+ add_custom_command(OUTPUT "${json_wizards_h}"
+ COMMAND "${PYTHON_EXECUTABLE}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/extract-jsonwizards.py"
+ "${PROJECT_SOURCE_DIR}/share/qtcreator/templates/wizards" "${json_wizards_h}"
+ COMMENT Generate translation data from JSON wizards
+ VERBATIM)
+
+ set(custom_wizards_h "${CMAKE_CURRENT_BINARY_DIR}/customwizards_tr.h")
+ add_custom_command(OUTPUT "${custom_wizards_h}"
+ COMMAND "${PYTHON_EXECUTABLE}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/extract-customwizards.py"
+ "${PROJECT_SOURCE_DIR}/share/qtcreator/templates/wizards" "${custom_wizards_h}"
+ COMMENT Generate translation data from XML wizards
+ VERBATIM)
+
+ set(externaltools_h "${CMAKE_CURRENT_BINARY_DIR}/externaltools_tr.h")
+ add_custom_command(OUTPUT "${externaltools_h}"
+ COMMAND "${PYTHON_EXECUTABLE}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/extract-externaltools.py"
+ "${PROJECT_SOURCE_DIR}/src/share/qtcreator/externaltools" "${externaltools_h}"
+ COMMENT Generate translation data from external tools definitions
+ VERBATIM)
+
+ set(snippets_h "${CMAKE_CURRENT_BINARY_DIR}/snippets_tr.h")
+ add_custom_command(OUTPUT "${snippets_h}"
+ COMMAND "${PYTHON_EXECUTABLE}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/extract-snippets.py"
+ "${PROJECT_SOURCE_DIR}/share/qtcreator/snippets" "${snippets_h}"
+ COMMENT Generate translation data from snippets definitions
+ VERBATIM)
+endif()
+
+function(_extract_ts_data_from_targets outprefix)
+ set(_sources "")
+ set(_includes "")
+
+ set(_targets "${ARGN}")
+ list(REMOVE_DUPLICATES _targets)
+
+ foreach(t IN ITEMS ${_targets})
+ if (TARGET "${t}")
+ get_target_property(_skip_translation "${t}" QT_SKIP_TRANSLATION)
+ get_target_property(_source_dir "${t}" SOURCE_DIR)
+ get_target_property(_interface_include_dirs "${t}" INTERFACE_INCLUDE_DIRECTORIES)
+ get_target_property(_include_dirs "${t}" INCLUDE_DIRECTORIES)
+ get_target_property(_source_files "${t}" SOURCES)
+ get_target_property(_extra_translations "${t}" QT_EXTRA_TRANSLATIONS)
+
+ if (NOT _skip_translation)
+ if(_include_dirs)
+ list(APPEND _includes ${_include_dirs})
+ endif()
+
+ if(_interface_include_dirs)
+ list(APPEND _interface_includes ${_include_dirs})
+ endif()
+
+ set(_target_sources "")
+ if(_source_files)
+ list(APPEND _target_sources ${_source_files})
+ endif()
+ if(_extra_translations)
+ list(APPEND _target_sources ${_extra_translations})
+ endif()
+ foreach(s IN ITEMS ${_target_sources})
+ get_filename_component(_abs_source "${s}" ABSOLUTE BASE_DIR "${_source_dir}")
+ list(APPEND _sources "${_abs_source}")
+ endforeach()
+ endif()
+ endif()
+ endforeach()
+
+ set("${outprefix}_sources" "${_sources}" PARENT_SCOPE)
+ set("${outprefix}_includes" "${_includes}" PARENT_SCOPE)
+endfunction()
+
+function(_create_ts_custom_target name)
+ cmake_parse_arguments(_arg "" "FILE_PREFIX;TS_TARGET_PREFIX" "LANGUAGES;SOURCES;INCLUDES" ${ARGN})
+ if (_arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Invalid parameters to _create_ts_custom_target: ${_arg_UNPARSED_ARGUMENTS}.")
+ endif()
+
+ if (NOT _arg_TS_TARGET_PREFIX)
+ set(_arg_TS_TARGET_PREFIX "ts_")
+ endif()
+
+ set(ts_languages ${_arg_LANGUAGES})
+ if (NOT ts_languages)
+ set(ts_languages "${name}")
+ endif()
+
+ foreach(l IN ITEMS ${ts_languages})
+ list(APPEND ts_files "${CMAKE_CURRENT_SOURCE_DIR}/${_arg_FILE_PREFIX}_${l}.ts")
+ endforeach()
+
+ set(_sources "${_arg_SOURCES}")
+ list(SORT _sources)
+
+ set(_includes "${_arg_INCLUDES}")
+
+ list(REMOVE_DUPLICATES _sources)
+ list(REMOVE_DUPLICATES _includes)
+
+ list(REMOVE_ITEM _sources "")
+ list(REMOVE_ITEM _includes "")
+
+ set(_prepended_includes)
+ foreach(include IN LISTS _includes)
+ list(APPEND _prepended_includes "-I${include}")
+ endforeach()
+ set(_includes "${_prepended_includes}")
+
+ string(REPLACE ";" "\n" _sources_str "${_sources}")
+ string(REPLACE ";" "\n" _includes_str "${_includes}")
+
+ set(ts_file_list "${CMAKE_CURRENT_BINARY_DIR}/ts_${name}.lst")
+ file(WRITE "${ts_file_list}" "${_sources_str}\n${_includes_str}\n")
+
+ add_custom_target("${_arg_TS_TARGET_PREFIX}${name}"
+ COMMAND Qt5::lupdate -locations relative -no-ui-lines -no-sort "@${ts_file_list}" -ts ${ts_files}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ COMMENT "Generate .ts files"
+ DEPENDS ${_sources}
+ VERBATIM)
+endfunction()
+
+function(add_translation_targets file_prefix)
+ if (NOT TARGET Qt5::lrelease)
+ # No Qt translation tools were found: Skip this directory
+ message(WARNING "No Qt translation tools found, skipping translation targets. Add find_package(Qt5 COMPONENTS LinguistTools) to CMake to enable.")
+ return()
+ endif()
+
+ cmake_parse_arguments(_arg ""
+ "OUTPUT_DIRECTORY;INSTALL_DESTINATION;TS_TARGET_PREFIX;QM_TARGET_PREFIX;ALL_QM_TARGET"
+ "LANGUAGES;TARGETS;SOURCES;INCLUDES" ${ARGN})
+ if (_arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Invalid parameters to add_translation_targets: ${_arg_UNPARSED_ARGUMENTS}.")
+ endif()
+
+ if (NOT _arg_TS_TARGET_PREFIX)
+ set(_arg_TS_TARGET_PREFIX "ts_")
+ endif()
+
+ if (NOT _arg_QM_TARGET_PREFIX)
+ set(_arg_QM_TARGET_PREFIX "generate_qm_file_")
+ endif()
+
+ if (NOT _arg_ALL_QM_TARGET)
+ set(_arg_ALL_QM_TARGET "generate_qm_files")
+ endif()
+
+ if (NOT _arg_OUTPUT_DIRECTORY)
+ set(_arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+
+ if (NOT _arg_INSTALL_DESTINATION)
+ message(FATAL_ERROR "Please provide a INSTALL_DESTINATION to add_translation_targets")
+ endif()
+
+ _extract_ts_data_from_targets(_to_process "${_arg_TARGETS}")
+
+ _create_ts_custom_target(untranslated
+ FILE_PREFIX "${file_prefix}" TS_TARGET_PREFIX "${_arg_TS_TARGET_PREFIX}"
+ SOURCES ${_to_process_sources} ${_arg_SOURCES} INCLUDES ${_to_process_includes} ${_arg_INCLUDES})
+
+ if (NOT TARGET "${_arg_ALL_QM_TARGET}")
+ add_custom_target("${_arg_ALL_QM_TARGET}" ALL COMMENT "Generate .qm-files")
+ endif()
+
+ foreach(l IN ITEMS ${_arg_LANGUAGES})
+ set(_ts_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_prefix}_${l}.ts")
+ set(_qm_file "${_arg_OUTPUT_DIRECTORY}/${file_prefix}_${l}.qm")
+
+ _create_ts_custom_target("${l}" FILE_PREFIX "${file_prefix}" TS_TARGET_PREFIX "${_arg_TS_TARGET_PREFIX}"
+ SOURCES ${_to_process_sources} ${_arg_SOURCES} INCLUDES ${_to_process_includes} ${_arg_INCLUDES})
+
+ add_custom_command(OUTPUT "${_qm_file}"
+ COMMAND Qt5::lrelease "${_ts_file}" -qm "${_qm_file}"
+ MAIN_DEPENDENCY "${_ts_file}"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ COMMENT "Generate .qm file"
+ VERBATIM)
+ add_custom_target("${_arg_QM_TARGET_PREFIX}${l}" DEPENDS "${_qm_file}")
+ install(FILES "${_qm_file}" DESTINATION ${_arg_INSTALL_DESTINATION})
+
+ add_dependencies("${_arg_ALL_QM_TARGET}" "${_arg_QM_TARGET_PREFIX}${l}")
+ endforeach()
+
+ _create_ts_custom_target(all LANGUAGES ${_arg_LANGUAGES} FILE_PREFIX "${file_prefix}"
+ SOURCES ${_to_process_sources} ${_arg_SOURCES} INCLUDES ${_to_process_includes} ${_arg_INCLUDES})
+endfunction()
+
+### collect targets to include in documentation:
+add_translation_targets(qtcreator
+ LANGUAGES ${languages}
+ OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${IDE_DATA_PATH}/translations"
+ INSTALL_DESTINATION "${IDE_DATA_PATH}/translations"
+ TARGETS "${__QTC_LIBRARIES}" "${__QTC_PLUGINS}"
+ SOURCES "${json_wizards_h}" "${custom_wizards_h}" "${externaltools_h}" "${snippets_h}")
diff --git a/share/qtcreator/translations/extract-customwizards.py b/share/qtcreator/translations/extract-customwizards.py
new file mode 100644
index 0000000000..14b7ddcf33
--- /dev/null
+++ b/share/qtcreator/translations/extract-customwizards.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+############################################################################
+#
+# Copyright (C) 2019 The Qt Company Ltd.
+# Contact: https://www.qt.io/licensing/
+#
+# This file is part of Qt Creator.
+#
+# Commercial License Usage
+# Licensees holding valid commercial Qt licenses may use this file in
+# accordance with the commercial license agreement provided with the
+# Software or, alternatively, in accordance with the terms contained in
+# a written agreement between you and The Qt Company. For licensing terms
+# and conditions see https://www.qt.io/terms-conditions. For further
+# information use the contact form at https://www.qt.io/contact-us.
+#
+# GNU General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU
+# General Public License version 3 as published by the Free Software
+# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+# included in the packaging of this file. Please review the following
+# information to ensure the GNU General Public License requirements will
+# be met: https://www.gnu.org/licenses/gpl-3.0.html.
+#
+############################################################################
+
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+if len(sys.argv) != 3:
+ print("Please provide a top level directory to scan and a file to write into.")
+ sys.exit(1)
+
+top_dir = sys.argv[1]
+target_file = sys.argv[2]
+
+
+def fix_value(value):
+ value = value.replace('\"', '\\\"')
+ value = value.replace('\n', '\\\n')
+ return value
+
+
+def parse_file(file_path):
+ root = ET.parse(file_path).getroot()
+ result = ''
+
+ for i in ['.//description', './/displayname', './/displaycategory',
+ './/fieldpagetitle', './/fielddescription',
+ './/comboentrytext',
+ './/message']:
+ for e in root.findall(i):
+ result += 'QT_TRANSLATE_NOOP("ProjectExplorer::CustomWizard", "{}"); // {}\n'.format(fix_value(e.text), file_path)
+
+ return result
+
+result = ''
+
+# traverse root directory, and list directories as dirs and files as files
+for root, _, files in os.walk(top_dir):
+ for file in files:
+ if file == "wizard.xml":
+ result += parse_file(os.path.join(root, file))
+
+with open(target_file, 'w') as header_file:
+ header_file.write(result)
diff --git a/share/qtcreator/translations/extract-externaltools.py b/share/qtcreator/translations/extract-externaltools.py
new file mode 100644
index 0000000000..ad4d19a844
--- /dev/null
+++ b/share/qtcreator/translations/extract-externaltools.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+############################################################################
+#
+# Copyright (C) 2019 The Qt Company Ltd.
+# Contact: https://www.qt.io/licensing/
+#
+# This file is part of Qt Creator.
+#
+# Commercial License Usage
+# Licensees holding valid commercial Qt licenses may use this file in
+# accordance with the commercial license agreement provided with the
+# Software or, alternatively, in accordance with the terms contained in
+# a written agreement between you and The Qt Company. For licensing terms
+# and conditions see https://www.qt.io/terms-conditions. For further
+# information use the contact form at https://www.qt.io/contact-us.
+#
+# GNU General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU
+# General Public License version 3 as published by the Free Software
+# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+# included in the packaging of this file. Please review the following
+# information to ensure the GNU General Public License requirements will
+# be met: https://www.gnu.org/licenses/gpl-3.0.html.
+#
+############################################################################
+
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+if len(sys.argv) != 3:
+ print("Please provide a top level directory to scan and a file to write into.")
+ sys.exit(1)
+
+top_dir = sys.argv[1]
+target_file = sys.argv[2]
+
+
+def fix_value(value):
+ value = value.replace('\"', '\\\"')
+ value = value.replace('\n', '\\\n')
+ return value
+
+
+def parse_file(file_path):
+ root = ET.parse(file_path).getroot()
+ result = ''
+
+ for i in ['.//description', './/displayname', './/category']:
+ for e in root.findall(i):
+ result += 'QT_TRANSLATE_NOOP("Core::Internal::ExternalTool", "{}"); // {}\n'.format(fix_value(e.text), file_path)
+
+ return result
+
+result = ''
+
+# traverse root directory, and list directories as dirs and files as files
+for root, _, files in os.walk(top_dir):
+ for file in files:
+ if file.endswith('.xml'):
+ result += parse_file(os.path.join(root, file))
+
+with open(target_file, 'w') as header_file:
+ header_file.write(result)
diff --git a/share/qtcreator/translations/extract-jsonwizards.py b/share/qtcreator/translations/extract-jsonwizards.py
new file mode 100644
index 0000000000..8242481131
--- /dev/null
+++ b/share/qtcreator/translations/extract-jsonwizards.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+############################################################################
+#
+# Copyright (C) 2019 The Qt Company Ltd.
+# Contact: https://www.qt.io/licensing/
+#
+# This file is part of Qt Creator.
+#
+# Commercial License Usage
+# Licensees holding valid commercial Qt licenses may use this file in
+# accordance with the commercial license agreement provided with the
+# Software or, alternatively, in accordance with the terms contained in
+# a written agreement between you and The Qt Company. For licensing terms
+# and conditions see https://www.qt.io/terms-conditions. For further
+# information use the contact form at https://www.qt.io/contact-us.
+#
+# GNU General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU
+# General Public License version 3 as published by the Free Software
+# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+# included in the packaging of this file. Please review the following
+# information to ensure the GNU General Public License requirements will
+# be met: https://www.gnu.org/licenses/gpl-3.0.html.
+#
+############################################################################
+
+import os
+import sys
+import json
+
+if len(sys.argv) != 3:
+ print("Please provide a top level directory to scan and a file to write into.")
+ sys.exit(1)
+
+top_dir = sys.argv[1]
+target_file = sys.argv[2]
+
+
+def recursive_iter(obj, key=''):
+ if isinstance(obj, dict):
+ for k in sorted(obj.keys()):
+ yield from recursive_iter(obj[k], k)
+ elif isinstance(obj, tuple):
+ for item in obj:
+ yield from recursive_iter(item, '')
+ elif isinstance(obj, list):
+ for item in obj:
+ yield from recursive_iter(item, '')
+ else:
+ yield key, obj
+
+
+def fix_value(value):
+ value = value.replace('\"', '\\\"')
+ value = value.replace('\n', '\\\n')
+ return value
+
+
+def parse_file(file_path):
+ root = ''
+ result = ''
+
+ with open(file_path) as f:
+ root = json.load(f)
+
+ for key, value in recursive_iter(root):
+ if key.startswith('tr'):
+ result += 'QT_TRANSLATE_NOOP("ProjectExplorer::JsonWizard", "{}"); // {}\n'.format(fix_value(value), file_path)
+
+ return result
+
+result = '// This file is autogenerated\n'
+
+# traverse root directory, and list directories as dirs and files as files
+for root, _, files in os.walk(top_dir):
+ for file in files:
+ if file == "wizard.json":
+ result += parse_file(os.path.join(root, file))
+
+with open(target_file, 'w') as header_file:
+ header_file.write(result)
diff --git a/share/qtcreator/translations/extract-snippets.py b/share/qtcreator/translations/extract-snippets.py
new file mode 100644
index 0000000000..2c393024a6
--- /dev/null
+++ b/share/qtcreator/translations/extract-snippets.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+############################################################################
+#
+# Copyright (C) 2019 The Qt Company Ltd.
+# Contact: https://www.qt.io/licensing/
+#
+# This file is part of Qt Creator.
+#
+# Commercial License Usage
+# Licensees holding valid commercial Qt licenses may use this file in
+# accordance with the commercial license agreement provided with the
+# Software or, alternatively, in accordance with the terms contained in
+# a written agreement between you and The Qt Company. For licensing terms
+# and conditions see https://www.qt.io/terms-conditions. For further
+# information use the contact form at https://www.qt.io/contact-us.
+#
+# GNU General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU
+# General Public License version 3 as published by the Free Software
+# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+# included in the packaging of this file. Please review the following
+# information to ensure the GNU General Public License requirements will
+# be met: https://www.gnu.org/licenses/gpl-3.0.html.
+#
+############################################################################
+
+import os
+import sys
+import xml.etree.ElementTree as ET
+
+if len(sys.argv) != 3:
+ print("Please provide a top level directory to scan and a file to write into.")
+ sys.exit(1)
+
+top_dir = sys.argv[1]
+target_file = sys.argv[2]
+
+
+def fix_value(value):
+ value = value.replace('\"', '\\\"')
+ value = value.replace('\n', '\\\n')
+ return value
+
+
+def parse_file(file_path):
+ root = ET.parse(file_path).getroot()
+ result = ''
+
+ for e in root.findall('snippet'):
+ if 'complement' in e.attrib:
+ result += 'QT_TRANSLATE_NOOP3("TextEditor::Internal::Snippets", "{}", "group:\'{}\' trigger:\'{}\'"); // {}\n' \
+ .format(fix_value(e.attrib['complement']), e.attrib['group'], e.attrib['trigger'], file_path)
+
+ return result
+
+result = ''
+
+# traverse root directory, and list directories as dirs and files as files
+for root, _, files in os.walk(top_dir):
+ for file in files:
+ if file.endswith('.xml'):
+ result += parse_file(os.path.join(root, file))
+
+with open(target_file, 'w') as header_file:
+ header_file.write(result)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d308c75c2f..a04ed8a959 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,13 +1,7 @@
-# Not in the main CMakeLists.txt file because some tests fail if we have the flags set as default
-list(APPEND DEFAULT_DEFINES
- QT_CREATOR QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII
- QT_DISABLE_DEPRECATED_BEFORE=0x050900
- QT_USE_FAST_OPERATOR_PLUS
- QT_USE_FAST_CONCATENATION
-)
-
add_library(app_version INTERFACE)
-target_include_directories(app_version INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
+target_include_directories(app_version
+ INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+ INTERFACE $<INSTALL_INTERFACE:include/src>)
install(TARGETS app_version EXPORT QtCreator)
add_subdirectory(libs)
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 0ef67b2943..dfb38ddd4b 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -1,5 +1,11 @@
configure_file(app_version.h.cmakein app_version.h ESCAPE_QUOTES)
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/app_version.h
+ DESTINATION include/src/app
+ COMPONENT Devel EXCLUDE_FROM_ALL
+)
+
add_qtc_executable(qtcreator
DEFINES IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
DEPENDS Aggregation ExtensionSystem Qt5::Core Qt5::Widgets Utils shared_qtsingleapplication app_version
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 55ade01871..359bb673b5 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -129,7 +129,7 @@ static void displayHelpText(const QString &t)
static void displayError(const QString &t)
{
if (Utils::HostOsInfo::isWindowsHost() && qApp)
- QMessageBox::critical(0, QLatin1String(Core::Constants::IDE_DISPLAY_NAME), t);
+ QMessageBox::critical(nullptr, QLatin1String(Core::Constants::IDE_DISPLAY_NAME), t);
else
qCritical("%s", qPrintable(t));
}
@@ -154,7 +154,7 @@ static void printHelp(const QString &a0)
displayHelpText(help);
}
-QString applicationDirPath(char *arg = 0)
+QString applicationDirPath(char *arg = nullptr)
{
static QString dir;
@@ -179,7 +179,7 @@ static inline QString msgCoreLoadFailure(const QString &why)
static inline int askMsgSendFailed()
{
- return QMessageBox::question(0, QApplication::translate("Application","Could not send message"),
+ return QMessageBox::question(nullptr, QApplication::translate("Application","Could not send message"),
QCoreApplication::translate("Application", "Unable to send command line arguments "
"to the already running instance. It does not appear to "
"be responding. Do you want to start a new instance of "
@@ -408,7 +408,7 @@ int main(int argc, char **argv)
{{"LD_LIBRARY_PATH", "", Utils::EnvironmentItem::Unset}});
} else {
Utils::Environment::modifySystemEnvironment(
- {{"LD_LIBRARY_PATH", *options.userLibraryPath, Utils::EnvironmentItem::Set}});
+ {{"LD_LIBRARY_PATH", *options.userLibraryPath, Utils::EnvironmentItem::SetEnabled}});
}
}
@@ -549,7 +549,7 @@ int main(int argc, char **argv)
}
const PluginSpecSet plugins = PluginManager::plugins();
- PluginSpec *coreplugin = 0;
+ PluginSpec *coreplugin = nullptr;
foreach (PluginSpec *spec, plugins) {
if (spec->name() == QLatin1String(corePluginNameC)) {
coreplugin = spec;
diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp
index 035c9baf73..3b91838eec 100644
--- a/src/libs/3rdparty/cplusplus/AST.cpp
+++ b/src/libs/3rdparty/cplusplus/AST.cpp
@@ -68,12 +68,12 @@ bool AST::match(AST *pattern, ASTMatcher *matcher)
return match0(pattern, matcher);
}
-unsigned GnuAttributeSpecifierAST::firstToken() const
+int GnuAttributeSpecifierAST::firstToken() const
{
return attribute_token;
}
-unsigned BaseSpecifierAST::firstToken() const
+int BaseSpecifierAST::firstToken() const
{
if (virtual_token && access_specifier_token)
return std::min(virtual_token, access_specifier_token);
@@ -87,7 +87,7 @@ unsigned BaseSpecifierAST::firstToken() const
return 0;
}
-unsigned BaseSpecifierAST::lastToken() const
+int BaseSpecifierAST::lastToken() const
{
if (ellipsis_token)
return ellipsis_token;
@@ -104,7 +104,7 @@ unsigned BaseSpecifierAST::lastToken() const
}
/** \generated */
-unsigned AccessDeclarationAST::firstToken() const
+int AccessDeclarationAST::firstToken() const
{
if (access_specifier_token)
return access_specifier_token;
@@ -116,7 +116,7 @@ unsigned AccessDeclarationAST::firstToken() const
}
/** \generated */
-unsigned AccessDeclarationAST::lastToken() const
+int AccessDeclarationAST::lastToken() const
{
if (colon_token)
return colon_token + 1;
@@ -128,15 +128,15 @@ unsigned AccessDeclarationAST::lastToken() const
}
/** \generated */
-unsigned ArrayAccessAST::firstToken() const
+int ArrayAccessAST::firstToken() const
{
if (base_expression)
- if (unsigned candidate = base_expression->firstToken())
+ if (int candidate = base_expression->firstToken())
return candidate;
if (lbracket_token)
return lbracket_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rbracket_token)
return rbracket_token;
@@ -144,28 +144,28 @@ unsigned ArrayAccessAST::firstToken() const
}
/** \generated */
-unsigned ArrayAccessAST::lastToken() const
+int ArrayAccessAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lbracket_token)
return lbracket_token + 1;
if (base_expression)
- if (unsigned candidate = base_expression->lastToken())
+ if (int candidate = base_expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ArrayDeclaratorAST::firstToken() const
+int ArrayDeclaratorAST::firstToken() const
{
if (lbracket_token)
return lbracket_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rbracket_token)
return rbracket_token;
@@ -173,12 +173,12 @@ unsigned ArrayDeclaratorAST::firstToken() const
}
/** \generated */
-unsigned ArrayDeclaratorAST::lastToken() const
+int ArrayDeclaratorAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lbracket_token)
return lbracket_token + 1;
@@ -186,12 +186,12 @@ unsigned ArrayDeclaratorAST::lastToken() const
}
/** \generated */
-unsigned ArrayInitializerAST::firstToken() const
+int ArrayInitializerAST::firstToken() const
{
if (lbrace_token)
return lbrace_token;
if (expression_list)
- if (unsigned candidate = expression_list->firstToken())
+ if (int candidate = expression_list->firstToken())
return candidate;
if (rbrace_token)
return rbrace_token;
@@ -199,12 +199,12 @@ unsigned ArrayInitializerAST::firstToken() const
}
/** \generated */
-unsigned ArrayInitializerAST::lastToken() const
+int ArrayInitializerAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (expression_list)
- if (unsigned candidate = expression_list->lastToken())
+ if (int candidate = expression_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
@@ -212,7 +212,7 @@ unsigned ArrayInitializerAST::lastToken() const
}
/** \generated */
-unsigned AsmDefinitionAST::firstToken() const
+int AsmDefinitionAST::firstToken() const
{
if (asm_token)
return asm_token;
@@ -228,7 +228,7 @@ unsigned AsmDefinitionAST::firstToken() const
}
/** \generated */
-unsigned AsmDefinitionAST::lastToken() const
+int AsmDefinitionAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
@@ -244,7 +244,7 @@ unsigned AsmDefinitionAST::lastToken() const
}
/** \generated */
-unsigned GnuAttributeAST::firstToken() const
+int GnuAttributeAST::firstToken() const
{
if (identifier_token)
return identifier_token;
@@ -253,7 +253,7 @@ unsigned GnuAttributeAST::firstToken() const
if (tag_token)
return tag_token;
if (expression_list)
- if (unsigned candidate = expression_list->firstToken())
+ if (int candidate = expression_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -261,12 +261,12 @@ unsigned GnuAttributeAST::firstToken() const
}
/** \generated */
-unsigned GnuAttributeAST::lastToken() const
+int GnuAttributeAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression_list)
- if (unsigned candidate = expression_list->lastToken())
+ if (int candidate = expression_list->lastToken())
return candidate;
if (tag_token)
return tag_token + 1;
@@ -278,35 +278,35 @@ unsigned GnuAttributeAST::lastToken() const
}
/** \generated */
-unsigned BinaryExpressionAST::firstToken() const
+int BinaryExpressionAST::firstToken() const
{
if (left_expression)
- if (unsigned candidate = left_expression->firstToken())
+ if (int candidate = left_expression->firstToken())
return candidate;
if (binary_op_token)
return binary_op_token;
if (right_expression)
- if (unsigned candidate = right_expression->firstToken())
+ if (int candidate = right_expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned BinaryExpressionAST::lastToken() const
+int BinaryExpressionAST::lastToken() const
{
if (right_expression)
- if (unsigned candidate = right_expression->lastToken())
+ if (int candidate = right_expression->lastToken())
return candidate;
if (binary_op_token)
return binary_op_token + 1;
if (left_expression)
- if (unsigned candidate = left_expression->lastToken())
+ if (int candidate = left_expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned BoolLiteralAST::firstToken() const
+int BoolLiteralAST::firstToken() const
{
if (literal_token)
return literal_token;
@@ -314,7 +314,7 @@ unsigned BoolLiteralAST::firstToken() const
}
/** \generated */
-unsigned BoolLiteralAST::lastToken() const
+int BoolLiteralAST::lastToken() const
{
if (literal_token)
return literal_token + 1;
@@ -322,12 +322,12 @@ unsigned BoolLiteralAST::lastToken() const
}
/** \generated */
-unsigned BracedInitializerAST::firstToken() const
+int BracedInitializerAST::firstToken() const
{
if (lbrace_token)
return lbrace_token;
if (expression_list)
- if (unsigned candidate = expression_list->firstToken())
+ if (int candidate = expression_list->firstToken())
return candidate;
if (comma_token)
return comma_token;
@@ -337,14 +337,14 @@ unsigned BracedInitializerAST::firstToken() const
}
/** \generated */
-unsigned BracedInitializerAST::lastToken() const
+int BracedInitializerAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (comma_token)
return comma_token + 1;
if (expression_list)
- if (unsigned candidate = expression_list->lastToken())
+ if (int candidate = expression_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
@@ -352,7 +352,7 @@ unsigned BracedInitializerAST::lastToken() const
}
/** \generated */
-unsigned BreakStatementAST::firstToken() const
+int BreakStatementAST::firstToken() const
{
if (break_token)
return break_token;
@@ -362,7 +362,7 @@ unsigned BreakStatementAST::firstToken() const
}
/** \generated */
-unsigned BreakStatementAST::lastToken() const
+int BreakStatementAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
@@ -372,15 +372,15 @@ unsigned BreakStatementAST::lastToken() const
}
/** \generated */
-unsigned CallAST::firstToken() const
+int CallAST::firstToken() const
{
if (base_expression)
- if (unsigned candidate = base_expression->firstToken())
+ if (int candidate = base_expression->firstToken())
return candidate;
if (lparen_token)
return lparen_token;
if (expression_list)
- if (unsigned candidate = expression_list->firstToken())
+ if (int candidate = expression_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -388,37 +388,37 @@ unsigned CallAST::firstToken() const
}
/** \generated */
-unsigned CallAST::lastToken() const
+int CallAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression_list)
- if (unsigned candidate = expression_list->lastToken())
+ if (int candidate = expression_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (base_expression)
- if (unsigned candidate = base_expression->lastToken())
+ if (int candidate = base_expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned CaptureAST::firstToken() const
+int CaptureAST::firstToken() const
{
if (amper_token)
return amper_token;
if (identifier)
- if (unsigned candidate = identifier->firstToken())
+ if (int candidate = identifier->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned CaptureAST::lastToken() const
+int CaptureAST::lastToken() const
{
if (identifier)
- if (unsigned candidate = identifier->lastToken())
+ if (int candidate = identifier->lastToken())
return candidate;
if (amper_token)
return amper_token + 1;
@@ -426,31 +426,31 @@ unsigned CaptureAST::lastToken() const
}
/** \generated */
-unsigned CaseStatementAST::firstToken() const
+int CaseStatementAST::firstToken() const
{
if (case_token)
return case_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (colon_token)
return colon_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned CaseStatementAST::lastToken() const
+int CaseStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (case_token)
return case_token + 1;
@@ -458,31 +458,31 @@ unsigned CaseStatementAST::lastToken() const
}
/** \generated */
-unsigned CastExpressionAST::firstToken() const
+int CastExpressionAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned CastExpressionAST::lastToken() const
+int CastExpressionAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -490,33 +490,33 @@ unsigned CastExpressionAST::lastToken() const
}
/** \generated */
-unsigned CatchClauseAST::firstToken() const
+int CatchClauseAST::firstToken() const
{
if (catch_token)
return catch_token;
if (lparen_token)
return lparen_token;
if (exception_declaration)
- if (unsigned candidate = exception_declaration->firstToken())
+ if (int candidate = exception_declaration->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned CatchClauseAST::lastToken() const
+int CatchClauseAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (exception_declaration)
- if (unsigned candidate = exception_declaration->lastToken())
+ if (int candidate = exception_declaration->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -526,29 +526,29 @@ unsigned CatchClauseAST::lastToken() const
}
/** \generated */
-unsigned ClassSpecifierAST::firstToken() const
+int ClassSpecifierAST::firstToken() const
{
if (classkey_token)
return classkey_token;
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (final_token)
return final_token;
if (colon_token)
return colon_token;
if (base_clause_list)
- if (unsigned candidate = base_clause_list->firstToken())
+ if (int candidate = base_clause_list->firstToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token;
if (lbrace_token)
return lbrace_token;
if (member_specifier_list)
- if (unsigned candidate = member_specifier_list->firstToken())
+ if (int candidate = member_specifier_list->firstToken())
return candidate;
if (rbrace_token)
return rbrace_token;
@@ -556,29 +556,29 @@ unsigned ClassSpecifierAST::firstToken() const
}
/** \generated */
-unsigned ClassSpecifierAST::lastToken() const
+int ClassSpecifierAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (member_specifier_list)
- if (unsigned candidate = member_specifier_list->lastToken())
+ if (int candidate = member_specifier_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
if (base_clause_list)
- if (unsigned candidate = base_clause_list->lastToken())
+ if (int candidate = base_clause_list->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
if (final_token)
return final_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
if (classkey_token)
return classkey_token + 1;
@@ -586,12 +586,12 @@ unsigned ClassSpecifierAST::lastToken() const
}
/** \generated */
-unsigned CompoundExpressionAST::firstToken() const
+int CompoundExpressionAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -599,12 +599,12 @@ unsigned CompoundExpressionAST::firstToken() const
}
/** \generated */
-unsigned CompoundExpressionAST::lastToken() const
+int CompoundExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -612,31 +612,31 @@ unsigned CompoundExpressionAST::lastToken() const
}
/** \generated */
-unsigned CompoundLiteralAST::firstToken() const
+int CompoundLiteralAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (initializer)
- if (unsigned candidate = initializer->firstToken())
+ if (int candidate = initializer->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned CompoundLiteralAST::lastToken() const
+int CompoundLiteralAST::lastToken() const
{
if (initializer)
- if (unsigned candidate = initializer->lastToken())
+ if (int candidate = initializer->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -644,12 +644,12 @@ unsigned CompoundLiteralAST::lastToken() const
}
/** \generated */
-unsigned CompoundStatementAST::firstToken() const
+int CompoundStatementAST::firstToken() const
{
if (lbrace_token)
return lbrace_token;
if (statement_list)
- if (unsigned candidate = statement_list->firstToken())
+ if (int candidate = statement_list->firstToken())
return candidate;
if (rbrace_token)
return rbrace_token;
@@ -657,12 +657,12 @@ unsigned CompoundStatementAST::firstToken() const
}
/** \generated */
-unsigned CompoundStatementAST::lastToken() const
+int CompoundStatementAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (statement_list)
- if (unsigned candidate = statement_list->lastToken())
+ if (int candidate = statement_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
@@ -670,69 +670,69 @@ unsigned CompoundStatementAST::lastToken() const
}
/** \generated */
-unsigned ConditionAST::firstToken() const
+int ConditionAST::firstToken() const
{
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ConditionAST::lastToken() const
+int ConditionAST::lastToken() const
{
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ConditionalExpressionAST::firstToken() const
+int ConditionalExpressionAST::firstToken() const
{
if (condition)
- if (unsigned candidate = condition->firstToken())
+ if (int candidate = condition->firstToken())
return candidate;
if (question_token)
return question_token;
if (left_expression)
- if (unsigned candidate = left_expression->firstToken())
+ if (int candidate = left_expression->firstToken())
return candidate;
if (colon_token)
return colon_token;
if (right_expression)
- if (unsigned candidate = right_expression->firstToken())
+ if (int candidate = right_expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ConditionalExpressionAST::lastToken() const
+int ConditionalExpressionAST::lastToken() const
{
if (right_expression)
- if (unsigned candidate = right_expression->lastToken())
+ if (int candidate = right_expression->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
if (left_expression)
- if (unsigned candidate = left_expression->lastToken())
+ if (int candidate = left_expression->lastToken())
return candidate;
if (question_token)
return question_token + 1;
if (condition)
- if (unsigned candidate = condition->lastToken())
+ if (int candidate = condition->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ContinueStatementAST::firstToken() const
+int ContinueStatementAST::firstToken() const
{
if (continue_token)
return continue_token;
@@ -742,7 +742,7 @@ unsigned ContinueStatementAST::firstToken() const
}
/** \generated */
-unsigned ContinueStatementAST::lastToken() const
+int ContinueStatementAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
@@ -752,27 +752,27 @@ unsigned ContinueStatementAST::lastToken() const
}
/** \generated */
-unsigned ConversionFunctionIdAST::firstToken() const
+int ConversionFunctionIdAST::firstToken() const
{
if (operator_token)
return operator_token;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (ptr_operator_list)
- if (unsigned candidate = ptr_operator_list->firstToken())
+ if (int candidate = ptr_operator_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ConversionFunctionIdAST::lastToken() const
+int ConversionFunctionIdAST::lastToken() const
{
if (ptr_operator_list)
- if (unsigned candidate = ptr_operator_list->lastToken())
+ if (int candidate = ptr_operator_list->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (operator_token)
return operator_token + 1;
@@ -780,21 +780,21 @@ unsigned ConversionFunctionIdAST::lastToken() const
}
/** \generated */
-unsigned CppCastExpressionAST::firstToken() const
+int CppCastExpressionAST::firstToken() const
{
if (cast_token)
return cast_token;
if (less_token)
return less_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (greater_token)
return greater_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -802,19 +802,19 @@ unsigned CppCastExpressionAST::firstToken() const
}
/** \generated */
-unsigned CppCastExpressionAST::lastToken() const
+int CppCastExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (greater_token)
return greater_token + 1;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (less_token)
return less_token + 1;
@@ -824,12 +824,12 @@ unsigned CppCastExpressionAST::lastToken() const
}
/** \generated */
-unsigned CtorInitializerAST::firstToken() const
+int CtorInitializerAST::firstToken() const
{
if (colon_token)
return colon_token;
if (member_initializer_list)
- if (unsigned candidate = member_initializer_list->firstToken())
+ if (int candidate = member_initializer_list->firstToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token;
@@ -837,12 +837,12 @@ unsigned CtorInitializerAST::firstToken() const
}
/** \generated */
-unsigned CtorInitializerAST::lastToken() const
+int CtorInitializerAST::lastToken() const
{
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
if (member_initializer_list)
- if (unsigned candidate = member_initializer_list->lastToken())
+ if (int candidate = member_initializer_list->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
@@ -850,91 +850,91 @@ unsigned CtorInitializerAST::lastToken() const
}
/** \generated */
-unsigned DeclarationStatementAST::firstToken() const
+int DeclarationStatementAST::firstToken() const
{
if (declaration)
- if (unsigned candidate = declaration->firstToken())
+ if (int candidate = declaration->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned DeclarationStatementAST::lastToken() const
+int DeclarationStatementAST::lastToken() const
{
if (declaration)
- if (unsigned candidate = declaration->lastToken())
+ if (int candidate = declaration->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned DeclaratorAST::firstToken() const
+int DeclaratorAST::firstToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (ptr_operator_list)
- if (unsigned candidate = ptr_operator_list->firstToken())
+ if (int candidate = ptr_operator_list->firstToken())
return candidate;
if (core_declarator)
- if (unsigned candidate = core_declarator->firstToken())
+ if (int candidate = core_declarator->firstToken())
return candidate;
if (postfix_declarator_list)
- if (unsigned candidate = postfix_declarator_list->firstToken())
+ if (int candidate = postfix_declarator_list->firstToken())
return candidate;
if (post_attribute_list)
- if (unsigned candidate = post_attribute_list->firstToken())
+ if (int candidate = post_attribute_list->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (initializer)
- if (unsigned candidate = initializer->firstToken())
+ if (int candidate = initializer->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned DeclaratorAST::lastToken() const
+int DeclaratorAST::lastToken() const
{
if (initializer)
- if (unsigned candidate = initializer->lastToken())
+ if (int candidate = initializer->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
if (post_attribute_list)
- if (unsigned candidate = post_attribute_list->lastToken())
+ if (int candidate = post_attribute_list->lastToken())
return candidate;
if (postfix_declarator_list)
- if (unsigned candidate = postfix_declarator_list->lastToken())
+ if (int candidate = postfix_declarator_list->lastToken())
return candidate;
if (core_declarator)
- if (unsigned candidate = core_declarator->lastToken())
+ if (int candidate = core_declarator->lastToken())
return candidate;
if (ptr_operator_list)
- if (unsigned candidate = ptr_operator_list->lastToken())
+ if (int candidate = ptr_operator_list->lastToken())
return candidate;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned DeclaratorIdAST::firstToken() const
+int DeclaratorIdAST::firstToken() const
{
if (dot_dot_dot_token)
return dot_dot_dot_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned DeclaratorIdAST::lastToken() const
+int DeclaratorIdAST::lastToken() const
{
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
@@ -942,7 +942,7 @@ unsigned DeclaratorIdAST::lastToken() const
}
/** \generated */
-unsigned DeleteExpressionAST::firstToken() const
+int DeleteExpressionAST::firstToken() const
{
if (scope_token)
return scope_token;
@@ -953,16 +953,16 @@ unsigned DeleteExpressionAST::firstToken() const
if (rbracket_token)
return rbracket_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned DeleteExpressionAST::lastToken() const
+int DeleteExpressionAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (rbracket_token)
return rbracket_token + 1;
@@ -976,21 +976,21 @@ unsigned DeleteExpressionAST::lastToken() const
}
/** \generated */
-unsigned DestructorNameAST::firstToken() const
+int DestructorNameAST::firstToken() const
{
if (tilde_token)
return tilde_token;
if (unqualified_name)
- if (unsigned candidate = unqualified_name->firstToken())
+ if (int candidate = unqualified_name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned DestructorNameAST::lastToken() const
+int DestructorNameAST::lastToken() const
{
if (unqualified_name)
- if (unsigned candidate = unqualified_name->lastToken())
+ if (int candidate = unqualified_name->lastToken())
return candidate;
if (tilde_token)
return tilde_token + 1;
@@ -998,19 +998,19 @@ unsigned DestructorNameAST::lastToken() const
}
/** \generated */
-unsigned DoStatementAST::firstToken() const
+int DoStatementAST::firstToken() const
{
if (do_token)
return do_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
if (while_token)
return while_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -1020,21 +1020,21 @@ unsigned DoStatementAST::firstToken() const
}
/** \generated */
-unsigned DoStatementAST::lastToken() const
+int DoStatementAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (while_token)
return while_token + 1;
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (do_token)
return do_token + 1;
@@ -1042,27 +1042,27 @@ unsigned DoStatementAST::lastToken() const
}
/** \generated */
-unsigned ElaboratedTypeSpecifierAST::firstToken() const
+int ElaboratedTypeSpecifierAST::firstToken() const
{
if (classkey_token)
return classkey_token;
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ElaboratedTypeSpecifierAST::lastToken() const
+int ElaboratedTypeSpecifierAST::lastToken() const
{
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
if (classkey_token)
return classkey_token + 1;
@@ -1070,7 +1070,7 @@ unsigned ElaboratedTypeSpecifierAST::lastToken() const
}
/** \generated */
-unsigned EmptyDeclarationAST::firstToken() const
+int EmptyDeclarationAST::firstToken() const
{
if (semicolon_token)
return semicolon_token;
@@ -1078,7 +1078,7 @@ unsigned EmptyDeclarationAST::firstToken() const
}
/** \generated */
-unsigned EmptyDeclarationAST::lastToken() const
+int EmptyDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
@@ -1086,24 +1086,24 @@ unsigned EmptyDeclarationAST::lastToken() const
}
/** \generated */
-unsigned EnumSpecifierAST::firstToken() const
+int EnumSpecifierAST::firstToken() const
{
if (enum_token)
return enum_token;
if (key_token)
return key_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (colon_token)
return colon_token;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (lbrace_token)
return lbrace_token;
if (enumerator_list)
- if (unsigned candidate = enumerator_list->firstToken())
+ if (int candidate = enumerator_list->firstToken())
return candidate;
if (stray_comma_token)
return stray_comma_token;
@@ -1113,24 +1113,24 @@ unsigned EnumSpecifierAST::firstToken() const
}
/** \generated */
-unsigned EnumSpecifierAST::lastToken() const
+int EnumSpecifierAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (stray_comma_token)
return stray_comma_token + 1;
if (enumerator_list)
- if (unsigned candidate = enumerator_list->lastToken())
+ if (int candidate = enumerator_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (key_token)
return key_token + 1;
@@ -1140,23 +1140,23 @@ unsigned EnumSpecifierAST::lastToken() const
}
/** \generated */
-unsigned EnumeratorAST::firstToken() const
+int EnumeratorAST::firstToken() const
{
if (identifier_token)
return identifier_token;
if (equal_token)
return equal_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned EnumeratorAST::lastToken() const
+int EnumeratorAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
@@ -1166,13 +1166,13 @@ unsigned EnumeratorAST::lastToken() const
}
/** \generated */
-unsigned ExceptionDeclarationAST::firstToken() const
+int ExceptionDeclarationAST::firstToken() const
{
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token;
@@ -1180,21 +1180,21 @@ unsigned ExceptionDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ExceptionDeclarationAST::lastToken() const
+int ExceptionDeclarationAST::lastToken() const
{
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned DynamicExceptionSpecificationAST::firstToken() const
+int DynamicExceptionSpecificationAST::firstToken() const
{
if (throw_token)
return throw_token;
@@ -1203,7 +1203,7 @@ unsigned DynamicExceptionSpecificationAST::firstToken() const
if (dot_dot_dot_token)
return dot_dot_dot_token;
if (type_id_list)
- if (unsigned candidate = type_id_list->firstToken())
+ if (int candidate = type_id_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -1211,12 +1211,12 @@ unsigned DynamicExceptionSpecificationAST::firstToken() const
}
/** \generated */
-unsigned DynamicExceptionSpecificationAST::lastToken() const
+int DynamicExceptionSpecificationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (type_id_list)
- if (unsigned candidate = type_id_list->lastToken())
+ if (int candidate = type_id_list->lastToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
@@ -1228,34 +1228,34 @@ unsigned DynamicExceptionSpecificationAST::lastToken() const
}
/** \generated */
-unsigned ExpressionOrDeclarationStatementAST::firstToken() const
+int ExpressionOrDeclarationStatementAST::firstToken() const
{
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (declaration)
- if (unsigned candidate = declaration->firstToken())
+ if (int candidate = declaration->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ExpressionOrDeclarationStatementAST::lastToken() const
+int ExpressionOrDeclarationStatementAST::lastToken() const
{
if (declaration)
- if (unsigned candidate = declaration->lastToken())
+ if (int candidate = declaration->lastToken())
return candidate;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ExpressionStatementAST::firstToken() const
+int ExpressionStatementAST::firstToken() const
{
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -1263,60 +1263,60 @@ unsigned ExpressionStatementAST::firstToken() const
}
/** \generated */
-unsigned ExpressionStatementAST::lastToken() const
+int ExpressionStatementAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ForStatementAST::firstToken() const
+int ForStatementAST::firstToken() const
{
if (for_token)
return for_token;
if (lparen_token)
return lparen_token;
if (initializer)
- if (unsigned candidate = initializer->firstToken())
+ if (int candidate = initializer->firstToken())
return candidate;
if (condition)
- if (unsigned candidate = condition->firstToken())
+ if (int candidate = condition->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ForStatementAST::lastToken() const
+int ForStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (semicolon_token)
return semicolon_token + 1;
if (condition)
- if (unsigned candidate = condition->lastToken())
+ if (int candidate = condition->lastToken())
return candidate;
if (initializer)
- if (unsigned candidate = initializer->lastToken())
+ if (int candidate = initializer->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1326,55 +1326,55 @@ unsigned ForStatementAST::lastToken() const
}
/** \generated */
-unsigned ForeachStatementAST::firstToken() const
+int ForeachStatementAST::firstToken() const
{
if (foreach_token)
return foreach_token;
if (lparen_token)
return lparen_token;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (initializer)
- if (unsigned candidate = initializer->firstToken())
+ if (int candidate = initializer->firstToken())
return candidate;
if (comma_token)
return comma_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ForeachStatementAST::lastToken() const
+int ForeachStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (comma_token)
return comma_token + 1;
if (initializer)
- if (unsigned candidate = initializer->lastToken())
+ if (int candidate = initializer->lastToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1384,53 +1384,53 @@ unsigned ForeachStatementAST::lastToken() const
}
/** \generated */
-unsigned FunctionDeclaratorAST::firstToken() const
+int FunctionDeclaratorAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (parameter_declaration_clause)
- if (unsigned candidate = parameter_declaration_clause->firstToken())
+ if (int candidate = parameter_declaration_clause->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (cv_qualifier_list)
- if (unsigned candidate = cv_qualifier_list->firstToken())
+ if (int candidate = cv_qualifier_list->firstToken())
return candidate;
if (ref_qualifier_token)
return ref_qualifier_token;
if (exception_specification)
- if (unsigned candidate = exception_specification->firstToken())
+ if (int candidate = exception_specification->firstToken())
return candidate;
if (trailing_return_type)
- if (unsigned candidate = trailing_return_type->firstToken())
+ if (int candidate = trailing_return_type->firstToken())
return candidate;
if (as_cpp_initializer)
- if (unsigned candidate = as_cpp_initializer->firstToken())
+ if (int candidate = as_cpp_initializer->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned FunctionDeclaratorAST::lastToken() const
+int FunctionDeclaratorAST::lastToken() const
{
if (as_cpp_initializer)
- if (unsigned candidate = as_cpp_initializer->lastToken())
+ if (int candidate = as_cpp_initializer->lastToken())
return candidate;
if (trailing_return_type)
- if (unsigned candidate = trailing_return_type->lastToken())
+ if (int candidate = trailing_return_type->lastToken())
return candidate;
if (exception_specification)
- if (unsigned candidate = exception_specification->lastToken())
+ if (int candidate = exception_specification->lastToken())
return candidate;
if (ref_qualifier_token)
return ref_qualifier_token + 1;
if (cv_qualifier_list)
- if (unsigned candidate = cv_qualifier_list->lastToken())
+ if (int candidate = cv_qualifier_list->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (parameter_declaration_clause)
- if (unsigned candidate = parameter_declaration_clause->lastToken())
+ if (int candidate = parameter_declaration_clause->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1438,39 +1438,39 @@ unsigned FunctionDeclaratorAST::lastToken() const
}
/** \generated */
-unsigned FunctionDefinitionAST::firstToken() const
+int FunctionDefinitionAST::firstToken() const
{
if (qt_invokable_token)
return qt_invokable_token;
if (decl_specifier_list)
- if (unsigned candidate = decl_specifier_list->firstToken())
+ if (int candidate = decl_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (ctor_initializer)
- if (unsigned candidate = ctor_initializer->firstToken())
+ if (int candidate = ctor_initializer->firstToken())
return candidate;
if (function_body)
- if (unsigned candidate = function_body->firstToken())
+ if (int candidate = function_body->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned FunctionDefinitionAST::lastToken() const
+int FunctionDefinitionAST::lastToken() const
{
if (function_body)
- if (unsigned candidate = function_body->lastToken())
+ if (int candidate = function_body->lastToken())
return candidate;
if (ctor_initializer)
- if (unsigned candidate = ctor_initializer->lastToken())
+ if (int candidate = ctor_initializer->lastToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (decl_specifier_list)
- if (unsigned candidate = decl_specifier_list->lastToken())
+ if (int candidate = decl_specifier_list->lastToken())
return candidate;
if (qt_invokable_token)
return qt_invokable_token + 1;
@@ -1478,7 +1478,7 @@ unsigned FunctionDefinitionAST::lastToken() const
}
/** \generated */
-unsigned GotoStatementAST::firstToken() const
+int GotoStatementAST::firstToken() const
{
if (goto_token)
return goto_token;
@@ -1490,7 +1490,7 @@ unsigned GotoStatementAST::firstToken() const
}
/** \generated */
-unsigned GotoStatementAST::lastToken() const
+int GotoStatementAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
@@ -1502,61 +1502,61 @@ unsigned GotoStatementAST::lastToken() const
}
/** \generated */
-unsigned IdExpressionAST::firstToken() const
+int IdExpressionAST::firstToken() const
{
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned IdExpressionAST::lastToken() const
+int IdExpressionAST::lastToken() const
{
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned IfStatementAST::firstToken() const
+int IfStatementAST::firstToken() const
{
if (if_token)
return if_token;
if (lparen_token)
return lparen_token;
if (condition)
- if (unsigned candidate = condition->firstToken())
+ if (int candidate = condition->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
if (else_token)
return else_token;
if (else_statement)
- if (unsigned candidate = else_statement->firstToken())
+ if (int candidate = else_statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned IfStatementAST::lastToken() const
+int IfStatementAST::lastToken() const
{
if (else_statement)
- if (unsigned candidate = else_statement->lastToken())
+ if (int candidate = else_statement->lastToken())
return candidate;
if (else_token)
return else_token + 1;
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (condition)
- if (unsigned candidate = condition->lastToken())
+ if (int candidate = condition->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1566,23 +1566,23 @@ unsigned IfStatementAST::lastToken() const
}
/** \generated */
-unsigned LabeledStatementAST::firstToken() const
+int LabeledStatementAST::firstToken() const
{
if (label_token)
return label_token;
if (colon_token)
return colon_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned LabeledStatementAST::lastToken() const
+int LabeledStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
@@ -1592,21 +1592,21 @@ unsigned LabeledStatementAST::lastToken() const
}
/** \generated */
-unsigned LambdaCaptureAST::firstToken() const
+int LambdaCaptureAST::firstToken() const
{
if (default_capture_token)
return default_capture_token;
if (capture_list)
- if (unsigned candidate = capture_list->firstToken())
+ if (int candidate = capture_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned LambdaCaptureAST::lastToken() const
+int LambdaCaptureAST::lastToken() const
{
if (capture_list)
- if (unsigned candidate = capture_list->lastToken())
+ if (int candidate = capture_list->lastToken())
return candidate;
if (default_capture_token)
return default_capture_token + 1;
@@ -1614,47 +1614,47 @@ unsigned LambdaCaptureAST::lastToken() const
}
/** \generated */
-unsigned LambdaDeclaratorAST::firstToken() const
+int LambdaDeclaratorAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (parameter_declaration_clause)
- if (unsigned candidate = parameter_declaration_clause->firstToken())
+ if (int candidate = parameter_declaration_clause->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (attributes)
- if (unsigned candidate = attributes->firstToken())
+ if (int candidate = attributes->firstToken())
return candidate;
if (mutable_token)
return mutable_token;
if (exception_specification)
- if (unsigned candidate = exception_specification->firstToken())
+ if (int candidate = exception_specification->firstToken())
return candidate;
if (trailing_return_type)
- if (unsigned candidate = trailing_return_type->firstToken())
+ if (int candidate = trailing_return_type->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned LambdaDeclaratorAST::lastToken() const
+int LambdaDeclaratorAST::lastToken() const
{
if (trailing_return_type)
- if (unsigned candidate = trailing_return_type->lastToken())
+ if (int candidate = trailing_return_type->lastToken())
return candidate;
if (exception_specification)
- if (unsigned candidate = exception_specification->lastToken())
+ if (int candidate = exception_specification->lastToken())
return candidate;
if (mutable_token)
return mutable_token + 1;
if (attributes)
- if (unsigned candidate = attributes->lastToken())
+ if (int candidate = attributes->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (parameter_declaration_clause)
- if (unsigned candidate = parameter_declaration_clause->lastToken())
+ if (int candidate = parameter_declaration_clause->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1662,42 +1662,42 @@ unsigned LambdaDeclaratorAST::lastToken() const
}
/** \generated */
-unsigned LambdaExpressionAST::firstToken() const
+int LambdaExpressionAST::firstToken() const
{
if (lambda_introducer)
- if (unsigned candidate = lambda_introducer->firstToken())
+ if (int candidate = lambda_introducer->firstToken())
return candidate;
if (lambda_declarator)
- if (unsigned candidate = lambda_declarator->firstToken())
+ if (int candidate = lambda_declarator->firstToken())
return candidate;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned LambdaExpressionAST::lastToken() const
+int LambdaExpressionAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (lambda_declarator)
- if (unsigned candidate = lambda_declarator->lastToken())
+ if (int candidate = lambda_declarator->lastToken())
return candidate;
if (lambda_introducer)
- if (unsigned candidate = lambda_introducer->lastToken())
+ if (int candidate = lambda_introducer->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned LambdaIntroducerAST::firstToken() const
+int LambdaIntroducerAST::firstToken() const
{
if (lbracket_token)
return lbracket_token;
if (lambda_capture)
- if (unsigned candidate = lambda_capture->firstToken())
+ if (int candidate = lambda_capture->firstToken())
return candidate;
if (rbracket_token)
return rbracket_token;
@@ -1705,12 +1705,12 @@ unsigned LambdaIntroducerAST::firstToken() const
}
/** \generated */
-unsigned LambdaIntroducerAST::lastToken() const
+int LambdaIntroducerAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
if (lambda_capture)
- if (unsigned candidate = lambda_capture->lastToken())
+ if (int candidate = lambda_capture->lastToken())
return candidate;
if (lbracket_token)
return lbracket_token + 1;
@@ -1718,12 +1718,12 @@ unsigned LambdaIntroducerAST::lastToken() const
}
/** \generated */
-unsigned LinkageBodyAST::firstToken() const
+int LinkageBodyAST::firstToken() const
{
if (lbrace_token)
return lbrace_token;
if (declaration_list)
- if (unsigned candidate = declaration_list->firstToken())
+ if (int candidate = declaration_list->firstToken())
return candidate;
if (rbrace_token)
return rbrace_token;
@@ -1731,12 +1731,12 @@ unsigned LinkageBodyAST::firstToken() const
}
/** \generated */
-unsigned LinkageBodyAST::lastToken() const
+int LinkageBodyAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (declaration_list)
- if (unsigned candidate = declaration_list->lastToken())
+ if (int candidate = declaration_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
@@ -1744,23 +1744,23 @@ unsigned LinkageBodyAST::lastToken() const
}
/** \generated */
-unsigned LinkageSpecificationAST::firstToken() const
+int LinkageSpecificationAST::firstToken() const
{
if (extern_token)
return extern_token;
if (extern_type_token)
return extern_type_token;
if (declaration)
- if (unsigned candidate = declaration->firstToken())
+ if (int candidate = declaration->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned LinkageSpecificationAST::lastToken() const
+int LinkageSpecificationAST::lastToken() const
{
if (declaration)
- if (unsigned candidate = declaration->lastToken())
+ if (int candidate = declaration->lastToken())
return candidate;
if (extern_type_token)
return extern_type_token + 1;
@@ -1770,81 +1770,81 @@ unsigned LinkageSpecificationAST::lastToken() const
}
/** \generated */
-unsigned MemInitializerAST::firstToken() const
+int MemInitializerAST::firstToken() const
{
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned MemInitializerAST::lastToken() const
+int MemInitializerAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned MemberAccessAST::firstToken() const
+int MemberAccessAST::firstToken() const
{
if (base_expression)
- if (unsigned candidate = base_expression->firstToken())
+ if (int candidate = base_expression->firstToken())
return candidate;
if (access_token)
return access_token;
if (template_token)
return template_token;
if (member_name)
- if (unsigned candidate = member_name->firstToken())
+ if (int candidate = member_name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned MemberAccessAST::lastToken() const
+int MemberAccessAST::lastToken() const
{
if (member_name)
- if (unsigned candidate = member_name->lastToken())
+ if (int candidate = member_name->lastToken())
return candidate;
if (template_token)
return template_token + 1;
if (access_token)
return access_token + 1;
if (base_expression)
- if (unsigned candidate = base_expression->lastToken())
+ if (int candidate = base_expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned NamedTypeSpecifierAST::firstToken() const
+int NamedTypeSpecifierAST::firstToken() const
{
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned NamedTypeSpecifierAST::lastToken() const
+int NamedTypeSpecifierAST::lastToken() const
{
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned NamespaceAST::firstToken() const
+int NamespaceAST::firstToken() const
{
if (inline_token)
return inline_token;
@@ -1853,22 +1853,22 @@ unsigned NamespaceAST::firstToken() const
if (identifier_token)
return identifier_token;
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (linkage_body)
- if (unsigned candidate = linkage_body->firstToken())
+ if (int candidate = linkage_body->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned NamespaceAST::lastToken() const
+int NamespaceAST::lastToken() const
{
if (linkage_body)
- if (unsigned candidate = linkage_body->lastToken())
+ if (int candidate = linkage_body->lastToken())
return candidate;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
if (identifier_token)
return identifier_token + 1;
@@ -1880,7 +1880,7 @@ unsigned NamespaceAST::lastToken() const
}
/** \generated */
-unsigned NamespaceAliasDefinitionAST::firstToken() const
+int NamespaceAliasDefinitionAST::firstToken() const
{
if (namespace_token)
return namespace_token;
@@ -1889,7 +1889,7 @@ unsigned NamespaceAliasDefinitionAST::firstToken() const
if (equal_token)
return equal_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -1897,12 +1897,12 @@ unsigned NamespaceAliasDefinitionAST::firstToken() const
}
/** \generated */
-unsigned NamespaceAliasDefinitionAST::lastToken() const
+int NamespaceAliasDefinitionAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
@@ -1914,12 +1914,12 @@ unsigned NamespaceAliasDefinitionAST::lastToken() const
}
/** \generated */
-unsigned NestedDeclaratorAST::firstToken() const
+int NestedDeclaratorAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -1927,12 +1927,12 @@ unsigned NestedDeclaratorAST::firstToken() const
}
/** \generated */
-unsigned NestedDeclaratorAST::lastToken() const
+int NestedDeclaratorAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1940,12 +1940,12 @@ unsigned NestedDeclaratorAST::lastToken() const
}
/** \generated */
-unsigned NestedExpressionAST::firstToken() const
+int NestedExpressionAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -1953,12 +1953,12 @@ unsigned NestedExpressionAST::firstToken() const
}
/** \generated */
-unsigned NestedExpressionAST::lastToken() const
+int NestedExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -1966,10 +1966,10 @@ unsigned NestedExpressionAST::lastToken() const
}
/** \generated */
-unsigned NestedNameSpecifierAST::firstToken() const
+int NestedNameSpecifierAST::firstToken() const
{
if (class_or_namespace_name)
- if (unsigned candidate = class_or_namespace_name->firstToken())
+ if (int candidate = class_or_namespace_name->firstToken())
return candidate;
if (scope_token)
return scope_token;
@@ -1977,23 +1977,23 @@ unsigned NestedNameSpecifierAST::firstToken() const
}
/** \generated */
-unsigned NestedNameSpecifierAST::lastToken() const
+int NestedNameSpecifierAST::lastToken() const
{
if (scope_token)
return scope_token + 1;
if (class_or_namespace_name)
- if (unsigned candidate = class_or_namespace_name->lastToken())
+ if (int candidate = class_or_namespace_name->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned NewArrayDeclaratorAST::firstToken() const
+int NewArrayDeclaratorAST::firstToken() const
{
if (lbracket_token)
return lbracket_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rbracket_token)
return rbracket_token;
@@ -2001,12 +2001,12 @@ unsigned NewArrayDeclaratorAST::firstToken() const
}
/** \generated */
-unsigned NewArrayDeclaratorAST::lastToken() const
+int NewArrayDeclaratorAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lbracket_token)
return lbracket_token + 1;
@@ -2014,49 +2014,49 @@ unsigned NewArrayDeclaratorAST::lastToken() const
}
/** \generated */
-unsigned NewExpressionAST::firstToken() const
+int NewExpressionAST::firstToken() const
{
if (scope_token)
return scope_token;
if (new_token)
return new_token;
if (new_placement)
- if (unsigned candidate = new_placement->firstToken())
+ if (int candidate = new_placement->firstToken())
return candidate;
if (lparen_token)
return lparen_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (new_type_id)
- if (unsigned candidate = new_type_id->firstToken())
+ if (int candidate = new_type_id->firstToken())
return candidate;
if (new_initializer)
- if (unsigned candidate = new_initializer->firstToken())
+ if (int candidate = new_initializer->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned NewExpressionAST::lastToken() const
+int NewExpressionAST::lastToken() const
{
if (new_initializer)
- if (unsigned candidate = new_initializer->lastToken())
+ if (int candidate = new_initializer->lastToken())
return candidate;
if (new_type_id)
- if (unsigned candidate = new_type_id->lastToken())
+ if (int candidate = new_type_id->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (new_placement)
- if (unsigned candidate = new_placement->lastToken())
+ if (int candidate = new_placement->lastToken())
return candidate;
if (new_token)
return new_token + 1;
@@ -2066,12 +2066,12 @@ unsigned NewExpressionAST::lastToken() const
}
/** \generated */
-unsigned ExpressionListParenAST::firstToken() const
+int ExpressionListParenAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (expression_list)
- if (unsigned candidate = expression_list->firstToken())
+ if (int candidate = expression_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -2079,12 +2079,12 @@ unsigned ExpressionListParenAST::firstToken() const
}
/** \generated */
-unsigned ExpressionListParenAST::lastToken() const
+int ExpressionListParenAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression_list)
- if (unsigned candidate = expression_list->lastToken())
+ if (int candidate = expression_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -2092,37 +2092,37 @@ unsigned ExpressionListParenAST::lastToken() const
}
/** \generated */
-unsigned NewTypeIdAST::firstToken() const
+int NewTypeIdAST::firstToken() const
{
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (ptr_operator_list)
- if (unsigned candidate = ptr_operator_list->firstToken())
+ if (int candidate = ptr_operator_list->firstToken())
return candidate;
if (new_array_declarator_list)
- if (unsigned candidate = new_array_declarator_list->firstToken())
+ if (int candidate = new_array_declarator_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned NewTypeIdAST::lastToken() const
+int NewTypeIdAST::lastToken() const
{
if (new_array_declarator_list)
- if (unsigned candidate = new_array_declarator_list->lastToken())
+ if (int candidate = new_array_declarator_list->lastToken())
return candidate;
if (ptr_operator_list)
- if (unsigned candidate = ptr_operator_list->lastToken())
+ if (int candidate = ptr_operator_list->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned NumericLiteralAST::firstToken() const
+int NumericLiteralAST::firstToken() const
{
if (literal_token)
return literal_token;
@@ -2130,7 +2130,7 @@ unsigned NumericLiteralAST::firstToken() const
}
/** \generated */
-unsigned NumericLiteralAST::lastToken() const
+int NumericLiteralAST::lastToken() const
{
if (literal_token)
return literal_token + 1;
@@ -2138,38 +2138,38 @@ unsigned NumericLiteralAST::lastToken() const
}
/** \generated */
-unsigned ObjCClassDeclarationAST::firstToken() const
+int ObjCClassDeclarationAST::firstToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (interface_token)
return interface_token;
if (implementation_token)
return implementation_token;
if (class_name)
- if (unsigned candidate = class_name->firstToken())
+ if (int candidate = class_name->firstToken())
return candidate;
if (lparen_token)
return lparen_token;
if (category_name)
- if (unsigned candidate = category_name->firstToken())
+ if (int candidate = category_name->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (colon_token)
return colon_token;
if (superclass)
- if (unsigned candidate = superclass->firstToken())
+ if (int candidate = superclass->firstToken())
return candidate;
if (protocol_refs)
- if (unsigned candidate = protocol_refs->firstToken())
+ if (int candidate = protocol_refs->firstToken())
return candidate;
if (inst_vars_decl)
- if (unsigned candidate = inst_vars_decl->firstToken())
+ if (int candidate = inst_vars_decl->firstToken())
return candidate;
if (member_declaration_list)
- if (unsigned candidate = member_declaration_list->firstToken())
+ if (int candidate = member_declaration_list->firstToken())
return candidate;
if (end_token)
return end_token;
@@ -2177,54 +2177,54 @@ unsigned ObjCClassDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCClassDeclarationAST::lastToken() const
+int ObjCClassDeclarationAST::lastToken() const
{
if (end_token)
return end_token + 1;
if (member_declaration_list)
- if (unsigned candidate = member_declaration_list->lastToken())
+ if (int candidate = member_declaration_list->lastToken())
return candidate;
if (inst_vars_decl)
- if (unsigned candidate = inst_vars_decl->lastToken())
+ if (int candidate = inst_vars_decl->lastToken())
return candidate;
if (protocol_refs)
- if (unsigned candidate = protocol_refs->lastToken())
+ if (int candidate = protocol_refs->lastToken())
return candidate;
if (superclass)
- if (unsigned candidate = superclass->lastToken())
+ if (int candidate = superclass->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
if (rparen_token)
return rparen_token + 1;
if (category_name)
- if (unsigned candidate = category_name->lastToken())
+ if (int candidate = category_name->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (class_name)
- if (unsigned candidate = class_name->lastToken())
+ if (int candidate = class_name->lastToken())
return candidate;
if (implementation_token)
return implementation_token + 1;
if (interface_token)
return interface_token + 1;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCClassForwardDeclarationAST::firstToken() const
+int ObjCClassForwardDeclarationAST::firstToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (class_token)
return class_token;
if (identifier_list)
- if (unsigned candidate = identifier_list->firstToken())
+ if (int candidate = identifier_list->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -2232,28 +2232,28 @@ unsigned ObjCClassForwardDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCClassForwardDeclarationAST::lastToken() const
+int ObjCClassForwardDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (identifier_list)
- if (unsigned candidate = identifier_list->lastToken())
+ if (int candidate = identifier_list->lastToken())
return candidate;
if (class_token)
return class_token + 1;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCDynamicPropertiesDeclarationAST::firstToken() const
+int ObjCDynamicPropertiesDeclarationAST::firstToken() const
{
if (dynamic_token)
return dynamic_token;
if (property_identifier_list)
- if (unsigned candidate = property_identifier_list->firstToken())
+ if (int candidate = property_identifier_list->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -2261,12 +2261,12 @@ unsigned ObjCDynamicPropertiesDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCDynamicPropertiesDeclarationAST::lastToken() const
+int ObjCDynamicPropertiesDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (property_identifier_list)
- if (unsigned candidate = property_identifier_list->lastToken())
+ if (int candidate = property_identifier_list->lastToken())
return candidate;
if (dynamic_token)
return dynamic_token + 1;
@@ -2274,21 +2274,21 @@ unsigned ObjCDynamicPropertiesDeclarationAST::lastToken() const
}
/** \generated */
-unsigned ObjCEncodeExpressionAST::firstToken() const
+int ObjCEncodeExpressionAST::firstToken() const
{
if (encode_token)
return encode_token;
if (type_name)
- if (unsigned candidate = type_name->firstToken())
+ if (int candidate = type_name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCEncodeExpressionAST::lastToken() const
+int ObjCEncodeExpressionAST::lastToken() const
{
if (type_name)
- if (unsigned candidate = type_name->lastToken())
+ if (int candidate = type_name->lastToken())
return candidate;
if (encode_token)
return encode_token + 1;
@@ -2296,55 +2296,55 @@ unsigned ObjCEncodeExpressionAST::lastToken() const
}
/** \generated */
-unsigned ObjCFastEnumerationAST::firstToken() const
+int ObjCFastEnumerationAST::firstToken() const
{
if (for_token)
return for_token;
if (lparen_token)
return lparen_token;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (initializer)
- if (unsigned candidate = initializer->firstToken())
+ if (int candidate = initializer->firstToken())
return candidate;
if (in_token)
return in_token;
if (fast_enumeratable_expression)
- if (unsigned candidate = fast_enumeratable_expression->firstToken())
+ if (int candidate = fast_enumeratable_expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCFastEnumerationAST::lastToken() const
+int ObjCFastEnumerationAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (fast_enumeratable_expression)
- if (unsigned candidate = fast_enumeratable_expression->lastToken())
+ if (int candidate = fast_enumeratable_expression->lastToken())
return candidate;
if (in_token)
return in_token + 1;
if (initializer)
- if (unsigned candidate = initializer->lastToken())
+ if (int candidate = initializer->lastToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -2354,12 +2354,12 @@ unsigned ObjCFastEnumerationAST::lastToken() const
}
/** \generated */
-unsigned ObjCInstanceVariablesDeclarationAST::firstToken() const
+int ObjCInstanceVariablesDeclarationAST::firstToken() const
{
if (lbrace_token)
return lbrace_token;
if (instance_variable_list)
- if (unsigned candidate = instance_variable_list->firstToken())
+ if (int candidate = instance_variable_list->firstToken())
return candidate;
if (rbrace_token)
return rbrace_token;
@@ -2367,12 +2367,12 @@ unsigned ObjCInstanceVariablesDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCInstanceVariablesDeclarationAST::lastToken() const
+int ObjCInstanceVariablesDeclarationAST::lastToken() const
{
if (rbrace_token)
return rbrace_token + 1;
if (instance_variable_list)
- if (unsigned candidate = instance_variable_list->lastToken())
+ if (int candidate = instance_variable_list->lastToken())
return candidate;
if (lbrace_token)
return lbrace_token + 1;
@@ -2380,66 +2380,66 @@ unsigned ObjCInstanceVariablesDeclarationAST::lastToken() const
}
/** \generated */
-unsigned ObjCMessageArgumentAST::firstToken() const
+int ObjCMessageArgumentAST::firstToken() const
{
if (parameter_value_expression)
- if (unsigned candidate = parameter_value_expression->firstToken())
+ if (int candidate = parameter_value_expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCMessageArgumentAST::lastToken() const
+int ObjCMessageArgumentAST::lastToken() const
{
if (parameter_value_expression)
- if (unsigned candidate = parameter_value_expression->lastToken())
+ if (int candidate = parameter_value_expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCMessageArgumentDeclarationAST::firstToken() const
+int ObjCMessageArgumentDeclarationAST::firstToken() const
{
if (type_name)
- if (unsigned candidate = type_name->firstToken())
+ if (int candidate = type_name->firstToken())
return candidate;
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (param_name)
- if (unsigned candidate = param_name->firstToken())
+ if (int candidate = param_name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCMessageArgumentDeclarationAST::lastToken() const
+int ObjCMessageArgumentDeclarationAST::lastToken() const
{
if (param_name)
- if (unsigned candidate = param_name->lastToken())
+ if (int candidate = param_name->lastToken())
return candidate;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
if (type_name)
- if (unsigned candidate = type_name->lastToken())
+ if (int candidate = type_name->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCMessageExpressionAST::firstToken() const
+int ObjCMessageExpressionAST::firstToken() const
{
if (lbracket_token)
return lbracket_token;
if (receiver_expression)
- if (unsigned candidate = receiver_expression->firstToken())
+ if (int candidate = receiver_expression->firstToken())
return candidate;
if (selector)
- if (unsigned candidate = selector->firstToken())
+ if (int candidate = selector->firstToken())
return candidate;
if (argument_list)
- if (unsigned candidate = argument_list->firstToken())
+ if (int candidate = argument_list->firstToken())
return candidate;
if (rbracket_token)
return rbracket_token;
@@ -2447,18 +2447,18 @@ unsigned ObjCMessageExpressionAST::firstToken() const
}
/** \generated */
-unsigned ObjCMessageExpressionAST::lastToken() const
+int ObjCMessageExpressionAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
if (argument_list)
- if (unsigned candidate = argument_list->lastToken())
+ if (int candidate = argument_list->lastToken())
return candidate;
if (selector)
- if (unsigned candidate = selector->lastToken())
+ if (int candidate = selector->lastToken())
return candidate;
if (receiver_expression)
- if (unsigned candidate = receiver_expression->lastToken())
+ if (int candidate = receiver_expression->lastToken())
return candidate;
if (lbracket_token)
return lbracket_token + 1;
@@ -2466,13 +2466,13 @@ unsigned ObjCMessageExpressionAST::lastToken() const
}
/** \generated */
-unsigned ObjCMethodDeclarationAST::firstToken() const
+int ObjCMethodDeclarationAST::firstToken() const
{
if (method_prototype)
- if (unsigned candidate = method_prototype->firstToken())
+ if (int candidate = method_prototype->firstToken())
return candidate;
if (function_body)
- if (unsigned candidate = function_body->firstToken())
+ if (int candidate = function_body->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -2480,57 +2480,57 @@ unsigned ObjCMethodDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCMethodDeclarationAST::lastToken() const
+int ObjCMethodDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (function_body)
- if (unsigned candidate = function_body->lastToken())
+ if (int candidate = function_body->lastToken())
return candidate;
if (method_prototype)
- if (unsigned candidate = method_prototype->lastToken())
+ if (int candidate = method_prototype->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCMethodPrototypeAST::firstToken() const
+int ObjCMethodPrototypeAST::firstToken() const
{
if (method_type_token)
return method_type_token;
if (type_name)
- if (unsigned candidate = type_name->firstToken())
+ if (int candidate = type_name->firstToken())
return candidate;
if (selector)
- if (unsigned candidate = selector->firstToken())
+ if (int candidate = selector->firstToken())
return candidate;
if (argument_list)
- if (unsigned candidate = argument_list->firstToken())
+ if (int candidate = argument_list->firstToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token;
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCMethodPrototypeAST::lastToken() const
+int ObjCMethodPrototypeAST::lastToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
if (argument_list)
- if (unsigned candidate = argument_list->lastToken())
+ if (int candidate = argument_list->lastToken())
return candidate;
if (selector)
- if (unsigned candidate = selector->lastToken())
+ if (int candidate = selector->lastToken())
return candidate;
if (type_name)
- if (unsigned candidate = type_name->lastToken())
+ if (int candidate = type_name->lastToken())
return candidate;
if (method_type_token)
return method_type_token + 1;
@@ -2538,23 +2538,23 @@ unsigned ObjCMethodPrototypeAST::lastToken() const
}
/** \generated */
-unsigned ObjCPropertyAttributeAST::firstToken() const
+int ObjCPropertyAttributeAST::firstToken() const
{
if (attribute_identifier_token)
return attribute_identifier_token;
if (equals_token)
return equals_token;
if (method_selector)
- if (unsigned candidate = method_selector->firstToken())
+ if (int candidate = method_selector->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCPropertyAttributeAST::lastToken() const
+int ObjCPropertyAttributeAST::lastToken() const
{
if (method_selector)
- if (unsigned candidate = method_selector->lastToken())
+ if (int candidate = method_selector->lastToken())
return candidate;
if (equals_token)
return equals_token + 1;
@@ -2564,63 +2564,63 @@ unsigned ObjCPropertyAttributeAST::lastToken() const
}
/** \generated */
-unsigned ObjCPropertyDeclarationAST::firstToken() const
+int ObjCPropertyDeclarationAST::firstToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (property_token)
return property_token;
if (lparen_token)
return lparen_token;
if (property_attribute_list)
- if (unsigned candidate = property_attribute_list->firstToken())
+ if (int candidate = property_attribute_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (simple_declaration)
- if (unsigned candidate = simple_declaration->firstToken())
+ if (int candidate = simple_declaration->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCPropertyDeclarationAST::lastToken() const
+int ObjCPropertyDeclarationAST::lastToken() const
{
if (simple_declaration)
- if (unsigned candidate = simple_declaration->lastToken())
+ if (int candidate = simple_declaration->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (property_attribute_list)
- if (unsigned candidate = property_attribute_list->lastToken())
+ if (int candidate = property_attribute_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
if (property_token)
return property_token + 1;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCProtocolDeclarationAST::firstToken() const
+int ObjCProtocolDeclarationAST::firstToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (protocol_token)
return protocol_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (protocol_refs)
- if (unsigned candidate = protocol_refs->firstToken())
+ if (int candidate = protocol_refs->firstToken())
return candidate;
if (member_declaration_list)
- if (unsigned candidate = member_declaration_list->firstToken())
+ if (int candidate = member_declaration_list->firstToken())
return candidate;
if (end_token)
return end_token;
@@ -2628,29 +2628,29 @@ unsigned ObjCProtocolDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCProtocolDeclarationAST::lastToken() const
+int ObjCProtocolDeclarationAST::lastToken() const
{
if (end_token)
return end_token + 1;
if (member_declaration_list)
- if (unsigned candidate = member_declaration_list->lastToken())
+ if (int candidate = member_declaration_list->lastToken())
return candidate;
if (protocol_refs)
- if (unsigned candidate = protocol_refs->lastToken())
+ if (int candidate = protocol_refs->lastToken())
return candidate;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (protocol_token)
return protocol_token + 1;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCProtocolExpressionAST::firstToken() const
+int ObjCProtocolExpressionAST::firstToken() const
{
if (protocol_token)
return protocol_token;
@@ -2664,7 +2664,7 @@ unsigned ObjCProtocolExpressionAST::firstToken() const
}
/** \generated */
-unsigned ObjCProtocolExpressionAST::lastToken() const
+int ObjCProtocolExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
@@ -2678,15 +2678,15 @@ unsigned ObjCProtocolExpressionAST::lastToken() const
}
/** \generated */
-unsigned ObjCProtocolForwardDeclarationAST::firstToken() const
+int ObjCProtocolForwardDeclarationAST::firstToken() const
{
if (attribute_list)
- if (unsigned candidate = attribute_list->firstToken())
+ if (int candidate = attribute_list->firstToken())
return candidate;
if (protocol_token)
return protocol_token;
if (identifier_list)
- if (unsigned candidate = identifier_list->firstToken())
+ if (int candidate = identifier_list->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -2694,28 +2694,28 @@ unsigned ObjCProtocolForwardDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCProtocolForwardDeclarationAST::lastToken() const
+int ObjCProtocolForwardDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (identifier_list)
- if (unsigned candidate = identifier_list->lastToken())
+ if (int candidate = identifier_list->lastToken())
return candidate;
if (protocol_token)
return protocol_token + 1;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCProtocolRefsAST::firstToken() const
+int ObjCProtocolRefsAST::firstToken() const
{
if (less_token)
return less_token;
if (identifier_list)
- if (unsigned candidate = identifier_list->firstToken())
+ if (int candidate = identifier_list->firstToken())
return candidate;
if (greater_token)
return greater_token;
@@ -2723,12 +2723,12 @@ unsigned ObjCProtocolRefsAST::firstToken() const
}
/** \generated */
-unsigned ObjCProtocolRefsAST::lastToken() const
+int ObjCProtocolRefsAST::lastToken() const
{
if (greater_token)
return greater_token + 1;
if (identifier_list)
- if (unsigned candidate = identifier_list->lastToken())
+ if (int candidate = identifier_list->lastToken())
return candidate;
if (less_token)
return less_token + 1;
@@ -2736,25 +2736,25 @@ unsigned ObjCProtocolRefsAST::lastToken() const
}
/** \generated */
-unsigned ObjCSelectorAST::firstToken() const
+int ObjCSelectorAST::firstToken() const
{
if (selector_argument_list)
- if (unsigned candidate = selector_argument_list->firstToken())
+ if (int candidate = selector_argument_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCSelectorAST::lastToken() const
+int ObjCSelectorAST::lastToken() const
{
if (selector_argument_list)
- if (unsigned candidate = selector_argument_list->lastToken())
+ if (int candidate = selector_argument_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ObjCSelectorArgumentAST::firstToken() const
+int ObjCSelectorArgumentAST::firstToken() const
{
if (name_token)
return name_token;
@@ -2764,7 +2764,7 @@ unsigned ObjCSelectorArgumentAST::firstToken() const
}
/** \generated */
-unsigned ObjCSelectorArgumentAST::lastToken() const
+int ObjCSelectorArgumentAST::lastToken() const
{
if (colon_token)
return colon_token + 1;
@@ -2774,14 +2774,14 @@ unsigned ObjCSelectorArgumentAST::lastToken() const
}
/** \generated */
-unsigned ObjCSelectorExpressionAST::firstToken() const
+int ObjCSelectorExpressionAST::firstToken() const
{
if (selector_token)
return selector_token;
if (lparen_token)
return lparen_token;
if (selector)
- if (unsigned candidate = selector->firstToken())
+ if (int candidate = selector->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -2789,12 +2789,12 @@ unsigned ObjCSelectorExpressionAST::firstToken() const
}
/** \generated */
-unsigned ObjCSelectorExpressionAST::lastToken() const
+int ObjCSelectorExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (selector)
- if (unsigned candidate = selector->lastToken())
+ if (int candidate = selector->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -2804,33 +2804,33 @@ unsigned ObjCSelectorExpressionAST::lastToken() const
}
/** \generated */
-unsigned ObjCSynchronizedStatementAST::firstToken() const
+int ObjCSynchronizedStatementAST::firstToken() const
{
if (synchronized_token)
return synchronized_token;
if (lparen_token)
return lparen_token;
if (synchronized_object)
- if (unsigned candidate = synchronized_object->firstToken())
+ if (int candidate = synchronized_object->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ObjCSynchronizedStatementAST::lastToken() const
+int ObjCSynchronizedStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (synchronized_object)
- if (unsigned candidate = synchronized_object->lastToken())
+ if (int candidate = synchronized_object->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -2840,12 +2840,12 @@ unsigned ObjCSynchronizedStatementAST::lastToken() const
}
/** \generated */
-unsigned ObjCSynthesizedPropertiesDeclarationAST::firstToken() const
+int ObjCSynthesizedPropertiesDeclarationAST::firstToken() const
{
if (synthesized_token)
return synthesized_token;
if (property_identifier_list)
- if (unsigned candidate = property_identifier_list->firstToken())
+ if (int candidate = property_identifier_list->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -2853,12 +2853,12 @@ unsigned ObjCSynthesizedPropertiesDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCSynthesizedPropertiesDeclarationAST::lastToken() const
+int ObjCSynthesizedPropertiesDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (property_identifier_list)
- if (unsigned candidate = property_identifier_list->lastToken())
+ if (int candidate = property_identifier_list->lastToken())
return candidate;
if (synthesized_token)
return synthesized_token + 1;
@@ -2866,7 +2866,7 @@ unsigned ObjCSynthesizedPropertiesDeclarationAST::lastToken() const
}
/** \generated */
-unsigned ObjCSynthesizedPropertyAST::firstToken() const
+int ObjCSynthesizedPropertyAST::firstToken() const
{
if (property_identifier_token)
return property_identifier_token;
@@ -2878,7 +2878,7 @@ unsigned ObjCSynthesizedPropertyAST::firstToken() const
}
/** \generated */
-unsigned ObjCSynthesizedPropertyAST::lastToken() const
+int ObjCSynthesizedPropertyAST::lastToken() const
{
if (alias_identifier_token)
return alias_identifier_token + 1;
@@ -2890,14 +2890,14 @@ unsigned ObjCSynthesizedPropertyAST::lastToken() const
}
/** \generated */
-unsigned ObjCTypeNameAST::firstToken() const
+int ObjCTypeNameAST::firstToken() const
{
if (lparen_token)
return lparen_token;
if (type_qualifier_token)
return type_qualifier_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -2905,12 +2905,12 @@ unsigned ObjCTypeNameAST::firstToken() const
}
/** \generated */
-unsigned ObjCTypeNameAST::lastToken() const
+int ObjCTypeNameAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (type_qualifier_token)
return type_qualifier_token + 1;
@@ -2920,7 +2920,7 @@ unsigned ObjCTypeNameAST::lastToken() const
}
/** \generated */
-unsigned ObjCVisibilityDeclarationAST::firstToken() const
+int ObjCVisibilityDeclarationAST::firstToken() const
{
if (visibility_token)
return visibility_token;
@@ -2928,7 +2928,7 @@ unsigned ObjCVisibilityDeclarationAST::firstToken() const
}
/** \generated */
-unsigned ObjCVisibilityDeclarationAST::lastToken() const
+int ObjCVisibilityDeclarationAST::lastToken() const
{
if (visibility_token)
return visibility_token + 1;
@@ -2936,7 +2936,7 @@ unsigned ObjCVisibilityDeclarationAST::lastToken() const
}
/** \generated */
-unsigned OperatorAST::firstToken() const
+int OperatorAST::firstToken() const
{
if (op_token)
return op_token;
@@ -2948,7 +2948,7 @@ unsigned OperatorAST::firstToken() const
}
/** \generated */
-unsigned OperatorAST::lastToken() const
+int OperatorAST::lastToken() const
{
if (close_token)
return close_token + 1;
@@ -2960,21 +2960,21 @@ unsigned OperatorAST::lastToken() const
}
/** \generated */
-unsigned OperatorFunctionIdAST::firstToken() const
+int OperatorFunctionIdAST::firstToken() const
{
if (operator_token)
return operator_token;
if (op)
- if (unsigned candidate = op->firstToken())
+ if (int candidate = op->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned OperatorFunctionIdAST::lastToken() const
+int OperatorFunctionIdAST::lastToken() const
{
if (op)
- if (unsigned candidate = op->lastToken())
+ if (int candidate = op->lastToken())
return candidate;
if (operator_token)
return operator_token + 1;
@@ -2982,44 +2982,44 @@ unsigned OperatorFunctionIdAST::lastToken() const
}
/** \generated */
-unsigned ParameterDeclarationAST::firstToken() const
+int ParameterDeclarationAST::firstToken() const
{
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ParameterDeclarationAST::lastToken() const
+int ParameterDeclarationAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned ParameterDeclarationClauseAST::firstToken() const
+int ParameterDeclarationClauseAST::firstToken() const
{
if (parameter_declaration_list)
- if (unsigned candidate = parameter_declaration_list->firstToken())
+ if (int candidate = parameter_declaration_list->firstToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token;
@@ -3027,32 +3027,32 @@ unsigned ParameterDeclarationClauseAST::firstToken() const
}
/** \generated */
-unsigned ParameterDeclarationClauseAST::lastToken() const
+int ParameterDeclarationClauseAST::lastToken() const
{
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
if (parameter_declaration_list)
- if (unsigned candidate = parameter_declaration_list->lastToken())
+ if (int candidate = parameter_declaration_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned PointerAST::firstToken() const
+int PointerAST::firstToken() const
{
if (star_token)
return star_token;
if (cv_qualifier_list)
- if (unsigned candidate = cv_qualifier_list->firstToken())
+ if (int candidate = cv_qualifier_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned PointerAST::lastToken() const
+int PointerAST::lastToken() const
{
if (cv_qualifier_list)
- if (unsigned candidate = cv_qualifier_list->lastToken())
+ if (int candidate = cv_qualifier_list->lastToken())
return candidate;
if (star_token)
return star_token + 1;
@@ -3060,17 +3060,17 @@ unsigned PointerAST::lastToken() const
}
/** \generated */
-unsigned PointerToMemberAST::firstToken() const
+int PointerToMemberAST::firstToken() const
{
if (global_scope_token)
return global_scope_token;
if (nested_name_specifier_list)
- if (unsigned candidate = nested_name_specifier_list->firstToken())
+ if (int candidate = nested_name_specifier_list->firstToken())
return candidate;
if (star_token)
return star_token;
if (cv_qualifier_list)
- if (unsigned candidate = cv_qualifier_list->firstToken())
+ if (int candidate = cv_qualifier_list->firstToken())
return candidate;
if (ref_qualifier_token)
return ref_qualifier_token;
@@ -3078,17 +3078,17 @@ unsigned PointerToMemberAST::firstToken() const
}
/** \generated */
-unsigned PointerToMemberAST::lastToken() const
+int PointerToMemberAST::lastToken() const
{
if (ref_qualifier_token)
return ref_qualifier_token + 1;
if (cv_qualifier_list)
- if (unsigned candidate = cv_qualifier_list->lastToken())
+ if (int candidate = cv_qualifier_list->lastToken())
return candidate;
if (star_token)
return star_token + 1;
if (nested_name_specifier_list)
- if (unsigned candidate = nested_name_specifier_list->lastToken())
+ if (int candidate = nested_name_specifier_list->lastToken())
return candidate;
if (global_scope_token)
return global_scope_token + 1;
@@ -3096,10 +3096,10 @@ unsigned PointerToMemberAST::lastToken() const
}
/** \generated */
-unsigned PostIncrDecrAST::firstToken() const
+int PostIncrDecrAST::firstToken() const
{
if (base_expression)
- if (unsigned candidate = base_expression->firstToken())
+ if (int candidate = base_expression->firstToken())
return candidate;
if (incr_decr_token)
return incr_decr_token;
@@ -3107,25 +3107,25 @@ unsigned PostIncrDecrAST::firstToken() const
}
/** \generated */
-unsigned PostIncrDecrAST::lastToken() const
+int PostIncrDecrAST::lastToken() const
{
if (incr_decr_token)
return incr_decr_token + 1;
if (base_expression)
- if (unsigned candidate = base_expression->lastToken())
+ if (int candidate = base_expression->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned QtEnumDeclarationAST::firstToken() const
+int QtEnumDeclarationAST::firstToken() const
{
if (enum_specifier_token)
return enum_specifier_token;
if (lparen_token)
return lparen_token;
if (enumerator_list)
- if (unsigned candidate = enumerator_list->firstToken())
+ if (int candidate = enumerator_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3133,12 +3133,12 @@ unsigned QtEnumDeclarationAST::firstToken() const
}
/** \generated */
-unsigned QtEnumDeclarationAST::lastToken() const
+int QtEnumDeclarationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (enumerator_list)
- if (unsigned candidate = enumerator_list->lastToken())
+ if (int candidate = enumerator_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3148,14 +3148,14 @@ unsigned QtEnumDeclarationAST::lastToken() const
}
/** \generated */
-unsigned QtFlagsDeclarationAST::firstToken() const
+int QtFlagsDeclarationAST::firstToken() const
{
if (flags_specifier_token)
return flags_specifier_token;
if (lparen_token)
return lparen_token;
if (flag_enums_list)
- if (unsigned candidate = flag_enums_list->firstToken())
+ if (int candidate = flag_enums_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3163,12 +3163,12 @@ unsigned QtFlagsDeclarationAST::firstToken() const
}
/** \generated */
-unsigned QtFlagsDeclarationAST::lastToken() const
+int QtFlagsDeclarationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (flag_enums_list)
- if (unsigned candidate = flag_enums_list->lastToken())
+ if (int candidate = flag_enums_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3178,38 +3178,38 @@ unsigned QtFlagsDeclarationAST::lastToken() const
}
/** \generated */
-unsigned QtInterfaceNameAST::firstToken() const
+int QtInterfaceNameAST::firstToken() const
{
if (interface_name)
- if (unsigned candidate = interface_name->firstToken())
+ if (int candidate = interface_name->firstToken())
return candidate;
if (constraint_list)
- if (unsigned candidate = constraint_list->firstToken())
+ if (int candidate = constraint_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned QtInterfaceNameAST::lastToken() const
+int QtInterfaceNameAST::lastToken() const
{
if (constraint_list)
- if (unsigned candidate = constraint_list->lastToken())
+ if (int candidate = constraint_list->lastToken())
return candidate;
if (interface_name)
- if (unsigned candidate = interface_name->lastToken())
+ if (int candidate = interface_name->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned QtInterfacesDeclarationAST::firstToken() const
+int QtInterfacesDeclarationAST::firstToken() const
{
if (interfaces_token)
return interfaces_token;
if (lparen_token)
return lparen_token;
if (interface_name_list)
- if (unsigned candidate = interface_name_list->firstToken())
+ if (int candidate = interface_name_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3217,12 +3217,12 @@ unsigned QtInterfacesDeclarationAST::firstToken() const
}
/** \generated */
-unsigned QtInterfacesDeclarationAST::lastToken() const
+int QtInterfacesDeclarationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (interface_name_list)
- if (unsigned candidate = interface_name_list->lastToken())
+ if (int candidate = interface_name_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3232,14 +3232,14 @@ unsigned QtInterfacesDeclarationAST::lastToken() const
}
/** \generated */
-unsigned QtMemberDeclarationAST::firstToken() const
+int QtMemberDeclarationAST::firstToken() const
{
if (q_token)
return q_token;
if (lparen_token)
return lparen_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3247,12 +3247,12 @@ unsigned QtMemberDeclarationAST::firstToken() const
}
/** \generated */
-unsigned QtMemberDeclarationAST::lastToken() const
+int QtMemberDeclarationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3262,14 +3262,14 @@ unsigned QtMemberDeclarationAST::lastToken() const
}
/** \generated */
-unsigned QtMethodAST::firstToken() const
+int QtMethodAST::firstToken() const
{
if (method_token)
return method_token;
if (lparen_token)
return lparen_token;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3277,12 +3277,12 @@ unsigned QtMethodAST::firstToken() const
}
/** \generated */
-unsigned QtMethodAST::lastToken() const
+int QtMethodAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3292,7 +3292,7 @@ unsigned QtMethodAST::lastToken() const
}
/** \generated */
-unsigned QtObjectTagAST::firstToken() const
+int QtObjectTagAST::firstToken() const
{
if (q_object_token)
return q_object_token;
@@ -3300,7 +3300,7 @@ unsigned QtObjectTagAST::firstToken() const
}
/** \generated */
-unsigned QtObjectTagAST::lastToken() const
+int QtObjectTagAST::lastToken() const
{
if (q_object_token)
return q_object_token + 1;
@@ -3308,7 +3308,7 @@ unsigned QtObjectTagAST::lastToken() const
}
/** \generated */
-unsigned QtPrivateSlotAST::firstToken() const
+int QtPrivateSlotAST::firstToken() const
{
if (q_private_slot_token)
return q_private_slot_token;
@@ -3323,10 +3323,10 @@ unsigned QtPrivateSlotAST::firstToken() const
if (comma_token)
return comma_token;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3334,15 +3334,15 @@ unsigned QtPrivateSlotAST::firstToken() const
}
/** \generated */
-unsigned QtPrivateSlotAST::lastToken() const
+int QtPrivateSlotAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (comma_token)
return comma_token + 1;
@@ -3360,25 +3360,25 @@ unsigned QtPrivateSlotAST::lastToken() const
}
/** \generated */
-unsigned QtPropertyDeclarationAST::firstToken() const
+int QtPropertyDeclarationAST::firstToken() const
{
if (property_specifier_token)
return property_specifier_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (comma_token)
return comma_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
if (property_name)
- if (unsigned candidate = property_name->firstToken())
+ if (int candidate = property_name->firstToken())
return candidate;
if (property_declaration_item_list)
- if (unsigned candidate = property_declaration_item_list->firstToken())
+ if (int candidate = property_declaration_item_list->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3386,23 +3386,23 @@ unsigned QtPropertyDeclarationAST::firstToken() const
}
/** \generated */
-unsigned QtPropertyDeclarationAST::lastToken() const
+int QtPropertyDeclarationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (property_declaration_item_list)
- if (unsigned candidate = property_declaration_item_list->lastToken())
+ if (int candidate = property_declaration_item_list->lastToken())
return candidate;
if (property_name)
- if (unsigned candidate = property_name->lastToken())
+ if (int candidate = property_name->lastToken())
return candidate;
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (comma_token)
return comma_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3412,21 +3412,21 @@ unsigned QtPropertyDeclarationAST::lastToken() const
}
/** \generated */
-unsigned QtPropertyDeclarationItemAST::firstToken() const
+int QtPropertyDeclarationItemAST::firstToken() const
{
if (item_name_token)
return item_name_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned QtPropertyDeclarationItemAST::lastToken() const
+int QtPropertyDeclarationItemAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (item_name_token)
return item_name_token + 1;
@@ -3434,27 +3434,27 @@ unsigned QtPropertyDeclarationItemAST::lastToken() const
}
/** \generated */
-unsigned QualifiedNameAST::firstToken() const
+int QualifiedNameAST::firstToken() const
{
if (global_scope_token)
return global_scope_token;
if (nested_name_specifier_list)
- if (unsigned candidate = nested_name_specifier_list->firstToken())
+ if (int candidate = nested_name_specifier_list->firstToken())
return candidate;
if (unqualified_name)
- if (unsigned candidate = unqualified_name->firstToken())
+ if (int candidate = unqualified_name->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned QualifiedNameAST::lastToken() const
+int QualifiedNameAST::lastToken() const
{
if (unqualified_name)
- if (unsigned candidate = unqualified_name->lastToken())
+ if (int candidate = unqualified_name->lastToken())
return candidate;
if (nested_name_specifier_list)
- if (unsigned candidate = nested_name_specifier_list->lastToken())
+ if (int candidate = nested_name_specifier_list->lastToken())
return candidate;
if (global_scope_token)
return global_scope_token + 1;
@@ -3462,7 +3462,7 @@ unsigned QualifiedNameAST::lastToken() const
}
/** \generated */
-unsigned ReferenceAST::firstToken() const
+int ReferenceAST::firstToken() const
{
if (reference_token)
return reference_token;
@@ -3470,7 +3470,7 @@ unsigned ReferenceAST::firstToken() const
}
/** \generated */
-unsigned ReferenceAST::lastToken() const
+int ReferenceAST::lastToken() const
{
if (reference_token)
return reference_token + 1;
@@ -3478,12 +3478,12 @@ unsigned ReferenceAST::lastToken() const
}
/** \generated */
-unsigned ReturnStatementAST::firstToken() const
+int ReturnStatementAST::firstToken() const
{
if (return_token)
return return_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -3491,12 +3491,12 @@ unsigned ReturnStatementAST::firstToken() const
}
/** \generated */
-unsigned ReturnStatementAST::lastToken() const
+int ReturnStatementAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (return_token)
return return_token + 1;
@@ -3504,15 +3504,15 @@ unsigned ReturnStatementAST::lastToken() const
}
/** \generated */
-unsigned SimpleDeclarationAST::firstToken() const
+int SimpleDeclarationAST::firstToken() const
{
if (qt_invokable_token)
return qt_invokable_token;
if (decl_specifier_list)
- if (unsigned candidate = decl_specifier_list->firstToken())
+ if (int candidate = decl_specifier_list->firstToken())
return candidate;
if (declarator_list)
- if (unsigned candidate = declarator_list->firstToken())
+ if (int candidate = declarator_list->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -3520,15 +3520,15 @@ unsigned SimpleDeclarationAST::firstToken() const
}
/** \generated */
-unsigned SimpleDeclarationAST::lastToken() const
+int SimpleDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (declarator_list)
- if (unsigned candidate = declarator_list->lastToken())
+ if (int candidate = declarator_list->lastToken())
return candidate;
if (decl_specifier_list)
- if (unsigned candidate = decl_specifier_list->lastToken())
+ if (int candidate = decl_specifier_list->lastToken())
return candidate;
if (qt_invokable_token)
return qt_invokable_token + 1;
@@ -3536,7 +3536,7 @@ unsigned SimpleDeclarationAST::lastToken() const
}
/** \generated */
-unsigned SimpleNameAST::firstToken() const
+int SimpleNameAST::firstToken() const
{
if (identifier_token)
return identifier_token;
@@ -3544,7 +3544,7 @@ unsigned SimpleNameAST::firstToken() const
}
/** \generated */
-unsigned SimpleNameAST::lastToken() const
+int SimpleNameAST::lastToken() const
{
if (identifier_token)
return identifier_token + 1;
@@ -3552,7 +3552,7 @@ unsigned SimpleNameAST::lastToken() const
}
/** \generated */
-unsigned SimpleSpecifierAST::firstToken() const
+int SimpleSpecifierAST::firstToken() const
{
if (specifier_token)
return specifier_token;
@@ -3560,7 +3560,7 @@ unsigned SimpleSpecifierAST::firstToken() const
}
/** \generated */
-unsigned SimpleSpecifierAST::lastToken() const
+int SimpleSpecifierAST::lastToken() const
{
if (specifier_token)
return specifier_token + 1;
@@ -3568,7 +3568,7 @@ unsigned SimpleSpecifierAST::lastToken() const
}
/** \generated */
-unsigned SizeofExpressionAST::firstToken() const
+int SizeofExpressionAST::firstToken() const
{
if (sizeof_token)
return sizeof_token;
@@ -3577,7 +3577,7 @@ unsigned SizeofExpressionAST::firstToken() const
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3585,12 +3585,12 @@ unsigned SizeofExpressionAST::firstToken() const
}
/** \generated */
-unsigned SizeofExpressionAST::lastToken() const
+int SizeofExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3602,21 +3602,21 @@ unsigned SizeofExpressionAST::lastToken() const
}
/** \generated */
-unsigned StringLiteralAST::firstToken() const
+int StringLiteralAST::firstToken() const
{
if (literal_token)
return literal_token;
if (next)
- if (unsigned candidate = next->firstToken())
+ if (int candidate = next->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned StringLiteralAST::lastToken() const
+int StringLiteralAST::lastToken() const
{
if (next)
- if (unsigned candidate = next->lastToken())
+ if (int candidate = next->lastToken())
return candidate;
if (literal_token)
return literal_token + 1;
@@ -3624,33 +3624,33 @@ unsigned StringLiteralAST::lastToken() const
}
/** \generated */
-unsigned SwitchStatementAST::firstToken() const
+int SwitchStatementAST::firstToken() const
{
if (switch_token)
return switch_token;
if (lparen_token)
return lparen_token;
if (condition)
- if (unsigned candidate = condition->firstToken())
+ if (int candidate = condition->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned SwitchStatementAST::lastToken() const
+int SwitchStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (condition)
- if (unsigned candidate = condition->lastToken())
+ if (int candidate = condition->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3660,7 +3660,7 @@ unsigned SwitchStatementAST::lastToken() const
}
/** \generated */
-unsigned TemplateDeclarationAST::firstToken() const
+int TemplateDeclarationAST::firstToken() const
{
if (export_token)
return export_token;
@@ -3669,26 +3669,26 @@ unsigned TemplateDeclarationAST::firstToken() const
if (less_token)
return less_token;
if (template_parameter_list)
- if (unsigned candidate = template_parameter_list->firstToken())
+ if (int candidate = template_parameter_list->firstToken())
return candidate;
if (greater_token)
return greater_token;
if (declaration)
- if (unsigned candidate = declaration->firstToken())
+ if (int candidate = declaration->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TemplateDeclarationAST::lastToken() const
+int TemplateDeclarationAST::lastToken() const
{
if (declaration)
- if (unsigned candidate = declaration->lastToken())
+ if (int candidate = declaration->lastToken())
return candidate;
if (greater_token)
return greater_token + 1;
if (template_parameter_list)
- if (unsigned candidate = template_parameter_list->lastToken())
+ if (int candidate = template_parameter_list->lastToken())
return candidate;
if (less_token)
return less_token + 1;
@@ -3700,7 +3700,7 @@ unsigned TemplateDeclarationAST::lastToken() const
}
/** \generated */
-unsigned TemplateIdAST::firstToken() const
+int TemplateIdAST::firstToken() const
{
if (template_token)
return template_token;
@@ -3709,7 +3709,7 @@ unsigned TemplateIdAST::firstToken() const
if (less_token)
return less_token;
if (template_argument_list)
- if (unsigned candidate = template_argument_list->firstToken())
+ if (int candidate = template_argument_list->firstToken())
return candidate;
if (greater_token)
return greater_token;
@@ -3717,12 +3717,12 @@ unsigned TemplateIdAST::firstToken() const
}
/** \generated */
-unsigned TemplateIdAST::lastToken() const
+int TemplateIdAST::lastToken() const
{
if (greater_token)
return greater_token + 1;
if (template_argument_list)
- if (unsigned candidate = template_argument_list->lastToken())
+ if (int candidate = template_argument_list->lastToken())
return candidate;
if (less_token)
return less_token + 1;
@@ -3734,14 +3734,14 @@ unsigned TemplateIdAST::lastToken() const
}
/** \generated */
-unsigned TemplateTypeParameterAST::firstToken() const
+int TemplateTypeParameterAST::firstToken() const
{
if (template_token)
return template_token;
if (less_token)
return less_token;
if (template_parameter_list)
- if (unsigned candidate = template_parameter_list->firstToken())
+ if (int candidate = template_parameter_list->firstToken())
return candidate;
if (greater_token)
return greater_token;
@@ -3750,26 +3750,26 @@ unsigned TemplateTypeParameterAST::firstToken() const
if (dot_dot_dot_token)
return dot_dot_dot_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TemplateTypeParameterAST::lastToken() const
+int TemplateTypeParameterAST::lastToken() const
{
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
@@ -3778,7 +3778,7 @@ unsigned TemplateTypeParameterAST::lastToken() const
if (greater_token)
return greater_token + 1;
if (template_parameter_list)
- if (unsigned candidate = template_parameter_list->lastToken())
+ if (int candidate = template_parameter_list->lastToken())
return candidate;
if (less_token)
return less_token + 1;
@@ -3788,7 +3788,7 @@ unsigned TemplateTypeParameterAST::lastToken() const
}
/** \generated */
-unsigned ThisExpressionAST::firstToken() const
+int ThisExpressionAST::firstToken() const
{
if (this_token)
return this_token;
@@ -3796,7 +3796,7 @@ unsigned ThisExpressionAST::firstToken() const
}
/** \generated */
-unsigned ThisExpressionAST::lastToken() const
+int ThisExpressionAST::lastToken() const
{
if (this_token)
return this_token + 1;
@@ -3804,21 +3804,21 @@ unsigned ThisExpressionAST::lastToken() const
}
/** \generated */
-unsigned ThrowExpressionAST::firstToken() const
+int ThrowExpressionAST::firstToken() const
{
if (throw_token)
return throw_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned ThrowExpressionAST::lastToken() const
+int ThrowExpressionAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (throw_token)
return throw_token + 1;
@@ -3826,33 +3826,33 @@ unsigned ThrowExpressionAST::lastToken() const
}
/** \generated */
-unsigned TrailingReturnTypeAST::firstToken() const
+int TrailingReturnTypeAST::firstToken() const
{
if (arrow_token)
return arrow_token;
if (attributes)
- if (unsigned candidate = attributes->firstToken())
+ if (int candidate = attributes->firstToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TrailingReturnTypeAST::lastToken() const
+int TrailingReturnTypeAST::lastToken() const
{
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (attributes)
- if (unsigned candidate = attributes->lastToken())
+ if (int candidate = attributes->lastToken())
return candidate;
if (arrow_token)
return arrow_token + 1;
@@ -3860,45 +3860,45 @@ unsigned TrailingReturnTypeAST::lastToken() const
}
/** \generated */
-unsigned TranslationUnitAST::firstToken() const
+int TranslationUnitAST::firstToken() const
{
if (declaration_list)
- if (unsigned candidate = declaration_list->firstToken())
+ if (int candidate = declaration_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TranslationUnitAST::lastToken() const
+int TranslationUnitAST::lastToken() const
{
if (declaration_list)
- if (unsigned candidate = declaration_list->lastToken())
+ if (int candidate = declaration_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned TryBlockStatementAST::firstToken() const
+int TryBlockStatementAST::firstToken() const
{
if (try_token)
return try_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
if (catch_clause_list)
- if (unsigned candidate = catch_clause_list->firstToken())
+ if (int candidate = catch_clause_list->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TryBlockStatementAST::lastToken() const
+int TryBlockStatementAST::lastToken() const
{
if (catch_clause_list)
- if (unsigned candidate = catch_clause_list->lastToken())
+ if (int candidate = catch_clause_list->lastToken())
return candidate;
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (try_token)
return try_token + 1;
@@ -3906,62 +3906,62 @@ unsigned TryBlockStatementAST::lastToken() const
}
/** \generated */
-unsigned TypeConstructorCallAST::firstToken() const
+int TypeConstructorCallAST::firstToken() const
{
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TypeConstructorCallAST::lastToken() const
+int TypeConstructorCallAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned TypeIdAST::firstToken() const
+int TypeIdAST::firstToken() const
{
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TypeIdAST::lastToken() const
+int TypeIdAST::lastToken() const
{
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned TypeidExpressionAST::firstToken() const
+int TypeidExpressionAST::firstToken() const
{
if (typeid_token)
return typeid_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -3969,12 +3969,12 @@ unsigned TypeidExpressionAST::firstToken() const
}
/** \generated */
-unsigned TypeidExpressionAST::lastToken() const
+int TypeidExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -3984,27 +3984,27 @@ unsigned TypeidExpressionAST::lastToken() const
}
/** \generated */
-unsigned TypenameCallExpressionAST::firstToken() const
+int TypenameCallExpressionAST::firstToken() const
{
if (typename_token)
return typename_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TypenameCallExpressionAST::lastToken() const
+int TypenameCallExpressionAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (typename_token)
return typename_token + 1;
@@ -4012,33 +4012,33 @@ unsigned TypenameCallExpressionAST::lastToken() const
}
/** \generated */
-unsigned TypenameTypeParameterAST::firstToken() const
+int TypenameTypeParameterAST::firstToken() const
{
if (classkey_token)
return classkey_token;
if (dot_dot_dot_token)
return dot_dot_dot_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (type_id)
- if (unsigned candidate = type_id->firstToken())
+ if (int candidate = type_id->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned TypenameTypeParameterAST::lastToken() const
+int TypenameTypeParameterAST::lastToken() const
{
if (type_id)
- if (unsigned candidate = type_id->lastToken())
+ if (int candidate = type_id->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (dot_dot_dot_token)
return dot_dot_dot_token + 1;
@@ -4048,14 +4048,14 @@ unsigned TypenameTypeParameterAST::lastToken() const
}
/** \generated */
-unsigned TypeofSpecifierAST::firstToken() const
+int TypeofSpecifierAST::firstToken() const
{
if (typeof_token)
return typeof_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -4063,12 +4063,12 @@ unsigned TypeofSpecifierAST::firstToken() const
}
/** \generated */
-unsigned TypeofSpecifierAST::lastToken() const
+int TypeofSpecifierAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4078,21 +4078,21 @@ unsigned TypeofSpecifierAST::lastToken() const
}
/** \generated */
-unsigned UnaryExpressionAST::firstToken() const
+int UnaryExpressionAST::firstToken() const
{
if (unary_op_token)
return unary_op_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned UnaryExpressionAST::lastToken() const
+int UnaryExpressionAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (unary_op_token)
return unary_op_token + 1;
@@ -4100,14 +4100,14 @@ unsigned UnaryExpressionAST::lastToken() const
}
/** \generated */
-unsigned UsingAST::firstToken() const
+int UsingAST::firstToken() const
{
if (using_token)
return using_token;
if (typename_token)
return typename_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -4115,12 +4115,12 @@ unsigned UsingAST::firstToken() const
}
/** \generated */
-unsigned UsingAST::lastToken() const
+int UsingAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (typename_token)
return typename_token + 1;
@@ -4130,14 +4130,14 @@ unsigned UsingAST::lastToken() const
}
/** \generated */
-unsigned UsingDirectiveAST::firstToken() const
+int UsingDirectiveAST::firstToken() const
{
if (using_token)
return using_token;
if (namespace_token)
return namespace_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -4145,12 +4145,12 @@ unsigned UsingDirectiveAST::firstToken() const
}
/** \generated */
-unsigned UsingDirectiveAST::lastToken() const
+int UsingDirectiveAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (namespace_token)
return namespace_token + 1;
@@ -4160,33 +4160,33 @@ unsigned UsingDirectiveAST::lastToken() const
}
/** \generated */
-unsigned WhileStatementAST::firstToken() const
+int WhileStatementAST::firstToken() const
{
if (while_token)
return while_token;
if (lparen_token)
return lparen_token;
if (condition)
- if (unsigned candidate = condition->firstToken())
+ if (int candidate = condition->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned WhileStatementAST::lastToken() const
+int WhileStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (condition)
- if (unsigned candidate = condition->lastToken())
+ if (int candidate = condition->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4196,14 +4196,14 @@ unsigned WhileStatementAST::lastToken() const
}
/** \generated */
-unsigned GnuAttributeSpecifierAST::lastToken() const
+int GnuAttributeSpecifierAST::lastToken() const
{
if (second_rparen_token)
return second_rparen_token + 1;
if (first_rparen_token)
return first_rparen_token + 1;
if (attribute_list)
- if (unsigned candidate = attribute_list->lastToken())
+ if (int candidate = attribute_list->lastToken())
return candidate;
if (second_lparen_token)
return second_lparen_token + 1;
@@ -4215,7 +4215,7 @@ unsigned GnuAttributeSpecifierAST::lastToken() const
}
/** \generated */
-unsigned PointerLiteralAST::firstToken() const
+int PointerLiteralAST::firstToken() const
{
if (literal_token)
return literal_token;
@@ -4223,7 +4223,7 @@ unsigned PointerLiteralAST::firstToken() const
}
/** \generated */
-unsigned PointerLiteralAST::lastToken() const
+int PointerLiteralAST::lastToken() const
{
if (literal_token)
return literal_token + 1;
@@ -4231,14 +4231,14 @@ unsigned PointerLiteralAST::lastToken() const
}
/** \generated */
-unsigned NoExceptSpecificationAST::firstToken() const
+int NoExceptSpecificationAST::firstToken() const
{
if (noexcept_token)
return noexcept_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -4246,12 +4246,12 @@ unsigned NoExceptSpecificationAST::firstToken() const
}
/** \generated */
-unsigned NoExceptSpecificationAST::lastToken() const
+int NoExceptSpecificationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4261,19 +4261,19 @@ unsigned NoExceptSpecificationAST::lastToken() const
}
/** \generated */
-unsigned StaticAssertDeclarationAST::firstToken() const
+int StaticAssertDeclarationAST::firstToken() const
{
if (static_assert_token)
return static_assert_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (comma_token)
return comma_token;
if (string_literal)
- if (unsigned candidate = string_literal->firstToken())
+ if (int candidate = string_literal->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -4283,19 +4283,19 @@ unsigned StaticAssertDeclarationAST::firstToken() const
}
/** \generated */
-unsigned StaticAssertDeclarationAST::lastToken() const
+int StaticAssertDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (rparen_token)
return rparen_token + 1;
if (string_literal)
- if (unsigned candidate = string_literal->lastToken())
+ if (int candidate = string_literal->lastToken())
return candidate;
if (comma_token)
return comma_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4305,14 +4305,14 @@ unsigned StaticAssertDeclarationAST::lastToken() const
}
/** \generated */
-unsigned DecltypeSpecifierAST::firstToken() const
+int DecltypeSpecifierAST::firstToken() const
{
if (decltype_token)
return decltype_token;
if (lparen_token)
return lparen_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -4320,12 +4320,12 @@ unsigned DecltypeSpecifierAST::firstToken() const
}
/** \generated */
-unsigned DecltypeSpecifierAST::lastToken() const
+int DecltypeSpecifierAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4335,49 +4335,49 @@ unsigned DecltypeSpecifierAST::lastToken() const
}
/** \generated */
-unsigned RangeBasedForStatementAST::firstToken() const
+int RangeBasedForStatementAST::firstToken() const
{
if (for_token)
return for_token;
if (lparen_token)
return lparen_token;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->firstToken())
+ if (int candidate = type_specifier_list->firstToken())
return candidate;
if (declarator)
- if (unsigned candidate = declarator->firstToken())
+ if (int candidate = declarator->firstToken())
return candidate;
if (colon_token)
return colon_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
if (statement)
- if (unsigned candidate = statement->firstToken())
+ if (int candidate = statement->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned RangeBasedForStatementAST::lastToken() const
+int RangeBasedForStatementAST::lastToken() const
{
if (statement)
- if (unsigned candidate = statement->lastToken())
+ if (int candidate = statement->lastToken())
return candidate;
if (rparen_token)
return rparen_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (colon_token)
return colon_token + 1;
if (declarator)
- if (unsigned candidate = declarator->lastToken())
+ if (int candidate = declarator->lastToken())
return candidate;
if (type_specifier_list)
- if (unsigned candidate = type_specifier_list->lastToken())
+ if (int candidate = type_specifier_list->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4387,14 +4387,14 @@ unsigned RangeBasedForStatementAST::lastToken() const
}
/** \generated */
-unsigned AlignofExpressionAST::firstToken() const
+int AlignofExpressionAST::firstToken() const
{
if (alignof_token)
return alignof_token;
if (lparen_token)
return lparen_token;
if (typeId)
- if (unsigned candidate = typeId->firstToken())
+ if (int candidate = typeId->firstToken())
return candidate;
if (rparen_token)
return rparen_token;
@@ -4402,12 +4402,12 @@ unsigned AlignofExpressionAST::firstToken() const
}
/** \generated */
-unsigned AlignofExpressionAST::lastToken() const
+int AlignofExpressionAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (typeId)
- if (unsigned candidate = typeId->lastToken())
+ if (int candidate = typeId->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4417,17 +4417,17 @@ unsigned AlignofExpressionAST::lastToken() const
}
/** \generated */
-unsigned AliasDeclarationAST::firstToken() const
+int AliasDeclarationAST::firstToken() const
{
if (using_token)
return using_token;
if (name)
- if (unsigned candidate = name->firstToken())
+ if (int candidate = name->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (typeId)
- if (unsigned candidate = typeId->firstToken())
+ if (int candidate = typeId->firstToken())
return candidate;
if (semicolon_token)
return semicolon_token;
@@ -4435,17 +4435,17 @@ unsigned AliasDeclarationAST::firstToken() const
}
/** \generated */
-unsigned AliasDeclarationAST::lastToken() const
+int AliasDeclarationAST::lastToken() const
{
if (semicolon_token)
return semicolon_token + 1;
if (typeId)
- if (unsigned candidate = typeId->lastToken())
+ if (int candidate = typeId->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
if (name)
- if (unsigned candidate = name->lastToken())
+ if (int candidate = name->lastToken())
return candidate;
if (using_token)
return using_token + 1;
@@ -4453,40 +4453,40 @@ unsigned AliasDeclarationAST::lastToken() const
}
/** \generated */
-unsigned DesignatedInitializerAST::firstToken() const
+int DesignatedInitializerAST::firstToken() const
{
if (designator_list)
- if (unsigned candidate = designator_list->firstToken())
+ if (int candidate = designator_list->firstToken())
return candidate;
if (equal_token)
return equal_token;
if (initializer)
- if (unsigned candidate = initializer->firstToken())
+ if (int candidate = initializer->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned DesignatedInitializerAST::lastToken() const
+int DesignatedInitializerAST::lastToken() const
{
if (initializer)
- if (unsigned candidate = initializer->lastToken())
+ if (int candidate = initializer->lastToken())
return candidate;
if (equal_token)
return equal_token + 1;
if (designator_list)
- if (unsigned candidate = designator_list->lastToken())
+ if (int candidate = designator_list->lastToken())
return candidate;
return 1;
}
/** \generated */
-unsigned BracketDesignatorAST::firstToken() const
+int BracketDesignatorAST::firstToken() const
{
if (lbracket_token)
return lbracket_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
if (rbracket_token)
return rbracket_token;
@@ -4494,12 +4494,12 @@ unsigned BracketDesignatorAST::firstToken() const
}
/** \generated */
-unsigned BracketDesignatorAST::lastToken() const
+int BracketDesignatorAST::lastToken() const
{
if (rbracket_token)
return rbracket_token + 1;
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (lbracket_token)
return lbracket_token + 1;
@@ -4507,7 +4507,7 @@ unsigned BracketDesignatorAST::lastToken() const
}
/** \generated */
-unsigned DotDesignatorAST::firstToken() const
+int DotDesignatorAST::firstToken() const
{
if (dot_token)
return dot_token;
@@ -4517,7 +4517,7 @@ unsigned DotDesignatorAST::firstToken() const
}
/** \generated */
-unsigned DotDesignatorAST::lastToken() const
+int DotDesignatorAST::lastToken() const
{
if (identifier_token)
return identifier_token + 1;
@@ -4527,14 +4527,14 @@ unsigned DotDesignatorAST::lastToken() const
}
/** \generated */
-unsigned AlignmentSpecifierAST::firstToken() const
+int AlignmentSpecifierAST::firstToken() const
{
if (align_token)
return align_token;
if (lparen_token)
return lparen_token;
if (typeIdExprOrAlignmentExpr)
- if (unsigned candidate = typeIdExprOrAlignmentExpr->firstToken())
+ if (int candidate = typeIdExprOrAlignmentExpr->firstToken())
return candidate;
if (ellipses_token)
return ellipses_token;
@@ -4544,14 +4544,14 @@ unsigned AlignmentSpecifierAST::firstToken() const
}
/** \generated */
-unsigned AlignmentSpecifierAST::lastToken() const
+int AlignmentSpecifierAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
if (ellipses_token)
return ellipses_token + 1;
if (typeIdExprOrAlignmentExpr)
- if (unsigned candidate = typeIdExprOrAlignmentExpr->lastToken())
+ if (int candidate = typeIdExprOrAlignmentExpr->lastToken())
return candidate;
if (lparen_token)
return lparen_token + 1;
@@ -4561,21 +4561,21 @@ unsigned AlignmentSpecifierAST::lastToken() const
}
/** \generated */
-unsigned NoExceptOperatorExpressionAST::firstToken() const
+int NoExceptOperatorExpressionAST::firstToken() const
{
if (noexcept_token)
return noexcept_token;
if (expression)
- if (unsigned candidate = expression->firstToken())
+ if (int candidate = expression->firstToken())
return candidate;
return 0;
}
/** \generated */
-unsigned NoExceptOperatorExpressionAST::lastToken() const
+int NoExceptOperatorExpressionAST::lastToken() const
{
if (expression)
- if (unsigned candidate = expression->lastToken())
+ if (int candidate = expression->lastToken())
return candidate;
if (noexcept_token)
return noexcept_token + 1;
diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h
index fc6750320b..dbc79f37e0 100644
--- a/src/libs/3rdparty/cplusplus/AST.h
+++ b/src/libs/3rdparty/cplusplus/AST.h
@@ -41,7 +41,7 @@ public:
: value(value), next(0)
{ }
- unsigned firstToken() const
+ int firstToken() const
{
if (value)
return value->firstToken();
@@ -50,7 +50,7 @@ public:
return 0;
}
- unsigned lastToken() const
+ int lastToken() const
{
Tptr lv = lastValue();
@@ -118,173 +118,173 @@ public:
return false;
}
- virtual unsigned firstToken() const = 0;
- virtual unsigned lastToken() const = 0;
+ virtual int firstToken() const = 0;
+ virtual int lastToken() const = 0;
virtual AST *clone(MemoryPool *pool) const = 0;
- virtual AccessDeclarationAST *asAccessDeclaration() { return 0; }
- virtual AliasDeclarationAST *asAliasDeclaration() { return 0; }
- virtual AlignmentSpecifierAST *asAlignmentSpecifier() { return 0; }
- virtual AlignofExpressionAST *asAlignofExpression() { return 0; }
- virtual AnonymousNameAST *asAnonymousName() { return 0; }
- virtual ArrayAccessAST *asArrayAccess() { return 0; }
- virtual ArrayDeclaratorAST *asArrayDeclarator() { return 0; }
- virtual ArrayInitializerAST *asArrayInitializer() { return 0; }
- virtual AsmDefinitionAST *asAsmDefinition() { return 0; }
- virtual AttributeSpecifierAST *asAttributeSpecifier() { return 0; }
- virtual BaseSpecifierAST *asBaseSpecifier() { return 0; }
- virtual BinaryExpressionAST *asBinaryExpression() { return 0; }
- virtual BoolLiteralAST *asBoolLiteral() { return 0; }
- virtual BracedInitializerAST *asBracedInitializer() { return 0; }
- virtual BracketDesignatorAST *asBracketDesignator() { return 0; }
- virtual BreakStatementAST *asBreakStatement() { return 0; }
- virtual CallAST *asCall() { return 0; }
- virtual CaptureAST *asCapture() { return 0; }
- virtual CaseStatementAST *asCaseStatement() { return 0; }
- virtual CastExpressionAST *asCastExpression() { return 0; }
- virtual CatchClauseAST *asCatchClause() { return 0; }
- virtual ClassSpecifierAST *asClassSpecifier() { return 0; }
- virtual CompoundExpressionAST *asCompoundExpression() { return 0; }
- virtual CompoundLiteralAST *asCompoundLiteral() { return 0; }
- virtual CompoundStatementAST *asCompoundStatement() { return 0; }
- virtual ConditionAST *asCondition() { return 0; }
- virtual ConditionalExpressionAST *asConditionalExpression() { return 0; }
- virtual ContinueStatementAST *asContinueStatement() { return 0; }
- virtual ConversionFunctionIdAST *asConversionFunctionId() { return 0; }
- virtual CoreDeclaratorAST *asCoreDeclarator() { return 0; }
- virtual CppCastExpressionAST *asCppCastExpression() { return 0; }
- virtual CtorInitializerAST *asCtorInitializer() { return 0; }
- virtual DeclarationAST *asDeclaration() { return 0; }
- virtual DeclarationStatementAST *asDeclarationStatement() { return 0; }
- virtual DeclaratorAST *asDeclarator() { return 0; }
- virtual DeclaratorIdAST *asDeclaratorId() { return 0; }
- virtual DecltypeSpecifierAST *asDecltypeSpecifier() { return 0; }
- virtual DeleteExpressionAST *asDeleteExpression() { return 0; }
- virtual DesignatedInitializerAST *asDesignatedInitializer() { return 0; }
- virtual DesignatorAST *asDesignator() { return 0; }
- virtual DestructorNameAST *asDestructorName() { return 0; }
- virtual DoStatementAST *asDoStatement() { return 0; }
- virtual DotDesignatorAST *asDotDesignator() { return 0; }
- virtual DynamicExceptionSpecificationAST *asDynamicExceptionSpecification() { return 0; }
- virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier() { return 0; }
- virtual EmptyDeclarationAST *asEmptyDeclaration() { return 0; }
- virtual EnumSpecifierAST *asEnumSpecifier() { return 0; }
- virtual EnumeratorAST *asEnumerator() { return 0; }
- virtual ExceptionDeclarationAST *asExceptionDeclaration() { return 0; }
- virtual ExceptionSpecificationAST *asExceptionSpecification() { return 0; }
- virtual ExpressionAST *asExpression() { return 0; }
- virtual ExpressionListParenAST *asExpressionListParen() { return 0; }
- virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return 0; }
- virtual ExpressionStatementAST *asExpressionStatement() { return 0; }
- virtual ForStatementAST *asForStatement() { return 0; }
- virtual ForeachStatementAST *asForeachStatement() { return 0; }
- virtual FunctionDeclaratorAST *asFunctionDeclarator() { return 0; }
- virtual FunctionDefinitionAST *asFunctionDefinition() { return 0; }
- virtual GnuAttributeAST *asGnuAttribute() { return 0; }
- virtual GnuAttributeSpecifierAST *asGnuAttributeSpecifier() { return 0; }
- virtual GotoStatementAST *asGotoStatement() { return 0; }
- virtual IdExpressionAST *asIdExpression() { return 0; }
- virtual IfStatementAST *asIfStatement() { return 0; }
- virtual LabeledStatementAST *asLabeledStatement() { return 0; }
- virtual LambdaCaptureAST *asLambdaCapture() { return 0; }
- virtual LambdaDeclaratorAST *asLambdaDeclarator() { return 0; }
- virtual LambdaExpressionAST *asLambdaExpression() { return 0; }
- virtual LambdaIntroducerAST *asLambdaIntroducer() { return 0; }
- virtual LinkageBodyAST *asLinkageBody() { return 0; }
- virtual LinkageSpecificationAST *asLinkageSpecification() { return 0; }
- virtual MemInitializerAST *asMemInitializer() { return 0; }
- virtual MemberAccessAST *asMemberAccess() { return 0; }
- virtual NameAST *asName() { return 0; }
- virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() { return 0; }
- virtual NamespaceAST *asNamespace() { return 0; }
- virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition() { return 0; }
- virtual NestedDeclaratorAST *asNestedDeclarator() { return 0; }
- virtual NestedExpressionAST *asNestedExpression() { return 0; }
- virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; }
- virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; }
- virtual NewExpressionAST *asNewExpression() { return 0; }
- virtual NewTypeIdAST *asNewTypeId() { return 0; }
- virtual NoExceptOperatorExpressionAST *asNoExceptOperatorExpression() { return 0; }
- virtual NoExceptSpecificationAST *asNoExceptSpecification() { return 0; }
- virtual NumericLiteralAST *asNumericLiteral() { return 0; }
- virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
- virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() { return 0; }
- virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return 0; }
- virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return 0; }
- virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return 0; }
- virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return 0; }
- virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return 0; }
- virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return 0; }
- virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return 0; }
- virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return 0; }
- virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return 0; }
- virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return 0; }
- virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return 0; }
- virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return 0; }
- virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return 0; }
- virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() { return 0; }
- virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return 0; }
- virtual ObjCSelectorAST *asObjCSelector() { return 0; }
- virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return 0; }
- virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return 0; }
- virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return 0; }
- virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return 0; }
- virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return 0; }
- virtual ObjCTypeNameAST *asObjCTypeName() { return 0; }
- virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return 0; }
- virtual OperatorAST *asOperator() { return 0; }
- virtual OperatorFunctionIdAST *asOperatorFunctionId() { return 0; }
- virtual ParameterDeclarationAST *asParameterDeclaration() { return 0; }
- virtual ParameterDeclarationClauseAST *asParameterDeclarationClause() { return 0; }
- virtual PointerAST *asPointer() { return 0; }
- virtual PointerLiteralAST *asPointerLiteral() { return 0; }
- virtual PointerToMemberAST *asPointerToMember() { return 0; }
- virtual PostIncrDecrAST *asPostIncrDecr() { return 0; }
- virtual PostfixAST *asPostfix() { return 0; }
- virtual PostfixDeclaratorAST *asPostfixDeclarator() { return 0; }
- virtual PtrOperatorAST *asPtrOperator() { return 0; }
- virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return 0; }
- virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return 0; }
- virtual QtInterfaceNameAST *asQtInterfaceName() { return 0; }
- virtual QtInterfacesDeclarationAST *asQtInterfacesDeclaration() { return 0; }
- virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return 0; }
- virtual QtMethodAST *asQtMethod() { return 0; }
- virtual QtObjectTagAST *asQtObjectTag() { return 0; }
- virtual QtPrivateSlotAST *asQtPrivateSlot() { return 0; }
- virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return 0; }
- virtual QtPropertyDeclarationItemAST *asQtPropertyDeclarationItem() { return 0; }
- virtual QualifiedNameAST *asQualifiedName() { return 0; }
- virtual RangeBasedForStatementAST *asRangeBasedForStatement() { return 0; }
- virtual ReferenceAST *asReference() { return 0; }
- virtual ReturnStatementAST *asReturnStatement() { return 0; }
- virtual SimpleDeclarationAST *asSimpleDeclaration() { return 0; }
- virtual SimpleNameAST *asSimpleName() { return 0; }
- virtual SimpleSpecifierAST *asSimpleSpecifier() { return 0; }
- virtual SizeofExpressionAST *asSizeofExpression() { return 0; }
- virtual SpecifierAST *asSpecifier() { return 0; }
- virtual StatementAST *asStatement() { return 0; }
- virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return 0; }
- virtual StringLiteralAST *asStringLiteral() { return 0; }
- virtual SwitchStatementAST *asSwitchStatement() { return 0; }
- virtual TemplateDeclarationAST *asTemplateDeclaration() { return 0; }
- virtual TemplateIdAST *asTemplateId() { return 0; }
- virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return 0; }
- virtual ThisExpressionAST *asThisExpression() { return 0; }
- virtual ThrowExpressionAST *asThrowExpression() { return 0; }
- virtual TrailingReturnTypeAST *asTrailingReturnType() { return 0; }
- virtual TranslationUnitAST *asTranslationUnit() { return 0; }
- virtual TryBlockStatementAST *asTryBlockStatement() { return 0; }
- virtual TypeConstructorCallAST *asTypeConstructorCall() { return 0; }
- virtual TypeIdAST *asTypeId() { return 0; }
- virtual TypeidExpressionAST *asTypeidExpression() { return 0; }
- virtual TypenameCallExpressionAST *asTypenameCallExpression() { return 0; }
- virtual TypenameTypeParameterAST *asTypenameTypeParameter() { return 0; }
- virtual TypeofSpecifierAST *asTypeofSpecifier() { return 0; }
- virtual UnaryExpressionAST *asUnaryExpression() { return 0; }
- virtual UsingAST *asUsing() { return 0; }
- virtual UsingDirectiveAST *asUsingDirective() { return 0; }
- virtual WhileStatementAST *asWhileStatement() { return 0; }
+ virtual AccessDeclarationAST *asAccessDeclaration() { return nullptr; }
+ virtual AliasDeclarationAST *asAliasDeclaration() { return nullptr; }
+ virtual AlignmentSpecifierAST *asAlignmentSpecifier() { return nullptr; }
+ virtual AlignofExpressionAST *asAlignofExpression() { return nullptr; }
+ virtual AnonymousNameAST *asAnonymousName() { return nullptr; }
+ virtual ArrayAccessAST *asArrayAccess() { return nullptr; }
+ virtual ArrayDeclaratorAST *asArrayDeclarator() { return nullptr; }
+ virtual ArrayInitializerAST *asArrayInitializer() { return nullptr; }
+ virtual AsmDefinitionAST *asAsmDefinition() { return nullptr; }
+ virtual AttributeSpecifierAST *asAttributeSpecifier() { return nullptr; }
+ virtual BaseSpecifierAST *asBaseSpecifier() { return nullptr; }
+ virtual BinaryExpressionAST *asBinaryExpression() { return nullptr; }
+ virtual BoolLiteralAST *asBoolLiteral() { return nullptr; }
+ virtual BracedInitializerAST *asBracedInitializer() { return nullptr; }
+ virtual BracketDesignatorAST *asBracketDesignator() { return nullptr; }
+ virtual BreakStatementAST *asBreakStatement() { return nullptr; }
+ virtual CallAST *asCall() { return nullptr; }
+ virtual CaptureAST *asCapture() { return nullptr; }
+ virtual CaseStatementAST *asCaseStatement() { return nullptr; }
+ virtual CastExpressionAST *asCastExpression() { return nullptr; }
+ virtual CatchClauseAST *asCatchClause() { return nullptr; }
+ virtual ClassSpecifierAST *asClassSpecifier() { return nullptr; }
+ virtual CompoundExpressionAST *asCompoundExpression() { return nullptr; }
+ virtual CompoundLiteralAST *asCompoundLiteral() { return nullptr; }
+ virtual CompoundStatementAST *asCompoundStatement() { return nullptr; }
+ virtual ConditionAST *asCondition() { return nullptr; }
+ virtual ConditionalExpressionAST *asConditionalExpression() { return nullptr; }
+ virtual ContinueStatementAST *asContinueStatement() { return nullptr; }
+ virtual ConversionFunctionIdAST *asConversionFunctionId() { return nullptr; }
+ virtual CoreDeclaratorAST *asCoreDeclarator() { return nullptr; }
+ virtual CppCastExpressionAST *asCppCastExpression() { return nullptr; }
+ virtual CtorInitializerAST *asCtorInitializer() { return nullptr; }
+ virtual DeclarationAST *asDeclaration() { return nullptr; }
+ virtual DeclarationStatementAST *asDeclarationStatement() { return nullptr; }
+ virtual DeclaratorAST *asDeclarator() { return nullptr; }
+ virtual DeclaratorIdAST *asDeclaratorId() { return nullptr; }
+ virtual DecltypeSpecifierAST *asDecltypeSpecifier() { return nullptr; }
+ virtual DeleteExpressionAST *asDeleteExpression() { return nullptr; }
+ virtual DesignatedInitializerAST *asDesignatedInitializer() { return nullptr; }
+ virtual DesignatorAST *asDesignator() { return nullptr; }
+ virtual DestructorNameAST *asDestructorName() { return nullptr; }
+ virtual DoStatementAST *asDoStatement() { return nullptr; }
+ virtual DotDesignatorAST *asDotDesignator() { return nullptr; }
+ virtual DynamicExceptionSpecificationAST *asDynamicExceptionSpecification() { return nullptr; }
+ virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier() { return nullptr; }
+ virtual EmptyDeclarationAST *asEmptyDeclaration() { return nullptr; }
+ virtual EnumSpecifierAST *asEnumSpecifier() { return nullptr; }
+ virtual EnumeratorAST *asEnumerator() { return nullptr; }
+ virtual ExceptionDeclarationAST *asExceptionDeclaration() { return nullptr; }
+ virtual ExceptionSpecificationAST *asExceptionSpecification() { return nullptr; }
+ virtual ExpressionAST *asExpression() { return nullptr; }
+ virtual ExpressionListParenAST *asExpressionListParen() { return nullptr; }
+ virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return nullptr; }
+ virtual ExpressionStatementAST *asExpressionStatement() { return nullptr; }
+ virtual ForStatementAST *asForStatement() { return nullptr; }
+ virtual ForeachStatementAST *asForeachStatement() { return nullptr; }
+ virtual FunctionDeclaratorAST *asFunctionDeclarator() { return nullptr; }
+ virtual FunctionDefinitionAST *asFunctionDefinition() { return nullptr; }
+ virtual GnuAttributeAST *asGnuAttribute() { return nullptr; }
+ virtual GnuAttributeSpecifierAST *asGnuAttributeSpecifier() { return nullptr; }
+ virtual GotoStatementAST *asGotoStatement() { return nullptr; }
+ virtual IdExpressionAST *asIdExpression() { return nullptr; }
+ virtual IfStatementAST *asIfStatement() { return nullptr; }
+ virtual LabeledStatementAST *asLabeledStatement() { return nullptr; }
+ virtual LambdaCaptureAST *asLambdaCapture() { return nullptr; }
+ virtual LambdaDeclaratorAST *asLambdaDeclarator() { return nullptr; }
+ virtual LambdaExpressionAST *asLambdaExpression() { return nullptr; }
+ virtual LambdaIntroducerAST *asLambdaIntroducer() { return nullptr; }
+ virtual LinkageBodyAST *asLinkageBody() { return nullptr; }
+ virtual LinkageSpecificationAST *asLinkageSpecification() { return nullptr; }
+ virtual MemInitializerAST *asMemInitializer() { return nullptr; }
+ virtual MemberAccessAST *asMemberAccess() { return nullptr; }
+ virtual NameAST *asName() { return nullptr; }
+ virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() { return nullptr; }
+ virtual NamespaceAST *asNamespace() { return nullptr; }
+ virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition() { return nullptr; }
+ virtual NestedDeclaratorAST *asNestedDeclarator() { return nullptr; }
+ virtual NestedExpressionAST *asNestedExpression() { return nullptr; }
+ virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return nullptr; }
+ virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return nullptr; }
+ virtual NewExpressionAST *asNewExpression() { return nullptr; }
+ virtual NewTypeIdAST *asNewTypeId() { return nullptr; }
+ virtual NoExceptOperatorExpressionAST *asNoExceptOperatorExpression() { return nullptr; }
+ virtual NoExceptSpecificationAST *asNoExceptSpecification() { return nullptr; }
+ virtual NumericLiteralAST *asNumericLiteral() { return nullptr; }
+ virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return nullptr; }
+ virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() { return nullptr; }
+ virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return nullptr; }
+ virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return nullptr; }
+ virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return nullptr; }
+ virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return nullptr; }
+ virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return nullptr; }
+ virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return nullptr; }
+ virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return nullptr; }
+ virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return nullptr; }
+ virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return nullptr; }
+ virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return nullptr; }
+ virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return nullptr; }
+ virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return nullptr; }
+ virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return nullptr; }
+ virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() { return nullptr; }
+ virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return nullptr; }
+ virtual ObjCSelectorAST *asObjCSelector() { return nullptr; }
+ virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return nullptr; }
+ virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return nullptr; }
+ virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return nullptr; }
+ virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return nullptr; }
+ virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return nullptr; }
+ virtual ObjCTypeNameAST *asObjCTypeName() { return nullptr; }
+ virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return nullptr; }
+ virtual OperatorAST *asOperator() { return nullptr; }
+ virtual OperatorFunctionIdAST *asOperatorFunctionId() { return nullptr; }
+ virtual ParameterDeclarationAST *asParameterDeclaration() { return nullptr; }
+ virtual ParameterDeclarationClauseAST *asParameterDeclarationClause() { return nullptr; }
+ virtual PointerAST *asPointer() { return nullptr; }
+ virtual PointerLiteralAST *asPointerLiteral() { return nullptr; }
+ virtual PointerToMemberAST *asPointerToMember() { return nullptr; }
+ virtual PostIncrDecrAST *asPostIncrDecr() { return nullptr; }
+ virtual PostfixAST *asPostfix() { return nullptr; }
+ virtual PostfixDeclaratorAST *asPostfixDeclarator() { return nullptr; }
+ virtual PtrOperatorAST *asPtrOperator() { return nullptr; }
+ virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return nullptr; }
+ virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return nullptr; }
+ virtual QtInterfaceNameAST *asQtInterfaceName() { return nullptr; }
+ virtual QtInterfacesDeclarationAST *asQtInterfacesDeclaration() { return nullptr; }
+ virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return nullptr; }
+ virtual QtMethodAST *asQtMethod() { return nullptr; }
+ virtual QtObjectTagAST *asQtObjectTag() { return nullptr; }
+ virtual QtPrivateSlotAST *asQtPrivateSlot() { return nullptr; }
+ virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return nullptr; }
+ virtual QtPropertyDeclarationItemAST *asQtPropertyDeclarationItem() { return nullptr; }
+ virtual QualifiedNameAST *asQualifiedName() { return nullptr; }
+ virtual RangeBasedForStatementAST *asRangeBasedForStatement() { return nullptr; }
+ virtual ReferenceAST *asReference() { return nullptr; }
+ virtual ReturnStatementAST *asReturnStatement() { return nullptr; }
+ virtual SimpleDeclarationAST *asSimpleDeclaration() { return nullptr; }
+ virtual SimpleNameAST *asSimpleName() { return nullptr; }
+ virtual SimpleSpecifierAST *asSimpleSpecifier() { return nullptr; }
+ virtual SizeofExpressionAST *asSizeofExpression() { return nullptr; }
+ virtual SpecifierAST *asSpecifier() { return nullptr; }
+ virtual StatementAST *asStatement() { return nullptr; }
+ virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return nullptr; }
+ virtual StringLiteralAST *asStringLiteral() { return nullptr; }
+ virtual SwitchStatementAST *asSwitchStatement() { return nullptr; }
+ virtual TemplateDeclarationAST *asTemplateDeclaration() { return nullptr; }
+ virtual TemplateIdAST *asTemplateId() { return nullptr; }
+ virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return nullptr; }
+ virtual ThisExpressionAST *asThisExpression() { return nullptr; }
+ virtual ThrowExpressionAST *asThrowExpression() { return nullptr; }
+ virtual TrailingReturnTypeAST *asTrailingReturnType() { return nullptr; }
+ virtual TranslationUnitAST *asTranslationUnit() { return nullptr; }
+ virtual TryBlockStatementAST *asTryBlockStatement() { return nullptr; }
+ virtual TypeConstructorCallAST *asTypeConstructorCall() { return nullptr; }
+ virtual TypeIdAST *asTypeId() { return nullptr; }
+ virtual TypeidExpressionAST *asTypeidExpression() { return nullptr; }
+ virtual TypenameCallExpressionAST *asTypenameCallExpression() { return nullptr; }
+ virtual TypenameTypeParameterAST *asTypenameTypeParameter() { return nullptr; }
+ virtual TypeofSpecifierAST *asTypeofSpecifier() { return nullptr; }
+ virtual UnaryExpressionAST *asUnaryExpression() { return nullptr; }
+ virtual UsingAST *asUsing() { return nullptr; }
+ virtual UsingDirectiveAST *asUsingDirective() { return nullptr; }
+ virtual WhileStatementAST *asWhileStatement() { return nullptr; }
protected:
virtual void accept0(ASTVisitor *visitor) = 0;
@@ -294,9 +294,6 @@ protected:
class CPLUSPLUS_EXPORT StatementAST: public AST
{
public:
- StatementAST()
- {}
-
virtual StatementAST *asStatement() { return this; }
virtual StatementAST *clone(MemoryPool *pool) const = 0;
@@ -305,9 +302,6 @@ public:
class CPLUSPLUS_EXPORT ExpressionAST: public AST
{
public:
- ExpressionAST()
- {}
-
virtual ExpressionAST *asExpression() { return this; }
virtual ExpressionAST *clone(MemoryPool *pool) const = 0;
@@ -316,9 +310,6 @@ public:
class CPLUSPLUS_EXPORT DeclarationAST: public AST
{
public:
- DeclarationAST()
- {}
-
virtual DeclarationAST *asDeclaration() { return this; }
virtual DeclarationAST *clone(MemoryPool *pool) const = 0;
@@ -327,13 +318,9 @@ public:
class CPLUSPLUS_EXPORT NameAST: public AST
{
public: // annotations
- const Name *name;
+ const Name *name = nullptr;
public:
- NameAST()
- : name(0)
- {}
-
virtual NameAST *asName() { return this; }
virtual NameAST *clone(MemoryPool *pool) const = 0;
@@ -342,9 +329,6 @@ public:
class CPLUSPLUS_EXPORT SpecifierAST: public AST
{
public:
- SpecifierAST()
- {}
-
virtual SpecifierAST *asSpecifier() { return this; }
virtual SpecifierAST *clone(MemoryPool *pool) const = 0;
@@ -353,9 +337,6 @@ public:
class CPLUSPLUS_EXPORT PtrOperatorAST: public AST
{
public:
- PtrOperatorAST()
- {}
-
virtual PtrOperatorAST *asPtrOperator() { return this; }
virtual PtrOperatorAST *clone(MemoryPool *pool) const = 0;
@@ -364,9 +345,6 @@ public:
class CPLUSPLUS_EXPORT PostfixAST: public ExpressionAST
{
public:
- PostfixAST()
- {}
-
virtual PostfixAST *asPostfix() { return this; }
virtual PostfixAST *clone(MemoryPool *pool) const = 0;
@@ -375,9 +353,6 @@ public:
class CPLUSPLUS_EXPORT CoreDeclaratorAST: public AST
{
public:
- CoreDeclaratorAST()
- {}
-
virtual CoreDeclaratorAST *asCoreDeclarator() { return this; }
virtual CoreDeclaratorAST *clone(MemoryPool *pool) const = 0;
@@ -386,9 +361,6 @@ public:
class CPLUSPLUS_EXPORT PostfixDeclaratorAST: public AST
{
public:
- PostfixDeclaratorAST()
- {}
-
virtual PostfixDeclaratorAST *asPostfixDeclarator() { return this; }
virtual PostfixDeclaratorAST *clone(MemoryPool *pool) const = 0;
@@ -397,19 +369,14 @@ public:
class CPLUSPLUS_EXPORT ObjCSelectorArgumentAST: public AST
{
public:
- unsigned name_token;
- unsigned colon_token;
+ int name_token = 0;
+ int colon_token = 0;
public:
- ObjCSelectorArgumentAST()
- : name_token(0)
- , colon_token(0)
- {}
-
virtual ObjCSelectorArgumentAST *asObjCSelectorArgument() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCSelectorArgumentAST *clone(MemoryPool *pool) const;
@@ -421,17 +388,13 @@ protected:
class CPLUSPLUS_EXPORT ObjCSelectorAST: public NameAST
{
public:
- ObjCSelectorArgumentListAST *selector_argument_list;
+ ObjCSelectorArgumentListAST *selector_argument_list = nullptr;
public:
- ObjCSelectorAST()
- : selector_argument_list(0)
- {}
-
virtual ObjCSelectorAST *asObjCSelector() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCSelectorAST *clone(MemoryPool *pool) const;
@@ -443,17 +406,13 @@ protected:
class CPLUSPLUS_EXPORT SimpleSpecifierAST: public SpecifierAST
{
public:
- unsigned specifier_token;
+ int specifier_token = 0;
public:
- SimpleSpecifierAST()
- : specifier_token(0)
- {}
-
virtual SimpleSpecifierAST *asSimpleSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual SimpleSpecifierAST *clone(MemoryPool *pool) const;
@@ -465,9 +424,6 @@ protected:
class CPLUSPLUS_EXPORT AttributeSpecifierAST: public SpecifierAST
{
public:
- AttributeSpecifierAST()
- {}
-
virtual AttributeSpecifierAST *asAttributeSpecifier() { return this; }
virtual AttributeSpecifierAST *clone(MemoryPool *pool) const = 0;
@@ -476,25 +432,17 @@ public:
class CPLUSPLUS_EXPORT AlignmentSpecifierAST: public AttributeSpecifierAST
{
public:
- unsigned align_token;
- unsigned lparen_token;
- ExpressionAST *typeIdExprOrAlignmentExpr;
- unsigned ellipses_token;
- unsigned rparen_token;
+ int align_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *typeIdExprOrAlignmentExpr = nullptr;
+ int ellipses_token = 0;
+ int rparen_token = 0;
public:
- AlignmentSpecifierAST()
- : align_token(0)
- , lparen_token(0)
- , typeIdExprOrAlignmentExpr(0)
- , ellipses_token(0)
- , rparen_token(0)
- {}
-
virtual AlignmentSpecifierAST *asAlignmentSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual AlignmentSpecifierAST *clone(MemoryPool *pool) const;
@@ -507,27 +455,18 @@ protected:
class CPLUSPLUS_EXPORT GnuAttributeSpecifierAST: public AttributeSpecifierAST
{
public:
- unsigned attribute_token;
- unsigned first_lparen_token;
- unsigned second_lparen_token;
- GnuAttributeListAST *attribute_list;
- unsigned first_rparen_token;
- unsigned second_rparen_token;
+ int attribute_token = 0;
+ int first_lparen_token = 0;
+ int second_lparen_token = 0;
+ GnuAttributeListAST *attribute_list = nullptr;
+ int first_rparen_token = 0;
+ int second_rparen_token = 0;
public:
- GnuAttributeSpecifierAST()
- : attribute_token(0)
- , first_lparen_token(0)
- , second_lparen_token(0)
- , attribute_list(0)
- , first_rparen_token(0)
- , second_rparen_token(0)
- {}
-
virtual GnuAttributeSpecifierAST *asGnuAttributeSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual GnuAttributeSpecifierAST *clone(MemoryPool *pool) const;
@@ -539,25 +478,17 @@ protected:
class CPLUSPLUS_EXPORT GnuAttributeAST: public AST
{
public:
- unsigned identifier_token;
- unsigned lparen_token;
- unsigned tag_token;
- ExpressionListAST *expression_list;
- unsigned rparen_token;
+ int identifier_token = 0;
+ int lparen_token = 0;
+ int tag_token = 0;
+ ExpressionListAST *expression_list = nullptr;
+ int rparen_token = 0;
public:
- GnuAttributeAST()
- : identifier_token(0)
- , lparen_token(0)
- , tag_token(0)
- , expression_list(0)
- , rparen_token(0)
- {}
-
virtual GnuAttributeAST *asGnuAttribute() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual GnuAttributeAST *clone(MemoryPool *pool) const;
@@ -569,23 +500,16 @@ protected:
class CPLUSPLUS_EXPORT TypeofSpecifierAST: public SpecifierAST
{
public:
- unsigned typeof_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int typeof_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- TypeofSpecifierAST()
- : typeof_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual TypeofSpecifierAST *asTypeofSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TypeofSpecifierAST *clone(MemoryPool *pool) const;
@@ -597,23 +521,16 @@ protected:
class CPLUSPLUS_EXPORT DecltypeSpecifierAST: public SpecifierAST
{
public:
- unsigned decltype_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int decltype_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- DecltypeSpecifierAST()
- : decltype_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual DecltypeSpecifierAST *asDecltypeSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DecltypeSpecifierAST *clone(MemoryPool *pool) const;
@@ -625,29 +542,19 @@ protected:
class CPLUSPLUS_EXPORT DeclaratorAST: public AST
{
public:
- SpecifierListAST *attribute_list;
- PtrOperatorListAST *ptr_operator_list;
- CoreDeclaratorAST *core_declarator;
- PostfixDeclaratorListAST *postfix_declarator_list;
- SpecifierListAST *post_attribute_list;
- unsigned equal_token;
- ExpressionAST *initializer;
+ SpecifierListAST *attribute_list = nullptr;
+ PtrOperatorListAST *ptr_operator_list = nullptr;
+ CoreDeclaratorAST *core_declarator = nullptr;
+ PostfixDeclaratorListAST *postfix_declarator_list = nullptr;
+ SpecifierListAST *post_attribute_list = nullptr;
+ int equal_token = 0;
+ ExpressionAST *initializer = nullptr;
public:
- DeclaratorAST()
- : attribute_list(0)
- , ptr_operator_list(0)
- , core_declarator(0)
- , postfix_declarator_list(0)
- , post_attribute_list(0)
- , equal_token(0)
- , initializer(0)
- {}
-
virtual DeclaratorAST *asDeclarator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DeclaratorAST *clone(MemoryPool *pool) const;
@@ -659,27 +566,19 @@ protected:
class CPLUSPLUS_EXPORT SimpleDeclarationAST: public DeclarationAST
{
public:
- unsigned qt_invokable_token;
- SpecifierListAST *decl_specifier_list;
- DeclaratorListAST *declarator_list;
- unsigned semicolon_token;
+ int qt_invokable_token = 0;
+ SpecifierListAST *decl_specifier_list = nullptr;
+ DeclaratorListAST *declarator_list = nullptr;
+ int semicolon_token = 0;
public:
- List<Symbol *> *symbols;
+ List<Symbol *> *symbols = nullptr;
public:
- SimpleDeclarationAST()
- : qt_invokable_token(0)
- , decl_specifier_list(0)
- , declarator_list(0)
- , semicolon_token(0)
- , symbols(0)
- {}
-
virtual SimpleDeclarationAST *asSimpleDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual SimpleDeclarationAST *clone(MemoryPool *pool) const;
@@ -691,17 +590,13 @@ protected:
class CPLUSPLUS_EXPORT EmptyDeclarationAST: public DeclarationAST
{
public:
- unsigned semicolon_token;
+ int semicolon_token = 0;
public:
- EmptyDeclarationAST()
- : semicolon_token(0)
- {}
-
virtual EmptyDeclarationAST *asEmptyDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual EmptyDeclarationAST *clone(MemoryPool *pool) const;
@@ -713,21 +608,15 @@ protected:
class CPLUSPLUS_EXPORT AccessDeclarationAST: public DeclarationAST
{
public:
- unsigned access_specifier_token;
- unsigned slots_token;
- unsigned colon_token;
+ int access_specifier_token = 0;
+ int slots_token = 0;
+ int colon_token = 0;
public:
- AccessDeclarationAST()
- : access_specifier_token(0)
- , slots_token(0)
- , colon_token(0)
- {}
-
virtual AccessDeclarationAST *asAccessDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual AccessDeclarationAST *clone(MemoryPool *pool) const;
@@ -739,17 +628,13 @@ protected:
class CPLUSPLUS_EXPORT QtObjectTagAST: public DeclarationAST
{
public:
- unsigned q_object_token;
+ int q_object_token = 0;
public:
- QtObjectTagAST()
- : q_object_token(0)
- {}
-
virtual QtObjectTagAST *asQtObjectTag() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtObjectTagAST *clone(MemoryPool *pool) const;
@@ -761,33 +646,21 @@ protected:
class CPLUSPLUS_EXPORT QtPrivateSlotAST: public DeclarationAST
{
public:
- unsigned q_private_slot_token;
- unsigned lparen_token;
- unsigned dptr_token;
- unsigned dptr_lparen_token;
- unsigned dptr_rparen_token;
- unsigned comma_token;
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
- unsigned rparen_token;
-
-public:
- QtPrivateSlotAST()
- : q_private_slot_token(0)
- , lparen_token(0)
- , dptr_token(0)
- , dptr_lparen_token(0)
- , dptr_rparen_token(0)
- , comma_token(0)
- , type_specifier_list(0)
- , declarator(0)
- , rparen_token(0)
- {}
+ int q_private_slot_token = 0;
+ int lparen_token = 0;
+ int dptr_token = 0;
+ int dptr_lparen_token = 0;
+ int dptr_rparen_token = 0;
+ int comma_token = 0;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
+ int rparen_token = 0;
+public:
virtual QtPrivateSlotAST *asQtPrivateSlot() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtPrivateSlotAST *clone(MemoryPool *pool) const;
@@ -799,19 +672,14 @@ protected:
class QtPropertyDeclarationItemAST: public AST
{
public:
- unsigned item_name_token;
- ExpressionAST *expression;
+ int item_name_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- QtPropertyDeclarationItemAST()
- : item_name_token(0)
- , expression(0)
- {}
-
virtual QtPropertyDeclarationItemAST *asQtPropertyDeclarationItem() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtPropertyDeclarationItemAST *clone(MemoryPool *pool) const;
@@ -823,31 +691,20 @@ protected:
class CPLUSPLUS_EXPORT QtPropertyDeclarationAST: public DeclarationAST
{
public:
- unsigned property_specifier_token;
- unsigned lparen_token;
- ExpressionAST *expression; // for Q_PRIVATE_PROPERTY(expression, ...)
- unsigned comma_token;
- ExpressionAST *type_id;
- NameAST *property_name;
- QtPropertyDeclarationItemListAST *property_declaration_item_list;
- unsigned rparen_token;
+ int property_specifier_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr; // for Q_PRIVATE_PROPERTY(expression, ...)
+ int comma_token = 0;
+ ExpressionAST *type_id = nullptr;
+ NameAST *property_name = nullptr;
+ QtPropertyDeclarationItemListAST *property_declaration_item_list = nullptr;
+ int rparen_token = 0;
public:
- QtPropertyDeclarationAST()
- : property_specifier_token(0)
- , lparen_token(0)
- , expression(0)
- , comma_token(0)
- , type_id(0)
- , property_name(0)
- , property_declaration_item_list(0)
- , rparen_token(0)
- {}
-
virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtPropertyDeclarationAST *clone(MemoryPool *pool) const;
@@ -859,23 +716,16 @@ protected:
class CPLUSPLUS_EXPORT QtEnumDeclarationAST: public DeclarationAST
{
public:
- unsigned enum_specifier_token;
- unsigned lparen_token;
- NameListAST *enumerator_list;
- unsigned rparen_token;
+ int enum_specifier_token = 0;
+ int lparen_token = 0;
+ NameListAST *enumerator_list = nullptr;
+ int rparen_token = 0;
public:
- QtEnumDeclarationAST()
- : enum_specifier_token(0)
- , lparen_token(0)
- , enumerator_list(0)
- , rparen_token(0)
- {}
-
virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtEnumDeclarationAST *clone(MemoryPool *pool) const;
@@ -887,23 +737,16 @@ protected:
class CPLUSPLUS_EXPORT QtFlagsDeclarationAST: public DeclarationAST
{
public:
- unsigned flags_specifier_token;
- unsigned lparen_token;
- NameListAST *flag_enums_list;
- unsigned rparen_token;
+ int flags_specifier_token = 0;
+ int lparen_token = 0;
+ NameListAST *flag_enums_list = nullptr;
+ int rparen_token = 0;
public:
- QtFlagsDeclarationAST()
- : flags_specifier_token(0)
- , lparen_token(0)
- , flag_enums_list(0)
- , rparen_token(0)
- {}
-
virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtFlagsDeclarationAST *clone(MemoryPool *pool) const;
@@ -915,19 +758,14 @@ protected:
class CPLUSPLUS_EXPORT QtInterfaceNameAST: public AST
{
public:
- NameAST *interface_name;
- NameListAST *constraint_list;
+ NameAST *interface_name = nullptr;
+ NameListAST *constraint_list = nullptr;
public:
- QtInterfaceNameAST()
- : interface_name(0)
- , constraint_list(0)
- {}
-
virtual QtInterfaceNameAST *asQtInterfaceName() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtInterfaceNameAST *clone(MemoryPool *pool) const;
@@ -939,23 +777,16 @@ protected:
class CPLUSPLUS_EXPORT QtInterfacesDeclarationAST: public DeclarationAST
{
public:
- unsigned interfaces_token;
- unsigned lparen_token;
- QtInterfaceNameListAST *interface_name_list;
- unsigned rparen_token;
+ int interfaces_token = 0;
+ int lparen_token = 0;
+ QtInterfaceNameListAST *interface_name_list = nullptr;
+ int rparen_token = 0;
public:
- QtInterfacesDeclarationAST()
- : interfaces_token(0)
- , lparen_token(0)
- , interface_name_list(0)
- , rparen_token(0)
- {}
-
virtual QtInterfacesDeclarationAST *asQtInterfacesDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtInterfacesDeclarationAST *clone(MemoryPool *pool) const;
@@ -967,27 +798,19 @@ protected:
class CPLUSPLUS_EXPORT AsmDefinitionAST: public DeclarationAST
{
public:
- unsigned asm_token;
- unsigned volatile_token;
- unsigned lparen_token;
+ int asm_token = 0;
+ int volatile_token = 0;
+ int lparen_token = 0;
// ### string literals
// ### asm operand list
- unsigned rparen_token;
- unsigned semicolon_token;
+ int rparen_token = 0;
+ int semicolon_token = 0;
public:
- AsmDefinitionAST()
- : asm_token(0)
- , volatile_token(0)
- , lparen_token(0)
- , rparen_token(0)
- , semicolon_token(0)
- {}
-
virtual AsmDefinitionAST *asAsmDefinition() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual AsmDefinitionAST *clone(MemoryPool *pool) const;
@@ -999,27 +822,19 @@ protected:
class CPLUSPLUS_EXPORT BaseSpecifierAST: public AST
{
public:
- unsigned virtual_token;
- unsigned access_specifier_token;
- NameAST *name;
- unsigned ellipsis_token;
+ int virtual_token = 0;
+ int access_specifier_token = 0;
+ NameAST *name = nullptr;
+ int ellipsis_token = 0;
public: // annotations
- BaseClass *symbol;
+ BaseClass *symbol = nullptr;
public:
- BaseSpecifierAST()
- : virtual_token(0)
- , access_specifier_token(0)
- , name(0)
- , ellipsis_token(0)
- , symbol(0)
- {}
-
virtual BaseSpecifierAST *asBaseSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual BaseSpecifierAST *clone(MemoryPool *pool) const;
@@ -1031,17 +846,13 @@ protected:
class CPLUSPLUS_EXPORT IdExpressionAST: public ExpressionAST
{
public:
- NameAST *name;
+ NameAST *name = nullptr;
public:
- IdExpressionAST()
- : name(0)
- {}
-
virtual IdExpressionAST *asIdExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual IdExpressionAST *clone(MemoryPool *pool) const;
@@ -1053,21 +864,15 @@ protected:
class CPLUSPLUS_EXPORT CompoundExpressionAST: public ExpressionAST
{
public:
- unsigned lparen_token;
- CompoundStatementAST *statement;
- unsigned rparen_token;
+ int lparen_token = 0;
+ CompoundStatementAST *statement = nullptr;
+ int rparen_token = 0;
public:
- CompoundExpressionAST()
- : lparen_token(0)
- , statement(0)
- , rparen_token(0)
- {}
-
virtual CompoundExpressionAST *asCompoundExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CompoundExpressionAST *clone(MemoryPool *pool) const;
@@ -1079,23 +884,16 @@ protected:
class CPLUSPLUS_EXPORT CompoundLiteralAST: public ExpressionAST
{
public:
- unsigned lparen_token;
- ExpressionAST *type_id;
- unsigned rparen_token;
- ExpressionAST *initializer;
+ int lparen_token = 0;
+ ExpressionAST *type_id = nullptr;
+ int rparen_token = 0;
+ ExpressionAST *initializer = nullptr;
public:
- CompoundLiteralAST()
- : lparen_token(0)
- , type_id(0)
- , rparen_token(0)
- , initializer(0)
- {}
-
virtual CompoundLiteralAST *asCompoundLiteral() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CompoundLiteralAST *clone(MemoryPool *pool) const;
@@ -1107,23 +905,16 @@ protected:
class CPLUSPLUS_EXPORT QtMethodAST: public ExpressionAST
{
public:
- unsigned method_token;
- unsigned lparen_token;
- DeclaratorAST *declarator;
- unsigned rparen_token;
+ int method_token = 0;
+ int lparen_token = 0;
+ DeclaratorAST *declarator = nullptr;
+ int rparen_token = 0;
public:
- QtMethodAST()
- : method_token(0)
- , lparen_token(0)
- , declarator(0)
- , rparen_token(0)
- {}
-
virtual QtMethodAST *asQtMethod() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtMethodAST *clone(MemoryPool *pool) const;
@@ -1135,23 +926,16 @@ protected:
class CPLUSPLUS_EXPORT QtMemberDeclarationAST: public StatementAST
{
public:
- unsigned q_token;
- unsigned lparen_token;
- ExpressionAST *type_id;
- unsigned rparen_token;
+ int q_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *type_id = nullptr;
+ int rparen_token = 0;
public:
- QtMemberDeclarationAST()
- : q_token(0)
- , lparen_token(0)
- , type_id(0)
- , rparen_token(0)
- {}
-
virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QtMemberDeclarationAST *clone(MemoryPool *pool) const;
@@ -1163,21 +947,15 @@ protected:
class CPLUSPLUS_EXPORT BinaryExpressionAST: public ExpressionAST
{
public:
- ExpressionAST *left_expression;
- unsigned binary_op_token;
- ExpressionAST *right_expression;
+ ExpressionAST *left_expression = nullptr;
+ int binary_op_token = 0;
+ ExpressionAST *right_expression = nullptr;
public:
- BinaryExpressionAST()
- : left_expression(0)
- , binary_op_token(0)
- , right_expression(0)
- {}
-
virtual BinaryExpressionAST *asBinaryExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual BinaryExpressionAST *clone(MemoryPool *pool) const;
@@ -1189,23 +967,16 @@ protected:
class CPLUSPLUS_EXPORT CastExpressionAST: public ExpressionAST
{
public:
- unsigned lparen_token;
- ExpressionAST *type_id;
- unsigned rparen_token;
- ExpressionAST *expression;
+ int lparen_token = 0;
+ ExpressionAST *type_id = nullptr;
+ int rparen_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- CastExpressionAST()
- : lparen_token(0)
- , type_id(0)
- , rparen_token(0)
- , expression(0)
- {}
-
virtual CastExpressionAST *asCastExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CastExpressionAST *clone(MemoryPool *pool) const;
@@ -1217,39 +988,25 @@ protected:
class CPLUSPLUS_EXPORT ClassSpecifierAST: public SpecifierAST
{
public:
- unsigned classkey_token;
- SpecifierListAST *attribute_list;
- NameAST *name;
- unsigned final_token;
- unsigned colon_token;
- BaseSpecifierListAST *base_clause_list;
- unsigned dot_dot_dot_token;
- unsigned lbrace_token;
- DeclarationListAST *member_specifier_list;
- unsigned rbrace_token;
+ int classkey_token = 0;
+ SpecifierListAST *attribute_list = nullptr;
+ NameAST *name = nullptr;
+ int final_token = 0;
+ int colon_token = 0;
+ BaseSpecifierListAST *base_clause_list = nullptr;
+ int dot_dot_dot_token = 0;
+ int lbrace_token = 0;
+ DeclarationListAST *member_specifier_list = nullptr;
+ int rbrace_token = 0;
public: // annotations
- Class *symbol;
-
-public:
- ClassSpecifierAST()
- : classkey_token(0)
- , attribute_list(0)
- , name(0)
- , final_token(0)
- , colon_token(0)
- , base_clause_list(0)
- , dot_dot_dot_token(0)
- , lbrace_token(0)
- , member_specifier_list(0)
- , rbrace_token(0)
- , symbol(0)
- {}
+ Class *symbol = nullptr;
+public:
virtual ClassSpecifierAST *asClassSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ClassSpecifierAST *clone(MemoryPool *pool) const;
@@ -1261,23 +1018,16 @@ protected:
class CPLUSPLUS_EXPORT CaseStatementAST: public StatementAST
{
public:
- unsigned case_token;
- ExpressionAST *expression;
- unsigned colon_token;
- StatementAST *statement;
+ int case_token = 0;
+ ExpressionAST *expression = nullptr;
+ int colon_token = 0;
+ StatementAST *statement = nullptr;
public:
- CaseStatementAST()
- : case_token(0)
- , expression(0)
- , colon_token(0)
- , statement(0)
- {}
-
virtual CaseStatementAST *asCaseStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CaseStatementAST *clone(MemoryPool *pool) const;
@@ -1289,25 +1039,18 @@ protected:
class CPLUSPLUS_EXPORT CompoundStatementAST: public StatementAST
{
public:
- unsigned lbrace_token;
- StatementListAST *statement_list;
- unsigned rbrace_token;
+ int lbrace_token = 0;
+ StatementListAST *statement_list = nullptr;
+ int rbrace_token = 0;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- CompoundStatementAST()
- : lbrace_token(0)
- , statement_list(0)
- , rbrace_token(0)
- , symbol(0)
- {}
-
virtual CompoundStatementAST *asCompoundStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CompoundStatementAST *clone(MemoryPool *pool) const;
@@ -1319,19 +1062,14 @@ protected:
class CPLUSPLUS_EXPORT ConditionAST: public ExpressionAST
{
public:
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
public:
- ConditionAST()
- : type_specifier_list(0)
- , declarator(0)
- {}
-
virtual ConditionAST *asCondition() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ConditionAST *clone(MemoryPool *pool) const;
@@ -1343,25 +1081,17 @@ protected:
class CPLUSPLUS_EXPORT ConditionalExpressionAST: public ExpressionAST
{
public:
- ExpressionAST *condition;
- unsigned question_token;
- ExpressionAST *left_expression;
- unsigned colon_token;
- ExpressionAST *right_expression;
+ ExpressionAST *condition = nullptr;
+ int question_token = 0;
+ ExpressionAST *left_expression = nullptr;
+ int colon_token = 0;
+ ExpressionAST *right_expression = nullptr;
public:
- ConditionalExpressionAST()
- : condition(0)
- , question_token(0)
- , left_expression(0)
- , colon_token(0)
- , right_expression(0)
- {}
-
virtual ConditionalExpressionAST *asConditionalExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ConditionalExpressionAST *clone(MemoryPool *pool) const;
@@ -1373,29 +1103,19 @@ protected:
class CPLUSPLUS_EXPORT CppCastExpressionAST: public ExpressionAST
{
public:
- unsigned cast_token;
- unsigned less_token;
- ExpressionAST *type_id;
- unsigned greater_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int cast_token = 0;
+ int less_token = 0;
+ ExpressionAST *type_id = nullptr;
+ int greater_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- CppCastExpressionAST()
- : cast_token(0)
- , less_token(0)
- , type_id(0)
- , greater_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual CppCastExpressionAST *asCppCastExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CppCastExpressionAST *clone(MemoryPool *pool) const;
@@ -1407,21 +1127,15 @@ protected:
class CPLUSPLUS_EXPORT CtorInitializerAST: public AST
{
public:
- unsigned colon_token;
- MemInitializerListAST *member_initializer_list;
- unsigned dot_dot_dot_token;
+ int colon_token = 0;
+ MemInitializerListAST *member_initializer_list = nullptr;
+ int dot_dot_dot_token = 0;
public:
- CtorInitializerAST()
- : colon_token(0)
- , member_initializer_list(0)
- , dot_dot_dot_token(0)
- {}
-
virtual CtorInitializerAST *asCtorInitializer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CtorInitializerAST *clone(MemoryPool *pool) const;
@@ -1433,17 +1147,13 @@ protected:
class CPLUSPLUS_EXPORT DeclarationStatementAST: public StatementAST
{
public:
- DeclarationAST *declaration;
+ DeclarationAST *declaration = nullptr;
public:
- DeclarationStatementAST()
- : declaration(0)
- {}
-
virtual DeclarationStatementAST *asDeclarationStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DeclarationStatementAST *clone(MemoryPool *pool) const;
@@ -1455,19 +1165,14 @@ protected:
class CPLUSPLUS_EXPORT DeclaratorIdAST: public CoreDeclaratorAST
{
public:
- unsigned dot_dot_dot_token;
- NameAST *name;
+ int dot_dot_dot_token = 0;
+ NameAST *name = nullptr;
public:
- DeclaratorIdAST()
- : dot_dot_dot_token(0)
- , name(0)
- {}
-
virtual DeclaratorIdAST *asDeclaratorId() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DeclaratorIdAST *clone(MemoryPool *pool) const;
@@ -1479,21 +1184,15 @@ protected:
class CPLUSPLUS_EXPORT NestedDeclaratorAST: public CoreDeclaratorAST
{
public:
- unsigned lparen_token;
- DeclaratorAST *declarator;
- unsigned rparen_token;
+ int lparen_token = 0;
+ DeclaratorAST *declarator = nullptr;
+ int rparen_token = 0;
public:
- NestedDeclaratorAST()
- : lparen_token(0)
- , declarator(0)
- , rparen_token(0)
- {}
-
virtual NestedDeclaratorAST *asNestedDeclarator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NestedDeclaratorAST *clone(MemoryPool *pool) const;
@@ -1505,36 +1204,24 @@ protected:
class CPLUSPLUS_EXPORT FunctionDeclaratorAST: public PostfixDeclaratorAST
{
public:
- unsigned lparen_token;
- ParameterDeclarationClauseAST *parameter_declaration_clause;
- unsigned rparen_token;
- SpecifierListAST *cv_qualifier_list;
- unsigned ref_qualifier_token;
- ExceptionSpecificationAST *exception_specification;
- TrailingReturnTypeAST *trailing_return_type;
+ int lparen_token = 0;
+ ParameterDeclarationClauseAST *parameter_declaration_clause = nullptr;
+ int rparen_token = 0;
+ SpecifierListAST *cv_qualifier_list = nullptr;
+ int ref_qualifier_token = 0;
+ ExceptionSpecificationAST *exception_specification = nullptr;
+ TrailingReturnTypeAST *trailing_return_type = nullptr;
// Some FunctionDeclarators can also be interpreted as an initializer, like for 'A b(c);'
- ExpressionAST *as_cpp_initializer;
+ ExpressionAST *as_cpp_initializer = nullptr;
public: // annotations
- Function *symbol;
+ Function *symbol = nullptr;
public:
- FunctionDeclaratorAST()
- : lparen_token(0)
- , parameter_declaration_clause(0)
- , rparen_token(0)
- , cv_qualifier_list(0)
- , ref_qualifier_token(0)
- , exception_specification(0)
- , trailing_return_type(0)
- , as_cpp_initializer(0)
- , symbol(0)
- {}
-
virtual FunctionDeclaratorAST *asFunctionDeclarator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual FunctionDeclaratorAST *clone(MemoryPool *pool) const;
@@ -1546,21 +1233,15 @@ protected:
class CPLUSPLUS_EXPORT ArrayDeclaratorAST: public PostfixDeclaratorAST
{
public:
- unsigned lbracket_token;
- ExpressionAST *expression;
- unsigned rbracket_token;
+ int lbracket_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rbracket_token = 0;
public:
- ArrayDeclaratorAST()
- : lbracket_token(0)
- , expression(0)
- , rbracket_token(0)
- {}
-
virtual ArrayDeclaratorAST *asArrayDeclarator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ArrayDeclaratorAST *clone(MemoryPool *pool) const;
@@ -1572,25 +1253,17 @@ protected:
class CPLUSPLUS_EXPORT DeleteExpressionAST: public ExpressionAST
{
public:
- unsigned scope_token;
- unsigned delete_token;
- unsigned lbracket_token;
- unsigned rbracket_token;
- ExpressionAST *expression;
+ int scope_token = 0;
+ int delete_token = 0;
+ int lbracket_token = 0;
+ int rbracket_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- DeleteExpressionAST()
- : scope_token(0)
- , delete_token(0)
- , lbracket_token(0)
- , rbracket_token(0)
- , expression(0)
- {}
-
virtual DeleteExpressionAST *asDeleteExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DeleteExpressionAST *clone(MemoryPool *pool) const;
@@ -1602,29 +1275,19 @@ protected:
class CPLUSPLUS_EXPORT DoStatementAST: public StatementAST
{
public:
- unsigned do_token;
- StatementAST *statement;
- unsigned while_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
- unsigned semicolon_token;
+ int do_token = 0;
+ StatementAST *statement = nullptr;
+ int while_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
+ int semicolon_token = 0;
public:
- DoStatementAST()
- : do_token(0)
- , statement(0)
- , while_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- , semicolon_token(0)
- {}
-
virtual DoStatementAST *asDoStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DoStatementAST *clone(MemoryPool *pool) const;
@@ -1636,17 +1299,13 @@ protected:
class CPLUSPLUS_EXPORT NamedTypeSpecifierAST: public SpecifierAST
{
public:
- NameAST *name;
+ NameAST *name = nullptr;
public:
- NamedTypeSpecifierAST()
- : name(0)
- {}
-
virtual NamedTypeSpecifierAST *asNamedTypeSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NamedTypeSpecifierAST *clone(MemoryPool *pool) const;
@@ -1658,21 +1317,15 @@ protected:
class CPLUSPLUS_EXPORT ElaboratedTypeSpecifierAST: public SpecifierAST
{
public:
- unsigned classkey_token;
- SpecifierListAST *attribute_list;
- NameAST *name;
+ int classkey_token = 0;
+ SpecifierListAST *attribute_list = nullptr;
+ NameAST *name = nullptr;
public:
- ElaboratedTypeSpecifierAST()
- : classkey_token(0)
- , attribute_list(0)
- , name(0)
- {}
-
virtual ElaboratedTypeSpecifierAST *asElaboratedTypeSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ElaboratedTypeSpecifierAST *clone(MemoryPool *pool) const;
@@ -1684,37 +1337,24 @@ protected:
class CPLUSPLUS_EXPORT EnumSpecifierAST: public SpecifierAST
{
public:
- unsigned enum_token;
- unsigned key_token; // struct, class or 0
- NameAST *name;
- unsigned colon_token; // can be 0 if there is no enum-base
- SpecifierListAST *type_specifier_list; // ditto
- unsigned lbrace_token;
- EnumeratorListAST *enumerator_list;
- unsigned stray_comma_token;
- unsigned rbrace_token;
+ int enum_token = 0;
+ int key_token = 0; // struct, class or 0
+ NameAST *name = nullptr;
+ int colon_token = 0; // can be 0 if there is no enum-base
+ SpecifierListAST *type_specifier_list = nullptr; // ditto
+ int lbrace_token = 0;
+ EnumeratorListAST *enumerator_list = nullptr;
+ int stray_comma_token = 0;
+ int rbrace_token = 0;
public: // annotations
- Enum *symbol;
-
-public:
- EnumSpecifierAST()
- : enum_token(0)
- , key_token(0)
- , name(0)
- , colon_token(0)
- , type_specifier_list(0)
- , lbrace_token(0)
- , enumerator_list(0)
- , stray_comma_token(0)
- , rbrace_token(0)
- , symbol(0)
- {}
+ Enum *symbol = nullptr;
+public:
virtual EnumSpecifierAST *asEnumSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual EnumSpecifierAST *clone(MemoryPool *pool) const;
@@ -1726,21 +1366,15 @@ protected:
class CPLUSPLUS_EXPORT EnumeratorAST: public AST
{
public:
- unsigned identifier_token;
- unsigned equal_token;
- ExpressionAST *expression;
+ int identifier_token = 0;
+ int equal_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- EnumeratorAST()
- : identifier_token(0)
- , equal_token(0)
- , expression(0)
- {}
-
virtual EnumeratorAST *asEnumerator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual EnumeratorAST *clone(MemoryPool *pool) const;
@@ -1752,21 +1386,15 @@ protected:
class CPLUSPLUS_EXPORT ExceptionDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
- unsigned dot_dot_dot_token;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
+ int dot_dot_dot_token = 0;
public:
- ExceptionDeclarationAST()
- : type_specifier_list(0)
- , declarator(0)
- , dot_dot_dot_token(0)
- {}
-
virtual ExceptionDeclarationAST *asExceptionDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ExceptionDeclarationAST *clone(MemoryPool *pool) const;
@@ -1778,9 +1406,6 @@ protected:
class CPLUSPLUS_EXPORT ExceptionSpecificationAST: public AST
{
public:
- ExceptionSpecificationAST()
- {}
-
virtual ExceptionSpecificationAST *asExceptionSpecification() { return this; }
virtual ExceptionSpecificationAST *clone(MemoryPool *pool) const = 0;
@@ -1789,25 +1414,17 @@ public:
class CPLUSPLUS_EXPORT DynamicExceptionSpecificationAST: public ExceptionSpecificationAST
{
public:
- unsigned throw_token;
- unsigned lparen_token;
- unsigned dot_dot_dot_token;
- ExpressionListAST *type_id_list;
- unsigned rparen_token;
+ int throw_token = 0;
+ int lparen_token = 0;
+ int dot_dot_dot_token = 0;
+ ExpressionListAST *type_id_list = nullptr;
+ int rparen_token = 0;
public:
- DynamicExceptionSpecificationAST()
- : throw_token(0)
- , lparen_token(0)
- , dot_dot_dot_token(0)
- , type_id_list(0)
- , rparen_token(0)
- {}
-
virtual DynamicExceptionSpecificationAST *asDynamicExceptionSpecification() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DynamicExceptionSpecificationAST *clone(MemoryPool *pool) const;
@@ -1819,23 +1436,16 @@ protected:
class CPLUSPLUS_EXPORT NoExceptSpecificationAST: public ExceptionSpecificationAST
{
public:
- unsigned noexcept_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int noexcept_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- NoExceptSpecificationAST()
- : noexcept_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual NoExceptSpecificationAST *asNoExceptSpecification() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NoExceptSpecificationAST *clone(MemoryPool *pool) const;
@@ -1847,19 +1457,14 @@ protected:
class CPLUSPLUS_EXPORT ExpressionOrDeclarationStatementAST: public StatementAST
{
public:
- ExpressionStatementAST *expression;
- DeclarationStatementAST *declaration;
+ ExpressionStatementAST *expression = nullptr;
+ DeclarationStatementAST *declaration = nullptr;
public:
- ExpressionOrDeclarationStatementAST()
- : expression(0)
- , declaration(0)
- {}
-
virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ExpressionOrDeclarationStatementAST *clone(MemoryPool *pool) const;
@@ -1871,19 +1476,14 @@ protected:
class CPLUSPLUS_EXPORT ExpressionStatementAST: public StatementAST
{
public:
- ExpressionAST *expression;
- unsigned semicolon_token;
+ ExpressionAST *expression = nullptr;
+ int semicolon_token = 0;
public:
- ExpressionStatementAST()
- : expression(0)
- , semicolon_token(0)
- {}
-
virtual ExpressionStatementAST *asExpressionStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ExpressionStatementAST *clone(MemoryPool *pool) const;
@@ -1895,29 +1495,20 @@ protected:
class CPLUSPLUS_EXPORT FunctionDefinitionAST: public DeclarationAST
{
public:
- unsigned qt_invokable_token;
- SpecifierListAST *decl_specifier_list;
- DeclaratorAST *declarator;
- CtorInitializerAST *ctor_initializer;
- StatementAST *function_body;
+ int qt_invokable_token = 0;
+ SpecifierListAST *decl_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
+ CtorInitializerAST *ctor_initializer = nullptr;
+ StatementAST *function_body = nullptr;
public: // annotations
- Function *symbol;
+ Function *symbol = nullptr;
public:
- FunctionDefinitionAST()
- : qt_invokable_token(0)
- , decl_specifier_list(0)
- , declarator(0)
- , ctor_initializer(0)
- , function_body(0)
- , symbol(0)
- {}
-
virtual FunctionDefinitionAST *asFunctionDefinition() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual FunctionDefinitionAST *clone(MemoryPool *pool) const;
@@ -1929,39 +1520,26 @@ protected:
class CPLUSPLUS_EXPORT ForeachStatementAST: public StatementAST
{
public:
- unsigned foreach_token;
- unsigned lparen_token;
+ int foreach_token = 0;
+ int lparen_token = 0;
// declaration
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
// or an expression
- ExpressionAST *initializer;
- unsigned comma_token;
- ExpressionAST *expression;
- unsigned rparen_token;
- StatementAST *statement;
+ ExpressionAST *initializer = nullptr;
+ int comma_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
-
-public:
- ForeachStatementAST()
- : foreach_token(0)
- , lparen_token(0)
- , type_specifier_list(0)
- , declarator(0)
- , initializer(0)
- , comma_token(0)
- , expression(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
+ Block *symbol = nullptr;
+public:
virtual ForeachStatementAST *asForeachStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ForeachStatementAST *clone(MemoryPool *pool) const;
@@ -1973,37 +1551,25 @@ protected:
class CPLUSPLUS_EXPORT RangeBasedForStatementAST : public StatementAST
{
public:
- unsigned for_token;
- unsigned lparen_token;
+ int for_token = 0;
+ int lparen_token = 0;
// declaration
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
// or an expression
- unsigned colon_token;
- ExpressionAST *expression;
- unsigned rparen_token;
- StatementAST *statement;
+ int colon_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- RangeBasedForStatementAST()
- : for_token(0)
- , lparen_token(0)
- , type_specifier_list(0)
- , declarator(0)
- , colon_token(0)
- , expression(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
-
virtual RangeBasedForStatementAST *asRangeBasedForStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual RangeBasedForStatementAST *clone(MemoryPool *pool) const;
@@ -2015,35 +1581,23 @@ protected:
class CPLUSPLUS_EXPORT ForStatementAST: public StatementAST
{
public:
- unsigned for_token;
- unsigned lparen_token;
- StatementAST *initializer;
- ExpressionAST *condition;
- unsigned semicolon_token;
- ExpressionAST *expression;
- unsigned rparen_token;
- StatementAST *statement;
+ int for_token = 0;
+ int lparen_token = 0;
+ StatementAST *initializer = nullptr;
+ ExpressionAST *condition = nullptr;
+ int semicolon_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- ForStatementAST()
- : for_token(0)
- , lparen_token(0)
- , initializer(0)
- , condition(0)
- , semicolon_token(0)
- , expression(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
-
virtual ForStatementAST *asForStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ForStatementAST *clone(MemoryPool *pool) const;
@@ -2055,33 +1609,22 @@ protected:
class CPLUSPLUS_EXPORT IfStatementAST: public StatementAST
{
public:
- unsigned if_token;
- unsigned lparen_token;
- ExpressionAST *condition;
- unsigned rparen_token;
- StatementAST *statement;
- unsigned else_token;
- StatementAST *else_statement;
+ int if_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *condition = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
+ int else_token = 0;
+ StatementAST *else_statement = nullptr;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- IfStatementAST()
- : if_token(0)
- , lparen_token(0)
- , condition(0)
- , rparen_token(0)
- , statement(0)
- , else_token(0)
- , else_statement(0)
- , symbol(0)
- {}
-
virtual IfStatementAST *asIfStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual IfStatementAST *clone(MemoryPool *pool) const;
@@ -2093,21 +1636,15 @@ protected:
class CPLUSPLUS_EXPORT ArrayInitializerAST: public ExpressionAST
{
public:
- unsigned lbrace_token;
- ExpressionListAST *expression_list;
- unsigned rbrace_token;
+ int lbrace_token = 0;
+ ExpressionListAST *expression_list = nullptr;
+ int rbrace_token = 0;
public:
- ArrayInitializerAST()
- : lbrace_token(0)
- , expression_list(0)
- , rbrace_token(0)
- {}
-
virtual ArrayInitializerAST *asArrayInitializer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ArrayInitializerAST *clone(MemoryPool *pool) const;
@@ -2119,21 +1656,15 @@ protected:
class CPLUSPLUS_EXPORT LabeledStatementAST: public StatementAST
{
public:
- unsigned label_token;
- unsigned colon_token;
- StatementAST *statement;
+ int label_token = 0;
+ int colon_token = 0;
+ StatementAST *statement = nullptr;
public:
- LabeledStatementAST()
- : label_token(0)
- , colon_token(0)
- , statement(0)
- {}
-
virtual LabeledStatementAST *asLabeledStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LabeledStatementAST *clone(MemoryPool *pool) const;
@@ -2145,20 +1676,14 @@ protected:
class CPLUSPLUS_EXPORT LinkageBodyAST: public DeclarationAST
{
public:
- unsigned lbrace_token;
- DeclarationListAST *declaration_list;
- unsigned rbrace_token;
+ int lbrace_token = 0;
+ DeclarationListAST *declaration_list = nullptr;
+ int rbrace_token = 0;
public:
- LinkageBodyAST()
- : lbrace_token(0)
- , declaration_list(0)
- , rbrace_token(0)
- {}
-
virtual LinkageBodyAST *asLinkageBody() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LinkageBodyAST *clone(MemoryPool *pool) const;
@@ -2170,21 +1695,15 @@ protected:
class CPLUSPLUS_EXPORT LinkageSpecificationAST: public DeclarationAST
{
public:
- unsigned extern_token;
- unsigned extern_type_token;
- DeclarationAST *declaration;
+ int extern_token = 0;
+ int extern_type_token = 0;
+ DeclarationAST *declaration = nullptr;
public:
- LinkageSpecificationAST()
- : extern_token(0)
- , extern_type_token(0)
- , declaration(0)
- {}
-
virtual LinkageSpecificationAST *asLinkageSpecification() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LinkageSpecificationAST *clone(MemoryPool *pool) const;
@@ -2196,20 +1715,15 @@ protected:
class CPLUSPLUS_EXPORT MemInitializerAST: public AST
{
public:
- NameAST *name;
+ NameAST *name = nullptr;
// either a BracedInitializerAST or a ExpressionListParenAST
- ExpressionAST *expression;
+ ExpressionAST *expression = nullptr;
public:
- MemInitializerAST()
- : name(0)
- , expression(0)
- {}
-
virtual MemInitializerAST *asMemInitializer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual MemInitializerAST *clone(MemoryPool *pool) const;
@@ -2221,19 +1735,14 @@ protected:
class CPLUSPLUS_EXPORT NestedNameSpecifierAST: public AST
{
public:
- NameAST *class_or_namespace_name;
- unsigned scope_token;
+ NameAST *class_or_namespace_name = nullptr;
+ int scope_token = 0;
public:
- NestedNameSpecifierAST()
- : class_or_namespace_name(0)
- , scope_token(0)
- {}
-
virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NestedNameSpecifierAST *clone(MemoryPool *pool) const;
@@ -2245,21 +1754,15 @@ protected:
class CPLUSPLUS_EXPORT QualifiedNameAST: public NameAST
{
public:
- unsigned global_scope_token;
- NestedNameSpecifierListAST *nested_name_specifier_list;
- NameAST *unqualified_name;
+ int global_scope_token = 0;
+ NestedNameSpecifierListAST *nested_name_specifier_list = nullptr;
+ NameAST *unqualified_name = nullptr;
public:
- QualifiedNameAST()
- : global_scope_token(0)
- , nested_name_specifier_list(0)
- , unqualified_name(0)
- {}
-
virtual QualifiedNameAST *asQualifiedName() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual QualifiedNameAST *clone(MemoryPool *pool) const;
@@ -2271,19 +1774,14 @@ protected:
class CPLUSPLUS_EXPORT OperatorFunctionIdAST: public NameAST
{
public:
- unsigned operator_token;
- OperatorAST *op;
+ int operator_token = 0;
+ OperatorAST *op = nullptr;
public:
- OperatorFunctionIdAST()
- : operator_token(0)
- , op(0)
- {}
-
virtual OperatorFunctionIdAST *asOperatorFunctionId() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual OperatorFunctionIdAST *clone(MemoryPool *pool) const;
@@ -2295,21 +1793,15 @@ protected:
class CPLUSPLUS_EXPORT ConversionFunctionIdAST: public NameAST
{
public:
- unsigned operator_token;
- SpecifierListAST *type_specifier_list;
- PtrOperatorListAST *ptr_operator_list;
+ int operator_token = 0;
+ SpecifierListAST *type_specifier_list = nullptr;
+ PtrOperatorListAST *ptr_operator_list = nullptr;
public:
- ConversionFunctionIdAST()
- : operator_token(0)
- , type_specifier_list(0)
- , ptr_operator_list(0)
- {}
-
virtual ConversionFunctionIdAST *asConversionFunctionId() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ConversionFunctionIdAST *clone(MemoryPool *pool) const;
@@ -2321,15 +1813,12 @@ protected:
class CPLUSPLUS_EXPORT AnonymousNameAST: public NameAST
{
public:
- unsigned class_token;
-public:
- AnonymousNameAST()
- : class_token(0)
- {}
+ int class_token = 0;
+public:
virtual AnonymousNameAST *asAnonymousName() { return this; }
- virtual unsigned firstToken() const { return 0; }
- virtual unsigned lastToken() const { return 0; }
+ virtual int firstToken() const { return 0; }
+ virtual int lastToken() const { return 0; }
virtual AnonymousNameAST *clone(MemoryPool *pool) const;
@@ -2341,17 +1830,13 @@ protected:
class CPLUSPLUS_EXPORT SimpleNameAST: public NameAST
{
public:
- unsigned identifier_token;
+ int identifier_token = 0;
public:
- SimpleNameAST()
- : identifier_token(0)
- {}
-
virtual SimpleNameAST *asSimpleName() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual SimpleNameAST *clone(MemoryPool *pool) const;
@@ -2363,19 +1848,14 @@ protected:
class CPLUSPLUS_EXPORT DestructorNameAST: public NameAST
{
public:
- unsigned tilde_token;
- NameAST *unqualified_name;
+ int tilde_token = 0;
+ NameAST *unqualified_name = nullptr;
public:
- DestructorNameAST()
- : tilde_token(0)
- , unqualified_name(0)
- {}
-
virtual DestructorNameAST *asDestructorName() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DestructorNameAST *clone(MemoryPool *pool) const;
@@ -2387,25 +1867,17 @@ protected:
class CPLUSPLUS_EXPORT TemplateIdAST: public NameAST
{
public:
- unsigned template_token;
- unsigned identifier_token;
- unsigned less_token;
- ExpressionListAST *template_argument_list;
- unsigned greater_token;
+ int template_token = 0;
+ int identifier_token = 0;
+ int less_token = 0;
+ ExpressionListAST *template_argument_list = nullptr;
+ int greater_token = 0;
public:
- TemplateIdAST()
- : template_token(0)
- , identifier_token(0)
- , less_token(0)
- , template_argument_list(0)
- , greater_token(0)
- {}
-
virtual TemplateIdAST *asTemplateId() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TemplateIdAST *clone(MemoryPool *pool) const;
@@ -2417,29 +1889,20 @@ protected:
class CPLUSPLUS_EXPORT NamespaceAST: public DeclarationAST
{
public:
- unsigned inline_token;
- unsigned namespace_token;
- unsigned identifier_token;
- SpecifierListAST *attribute_list;
- DeclarationAST *linkage_body;
+ int inline_token = 0;
+ int namespace_token = 0;
+ int identifier_token = 0;
+ SpecifierListAST *attribute_list = nullptr;
+ DeclarationAST *linkage_body = nullptr;
public: // annotations
- Namespace *symbol;
+ Namespace *symbol = nullptr;
public:
- NamespaceAST()
- : inline_token(0)
- , namespace_token(0)
- , identifier_token(0)
- , attribute_list(0)
- , linkage_body(0)
- , symbol(0)
- {}
-
virtual NamespaceAST *asNamespace() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NamespaceAST *clone(MemoryPool *pool) const;
@@ -2451,25 +1914,17 @@ protected:
class CPLUSPLUS_EXPORT NamespaceAliasDefinitionAST: public DeclarationAST
{
public:
- unsigned namespace_token;
- unsigned namespace_name_token;
- unsigned equal_token;
- NameAST *name;
- unsigned semicolon_token;
+ int namespace_token = 0;
+ int namespace_name_token = 0;
+ int equal_token = 0;
+ NameAST *name = nullptr;
+ int semicolon_token = 0;
public:
- NamespaceAliasDefinitionAST()
- : namespace_token(0)
- , namespace_name_token(0)
- , equal_token(0)
- , name(0)
- , semicolon_token(0)
- {}
-
virtual NamespaceAliasDefinitionAST *asNamespaceAliasDefinition() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NamespaceAliasDefinitionAST *clone(MemoryPool *pool) const;
@@ -2481,29 +1936,20 @@ protected:
class CPLUSPLUS_EXPORT AliasDeclarationAST: public DeclarationAST
{
public:
- unsigned using_token;
- NameAST *name;
- unsigned equal_token;
- TypeIdAST *typeId;
- unsigned semicolon_token;
+ int using_token = 0;
+ NameAST *name = nullptr;
+ int equal_token = 0;
+ TypeIdAST *typeId = nullptr;
+ int semicolon_token = 0;
public: // annotations
- Declaration *symbol;
+ Declaration *symbol = nullptr;
public:
- AliasDeclarationAST()
- : using_token(0)
- , name(0)
- , equal_token(0)
- , typeId(0)
- , semicolon_token(0)
- , symbol(0)
- {}
-
virtual AliasDeclarationAST *asAliasDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual AliasDeclarationAST *clone(MemoryPool *pool) const;
@@ -2515,21 +1961,15 @@ protected:
class CPLUSPLUS_EXPORT ExpressionListParenAST: public ExpressionAST
{
public:
- unsigned lparen_token;
- ExpressionListAST *expression_list;
- unsigned rparen_token;
+ int lparen_token = 0;
+ ExpressionListAST *expression_list = nullptr;
+ int rparen_token = 0;
public:
- ExpressionListParenAST()
- : lparen_token(0)
- , expression_list(0)
- , rparen_token(0)
- {}
-
virtual ExpressionListParenAST *asExpressionListParen() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ExpressionListParenAST *clone(MemoryPool *pool) const;
@@ -2541,21 +1981,15 @@ protected:
class CPLUSPLUS_EXPORT NewArrayDeclaratorAST: public AST
{
public:
- unsigned lbracket_token;
- ExpressionAST *expression;
- unsigned rbracket_token;
+ int lbracket_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rbracket_token = 0;
public:
- NewArrayDeclaratorAST()
- : lbracket_token(0)
- , expression(0)
- , rbracket_token(0)
- {}
-
virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NewArrayDeclaratorAST *clone(MemoryPool *pool) const;
@@ -2567,34 +2001,23 @@ protected:
class CPLUSPLUS_EXPORT NewExpressionAST: public ExpressionAST
{
public:
- unsigned scope_token;
- unsigned new_token;
- ExpressionListParenAST *new_placement;
+ int scope_token = 0;
+ int new_token = 0;
+ ExpressionListParenAST *new_placement = nullptr;
- unsigned lparen_token;
- ExpressionAST *type_id;
- unsigned rparen_token;
+ int lparen_token = 0;
+ ExpressionAST *type_id = nullptr;
+ int rparen_token = 0;
- NewTypeIdAST *new_type_id;
+ NewTypeIdAST *new_type_id = nullptr;
- ExpressionAST *new_initializer; // either ExpressionListParenAST or BracedInitializerAST
+ ExpressionAST *new_initializer = nullptr; // either ExpressionListParenAST or BracedInitializerAST
public:
- NewExpressionAST()
- : scope_token(0)
- , new_token(0)
- , new_placement(0)
- , lparen_token(0)
- , type_id(0)
- , rparen_token(0)
- , new_type_id(0)
- , new_initializer(0)
- {}
-
virtual NewExpressionAST *asNewExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NewExpressionAST *clone(MemoryPool *pool) const;
@@ -2606,21 +2029,15 @@ protected:
class CPLUSPLUS_EXPORT NewTypeIdAST: public AST
{
public:
- SpecifierListAST *type_specifier_list;
- PtrOperatorListAST *ptr_operator_list;
- NewArrayDeclaratorListAST *new_array_declarator_list;
+ SpecifierListAST *type_specifier_list = nullptr;
+ PtrOperatorListAST *ptr_operator_list = nullptr;
+ NewArrayDeclaratorListAST *new_array_declarator_list = nullptr;
public:
- NewTypeIdAST()
- : type_specifier_list(0)
- , ptr_operator_list(0)
- , new_array_declarator_list(0)
- {}
-
virtual NewTypeIdAST *asNewTypeId() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NewTypeIdAST *clone(MemoryPool *pool) const;
@@ -2632,21 +2049,15 @@ protected:
class CPLUSPLUS_EXPORT OperatorAST: public AST
{
public:
- unsigned op_token;
- unsigned open_token;
- unsigned close_token;
+ int op_token = 0;
+ int open_token = 0;
+ int close_token = 0;
public:
- OperatorAST()
- : op_token(0)
- , open_token(0)
- , close_token(0)
- {}
-
virtual OperatorAST *asOperator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual OperatorAST *clone(MemoryPool *pool) const;
@@ -2658,27 +2069,19 @@ protected:
class CPLUSPLUS_EXPORT ParameterDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
- unsigned equal_token;
- ExpressionAST *expression;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
+ int equal_token = 0;
+ ExpressionAST *expression = nullptr;
public: // annotations
- Argument *symbol;
+ Argument *symbol = nullptr;
public:
- ParameterDeclarationAST()
- : type_specifier_list(0)
- , declarator(0)
- , equal_token(0)
- , expression(0)
- , symbol(0)
- {}
-
virtual ParameterDeclarationAST *asParameterDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ParameterDeclarationAST *clone(MemoryPool *pool) const;
@@ -2690,19 +2093,14 @@ protected:
class CPLUSPLUS_EXPORT ParameterDeclarationClauseAST: public AST
{
public:
- ParameterDeclarationListAST *parameter_declaration_list;
- unsigned dot_dot_dot_token;
+ ParameterDeclarationListAST *parameter_declaration_list = nullptr;
+ int dot_dot_dot_token = 0;
public:
- ParameterDeclarationClauseAST()
- : parameter_declaration_list(0)
- , dot_dot_dot_token(0)
- {}
-
virtual ParameterDeclarationClauseAST *asParameterDeclarationClause() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ParameterDeclarationClauseAST *clone(MemoryPool *pool) const;
@@ -2714,23 +2112,16 @@ protected:
class CPLUSPLUS_EXPORT CallAST: public PostfixAST
{
public:
- ExpressionAST *base_expression;
- unsigned lparen_token;
- ExpressionListAST *expression_list;
- unsigned rparen_token;
+ ExpressionAST *base_expression = nullptr;
+ int lparen_token = 0;
+ ExpressionListAST *expression_list = nullptr;
+ int rparen_token = 0;
public:
- CallAST()
- : base_expression(0)
- , lparen_token(0)
- , expression_list(0)
- , rparen_token(0)
- {}
-
virtual CallAST *asCall() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CallAST *clone(MemoryPool *pool) const;
@@ -2742,23 +2133,16 @@ protected:
class CPLUSPLUS_EXPORT ArrayAccessAST: public PostfixAST
{
public:
- ExpressionAST *base_expression;
- unsigned lbracket_token;
- ExpressionAST *expression;
- unsigned rbracket_token;
+ ExpressionAST *base_expression = nullptr;
+ int lbracket_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rbracket_token = 0;
public:
- ArrayAccessAST()
- : base_expression(0)
- , lbracket_token(0)
- , expression(0)
- , rbracket_token(0)
- {}
-
virtual ArrayAccessAST *asArrayAccess() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ArrayAccessAST *clone(MemoryPool *pool) const;
@@ -2770,19 +2154,14 @@ protected:
class CPLUSPLUS_EXPORT PostIncrDecrAST: public PostfixAST
{
public:
- ExpressionAST *base_expression;
- unsigned incr_decr_token;
+ ExpressionAST *base_expression = nullptr;
+ int incr_decr_token = 0;
public:
- PostIncrDecrAST()
- : base_expression(0)
- , incr_decr_token(0)
- {}
-
virtual PostIncrDecrAST *asPostIncrDecr() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual PostIncrDecrAST *clone(MemoryPool *pool) const;
@@ -2794,23 +2173,16 @@ protected:
class CPLUSPLUS_EXPORT MemberAccessAST: public PostfixAST
{
public:
- ExpressionAST *base_expression;
- unsigned access_token;
- unsigned template_token;
- NameAST *member_name;
+ ExpressionAST *base_expression = nullptr;
+ int access_token = 0;
+ int template_token = 0;
+ NameAST *member_name = nullptr;
public:
- MemberAccessAST()
- : base_expression(0)
- , access_token(0)
- , template_token(0)
- , member_name(0)
- {}
-
virtual MemberAccessAST *asMemberAccess() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual MemberAccessAST *clone(MemoryPool *pool) const;
@@ -2822,23 +2194,16 @@ protected:
class CPLUSPLUS_EXPORT TypeidExpressionAST: public ExpressionAST
{
public:
- unsigned typeid_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int typeid_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- TypeidExpressionAST()
- : typeid_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual TypeidExpressionAST *asTypeidExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TypeidExpressionAST *clone(MemoryPool *pool) const;
@@ -2850,21 +2215,15 @@ protected:
class CPLUSPLUS_EXPORT TypenameCallExpressionAST: public ExpressionAST
{
public:
- unsigned typename_token;
- NameAST *name;
- ExpressionAST *expression; // either ExpressionListParenAST or BracedInitializerAST
+ int typename_token = 0;
+ NameAST *name = nullptr;
+ ExpressionAST *expression = nullptr; // either ExpressionListParenAST or BracedInitializerAST
public:
- TypenameCallExpressionAST()
- : typename_token(0)
- , name(0)
- , expression(0)
- {}
-
virtual TypenameCallExpressionAST *asTypenameCallExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TypenameCallExpressionAST *clone(MemoryPool *pool) const;
@@ -2876,19 +2235,14 @@ protected:
class CPLUSPLUS_EXPORT TypeConstructorCallAST: public ExpressionAST
{
public:
- SpecifierListAST *type_specifier_list;
- ExpressionAST *expression; // either ExpressionListParenAST or BracedInitializerAST
+ SpecifierListAST *type_specifier_list = nullptr;
+ ExpressionAST *expression = nullptr; // either ExpressionListParenAST or BracedInitializerAST
public:
- TypeConstructorCallAST()
- : type_specifier_list(0)
- , expression(0)
- {}
-
virtual TypeConstructorCallAST *asTypeConstructorCall() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TypeConstructorCallAST *clone(MemoryPool *pool) const;
@@ -2900,25 +2254,17 @@ protected:
class CPLUSPLUS_EXPORT PointerToMemberAST: public PtrOperatorAST
{
public:
- unsigned global_scope_token;
- NestedNameSpecifierListAST *nested_name_specifier_list;
- unsigned star_token;
- SpecifierListAST *cv_qualifier_list;
- unsigned ref_qualifier_token;
+ int global_scope_token = 0;
+ NestedNameSpecifierListAST *nested_name_specifier_list = nullptr;
+ int star_token = 0;
+ SpecifierListAST *cv_qualifier_list = nullptr;
+ int ref_qualifier_token = 0;
public:
- PointerToMemberAST()
- : global_scope_token(0)
- , nested_name_specifier_list(0)
- , star_token(0)
- , cv_qualifier_list(0)
- , ref_qualifier_token(0)
- {}
-
virtual PointerToMemberAST *asPointerToMember() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual PointerToMemberAST *clone(MemoryPool *pool) const;
@@ -2930,19 +2276,14 @@ protected:
class CPLUSPLUS_EXPORT PointerAST: public PtrOperatorAST
{
public:
- unsigned star_token;
- SpecifierListAST *cv_qualifier_list;
+ int star_token = 0;
+ SpecifierListAST *cv_qualifier_list = nullptr;
public:
- PointerAST()
- : star_token(0)
- , cv_qualifier_list(0)
- {}
-
virtual PointerAST *asPointer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual PointerAST *clone(MemoryPool *pool) const;
@@ -2954,17 +2295,13 @@ protected:
class CPLUSPLUS_EXPORT ReferenceAST: public PtrOperatorAST
{
public:
- unsigned reference_token;
+ int reference_token = 0;
public:
- ReferenceAST()
- : reference_token(0)
- {}
-
virtual ReferenceAST *asReference() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ReferenceAST *clone(MemoryPool *pool) const;
@@ -2976,19 +2313,14 @@ protected:
class CPLUSPLUS_EXPORT BreakStatementAST: public StatementAST
{
public:
- unsigned break_token;
- unsigned semicolon_token;
+ int break_token = 0;
+ int semicolon_token = 0;
public:
- BreakStatementAST()
- : break_token(0)
- , semicolon_token(0)
- {}
-
virtual BreakStatementAST *asBreakStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual BreakStatementAST *clone(MemoryPool *pool) const;
@@ -3000,19 +2332,14 @@ protected:
class CPLUSPLUS_EXPORT ContinueStatementAST: public StatementAST
{
public:
- unsigned continue_token;
- unsigned semicolon_token;
+ int continue_token = 0;
+ int semicolon_token = 0;
public:
- ContinueStatementAST()
- : continue_token(0)
- , semicolon_token(0)
- {}
-
virtual ContinueStatementAST *asContinueStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ContinueStatementAST *clone(MemoryPool *pool) const;
@@ -3024,21 +2351,15 @@ protected:
class CPLUSPLUS_EXPORT GotoStatementAST: public StatementAST
{
public:
- unsigned goto_token;
- unsigned identifier_token;
- unsigned semicolon_token;
+ int goto_token = 0;
+ int identifier_token = 0;
+ int semicolon_token = 0;
public:
- GotoStatementAST()
- : goto_token(0)
- , identifier_token(0)
- , semicolon_token(0)
- {}
-
virtual GotoStatementAST *asGotoStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual GotoStatementAST *clone(MemoryPool *pool) const;
@@ -3050,21 +2371,15 @@ protected:
class CPLUSPLUS_EXPORT ReturnStatementAST: public StatementAST
{
public:
- unsigned return_token;
- ExpressionAST *expression;
- unsigned semicolon_token;
+ int return_token = 0;
+ ExpressionAST *expression = nullptr;
+ int semicolon_token = 0;
public:
- ReturnStatementAST()
- : return_token(0)
- , expression(0)
- , semicolon_token(0)
- {}
-
virtual ReturnStatementAST *asReturnStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ReturnStatementAST *clone(MemoryPool *pool) const;
@@ -3076,25 +2391,17 @@ protected:
class CPLUSPLUS_EXPORT SizeofExpressionAST: public ExpressionAST
{
public:
- unsigned sizeof_token;
- unsigned dot_dot_dot_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int sizeof_token = 0;
+ int dot_dot_dot_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- SizeofExpressionAST()
- : sizeof_token(0)
- , dot_dot_dot_token(0)
- , lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual SizeofExpressionAST *asSizeofExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual SizeofExpressionAST *clone(MemoryPool *pool) const;
@@ -3106,23 +2413,16 @@ protected:
class CPLUSPLUS_EXPORT AlignofExpressionAST: public ExpressionAST
{
public:
- unsigned alignof_token;
- unsigned lparen_token;
+ int alignof_token = 0;
+ int lparen_token = 0;
TypeIdAST *typeId;
- unsigned rparen_token;
+ int rparen_token = 0;
public:
- AlignofExpressionAST()
- : alignof_token(0)
- , lparen_token(0)
- , typeId(0)
- , rparen_token(0)
- {}
-
virtual AlignofExpressionAST *asAlignofExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual AlignofExpressionAST *clone(MemoryPool *pool) const;
@@ -3134,17 +2434,13 @@ protected:
class CPLUSPLUS_EXPORT PointerLiteralAST: public ExpressionAST
{
public:
- unsigned literal_token;
+ int literal_token = 0;
public:
- PointerLiteralAST()
- : literal_token(0)
- {}
-
virtual PointerLiteralAST *asPointerLiteral() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual PointerLiteralAST *clone(MemoryPool *pool) const;
@@ -3156,17 +2452,13 @@ protected:
class CPLUSPLUS_EXPORT NumericLiteralAST: public ExpressionAST
{
public:
- unsigned literal_token;
+ int literal_token = 0;
public:
- NumericLiteralAST()
- : literal_token(0)
- {}
-
virtual NumericLiteralAST *asNumericLiteral() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NumericLiteralAST *clone(MemoryPool *pool) const;
@@ -3178,17 +2470,13 @@ protected:
class CPLUSPLUS_EXPORT BoolLiteralAST: public ExpressionAST
{
public:
- unsigned literal_token;
+ int literal_token = 0;
public:
- BoolLiteralAST()
- : literal_token(0)
- {}
-
virtual BoolLiteralAST *asBoolLiteral() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual BoolLiteralAST *clone(MemoryPool *pool) const;
@@ -3200,17 +2488,13 @@ protected:
class CPLUSPLUS_EXPORT ThisExpressionAST: public ExpressionAST
{
public:
- unsigned this_token;
+ int this_token = 0;
public:
- ThisExpressionAST()
- : this_token(0)
- {}
-
virtual ThisExpressionAST *asThisExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ThisExpressionAST *clone(MemoryPool *pool) const;
@@ -3222,21 +2506,15 @@ protected:
class CPLUSPLUS_EXPORT NestedExpressionAST: public ExpressionAST
{
public:
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned rparen_token;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rparen_token = 0;
public:
- NestedExpressionAST()
- : lparen_token(0)
- , expression(0)
- , rparen_token(0)
- {}
-
virtual NestedExpressionAST *asNestedExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NestedExpressionAST *clone(MemoryPool *pool) const;
@@ -3248,29 +2526,19 @@ protected:
class CPLUSPLUS_EXPORT StaticAssertDeclarationAST: public DeclarationAST
{
public:
- unsigned static_assert_token;
- unsigned lparen_token;
- ExpressionAST *expression;
- unsigned comma_token;
- ExpressionAST *string_literal;
- unsigned rparen_token;
- unsigned semicolon_token;
+ int static_assert_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *expression = nullptr;
+ int comma_token = 0;
+ ExpressionAST *string_literal = nullptr;
+ int rparen_token = 0;
+ int semicolon_token = 0;
public:
- StaticAssertDeclarationAST()
- : static_assert_token(0)
- , lparen_token(0)
- , expression(0)
- , comma_token(0)
- , string_literal(0)
- , rparen_token(0)
- , semicolon_token(0)
- {}
-
virtual StaticAssertDeclarationAST *asStaticAssertDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual StaticAssertDeclarationAST *clone(MemoryPool *pool) const;
@@ -3282,19 +2550,14 @@ protected:
class CPLUSPLUS_EXPORT StringLiteralAST: public ExpressionAST
{
public:
- unsigned literal_token;
- StringLiteralAST *next;
+ int literal_token = 0;
+ StringLiteralAST *next = nullptr;
public:
- StringLiteralAST()
- : literal_token(0)
- , next(0)
- {}
-
virtual StringLiteralAST *asStringLiteral() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual StringLiteralAST *clone(MemoryPool *pool) const;
@@ -3306,29 +2569,20 @@ protected:
class CPLUSPLUS_EXPORT SwitchStatementAST: public StatementAST
{
public:
- unsigned switch_token;
- unsigned lparen_token;
- ExpressionAST *condition;
- unsigned rparen_token;
- StatementAST *statement;
+ int switch_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *condition = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- SwitchStatementAST()
- : switch_token(0)
- , lparen_token(0)
- , condition(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
-
virtual SwitchStatementAST *asSwitchStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual SwitchStatementAST *clone(MemoryPool *pool) const;
@@ -3340,31 +2594,21 @@ protected:
class CPLUSPLUS_EXPORT TemplateDeclarationAST: public DeclarationAST
{
public:
- unsigned export_token;
- unsigned template_token;
- unsigned less_token;
- DeclarationListAST *template_parameter_list;
- unsigned greater_token;
- DeclarationAST *declaration;
+ int export_token = 0;
+ int template_token = 0;
+ int less_token = 0;
+ DeclarationListAST *template_parameter_list = nullptr;
+ int greater_token = 0;
+ DeclarationAST *declaration = nullptr;
public: // annotations
- Template *symbol;
+ Template *symbol = nullptr;
public:
- TemplateDeclarationAST()
- : export_token(0)
- , template_token(0)
- , less_token(0)
- , template_parameter_list(0)
- , greater_token(0)
- , declaration(0)
- , symbol(0)
- {}
-
virtual TemplateDeclarationAST *asTemplateDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TemplateDeclarationAST *clone(MemoryPool *pool) const;
@@ -3376,19 +2620,14 @@ protected:
class CPLUSPLUS_EXPORT ThrowExpressionAST: public ExpressionAST
{
public:
- unsigned throw_token;
- ExpressionAST *expression;
+ int throw_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- ThrowExpressionAST()
- : throw_token(0)
- , expression(0)
- {}
-
virtual ThrowExpressionAST *asThrowExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ThrowExpressionAST *clone(MemoryPool *pool) const;
@@ -3400,19 +2639,14 @@ protected:
class CPLUSPLUS_EXPORT NoExceptOperatorExpressionAST: public ExpressionAST
{
public:
- unsigned noexcept_token;
- ExpressionAST *expression;
+ int noexcept_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- NoExceptOperatorExpressionAST()
- : noexcept_token(0)
- , expression(0)
- {}
-
virtual NoExceptOperatorExpressionAST *asNoExceptOperatorExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual NoExceptOperatorExpressionAST *clone(MemoryPool *pool) const;
@@ -3424,17 +2658,13 @@ protected:
class CPLUSPLUS_EXPORT TranslationUnitAST: public AST
{
public:
- DeclarationListAST *declaration_list;
+ DeclarationListAST *declaration_list = nullptr;
public:
- TranslationUnitAST()
- : declaration_list(0)
- {}
-
virtual TranslationUnitAST *asTranslationUnit() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TranslationUnitAST *clone(MemoryPool *pool) const;
@@ -3446,21 +2676,15 @@ protected:
class CPLUSPLUS_EXPORT TryBlockStatementAST: public StatementAST
{
public:
- unsigned try_token;
- StatementAST *statement;
- CatchClauseListAST *catch_clause_list;
+ int try_token = 0;
+ StatementAST *statement = nullptr;
+ CatchClauseListAST *catch_clause_list = nullptr;
public:
- TryBlockStatementAST()
- : try_token(0)
- , statement(0)
- , catch_clause_list(0)
- {}
-
virtual TryBlockStatementAST *asTryBlockStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TryBlockStatementAST *clone(MemoryPool *pool) const;
@@ -3472,29 +2696,20 @@ protected:
class CPLUSPLUS_EXPORT CatchClauseAST: public StatementAST
{
public:
- unsigned catch_token;
- unsigned lparen_token;
- ExceptionDeclarationAST *exception_declaration;
- unsigned rparen_token;
- StatementAST *statement;
+ int catch_token = 0;
+ int lparen_token = 0;
+ ExceptionDeclarationAST *exception_declaration = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- CatchClauseAST()
- : catch_token(0)
- , lparen_token(0)
- , exception_declaration(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
-
virtual CatchClauseAST *asCatchClause() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CatchClauseAST *clone(MemoryPool *pool) const;
@@ -3506,19 +2721,14 @@ protected:
class CPLUSPLUS_EXPORT TypeIdAST: public ExpressionAST
{
public:
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
public:
- TypeIdAST()
- : type_specifier_list(0)
- , declarator(0)
- {}
-
virtual TypeIdAST *asTypeId() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TypeIdAST *clone(MemoryPool *pool) const;
@@ -3530,29 +2740,20 @@ protected:
class CPLUSPLUS_EXPORT TypenameTypeParameterAST: public DeclarationAST
{
public:
- unsigned classkey_token;
- unsigned dot_dot_dot_token;
- NameAST *name;
- unsigned equal_token;
- ExpressionAST *type_id;
+ int classkey_token = 0;
+ int dot_dot_dot_token = 0;
+ NameAST *name = nullptr;
+ int equal_token = 0;
+ ExpressionAST *type_id = nullptr;
public: // annotations
- TypenameArgument *symbol;
+ TypenameArgument *symbol = nullptr;
public:
- TypenameTypeParameterAST()
- : classkey_token(0)
- , dot_dot_dot_token(0)
- , name(0)
- , equal_token(0)
- , type_id(0)
- , symbol(0)
- {}
-
virtual TypenameTypeParameterAST *asTypenameTypeParameter() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TypenameTypeParameterAST *clone(MemoryPool *pool) const;
@@ -3564,37 +2765,24 @@ protected:
class CPLUSPLUS_EXPORT TemplateTypeParameterAST: public DeclarationAST
{
public:
- unsigned template_token;
- unsigned less_token;
- DeclarationListAST *template_parameter_list;
- unsigned greater_token;
- unsigned class_token;
- unsigned dot_dot_dot_token;
- NameAST *name;
- unsigned equal_token;
- ExpressionAST *type_id;
+ int template_token = 0;
+ int less_token = 0;
+ DeclarationListAST *template_parameter_list = nullptr;
+ int greater_token = 0;
+ int class_token = 0;
+ int dot_dot_dot_token = 0;
+ NameAST *name = nullptr;
+ int equal_token = 0;
+ ExpressionAST *type_id = nullptr;
public:
- TypenameArgument *symbol;
+ TypenameArgument *symbol = nullptr;
public:
- TemplateTypeParameterAST()
- : template_token(0)
- , less_token(0)
- , template_parameter_list(0)
- , greater_token(0)
- , class_token(0)
- , dot_dot_dot_token(0)
- , name(0)
- , equal_token(0)
- , type_id(0)
- , symbol(0)
- {}
-
virtual TemplateTypeParameterAST *asTemplateTypeParameter() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TemplateTypeParameterAST *clone(MemoryPool *pool) const;
@@ -3606,19 +2794,14 @@ protected:
class CPLUSPLUS_EXPORT UnaryExpressionAST: public ExpressionAST
{
public:
- unsigned unary_op_token;
- ExpressionAST *expression;
+ int unary_op_token = 0;
+ ExpressionAST *expression = nullptr;
public:
- UnaryExpressionAST()
- : unary_op_token(0)
- , expression(0)
- {}
-
virtual UnaryExpressionAST *asUnaryExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual UnaryExpressionAST *clone(MemoryPool *pool) const;
@@ -3630,27 +2813,19 @@ protected:
class CPLUSPLUS_EXPORT UsingAST: public DeclarationAST
{
public:
- unsigned using_token;
- unsigned typename_token;
- NameAST *name;
- unsigned semicolon_token;
+ int using_token = 0;
+ int typename_token = 0;
+ NameAST *name = nullptr;
+ int semicolon_token = 0;
public: // annotations
- UsingDeclaration *symbol;
+ UsingDeclaration *symbol = nullptr;
public:
- UsingAST()
- : using_token(0)
- , typename_token(0)
- , name(0)
- , semicolon_token(0)
- , symbol(0)
- {}
-
virtual UsingAST *asUsing() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual UsingAST *clone(MemoryPool *pool) const;
@@ -3662,27 +2837,19 @@ protected:
class CPLUSPLUS_EXPORT UsingDirectiveAST: public DeclarationAST
{
public:
- unsigned using_token;
- unsigned namespace_token;
- NameAST *name;
- unsigned semicolon_token;
+ int using_token = 0;
+ int namespace_token = 0;
+ NameAST *name = nullptr;
+ int semicolon_token = 0;
public:
- UsingNamespaceDirective *symbol;
+ UsingNamespaceDirective *symbol = nullptr;
public:
- UsingDirectiveAST()
- : using_token(0)
- , namespace_token(0)
- , name(0)
- , semicolon_token(0)
- , symbol(0)
- {}
-
virtual UsingDirectiveAST *asUsingDirective() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual UsingDirectiveAST *clone(MemoryPool *pool) const;
@@ -3694,29 +2861,20 @@ protected:
class CPLUSPLUS_EXPORT WhileStatementAST: public StatementAST
{
public:
- unsigned while_token;
- unsigned lparen_token;
- ExpressionAST *condition;
- unsigned rparen_token;
- StatementAST *statement;
+ int while_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *condition = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
+ Block *symbol = nullptr;
public:
- WhileStatementAST()
- : while_token(0)
- , lparen_token(0)
- , condition(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
-
virtual WhileStatementAST *asWhileStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual WhileStatementAST *clone(MemoryPool *pool) const;
@@ -3728,27 +2886,19 @@ protected:
class CPLUSPLUS_EXPORT ObjCClassForwardDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *attribute_list;
- unsigned class_token;
- NameListAST *identifier_list;
- unsigned semicolon_token;
+ SpecifierListAST *attribute_list = nullptr;
+ int class_token = 0;
+ NameListAST *identifier_list = nullptr;
+ int semicolon_token = 0;
public: // annotations
- List<ObjCForwardClassDeclaration *> *symbols;
+ List<ObjCForwardClassDeclaration *> *symbols = nullptr;
public:
- ObjCClassForwardDeclarationAST()
- : attribute_list(0)
- , class_token(0)
- , identifier_list(0)
- , semicolon_token(0)
- , symbols(0)
- {}
-
virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCClassForwardDeclarationAST *clone(MemoryPool *pool) const;
@@ -3760,45 +2910,28 @@ protected:
class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *attribute_list;
- unsigned interface_token;
- unsigned implementation_token;
- NameAST *class_name;
- unsigned lparen_token;
- NameAST *category_name;
- unsigned rparen_token;
- unsigned colon_token;
- NameAST *superclass;
- ObjCProtocolRefsAST *protocol_refs;
- ObjCInstanceVariablesDeclarationAST *inst_vars_decl;
- DeclarationListAST *member_declaration_list;
- unsigned end_token;
+ SpecifierListAST *attribute_list = nullptr;
+ int interface_token = 0;
+ int implementation_token = 0;
+ NameAST *class_name = nullptr;
+ int lparen_token = 0;
+ NameAST *category_name = nullptr;
+ int rparen_token = 0;
+ int colon_token = 0;
+ NameAST *superclass = nullptr;
+ ObjCProtocolRefsAST *protocol_refs = nullptr;
+ ObjCInstanceVariablesDeclarationAST *inst_vars_decl = nullptr;
+ DeclarationListAST *member_declaration_list = nullptr;
+ int end_token = 0;
public: // annotations
- ObjCClass *symbol;
-
-public:
- ObjCClassDeclarationAST()
- : attribute_list(0)
- , interface_token(0)
- , implementation_token(0)
- , class_name(0)
- , lparen_token(0)
- , category_name(0)
- , rparen_token(0)
- , colon_token(0)
- , superclass(0)
- , protocol_refs(0)
- , inst_vars_decl(0)
- , member_declaration_list(0)
- , end_token(0)
- , symbol(0)
- {}
+ ObjCClass *symbol = nullptr;
+public:
virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCClassDeclarationAST *clone(MemoryPool *pool) const;
@@ -3810,27 +2943,19 @@ protected:
class CPLUSPLUS_EXPORT ObjCProtocolForwardDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *attribute_list;
- unsigned protocol_token;
- NameListAST *identifier_list;
- unsigned semicolon_token;
+ SpecifierListAST *attribute_list = nullptr;
+ int protocol_token = 0;
+ NameListAST *identifier_list = nullptr;
+ int semicolon_token = 0;
public: // annotations
- List<ObjCForwardProtocolDeclaration *> *symbols;
+ List<ObjCForwardProtocolDeclaration *> *symbols = nullptr;
public:
- ObjCProtocolForwardDeclarationAST()
- : attribute_list(0)
- , protocol_token(0)
- , identifier_list(0)
- , semicolon_token(0)
- , symbols(0)
- {}
-
virtual ObjCProtocolForwardDeclarationAST *asObjCProtocolForwardDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCProtocolForwardDeclarationAST *clone(MemoryPool *pool) const;
@@ -3842,31 +2967,21 @@ protected:
class CPLUSPLUS_EXPORT ObjCProtocolDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *attribute_list;
- unsigned protocol_token;
- NameAST *name;
- ObjCProtocolRefsAST *protocol_refs;
- DeclarationListAST *member_declaration_list;
- unsigned end_token;
+ SpecifierListAST *attribute_list = nullptr;
+ int protocol_token = 0;
+ NameAST *name = nullptr;
+ ObjCProtocolRefsAST *protocol_refs = nullptr;
+ DeclarationListAST *member_declaration_list = nullptr;
+ int end_token = 0;
public: // annotations
- ObjCProtocol *symbol;
+ ObjCProtocol *symbol = nullptr;
public:
- ObjCProtocolDeclarationAST()
- : attribute_list(0)
- , protocol_token(0)
- , name(0)
- , protocol_refs(0)
- , member_declaration_list(0)
- , end_token(0)
- , symbol(0)
- {}
-
virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCProtocolDeclarationAST *clone(MemoryPool *pool) const;
@@ -3878,21 +2993,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCProtocolRefsAST: public AST
{
public:
- unsigned less_token;
- NameListAST *identifier_list;
- unsigned greater_token;
+ int less_token = 0;
+ NameListAST *identifier_list = nullptr;
+ int greater_token = 0;
public:
- ObjCProtocolRefsAST()
- : less_token(0)
- , identifier_list(0)
- , greater_token(0)
- {}
-
virtual ObjCProtocolRefsAST *asObjCProtocolRefs() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCProtocolRefsAST *clone(MemoryPool *pool) const;
@@ -3904,17 +3013,13 @@ protected:
class CPLUSPLUS_EXPORT ObjCMessageArgumentAST: public AST
{
public:
- ExpressionAST *parameter_value_expression;
+ ExpressionAST *parameter_value_expression = nullptr;
public:
- ObjCMessageArgumentAST()
- : parameter_value_expression(0)
- {}
-
virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCMessageArgumentAST *clone(MemoryPool *pool) const;
@@ -3926,25 +3031,17 @@ protected:
class CPLUSPLUS_EXPORT ObjCMessageExpressionAST: public ExpressionAST
{
public:
- unsigned lbracket_token;
- ExpressionAST *receiver_expression;
- ObjCSelectorAST *selector;
- ObjCMessageArgumentListAST *argument_list;
- unsigned rbracket_token;
+ int lbracket_token = 0;
+ ExpressionAST *receiver_expression = nullptr;
+ ObjCSelectorAST *selector = nullptr;
+ ObjCMessageArgumentListAST *argument_list = nullptr;
+ int rbracket_token = 0;
public:
- ObjCMessageExpressionAST()
- : lbracket_token(0)
- , receiver_expression(0)
- , selector(0)
- , argument_list(0)
- , rbracket_token(0)
- {}
-
virtual ObjCMessageExpressionAST *asObjCMessageExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCMessageExpressionAST *clone(MemoryPool *pool) const;
@@ -3956,23 +3053,16 @@ protected:
class CPLUSPLUS_EXPORT ObjCProtocolExpressionAST: public ExpressionAST
{
public:
- unsigned protocol_token;
- unsigned lparen_token;
- unsigned identifier_token;
- unsigned rparen_token;
+ int protocol_token = 0;
+ int lparen_token = 0;
+ int identifier_token = 0;
+ int rparen_token = 0;
public:
- ObjCProtocolExpressionAST()
- : protocol_token(0)
- , lparen_token(0)
- , identifier_token(0)
- , rparen_token(0)
- {}
-
virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCProtocolExpressionAST *clone(MemoryPool *pool) const;
@@ -3984,23 +3074,16 @@ protected:
class CPLUSPLUS_EXPORT ObjCTypeNameAST: public AST
{
public:
- unsigned lparen_token;
- unsigned type_qualifier_token;
- ExpressionAST *type_id;
- unsigned rparen_token;
+ int lparen_token = 0;
+ int type_qualifier_token = 0;
+ ExpressionAST *type_id = nullptr;
+ int rparen_token = 0;
public:
- ObjCTypeNameAST()
- : lparen_token(0)
- , type_qualifier_token(0)
- , type_id(0)
- , rparen_token(0)
- {}
-
virtual ObjCTypeNameAST *asObjCTypeName() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCTypeNameAST *clone(MemoryPool *pool) const;
@@ -4012,19 +3095,14 @@ protected:
class CPLUSPLUS_EXPORT ObjCEncodeExpressionAST: public ExpressionAST
{
public:
- unsigned encode_token;
- ObjCTypeNameAST *type_name;
+ int encode_token = 0;
+ ObjCTypeNameAST *type_name = nullptr;
public:
- ObjCEncodeExpressionAST()
- : encode_token(0)
- , type_name(0)
- {}
-
virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCEncodeExpressionAST *clone(MemoryPool *pool) const;
@@ -4036,23 +3114,16 @@ protected:
class CPLUSPLUS_EXPORT ObjCSelectorExpressionAST: public ExpressionAST
{
public:
- unsigned selector_token;
- unsigned lparen_token;
- ObjCSelectorAST *selector;
- unsigned rparen_token;
+ int selector_token = 0;
+ int lparen_token = 0;
+ ObjCSelectorAST *selector = nullptr;
+ int rparen_token = 0;
public:
- ObjCSelectorExpressionAST()
- : selector_token(0)
- , lparen_token(0)
- , selector(0)
- , rparen_token(0)
- {}
-
virtual ObjCSelectorExpressionAST *asObjCSelectorExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCSelectorExpressionAST *clone(MemoryPool *pool) const;
@@ -4064,21 +3135,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCInstanceVariablesDeclarationAST: public AST
{
public:
- unsigned lbrace_token;
- DeclarationListAST *instance_variable_list;
- unsigned rbrace_token;
+ int lbrace_token = 0;
+ DeclarationListAST *instance_variable_list = nullptr;
+ int rbrace_token = 0;
public:
- ObjCInstanceVariablesDeclarationAST()
- : lbrace_token(0)
- , instance_variable_list(0)
- , rbrace_token(0)
- {}
-
virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCInstanceVariablesDeclarationAST *clone(MemoryPool *pool) const;
@@ -4090,17 +3155,13 @@ protected:
class CPLUSPLUS_EXPORT ObjCVisibilityDeclarationAST: public DeclarationAST
{
public:
- unsigned visibility_token;
+ int visibility_token = 0;
public:
- ObjCVisibilityDeclarationAST()
- : visibility_token(0)
- {}
-
virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCVisibilityDeclarationAST *clone(MemoryPool *pool) const;
@@ -4112,21 +3173,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCPropertyAttributeAST: public AST
{
public:
- unsigned attribute_identifier_token;
- unsigned equals_token;
- ObjCSelectorAST *method_selector;
+ int attribute_identifier_token = 0;
+ int equals_token = 0;
+ ObjCSelectorAST *method_selector = nullptr;
public:
- ObjCPropertyAttributeAST()
- : attribute_identifier_token(0)
- , equals_token(0)
- , method_selector(0)
- {}
-
virtual ObjCPropertyAttributeAST *asObjCPropertyAttribute() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCPropertyAttributeAST *clone(MemoryPool *pool) const;
@@ -4138,31 +3193,21 @@ protected:
class CPLUSPLUS_EXPORT ObjCPropertyDeclarationAST: public DeclarationAST
{
public:
- SpecifierListAST *attribute_list;
- unsigned property_token;
- unsigned lparen_token;
- ObjCPropertyAttributeListAST *property_attribute_list;
- unsigned rparen_token;
- DeclarationAST *simple_declaration;
+ SpecifierListAST *attribute_list = nullptr;
+ int property_token = 0;
+ int lparen_token = 0;
+ ObjCPropertyAttributeListAST *property_attribute_list = nullptr;
+ int rparen_token = 0;
+ DeclarationAST *simple_declaration = nullptr;
public: // annotations
- List<ObjCPropertyDeclaration *> *symbols;
+ List<ObjCPropertyDeclaration *> *symbols = nullptr;
public:
- ObjCPropertyDeclarationAST()
- : attribute_list(0)
- , property_token(0)
- , lparen_token(0)
- , property_attribute_list(0)
- , rparen_token(0)
- , simple_declaration(0)
- , symbols(0)
- {}
-
virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCPropertyDeclarationAST *clone(MemoryPool *pool) const;
@@ -4174,25 +3219,18 @@ protected:
class CPLUSPLUS_EXPORT ObjCMessageArgumentDeclarationAST: public AST
{
public:
- ObjCTypeNameAST* type_name;
- SpecifierListAST *attribute_list;
- NameAST *param_name;
+ ObjCTypeNameAST *type_name = nullptr;
+ SpecifierListAST *attribute_list = nullptr;
+ NameAST *param_name = nullptr;
public: // annotations
- Argument *argument;
+ Argument *argument = nullptr;
public:
- ObjCMessageArgumentDeclarationAST()
- : type_name(0)
- , attribute_list(0)
- , param_name(0)
- , argument(0)
- {}
-
virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCMessageArgumentDeclarationAST *clone(MemoryPool *pool) const;
@@ -4204,31 +3242,21 @@ protected:
class CPLUSPLUS_EXPORT ObjCMethodPrototypeAST: public AST
{
public:
- unsigned method_type_token;
- ObjCTypeNameAST *type_name;
- ObjCSelectorAST *selector;
- ObjCMessageArgumentDeclarationListAST *argument_list;
- unsigned dot_dot_dot_token;
- SpecifierListAST *attribute_list;
+ int method_type_token = 0;
+ ObjCTypeNameAST *type_name = nullptr;
+ ObjCSelectorAST *selector = nullptr;
+ ObjCMessageArgumentDeclarationListAST *argument_list = nullptr;
+ int dot_dot_dot_token = 0;
+ SpecifierListAST *attribute_list = nullptr;
public: // annotations
- ObjCMethod *symbol;
+ ObjCMethod *symbol = nullptr;
public:
- ObjCMethodPrototypeAST()
- : method_type_token(0)
- , type_name(0)
- , selector(0)
- , argument_list(0)
- , dot_dot_dot_token(0)
- , attribute_list(0)
- , symbol(0)
- {}
-
virtual ObjCMethodPrototypeAST *asObjCMethodPrototype() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCMethodPrototypeAST *clone(MemoryPool *pool) const;
@@ -4240,21 +3268,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCMethodDeclarationAST: public DeclarationAST
{
public:
- ObjCMethodPrototypeAST *method_prototype;
- StatementAST *function_body;
- unsigned semicolon_token;
+ ObjCMethodPrototypeAST *method_prototype = nullptr;
+ StatementAST *function_body = nullptr;
+ int semicolon_token = 0;
public:
- ObjCMethodDeclarationAST()
- : method_prototype(0)
- , function_body(0)
- , semicolon_token(0)
- {}
-
virtual ObjCMethodDeclarationAST *asObjCMethodDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCMethodDeclarationAST *clone(MemoryPool *pool) const;
@@ -4266,21 +3288,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCSynthesizedPropertyAST: public AST
{
public:
- unsigned property_identifier_token;
- unsigned equals_token;
- unsigned alias_identifier_token;
+ int property_identifier_token = 0;
+ int equals_token = 0;
+ int alias_identifier_token = 0;
public:
- ObjCSynthesizedPropertyAST()
- : property_identifier_token(0)
- , equals_token(0)
- , alias_identifier_token(0)
- {}
-
virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCSynthesizedPropertyAST *clone(MemoryPool *pool) const;
@@ -4292,21 +3308,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCSynthesizedPropertiesDeclarationAST: public DeclarationAST
{
public:
- unsigned synthesized_token;
- ObjCSynthesizedPropertyListAST *property_identifier_list;
- unsigned semicolon_token;
+ int synthesized_token = 0;
+ ObjCSynthesizedPropertyListAST *property_identifier_list = nullptr;
+ int semicolon_token = 0;
public:
- ObjCSynthesizedPropertiesDeclarationAST()
- : synthesized_token(0)
- , property_identifier_list(0)
- , semicolon_token(0)
- {}
-
virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCSynthesizedPropertiesDeclarationAST *clone(MemoryPool *pool) const;
@@ -4318,21 +3328,15 @@ protected:
class CPLUSPLUS_EXPORT ObjCDynamicPropertiesDeclarationAST: public DeclarationAST
{
public:
- unsigned dynamic_token;
- NameListAST *property_identifier_list;
- unsigned semicolon_token;
+ int dynamic_token = 0;
+ NameListAST *property_identifier_list = nullptr;
+ int semicolon_token = 0;
public:
- ObjCDynamicPropertiesDeclarationAST()
- : dynamic_token(0)
- , property_identifier_list(0)
- , semicolon_token(0)
- {}
-
virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCDynamicPropertiesDeclarationAST *clone(MemoryPool *pool) const;
@@ -4344,41 +3348,28 @@ protected:
class CPLUSPLUS_EXPORT ObjCFastEnumerationAST: public StatementAST
{
public:
- unsigned for_token;
- unsigned lparen_token;
+ int for_token = 0;
+ int lparen_token = 0;
// declaration
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
// or an expression
- ExpressionAST *initializer;
+ ExpressionAST *initializer = nullptr;
- unsigned in_token;
- ExpressionAST *fast_enumeratable_expression;
- unsigned rparen_token;
- StatementAST *statement;
+ int in_token = 0;
+ ExpressionAST *fast_enumeratable_expression = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public: // annotations
- Block *symbol;
-
-public:
- ObjCFastEnumerationAST()
- : for_token(0)
- , lparen_token(0)
- , type_specifier_list(0)
- , declarator(0)
- , initializer(0)
- , in_token(0)
- , fast_enumeratable_expression(0)
- , rparen_token(0)
- , statement(0)
- , symbol(0)
- {}
+ Block *symbol = nullptr;
+public:
virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCFastEnumerationAST *clone(MemoryPool *pool) const;
@@ -4390,25 +3381,17 @@ protected:
class CPLUSPLUS_EXPORT ObjCSynchronizedStatementAST: public StatementAST
{
public:
- unsigned synchronized_token;
- unsigned lparen_token;
- ExpressionAST *synchronized_object;
- unsigned rparen_token;
- StatementAST *statement;
+ int synchronized_token = 0;
+ int lparen_token = 0;
+ ExpressionAST *synchronized_object = nullptr;
+ int rparen_token = 0;
+ StatementAST *statement = nullptr;
public:
- ObjCSynchronizedStatementAST()
- : synchronized_token(0)
- , lparen_token(0)
- , synchronized_object(0)
- , rparen_token(0)
- , statement(0)
- {}
-
virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual ObjCSynchronizedStatementAST *clone(MemoryPool *pool) const;
@@ -4421,21 +3404,15 @@ protected:
class LambdaExpressionAST: public ExpressionAST
{
public:
- LambdaIntroducerAST *lambda_introducer;
- LambdaDeclaratorAST *lambda_declarator;
- StatementAST *statement;
+ LambdaIntroducerAST *lambda_introducer = nullptr;
+ LambdaDeclaratorAST *lambda_declarator = nullptr;
+ StatementAST *statement = nullptr;
public:
- LambdaExpressionAST()
- : lambda_introducer(0)
- , lambda_declarator(0)
- , statement(0)
- {}
-
virtual LambdaExpressionAST *asLambdaExpression() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LambdaExpressionAST *clone(MemoryPool *pool) const;
protected:
@@ -4446,20 +3423,14 @@ protected:
class LambdaIntroducerAST: public AST
{
public:
- unsigned lbracket_token;
- LambdaCaptureAST *lambda_capture;
- unsigned rbracket_token;
+ int lbracket_token = 0;
+ LambdaCaptureAST *lambda_capture = nullptr;
+ int rbracket_token = 0;
public:
- LambdaIntroducerAST()
- : lbracket_token(0)
- , lambda_capture(0)
- , rbracket_token(0)
- {}
-
virtual LambdaIntroducerAST *asLambdaIntroducer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LambdaIntroducerAST *clone(MemoryPool *pool) const;
@@ -4471,18 +3442,13 @@ protected:
class LambdaCaptureAST: public AST
{
public:
- unsigned default_capture_token;
- CaptureListAST *capture_list;
+ int default_capture_token = 0;
+ CaptureListAST *capture_list = nullptr;
public:
- LambdaCaptureAST()
- : default_capture_token(0)
- , capture_list(0)
- {}
-
virtual LambdaCaptureAST *asLambdaCapture() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LambdaCaptureAST *clone(MemoryPool *pool) const;
@@ -4494,18 +3460,13 @@ protected:
class CaptureAST: public AST
{
public:
- unsigned amper_token;
- NameAST *identifier;
+ int amper_token = 0;
+ NameAST *identifier = nullptr;
public:
- CaptureAST()
- : amper_token(0)
- , identifier(0)
- {}
-
virtual CaptureAST *asCapture() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual CaptureAST *clone(MemoryPool *pool) const;
@@ -4517,32 +3478,21 @@ protected:
class LambdaDeclaratorAST: public AST
{
public:
- unsigned lparen_token;
- ParameterDeclarationClauseAST *parameter_declaration_clause;
- unsigned rparen_token;
- SpecifierListAST *attributes;
- unsigned mutable_token;
- ExceptionSpecificationAST *exception_specification;
- TrailingReturnTypeAST *trailing_return_type;
+ int lparen_token = 0;
+ ParameterDeclarationClauseAST *parameter_declaration_clause = nullptr;
+ int rparen_token = 0;
+ SpecifierListAST *attributes = nullptr;
+ int mutable_token = 0;
+ ExceptionSpecificationAST *exception_specification = nullptr;
+ TrailingReturnTypeAST *trailing_return_type = nullptr;
public: // annotations
- Function *symbol;
+ Function *symbol = nullptr;
public:
- LambdaDeclaratorAST()
- : lparen_token(0)
- , parameter_declaration_clause(0)
- , rparen_token(0)
- , attributes(0)
- , mutable_token(0)
- , exception_specification(0)
- , trailing_return_type(0)
- , symbol(0)
- {}
-
virtual LambdaDeclaratorAST *asLambdaDeclarator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual LambdaDeclaratorAST *clone(MemoryPool *pool) const;
@@ -4554,22 +3504,15 @@ protected:
class TrailingReturnTypeAST: public AST
{
public:
- unsigned arrow_token;
- SpecifierListAST *attributes;
- SpecifierListAST *type_specifier_list;
- DeclaratorAST *declarator;
+ int arrow_token = 0;
+ SpecifierListAST *attributes = nullptr;
+ SpecifierListAST *type_specifier_list = nullptr;
+ DeclaratorAST *declarator = nullptr;
public:
- TrailingReturnTypeAST()
- : arrow_token(0)
- , attributes(0)
- , type_specifier_list(0)
- , declarator(0)
- {}
-
virtual TrailingReturnTypeAST *asTrailingReturnType() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual TrailingReturnTypeAST *clone(MemoryPool *pool) const;
@@ -4581,22 +3524,15 @@ protected:
class BracedInitializerAST: public ExpressionAST
{
public:
- unsigned lbrace_token;
- ExpressionListAST *expression_list;
- unsigned comma_token;
- unsigned rbrace_token;
+ int lbrace_token = 0;
+ ExpressionListAST *expression_list = nullptr;
+ int comma_token = 0;
+ int rbrace_token = 0;
public:
- BracedInitializerAST()
- : lbrace_token(0)
- , expression_list(0)
- , comma_token(0)
- , rbrace_token(0)
- {}
-
virtual BracedInitializerAST *asBracedInitializer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual BracedInitializerAST *clone(MemoryPool *pool) const;
@@ -4608,9 +3544,6 @@ protected:
class DesignatorAST: public AST
{
public:
- DesignatorAST()
- {}
-
virtual DesignatorAST *asDesignator() { return this; }
virtual DesignatorAST *clone(MemoryPool *pool) const = 0;
};
@@ -4618,17 +3551,13 @@ public:
class DotDesignatorAST: public DesignatorAST
{
public:
- unsigned dot_token;
- unsigned identifier_token;
-public:
- DotDesignatorAST()
- : dot_token(0)
- , identifier_token(0)
- {}
+ int dot_token = 0;
+ int identifier_token = 0;
+public:
virtual DotDesignatorAST *asDotDesignator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DotDesignatorAST *clone(MemoryPool *pool) const;
@@ -4640,19 +3569,14 @@ protected:
class BracketDesignatorAST: public DesignatorAST
{
public:
- unsigned lbracket_token;
- ExpressionAST *expression;
- unsigned rbracket_token;
-public:
- BracketDesignatorAST()
- : lbracket_token(0)
- , expression(0)
- , rbracket_token(0)
- {}
+ int lbracket_token = 0;
+ ExpressionAST *expression = nullptr;
+ int rbracket_token = 0;
+public:
virtual BracketDesignatorAST *asBracketDesignator() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual BracketDesignatorAST *clone(MemoryPool *pool) const;
@@ -4664,20 +3588,14 @@ protected:
class DesignatedInitializerAST: public ExpressionAST
{
public:
- DesignatorListAST *designator_list;
- unsigned equal_token;
- ExpressionAST *initializer;
+ DesignatorListAST *designator_list = nullptr;
+ int equal_token = 0;
+ ExpressionAST *initializer = nullptr;
public:
- DesignatedInitializerAST()
- : designator_list(0)
- , equal_token(0)
- , initializer(0)
- {}
-
virtual DesignatedInitializerAST *asDesignatedInitializer() { return this; }
- virtual unsigned firstToken() const;
- virtual unsigned lastToken() const;
+ virtual int firstToken() const;
+ virtual int lastToken() const;
virtual DesignatedInitializerAST *clone(MemoryPool *pool) const;
diff --git a/src/libs/3rdparty/cplusplus/ASTClone.cpp b/src/libs/3rdparty/cplusplus/ASTClone.cpp
index 17a1af18d9..65350e3eab 100644
--- a/src/libs/3rdparty/cplusplus/ASTClone.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTClone.cpp
@@ -44,7 +44,7 @@ ObjCSelectorAST *ObjCSelectorAST::clone(MemoryPool *pool) const
ObjCSelectorAST *ast = new (pool) ObjCSelectorAST;
for (ObjCSelectorArgumentListAST *iter = selector_argument_list, **ast_iter = &ast->selector_argument_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ObjCSelectorArgumentListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ObjCSelectorArgumentListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -75,7 +75,7 @@ GnuAttributeSpecifierAST *GnuAttributeSpecifierAST::clone(MemoryPool *pool) cons
ast->second_lparen_token = second_lparen_token;
for (GnuAttributeListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) GnuAttributeListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) GnuAttributeListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->first_rparen_token = first_rparen_token;
ast->second_rparen_token = second_rparen_token;
return ast;
@@ -89,7 +89,7 @@ GnuAttributeAST *GnuAttributeAST::clone(MemoryPool *pool) const
ast->tag_token = tag_token;
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -121,18 +121,18 @@ DeclaratorAST *DeclaratorAST::clone(MemoryPool *pool) const
DeclaratorAST *ast = new (pool) DeclaratorAST;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (PtrOperatorListAST *iter = ptr_operator_list, **ast_iter = &ast->ptr_operator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) PtrOperatorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) PtrOperatorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (core_declarator)
ast->core_declarator = core_declarator->clone(pool);
for (PostfixDeclaratorListAST *iter = postfix_declarator_list, **ast_iter = &ast->postfix_declarator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) PostfixDeclaratorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) PostfixDeclaratorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (SpecifierListAST *iter = post_attribute_list, **ast_iter = &ast->post_attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->equal_token = equal_token;
if (initializer)
ast->initializer = initializer->clone(pool);
@@ -145,10 +145,10 @@ SimpleDeclarationAST *SimpleDeclarationAST::clone(MemoryPool *pool) const
ast->qt_invokable_token = qt_invokable_token;
for (SpecifierListAST *iter = decl_specifier_list, **ast_iter = &ast->decl_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (DeclaratorListAST *iter = declarator_list, **ast_iter = &ast->declarator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclaratorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclaratorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->semicolon_token = semicolon_token;
return ast;
}
@@ -187,7 +187,7 @@ QtPrivateSlotAST *QtPrivateSlotAST::clone(MemoryPool *pool) const
ast->comma_token = comma_token;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
ast->rparen_token = rparen_token;
@@ -217,7 +217,7 @@ QtPropertyDeclarationAST *QtPropertyDeclarationAST::clone(MemoryPool *pool) cons
ast->property_name = property_name->clone(pool);
for (QtPropertyDeclarationItemListAST *iter = property_declaration_item_list, **ast_iter = &ast->property_declaration_item_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) QtPropertyDeclarationItemListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) QtPropertyDeclarationItemListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -229,7 +229,7 @@ QtEnumDeclarationAST *QtEnumDeclarationAST::clone(MemoryPool *pool) const
ast->lparen_token = lparen_token;
for (NameListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -241,7 +241,7 @@ QtFlagsDeclarationAST *QtFlagsDeclarationAST::clone(MemoryPool *pool) const
ast->lparen_token = lparen_token;
for (NameListAST *iter = flag_enums_list, **ast_iter = &ast->flag_enums_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -253,7 +253,7 @@ QtInterfaceNameAST *QtInterfaceNameAST::clone(MemoryPool *pool) const
ast->interface_name = interface_name->clone(pool);
for (NameListAST *iter = constraint_list, **ast_iter = &ast->constraint_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -264,7 +264,7 @@ QtInterfacesDeclarationAST *QtInterfacesDeclarationAST::clone(MemoryPool *pool)
ast->lparen_token = lparen_token;
for (QtInterfaceNameListAST *iter = interface_name_list, **ast_iter = &ast->interface_name_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) QtInterfaceNameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) QtInterfaceNameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -372,19 +372,19 @@ ClassSpecifierAST *ClassSpecifierAST::clone(MemoryPool *pool) const
ast->classkey_token = classkey_token;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (name)
ast->name = name->clone(pool);
ast->final_token = final_token;
ast->colon_token = colon_token;
for (BaseSpecifierListAST *iter = base_clause_list, **ast_iter = &ast->base_clause_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) BaseSpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) BaseSpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->dot_dot_dot_token = dot_dot_dot_token;
ast->lbrace_token = lbrace_token;
for (DeclarationListAST *iter = member_specifier_list, **ast_iter = &ast->member_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rbrace_token = rbrace_token;
return ast;
}
@@ -407,7 +407,7 @@ CompoundStatementAST *CompoundStatementAST::clone(MemoryPool *pool) const
ast->lbrace_token = lbrace_token;
for (StatementListAST *iter = statement_list, **ast_iter = &ast->statement_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) StatementListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) StatementListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rbrace_token = rbrace_token;
return ast;
}
@@ -417,7 +417,7 @@ ConditionAST *ConditionAST::clone(MemoryPool *pool) const
ConditionAST *ast = new (pool) ConditionAST;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
return ast;
@@ -458,7 +458,7 @@ CtorInitializerAST *CtorInitializerAST::clone(MemoryPool *pool) const
ast->colon_token = colon_token;
for (MemInitializerListAST *iter = member_initializer_list, **ast_iter = &ast->member_initializer_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) MemInitializerListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) MemInitializerListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->dot_dot_dot_token = dot_dot_dot_token;
return ast;
}
@@ -499,7 +499,7 @@ FunctionDeclaratorAST *FunctionDeclaratorAST::clone(MemoryPool *pool) const
ast->rparen_token = rparen_token;
for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->ref_qualifier_token = ref_qualifier_token;
if (exception_specification)
ast->exception_specification = exception_specification->clone(pool);
@@ -561,7 +561,7 @@ ElaboratedTypeSpecifierAST *ElaboratedTypeSpecifierAST::clone(MemoryPool *pool)
ast->classkey_token = classkey_token;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (name)
ast->name = name->clone(pool);
return ast;
@@ -577,11 +577,11 @@ EnumSpecifierAST *EnumSpecifierAST::clone(MemoryPool *pool) const
ast->colon_token = colon_token;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->lbrace_token = lbrace_token;
for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) EnumeratorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) EnumeratorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->stray_comma_token = stray_comma_token;
ast->rbrace_token = rbrace_token;
return ast;
@@ -602,7 +602,7 @@ ExceptionDeclarationAST *ExceptionDeclarationAST::clone(MemoryPool *pool) const
ExceptionDeclarationAST *ast = new (pool) ExceptionDeclarationAST;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
ast->dot_dot_dot_token = dot_dot_dot_token;
@@ -617,7 +617,7 @@ DynamicExceptionSpecificationAST *DynamicExceptionSpecificationAST::clone(Memory
ast->dot_dot_dot_token = dot_dot_dot_token;
for (ExpressionListAST *iter = type_id_list, **ast_iter = &ast->type_id_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -658,7 +658,7 @@ FunctionDefinitionAST *FunctionDefinitionAST::clone(MemoryPool *pool) const
ast->qt_invokable_token = qt_invokable_token;
for (SpecifierListAST *iter = decl_specifier_list, **ast_iter = &ast->decl_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
if (ctor_initializer)
@@ -675,7 +675,7 @@ ForeachStatementAST *ForeachStatementAST::clone(MemoryPool *pool) const
ast->lparen_token = lparen_token;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
if (initializer)
@@ -696,7 +696,7 @@ RangeBasedForStatementAST *RangeBasedForStatementAST::clone(MemoryPool *pool) co
ast->lparen_token = lparen_token;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
ast->colon_token = colon_token;
@@ -748,7 +748,7 @@ ArrayInitializerAST *ArrayInitializerAST::clone(MemoryPool *pool) const
ast->lbrace_token = lbrace_token;
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rbrace_token = rbrace_token;
return ast;
}
@@ -769,7 +769,7 @@ LinkageBodyAST *LinkageBodyAST::clone(MemoryPool *pool) const
ast->lbrace_token = lbrace_token;
for (DeclarationListAST *iter = declaration_list, **ast_iter = &ast->declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rbrace_token = rbrace_token;
return ast;
}
@@ -809,7 +809,7 @@ QualifiedNameAST *QualifiedNameAST::clone(MemoryPool *pool) const
ast->global_scope_token = global_scope_token;
for (NestedNameSpecifierListAST *iter = nested_name_specifier_list, **ast_iter = &ast->nested_name_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NestedNameSpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NestedNameSpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (unqualified_name)
ast->unqualified_name = unqualified_name->clone(pool);
return ast;
@@ -830,10 +830,10 @@ ConversionFunctionIdAST *ConversionFunctionIdAST::clone(MemoryPool *pool) const
ast->operator_token = operator_token;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (PtrOperatorListAST *iter = ptr_operator_list, **ast_iter = &ast->ptr_operator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) PtrOperatorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) PtrOperatorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -868,7 +868,7 @@ TemplateIdAST *TemplateIdAST::clone(MemoryPool *pool) const
ast->less_token = less_token;
for (ExpressionListAST *iter = template_argument_list, **ast_iter = &ast->template_argument_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->greater_token = greater_token;
return ast;
}
@@ -881,7 +881,7 @@ NamespaceAST *NamespaceAST::clone(MemoryPool *pool) const
ast->identifier_token = identifier_token;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (linkage_body)
ast->linkage_body = linkage_body->clone(pool);
return ast;
@@ -918,7 +918,7 @@ ExpressionListParenAST *ExpressionListParenAST::clone(MemoryPool *pool) const
ast->lparen_token = lparen_token;
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -956,13 +956,13 @@ NewTypeIdAST *NewTypeIdAST::clone(MemoryPool *pool) const
NewTypeIdAST *ast = new (pool) NewTypeIdAST;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (PtrOperatorListAST *iter = ptr_operator_list, **ast_iter = &ast->ptr_operator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) PtrOperatorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) PtrOperatorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (NewArrayDeclaratorListAST *iter = new_array_declarator_list, **ast_iter = &ast->new_array_declarator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NewArrayDeclaratorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NewArrayDeclaratorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -980,7 +980,7 @@ ParameterDeclarationAST *ParameterDeclarationAST::clone(MemoryPool *pool) const
ParameterDeclarationAST *ast = new (pool) ParameterDeclarationAST;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
ast->equal_token = equal_token;
@@ -994,7 +994,7 @@ ParameterDeclarationClauseAST *ParameterDeclarationClauseAST::clone(MemoryPool *
ParameterDeclarationClauseAST *ast = new (pool) ParameterDeclarationClauseAST;
for (ParameterDeclarationListAST *iter = parameter_declaration_list, **ast_iter = &ast->parameter_declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ParameterDeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ParameterDeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->dot_dot_dot_token = dot_dot_dot_token;
return ast;
}
@@ -1007,7 +1007,7 @@ CallAST *CallAST::clone(MemoryPool *pool) const
ast->lparen_token = lparen_token;
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
return ast;
}
@@ -1072,7 +1072,7 @@ TypeConstructorCallAST *TypeConstructorCallAST::clone(MemoryPool *pool) const
TypeConstructorCallAST *ast = new (pool) TypeConstructorCallAST;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (expression)
ast->expression = expression->clone(pool);
return ast;
@@ -1084,11 +1084,11 @@ PointerToMemberAST *PointerToMemberAST::clone(MemoryPool *pool) const
ast->global_scope_token = global_scope_token;
for (NestedNameSpecifierListAST *iter = nested_name_specifier_list, **ast_iter = &ast->nested_name_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NestedNameSpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NestedNameSpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->star_token = star_token;
for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->ref_qualifier_token = ref_qualifier_token;
return ast;
}
@@ -1099,7 +1099,7 @@ PointerAST *PointerAST::clone(MemoryPool *pool) const
ast->star_token = star_token;
for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -1251,7 +1251,7 @@ TemplateDeclarationAST *TemplateDeclarationAST::clone(MemoryPool *pool) const
ast->less_token = less_token;
for (DeclarationListAST *iter = template_parameter_list, **ast_iter = &ast->template_parameter_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->greater_token = greater_token;
if (declaration)
ast->declaration = declaration->clone(pool);
@@ -1281,7 +1281,7 @@ TranslationUnitAST *TranslationUnitAST::clone(MemoryPool *pool) const
TranslationUnitAST *ast = new (pool) TranslationUnitAST;
for (DeclarationListAST *iter = declaration_list, **ast_iter = &ast->declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -1293,7 +1293,7 @@ TryBlockStatementAST *TryBlockStatementAST::clone(MemoryPool *pool) const
ast->statement = statement->clone(pool);
for (CatchClauseListAST *iter = catch_clause_list, **ast_iter = &ast->catch_clause_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) CatchClauseListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) CatchClauseListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -1315,7 +1315,7 @@ TypeIdAST *TypeIdAST::clone(MemoryPool *pool) const
TypeIdAST *ast = new (pool) TypeIdAST;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
return ast;
@@ -1341,7 +1341,7 @@ TemplateTypeParameterAST *TemplateTypeParameterAST::clone(MemoryPool *pool) cons
ast->less_token = less_token;
for (DeclarationListAST *iter = template_parameter_list, **ast_iter = &ast->template_parameter_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->greater_token = greater_token;
ast->class_token = class_token;
ast->dot_dot_dot_token = dot_dot_dot_token;
@@ -1402,11 +1402,11 @@ ObjCClassForwardDeclarationAST *ObjCClassForwardDeclarationAST::clone(MemoryPool
ObjCClassForwardDeclarationAST *ast = new (pool) ObjCClassForwardDeclarationAST;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->class_token = class_token;
for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->semicolon_token = semicolon_token;
return ast;
}
@@ -1416,7 +1416,7 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
ObjCClassDeclarationAST *ast = new (pool) ObjCClassDeclarationAST;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->interface_token = interface_token;
ast->implementation_token = implementation_token;
if (class_name)
@@ -1434,7 +1434,7 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
ast->inst_vars_decl = inst_vars_decl->clone(pool);
for (DeclarationListAST *iter = member_declaration_list, **ast_iter = &ast->member_declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->end_token = end_token;
return ast;
}
@@ -1444,11 +1444,11 @@ ObjCProtocolForwardDeclarationAST *ObjCProtocolForwardDeclarationAST::clone(Memo
ObjCProtocolForwardDeclarationAST *ast = new (pool) ObjCProtocolForwardDeclarationAST;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->protocol_token = protocol_token;
for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->semicolon_token = semicolon_token;
return ast;
}
@@ -1458,7 +1458,7 @@ ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool)
ObjCProtocolDeclarationAST *ast = new (pool) ObjCProtocolDeclarationAST;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->protocol_token = protocol_token;
if (name)
ast->name = name->clone(pool);
@@ -1466,7 +1466,7 @@ ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool)
ast->protocol_refs = protocol_refs->clone(pool);
for (DeclarationListAST *iter = member_declaration_list, **ast_iter = &ast->member_declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->end_token = end_token;
return ast;
}
@@ -1477,7 +1477,7 @@ ObjCProtocolRefsAST *ObjCProtocolRefsAST::clone(MemoryPool *pool) const
ast->less_token = less_token;
for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->greater_token = greater_token;
return ast;
}
@@ -1500,7 +1500,7 @@ ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) cons
ast->selector = selector->clone(pool);
for (ObjCMessageArgumentListAST *iter = argument_list, **ast_iter = &ast->argument_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ObjCMessageArgumentListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ObjCMessageArgumentListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rbracket_token = rbracket_token;
return ast;
}
@@ -1552,7 +1552,7 @@ ObjCInstanceVariablesDeclarationAST *ObjCInstanceVariablesDeclarationAST::clone(
ast->lbrace_token = lbrace_token;
for (DeclarationListAST *iter = instance_variable_list, **ast_iter = &ast->instance_variable_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rbrace_token = rbrace_token;
return ast;
}
@@ -1579,12 +1579,12 @@ ObjCPropertyDeclarationAST *ObjCPropertyDeclarationAST::clone(MemoryPool *pool)
ObjCPropertyDeclarationAST *ast = new (pool) ObjCPropertyDeclarationAST;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->property_token = property_token;
ast->lparen_token = lparen_token;
for (ObjCPropertyAttributeListAST *iter = property_attribute_list, **ast_iter = &ast->property_attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ObjCPropertyAttributeListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ObjCPropertyAttributeListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->rparen_token = rparen_token;
if (simple_declaration)
ast->simple_declaration = simple_declaration->clone(pool);
@@ -1598,7 +1598,7 @@ ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclarationAST::clone(Memo
ast->type_name = type_name->clone(pool);
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (param_name)
ast->param_name = param_name->clone(pool);
return ast;
@@ -1614,11 +1614,11 @@ ObjCMethodPrototypeAST *ObjCMethodPrototypeAST::clone(MemoryPool *pool) const
ast->selector = selector->clone(pool);
for (ObjCMessageArgumentDeclarationListAST *iter = argument_list, **ast_iter = &ast->argument_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ObjCMessageArgumentDeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ObjCMessageArgumentDeclarationListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->dot_dot_dot_token = dot_dot_dot_token;
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -1648,7 +1648,7 @@ ObjCSynthesizedPropertiesDeclarationAST *ObjCSynthesizedPropertiesDeclarationAST
ast->synthesized_token = synthesized_token;
for (ObjCSynthesizedPropertyListAST *iter = property_identifier_list, **ast_iter = &ast->property_identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ObjCSynthesizedPropertyListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ObjCSynthesizedPropertyListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->semicolon_token = semicolon_token;
return ast;
}
@@ -1659,7 +1659,7 @@ ObjCDynamicPropertiesDeclarationAST *ObjCDynamicPropertiesDeclarationAST::clone(
ast->dynamic_token = dynamic_token;
for (NameListAST *iter = property_identifier_list, **ast_iter = &ast->property_identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->semicolon_token = semicolon_token;
return ast;
}
@@ -1671,7 +1671,7 @@ ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const
ast->lparen_token = lparen_token;
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
if (initializer)
@@ -1726,7 +1726,7 @@ LambdaCaptureAST *LambdaCaptureAST::clone(MemoryPool *pool) const
ast->default_capture_token = default_capture_token;
for (CaptureListAST *iter = capture_list, **ast_iter = &ast->capture_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) CaptureListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) CaptureListAST((iter->value) ? iter->value->clone(pool) : nullptr);
return ast;
}
@@ -1748,7 +1748,7 @@ LambdaDeclaratorAST *LambdaDeclaratorAST::clone(MemoryPool *pool) const
ast->rparen_token = rparen_token;
for (SpecifierListAST *iter = attributes, **ast_iter = &ast->attributes;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->mutable_token = mutable_token;
if (exception_specification)
ast->exception_specification = exception_specification->clone(pool);
@@ -1763,10 +1763,10 @@ TrailingReturnTypeAST *TrailingReturnTypeAST::clone(MemoryPool *pool) const
ast->arrow_token = arrow_token;
for (SpecifierListAST *iter = attributes, **ast_iter = &ast->attributes;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
for (SpecifierListAST *iter = type_specifier_list, **ast_iter = &ast->type_specifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : nullptr);
if (declarator)
ast->declarator = declarator->clone(pool);
return ast;
@@ -1778,7 +1778,7 @@ BracedInitializerAST *BracedInitializerAST::clone(MemoryPool *pool) const
ast->lbrace_token = lbrace_token;
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->comma_token = comma_token;
ast->rbrace_token = rbrace_token;
return ast;
@@ -1807,7 +1807,7 @@ DesignatedInitializerAST *DesignatedInitializerAST::clone(MemoryPool *pool) cons
DesignatedInitializerAST *ast = new (pool) DesignatedInitializerAST;
for (DesignatorListAST *iter = designator_list, **ast_iter = &ast->designator_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) DesignatorListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) DesignatorListAST((iter->value) ? iter->value->clone(pool) : nullptr);
ast->equal_token = equal_token;
if (initializer)
ast->initializer = initializer->clone(pool);
diff --git a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
index 9270a3429c..c2888b3e2e 100644
--- a/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
+++ b/src/libs/3rdparty/cplusplus/ASTPatternBuilder.h
@@ -49,7 +49,7 @@ public:
return ast;
}
- ObjCSelectorAST *ObjCSelector(ObjCSelectorArgumentListAST *selector_argument_list = 0)
+ ObjCSelectorAST *ObjCSelector(ObjCSelectorArgumentListAST *selector_argument_list = nullptr)
{
ObjCSelectorAST *ast = new (&pool) ObjCSelectorAST;
ast->selector_argument_list = selector_argument_list;
@@ -62,42 +62,42 @@ public:
return ast;
}
- AlignmentSpecifierAST *AlignmentSpecifier(ExpressionAST *typeIdExprOrAlignmentExpr = 0)
+ AlignmentSpecifierAST *AlignmentSpecifier(ExpressionAST *typeIdExprOrAlignmentExpr = nullptr)
{
AlignmentSpecifierAST *ast = new (&pool) AlignmentSpecifierAST;
ast->typeIdExprOrAlignmentExpr = typeIdExprOrAlignmentExpr;
return ast;
}
- GnuAttributeSpecifierAST *GnuAttributeSpecifier(GnuAttributeListAST *attribute_list = 0)
+ GnuAttributeSpecifierAST *GnuAttributeSpecifier(GnuAttributeListAST *attribute_list = nullptr)
{
GnuAttributeSpecifierAST *ast = new (&pool) GnuAttributeSpecifierAST;
ast->attribute_list = attribute_list;
return ast;
}
- GnuAttributeAST *GnuAttribute(ExpressionListAST *expression_list = 0)
+ GnuAttributeAST *GnuAttribute(ExpressionListAST *expression_list = nullptr)
{
GnuAttributeAST *ast = new (&pool) GnuAttributeAST;
ast->expression_list = expression_list;
return ast;
}
- TypeofSpecifierAST *TypeofSpecifier(ExpressionAST *expression = 0)
+ TypeofSpecifierAST *TypeofSpecifier(ExpressionAST *expression = nullptr)
{
TypeofSpecifierAST *ast = new (&pool) TypeofSpecifierAST;
ast->expression = expression;
return ast;
}
- DecltypeSpecifierAST *DecltypeSpecifier(ExpressionAST *expression = 0)
+ DecltypeSpecifierAST *DecltypeSpecifier(ExpressionAST *expression = nullptr)
{
DecltypeSpecifierAST *ast = new (&pool) DecltypeSpecifierAST;
ast->expression = expression;
return ast;
}
- DeclaratorAST *Declarator(SpecifierListAST *attribute_list = 0, PtrOperatorListAST *ptr_operator_list = 0, CoreDeclaratorAST *core_declarator = 0, PostfixDeclaratorListAST *postfix_declarator_list = 0, SpecifierListAST *post_attribute_list = 0, ExpressionAST *initializer = 0)
+ DeclaratorAST *Declarator(SpecifierListAST *attribute_list = nullptr, PtrOperatorListAST *ptr_operator_list = nullptr, CoreDeclaratorAST *core_declarator = nullptr, PostfixDeclaratorListAST *postfix_declarator_list = nullptr, SpecifierListAST *post_attribute_list = nullptr, ExpressionAST *initializer = nullptr)
{
DeclaratorAST *ast = new (&pool) DeclaratorAST;
ast->attribute_list = attribute_list;
@@ -109,7 +109,7 @@ public:
return ast;
}
- SimpleDeclarationAST *SimpleDeclaration(SpecifierListAST *decl_specifier_list = 0, DeclaratorListAST *declarator_list = 0)
+ SimpleDeclarationAST *SimpleDeclaration(SpecifierListAST *decl_specifier_list = nullptr, DeclaratorListAST *declarator_list = nullptr)
{
SimpleDeclarationAST *ast = new (&pool) SimpleDeclarationAST;
ast->decl_specifier_list = decl_specifier_list;
@@ -135,7 +135,7 @@ public:
return ast;
}
- QtPrivateSlotAST *QtPrivateSlot(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0)
+ QtPrivateSlotAST *QtPrivateSlot(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr)
{
QtPrivateSlotAST *ast = new (&pool) QtPrivateSlotAST;
ast->type_specifier_list = type_specifier_list;
@@ -143,14 +143,14 @@ public:
return ast;
}
- QtPropertyDeclarationItemAST *QtPropertyDeclarationItem(ExpressionAST *expression = 0)
+ QtPropertyDeclarationItemAST *QtPropertyDeclarationItem(ExpressionAST *expression = nullptr)
{
QtPropertyDeclarationItemAST *ast = new (&pool) QtPropertyDeclarationItemAST;
ast->expression = expression;
return ast;
}
- QtPropertyDeclarationAST *QtPropertyDeclaration(ExpressionAST *expression = 0, ExpressionAST *type_id = 0, NameAST *property_name = 0, QtPropertyDeclarationItemListAST *property_declaration_item_list = 0)
+ QtPropertyDeclarationAST *QtPropertyDeclaration(ExpressionAST *expression = nullptr, ExpressionAST *type_id = nullptr, NameAST *property_name = nullptr, QtPropertyDeclarationItemListAST *property_declaration_item_list = nullptr)
{
QtPropertyDeclarationAST *ast = new (&pool) QtPropertyDeclarationAST;
ast->expression = expression;
@@ -160,21 +160,21 @@ public:
return ast;
}
- QtEnumDeclarationAST *QtEnumDeclaration(NameListAST *enumerator_list = 0)
+ QtEnumDeclarationAST *QtEnumDeclaration(NameListAST *enumerator_list = nullptr)
{
QtEnumDeclarationAST *ast = new (&pool) QtEnumDeclarationAST;
ast->enumerator_list = enumerator_list;
return ast;
}
- QtFlagsDeclarationAST *QtFlagsDeclaration(NameListAST *flag_enums_list = 0)
+ QtFlagsDeclarationAST *QtFlagsDeclaration(NameListAST *flag_enums_list = nullptr)
{
QtFlagsDeclarationAST *ast = new (&pool) QtFlagsDeclarationAST;
ast->flag_enums_list = flag_enums_list;
return ast;
}
- QtInterfaceNameAST *QtInterfaceName(NameAST *interface_name = 0, NameListAST *constraint_list = 0)
+ QtInterfaceNameAST *QtInterfaceName(NameAST *interface_name = nullptr, NameListAST *constraint_list = nullptr)
{
QtInterfaceNameAST *ast = new (&pool) QtInterfaceNameAST;
ast->interface_name = interface_name;
@@ -182,7 +182,7 @@ public:
return ast;
}
- QtInterfacesDeclarationAST *QtInterfacesDeclaration(QtInterfaceNameListAST *interface_name_list = 0)
+ QtInterfacesDeclarationAST *QtInterfacesDeclaration(QtInterfaceNameListAST *interface_name_list = nullptr)
{
QtInterfacesDeclarationAST *ast = new (&pool) QtInterfacesDeclarationAST;
ast->interface_name_list = interface_name_list;
@@ -195,28 +195,28 @@ public:
return ast;
}
- BaseSpecifierAST *BaseSpecifier(NameAST *name = 0)
+ BaseSpecifierAST *BaseSpecifier(NameAST *name = nullptr)
{
BaseSpecifierAST *ast = new (&pool) BaseSpecifierAST;
ast->name = name;
return ast;
}
- IdExpressionAST *IdExpression(NameAST *name = 0)
+ IdExpressionAST *IdExpression(NameAST *name = nullptr)
{
IdExpressionAST *ast = new (&pool) IdExpressionAST;
ast->name = name;
return ast;
}
- CompoundExpressionAST *CompoundExpression(CompoundStatementAST *statement = 0)
+ CompoundExpressionAST *CompoundExpression(CompoundStatementAST *statement = nullptr)
{
CompoundExpressionAST *ast = new (&pool) CompoundExpressionAST;
ast->statement = statement;
return ast;
}
- CompoundLiteralAST *CompoundLiteral(ExpressionAST *type_id = 0, ExpressionAST *initializer = 0)
+ CompoundLiteralAST *CompoundLiteral(ExpressionAST *type_id = nullptr, ExpressionAST *initializer = nullptr)
{
CompoundLiteralAST *ast = new (&pool) CompoundLiteralAST;
ast->type_id = type_id;
@@ -224,21 +224,21 @@ public:
return ast;
}
- QtMethodAST *QtMethod(DeclaratorAST *declarator = 0)
+ QtMethodAST *QtMethod(DeclaratorAST *declarator = nullptr)
{
QtMethodAST *ast = new (&pool) QtMethodAST;
ast->declarator = declarator;
return ast;
}
- QtMemberDeclarationAST *QtMemberDeclaration(ExpressionAST *type_id = 0)
+ QtMemberDeclarationAST *QtMemberDeclaration(ExpressionAST *type_id = nullptr)
{
QtMemberDeclarationAST *ast = new (&pool) QtMemberDeclarationAST;
ast->type_id = type_id;
return ast;
}
- BinaryExpressionAST *BinaryExpression(ExpressionAST *left_expression = 0, ExpressionAST *right_expression = 0)
+ BinaryExpressionAST *BinaryExpression(ExpressionAST *left_expression = nullptr, ExpressionAST *right_expression = nullptr)
{
BinaryExpressionAST *ast = new (&pool) BinaryExpressionAST;
ast->left_expression = left_expression;
@@ -246,7 +246,7 @@ public:
return ast;
}
- CastExpressionAST *CastExpression(ExpressionAST *type_id = 0, ExpressionAST *expression = 0)
+ CastExpressionAST *CastExpression(ExpressionAST *type_id = nullptr, ExpressionAST *expression = nullptr)
{
CastExpressionAST *ast = new (&pool) CastExpressionAST;
ast->type_id = type_id;
@@ -254,7 +254,7 @@ public:
return ast;
}
- ClassSpecifierAST *ClassSpecifier(SpecifierListAST *attribute_list = 0, NameAST *name = 0, BaseSpecifierListAST *base_clause_list = 0, DeclarationListAST *member_specifier_list = 0)
+ ClassSpecifierAST *ClassSpecifier(SpecifierListAST *attribute_list = nullptr, NameAST *name = nullptr, BaseSpecifierListAST *base_clause_list = nullptr, DeclarationListAST *member_specifier_list = nullptr)
{
ClassSpecifierAST *ast = new (&pool) ClassSpecifierAST;
ast->attribute_list = attribute_list;
@@ -264,7 +264,7 @@ public:
return ast;
}
- CaseStatementAST *CaseStatement(ExpressionAST *expression = 0, StatementAST *statement = 0)
+ CaseStatementAST *CaseStatement(ExpressionAST *expression = nullptr, StatementAST *statement = nullptr)
{
CaseStatementAST *ast = new (&pool) CaseStatementAST;
ast->expression = expression;
@@ -272,14 +272,14 @@ public:
return ast;
}
- CompoundStatementAST *CompoundStatement(StatementListAST *statement_list = 0)
+ CompoundStatementAST *CompoundStatement(StatementListAST *statement_list = nullptr)
{
CompoundStatementAST *ast = new (&pool) CompoundStatementAST;
ast->statement_list = statement_list;
return ast;
}
- ConditionAST *Condition(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0)
+ ConditionAST *Condition(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr)
{
ConditionAST *ast = new (&pool) ConditionAST;
ast->type_specifier_list = type_specifier_list;
@@ -287,7 +287,7 @@ public:
return ast;
}
- ConditionalExpressionAST *ConditionalExpression(ExpressionAST *condition = 0, ExpressionAST *left_expression = 0, ExpressionAST *right_expression = 0)
+ ConditionalExpressionAST *ConditionalExpression(ExpressionAST *condition = nullptr, ExpressionAST *left_expression = nullptr, ExpressionAST *right_expression = nullptr)
{
ConditionalExpressionAST *ast = new (&pool) ConditionalExpressionAST;
ast->condition = condition;
@@ -296,7 +296,7 @@ public:
return ast;
}
- CppCastExpressionAST *CppCastExpression(ExpressionAST *type_id = 0, ExpressionAST *expression = 0)
+ CppCastExpressionAST *CppCastExpression(ExpressionAST *type_id = nullptr, ExpressionAST *expression = nullptr)
{
CppCastExpressionAST *ast = new (&pool) CppCastExpressionAST;
ast->type_id = type_id;
@@ -304,35 +304,35 @@ public:
return ast;
}
- CtorInitializerAST *CtorInitializer(MemInitializerListAST *member_initializer_list = 0)
+ CtorInitializerAST *CtorInitializer(MemInitializerListAST *member_initializer_list = nullptr)
{
CtorInitializerAST *ast = new (&pool) CtorInitializerAST;
ast->member_initializer_list = member_initializer_list;
return ast;
}
- DeclarationStatementAST *DeclarationStatement(DeclarationAST *declaration = 0)
+ DeclarationStatementAST *DeclarationStatement(DeclarationAST *declaration = nullptr)
{
DeclarationStatementAST *ast = new (&pool) DeclarationStatementAST;
ast->declaration = declaration;
return ast;
}
- DeclaratorIdAST *DeclaratorId(NameAST *name = 0)
+ DeclaratorIdAST *DeclaratorId(NameAST *name = nullptr)
{
DeclaratorIdAST *ast = new (&pool) DeclaratorIdAST;
ast->name = name;
return ast;
}
- NestedDeclaratorAST *NestedDeclarator(DeclaratorAST *declarator = 0)
+ NestedDeclaratorAST *NestedDeclarator(DeclaratorAST *declarator = nullptr)
{
NestedDeclaratorAST *ast = new (&pool) NestedDeclaratorAST;
ast->declarator = declarator;
return ast;
}
- FunctionDeclaratorAST *FunctionDeclarator(ParameterDeclarationClauseAST *parameter_declaration_clause = 0, SpecifierListAST *cv_qualifier_list = 0, ExceptionSpecificationAST *exception_specification = 0, TrailingReturnTypeAST *trailing_return_type = 0, ExpressionAST *as_cpp_initializer = 0)
+ FunctionDeclaratorAST *FunctionDeclarator(ParameterDeclarationClauseAST *parameter_declaration_clause = nullptr, SpecifierListAST *cv_qualifier_list = nullptr, ExceptionSpecificationAST *exception_specification = nullptr, TrailingReturnTypeAST *trailing_return_type = nullptr, ExpressionAST *as_cpp_initializer = nullptr)
{
FunctionDeclaratorAST *ast = new (&pool) FunctionDeclaratorAST;
ast->parameter_declaration_clause = parameter_declaration_clause;
@@ -343,21 +343,21 @@ public:
return ast;
}
- ArrayDeclaratorAST *ArrayDeclarator(ExpressionAST *expression = 0)
+ ArrayDeclaratorAST *ArrayDeclarator(ExpressionAST *expression = nullptr)
{
ArrayDeclaratorAST *ast = new (&pool) ArrayDeclaratorAST;
ast->expression = expression;
return ast;
}
- DeleteExpressionAST *DeleteExpression(ExpressionAST *expression = 0)
+ DeleteExpressionAST *DeleteExpression(ExpressionAST *expression = nullptr)
{
DeleteExpressionAST *ast = new (&pool) DeleteExpressionAST;
ast->expression = expression;
return ast;
}
- DoStatementAST *DoStatement(StatementAST *statement = 0, ExpressionAST *expression = 0)
+ DoStatementAST *DoStatement(StatementAST *statement = nullptr, ExpressionAST *expression = nullptr)
{
DoStatementAST *ast = new (&pool) DoStatementAST;
ast->statement = statement;
@@ -365,14 +365,14 @@ public:
return ast;
}
- NamedTypeSpecifierAST *NamedTypeSpecifier(NameAST *name = 0)
+ NamedTypeSpecifierAST *NamedTypeSpecifier(NameAST *name = nullptr)
{
NamedTypeSpecifierAST *ast = new (&pool) NamedTypeSpecifierAST;
ast->name = name;
return ast;
}
- ElaboratedTypeSpecifierAST *ElaboratedTypeSpecifier(SpecifierListAST *attribute_list = 0, NameAST *name = 0)
+ ElaboratedTypeSpecifierAST *ElaboratedTypeSpecifier(SpecifierListAST *attribute_list = nullptr, NameAST *name = nullptr)
{
ElaboratedTypeSpecifierAST *ast = new (&pool) ElaboratedTypeSpecifierAST;
ast->attribute_list = attribute_list;
@@ -380,7 +380,7 @@ public:
return ast;
}
- EnumSpecifierAST *EnumSpecifier(NameAST *name = 0, SpecifierListAST *type_specifier_list = 0, EnumeratorListAST *enumerator_list = 0)
+ EnumSpecifierAST *EnumSpecifier(NameAST *name = nullptr, SpecifierListAST *type_specifier_list = nullptr, EnumeratorListAST *enumerator_list = nullptr)
{
EnumSpecifierAST *ast = new (&pool) EnumSpecifierAST;
ast->name = name;
@@ -389,14 +389,14 @@ public:
return ast;
}
- EnumeratorAST *Enumerator(ExpressionAST *expression = 0)
+ EnumeratorAST *Enumerator(ExpressionAST *expression = nullptr)
{
EnumeratorAST *ast = new (&pool) EnumeratorAST;
ast->expression = expression;
return ast;
}
- ExceptionDeclarationAST *ExceptionDeclaration(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0)
+ ExceptionDeclarationAST *ExceptionDeclaration(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr)
{
ExceptionDeclarationAST *ast = new (&pool) ExceptionDeclarationAST;
ast->type_specifier_list = type_specifier_list;
@@ -404,21 +404,21 @@ public:
return ast;
}
- DynamicExceptionSpecificationAST *DynamicExceptionSpecification(ExpressionListAST *type_id_list = 0)
+ DynamicExceptionSpecificationAST *DynamicExceptionSpecification(ExpressionListAST *type_id_list = nullptr)
{
DynamicExceptionSpecificationAST *ast = new (&pool) DynamicExceptionSpecificationAST;
ast->type_id_list = type_id_list;
return ast;
}
- NoExceptSpecificationAST *NoExceptSpecification(ExpressionAST *expression = 0)
+ NoExceptSpecificationAST *NoExceptSpecification(ExpressionAST *expression = nullptr)
{
NoExceptSpecificationAST *ast = new (&pool) NoExceptSpecificationAST;
ast->expression = expression;
return ast;
}
- ExpressionOrDeclarationStatementAST *ExpressionOrDeclarationStatement(ExpressionStatementAST *expression = 0, DeclarationStatementAST *declaration = 0)
+ ExpressionOrDeclarationStatementAST *ExpressionOrDeclarationStatement(ExpressionStatementAST *expression = nullptr, DeclarationStatementAST *declaration = nullptr)
{
ExpressionOrDeclarationStatementAST *ast = new (&pool) ExpressionOrDeclarationStatementAST;
ast->expression = expression;
@@ -426,14 +426,14 @@ public:
return ast;
}
- ExpressionStatementAST *ExpressionStatement(ExpressionAST *expression = 0)
+ ExpressionStatementAST *ExpressionStatement(ExpressionAST *expression = nullptr)
{
ExpressionStatementAST *ast = new (&pool) ExpressionStatementAST;
ast->expression = expression;
return ast;
}
- FunctionDefinitionAST *FunctionDefinition(SpecifierListAST *decl_specifier_list = 0, DeclaratorAST *declarator = 0, CtorInitializerAST *ctor_initializer = 0, StatementAST *function_body = 0)
+ FunctionDefinitionAST *FunctionDefinition(SpecifierListAST *decl_specifier_list = nullptr, DeclaratorAST *declarator = nullptr, CtorInitializerAST *ctor_initializer = nullptr, StatementAST *function_body = nullptr)
{
FunctionDefinitionAST *ast = new (&pool) FunctionDefinitionAST;
ast->decl_specifier_list = decl_specifier_list;
@@ -443,7 +443,7 @@ public:
return ast;
}
- ForeachStatementAST *ForeachStatement(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *initializer = 0, ExpressionAST *expression = 0, StatementAST *statement = 0)
+ ForeachStatementAST *ForeachStatement(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr, ExpressionAST *initializer = nullptr, ExpressionAST *expression = nullptr, StatementAST *statement = nullptr)
{
ForeachStatementAST *ast = new (&pool) ForeachStatementAST;
ast->type_specifier_list = type_specifier_list;
@@ -454,7 +454,7 @@ public:
return ast;
}
- RangeBasedForStatementAST *RangeBasedForStatement(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *expression = 0, StatementAST *statement = 0)
+ RangeBasedForStatementAST *RangeBasedForStatement(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr, ExpressionAST *expression = nullptr, StatementAST *statement = nullptr)
{
RangeBasedForStatementAST *ast = new (&pool) RangeBasedForStatementAST;
ast->type_specifier_list = type_specifier_list;
@@ -464,7 +464,7 @@ public:
return ast;
}
- ForStatementAST *ForStatement(StatementAST *initializer = 0, ExpressionAST *condition = 0, ExpressionAST *expression = 0, StatementAST *statement = 0)
+ ForStatementAST *ForStatement(StatementAST *initializer = nullptr, ExpressionAST *condition = nullptr, ExpressionAST *expression = nullptr, StatementAST *statement = nullptr)
{
ForStatementAST *ast = new (&pool) ForStatementAST;
ast->initializer = initializer;
@@ -474,7 +474,7 @@ public:
return ast;
}
- IfStatementAST *IfStatement(ExpressionAST *condition = 0, StatementAST *statement = 0, StatementAST *else_statement = 0)
+ IfStatementAST *IfStatement(ExpressionAST *condition = nullptr, StatementAST *statement = nullptr, StatementAST *else_statement = nullptr)
{
IfStatementAST *ast = new (&pool) IfStatementAST;
ast->condition = condition;
@@ -483,35 +483,35 @@ public:
return ast;
}
- ArrayInitializerAST *ArrayInitializer(ExpressionListAST *expression_list = 0)
+ ArrayInitializerAST *ArrayInitializer(ExpressionListAST *expression_list = nullptr)
{
ArrayInitializerAST *ast = new (&pool) ArrayInitializerAST;
ast->expression_list = expression_list;
return ast;
}
- LabeledStatementAST *LabeledStatement(StatementAST *statement = 0)
+ LabeledStatementAST *LabeledStatement(StatementAST *statement = nullptr)
{
LabeledStatementAST *ast = new (&pool) LabeledStatementAST;
ast->statement = statement;
return ast;
}
- LinkageBodyAST *LinkageBody(DeclarationListAST *declaration_list = 0)
+ LinkageBodyAST *LinkageBody(DeclarationListAST *declaration_list = nullptr)
{
LinkageBodyAST *ast = new (&pool) LinkageBodyAST;
ast->declaration_list = declaration_list;
return ast;
}
- LinkageSpecificationAST *LinkageSpecification(DeclarationAST *declaration = 0)
+ LinkageSpecificationAST *LinkageSpecification(DeclarationAST *declaration = nullptr)
{
LinkageSpecificationAST *ast = new (&pool) LinkageSpecificationAST;
ast->declaration = declaration;
return ast;
}
- MemInitializerAST *MemInitializer(NameAST *name = 0, ExpressionAST *expression = 0)
+ MemInitializerAST *MemInitializer(NameAST *name = nullptr, ExpressionAST *expression = nullptr)
{
MemInitializerAST *ast = new (&pool) MemInitializerAST;
ast->name = name;
@@ -519,14 +519,14 @@ public:
return ast;
}
- NestedNameSpecifierAST *NestedNameSpecifier(NameAST *class_or_namespace_name = 0)
+ NestedNameSpecifierAST *NestedNameSpecifier(NameAST *class_or_namespace_name = nullptr)
{
NestedNameSpecifierAST *ast = new (&pool) NestedNameSpecifierAST;
ast->class_or_namespace_name = class_or_namespace_name;
return ast;
}
- QualifiedNameAST *QualifiedName(NestedNameSpecifierListAST *nested_name_specifier_list = 0, NameAST *unqualified_name = 0)
+ QualifiedNameAST *QualifiedName(NestedNameSpecifierListAST *nested_name_specifier_list = nullptr, NameAST *unqualified_name = nullptr)
{
QualifiedNameAST *ast = new (&pool) QualifiedNameAST;
ast->nested_name_specifier_list = nested_name_specifier_list;
@@ -534,14 +534,14 @@ public:
return ast;
}
- OperatorFunctionIdAST *OperatorFunctionId(OperatorAST *op = 0)
+ OperatorFunctionIdAST *OperatorFunctionId(OperatorAST *op = nullptr)
{
OperatorFunctionIdAST *ast = new (&pool) OperatorFunctionIdAST;
ast->op = op;
return ast;
}
- ConversionFunctionIdAST *ConversionFunctionId(SpecifierListAST *type_specifier_list = 0, PtrOperatorListAST *ptr_operator_list = 0)
+ ConversionFunctionIdAST *ConversionFunctionId(SpecifierListAST *type_specifier_list = nullptr, PtrOperatorListAST *ptr_operator_list = nullptr)
{
ConversionFunctionIdAST *ast = new (&pool) ConversionFunctionIdAST;
ast->type_specifier_list = type_specifier_list;
@@ -561,21 +561,21 @@ public:
return ast;
}
- DestructorNameAST *DestructorName(NameAST *unqualified_name = 0)
+ DestructorNameAST *DestructorName(NameAST *unqualified_name = nullptr)
{
DestructorNameAST *ast = new (&pool) DestructorNameAST;
ast->unqualified_name = unqualified_name;
return ast;
}
- TemplateIdAST *TemplateId(ExpressionListAST *template_argument_list = 0)
+ TemplateIdAST *TemplateId(ExpressionListAST *template_argument_list = nullptr)
{
TemplateIdAST *ast = new (&pool) TemplateIdAST;
ast->template_argument_list = template_argument_list;
return ast;
}
- NamespaceAST *Namespace(SpecifierListAST *attribute_list = 0, DeclarationAST *linkage_body = 0)
+ NamespaceAST *Namespace(SpecifierListAST *attribute_list = nullptr, DeclarationAST *linkage_body = nullptr)
{
NamespaceAST *ast = new (&pool) NamespaceAST;
ast->attribute_list = attribute_list;
@@ -583,14 +583,14 @@ public:
return ast;
}
- NamespaceAliasDefinitionAST *NamespaceAliasDefinition(NameAST *name = 0)
+ NamespaceAliasDefinitionAST *NamespaceAliasDefinition(NameAST *name = nullptr)
{
NamespaceAliasDefinitionAST *ast = new (&pool) NamespaceAliasDefinitionAST;
ast->name = name;
return ast;
}
- AliasDeclarationAST *AliasDeclaration(NameAST *name = 0, TypeIdAST *typeId = 0)
+ AliasDeclarationAST *AliasDeclaration(NameAST *name = nullptr, TypeIdAST *typeId = nullptr)
{
AliasDeclarationAST *ast = new (&pool) AliasDeclarationAST;
ast->name = name;
@@ -598,21 +598,21 @@ public:
return ast;
}
- ExpressionListParenAST *ExpressionListParen(ExpressionListAST *expression_list = 0)
+ ExpressionListParenAST *ExpressionListParen(ExpressionListAST *expression_list = nullptr)
{
ExpressionListParenAST *ast = new (&pool) ExpressionListParenAST;
ast->expression_list = expression_list;
return ast;
}
- NewArrayDeclaratorAST *NewArrayDeclarator(ExpressionAST *expression = 0)
+ NewArrayDeclaratorAST *NewArrayDeclarator(ExpressionAST *expression = nullptr)
{
NewArrayDeclaratorAST *ast = new (&pool) NewArrayDeclaratorAST;
ast->expression = expression;
return ast;
}
- NewExpressionAST *NewExpression(ExpressionListParenAST *new_placement = 0, ExpressionAST *type_id = 0, NewTypeIdAST *new_type_id = 0, ExpressionAST *new_initializer = 0)
+ NewExpressionAST *NewExpression(ExpressionListParenAST *new_placement = nullptr, ExpressionAST *type_id = nullptr, NewTypeIdAST *new_type_id = nullptr, ExpressionAST *new_initializer = nullptr)
{
NewExpressionAST *ast = new (&pool) NewExpressionAST;
ast->new_placement = new_placement;
@@ -622,7 +622,7 @@ public:
return ast;
}
- NewTypeIdAST *NewTypeId(SpecifierListAST *type_specifier_list = 0, PtrOperatorListAST *ptr_operator_list = 0, NewArrayDeclaratorListAST *new_array_declarator_list = 0)
+ NewTypeIdAST *NewTypeId(SpecifierListAST *type_specifier_list = nullptr, PtrOperatorListAST *ptr_operator_list = nullptr, NewArrayDeclaratorListAST *new_array_declarator_list = nullptr)
{
NewTypeIdAST *ast = new (&pool) NewTypeIdAST;
ast->type_specifier_list = type_specifier_list;
@@ -637,7 +637,7 @@ public:
return ast;
}
- ParameterDeclarationAST *ParameterDeclaration(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *expression = 0)
+ ParameterDeclarationAST *ParameterDeclaration(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr, ExpressionAST *expression = nullptr)
{
ParameterDeclarationAST *ast = new (&pool) ParameterDeclarationAST;
ast->type_specifier_list = type_specifier_list;
@@ -646,14 +646,14 @@ public:
return ast;
}
- ParameterDeclarationClauseAST *ParameterDeclarationClause(ParameterDeclarationListAST *parameter_declaration_list = 0)
+ ParameterDeclarationClauseAST *ParameterDeclarationClause(ParameterDeclarationListAST *parameter_declaration_list = nullptr)
{
ParameterDeclarationClauseAST *ast = new (&pool) ParameterDeclarationClauseAST;
ast->parameter_declaration_list = parameter_declaration_list;
return ast;
}
- CallAST *Call(ExpressionAST *base_expression = 0, ExpressionListAST *expression_list = 0)
+ CallAST *Call(ExpressionAST *base_expression = nullptr, ExpressionListAST *expression_list = nullptr)
{
CallAST *ast = new (&pool) CallAST;
ast->base_expression = base_expression;
@@ -661,7 +661,7 @@ public:
return ast;
}
- ArrayAccessAST *ArrayAccess(ExpressionAST *base_expression = 0, ExpressionAST *expression = 0)
+ ArrayAccessAST *ArrayAccess(ExpressionAST *base_expression = nullptr, ExpressionAST *expression = nullptr)
{
ArrayAccessAST *ast = new (&pool) ArrayAccessAST;
ast->base_expression = base_expression;
@@ -669,14 +669,14 @@ public:
return ast;
}
- PostIncrDecrAST *PostIncrDecr(ExpressionAST *base_expression = 0)
+ PostIncrDecrAST *PostIncrDecr(ExpressionAST *base_expression = nullptr)
{
PostIncrDecrAST *ast = new (&pool) PostIncrDecrAST;
ast->base_expression = base_expression;
return ast;
}
- MemberAccessAST *MemberAccess(ExpressionAST *base_expression = 0, NameAST *member_name = 0)
+ MemberAccessAST *MemberAccess(ExpressionAST *base_expression = nullptr, NameAST *member_name = nullptr)
{
MemberAccessAST *ast = new (&pool) MemberAccessAST;
ast->base_expression = base_expression;
@@ -684,14 +684,14 @@ public:
return ast;
}
- TypeidExpressionAST *TypeidExpression(ExpressionAST *expression = 0)
+ TypeidExpressionAST *TypeidExpression(ExpressionAST *expression = nullptr)
{
TypeidExpressionAST *ast = new (&pool) TypeidExpressionAST;
ast->expression = expression;
return ast;
}
- TypenameCallExpressionAST *TypenameCallExpression(NameAST *name = 0, ExpressionAST *expression = 0)
+ TypenameCallExpressionAST *TypenameCallExpression(NameAST *name = nullptr, ExpressionAST *expression = nullptr)
{
TypenameCallExpressionAST *ast = new (&pool) TypenameCallExpressionAST;
ast->name = name;
@@ -699,7 +699,7 @@ public:
return ast;
}
- TypeConstructorCallAST *TypeConstructorCall(SpecifierListAST *type_specifier_list = 0, ExpressionAST *expression = 0)
+ TypeConstructorCallAST *TypeConstructorCall(SpecifierListAST *type_specifier_list = nullptr, ExpressionAST *expression = nullptr)
{
TypeConstructorCallAST *ast = new (&pool) TypeConstructorCallAST;
ast->type_specifier_list = type_specifier_list;
@@ -707,7 +707,7 @@ public:
return ast;
}
- PointerToMemberAST *PointerToMember(NestedNameSpecifierListAST *nested_name_specifier_list = 0, SpecifierListAST *cv_qualifier_list = 0)
+ PointerToMemberAST *PointerToMember(NestedNameSpecifierListAST *nested_name_specifier_list = nullptr, SpecifierListAST *cv_qualifier_list = nullptr)
{
PointerToMemberAST *ast = new (&pool) PointerToMemberAST;
ast->nested_name_specifier_list = nested_name_specifier_list;
@@ -715,7 +715,7 @@ public:
return ast;
}
- PointerAST *Pointer(SpecifierListAST *cv_qualifier_list = 0)
+ PointerAST *Pointer(SpecifierListAST *cv_qualifier_list = nullptr)
{
PointerAST *ast = new (&pool) PointerAST;
ast->cv_qualifier_list = cv_qualifier_list;
@@ -746,21 +746,21 @@ public:
return ast;
}
- ReturnStatementAST *ReturnStatement(ExpressionAST *expression = 0)
+ ReturnStatementAST *ReturnStatement(ExpressionAST *expression = nullptr)
{
ReturnStatementAST *ast = new (&pool) ReturnStatementAST;
ast->expression = expression;
return ast;
}
- SizeofExpressionAST *SizeofExpression(ExpressionAST *expression = 0)
+ SizeofExpressionAST *SizeofExpression(ExpressionAST *expression = nullptr)
{
SizeofExpressionAST *ast = new (&pool) SizeofExpressionAST;
ast->expression = expression;
return ast;
}
- AlignofExpressionAST *AlignofExpression(TypeIdAST *typeId = 0)
+ AlignofExpressionAST *AlignofExpression(TypeIdAST *typeId = nullptr)
{
AlignofExpressionAST *ast = new (&pool) AlignofExpressionAST;
ast->typeId = typeId;
@@ -791,14 +791,14 @@ public:
return ast;
}
- NestedExpressionAST *NestedExpression(ExpressionAST *expression = 0)
+ NestedExpressionAST *NestedExpression(ExpressionAST *expression = nullptr)
{
NestedExpressionAST *ast = new (&pool) NestedExpressionAST;
ast->expression = expression;
return ast;
}
- StaticAssertDeclarationAST *StaticAssertDeclaration(ExpressionAST *expression = 0, ExpressionAST *string_literal = 0)
+ StaticAssertDeclarationAST *StaticAssertDeclaration(ExpressionAST *expression = nullptr, ExpressionAST *string_literal = nullptr)
{
StaticAssertDeclarationAST *ast = new (&pool) StaticAssertDeclarationAST;
ast->expression = expression;
@@ -806,14 +806,14 @@ public:
return ast;
}
- StringLiteralAST *StringLiteral(StringLiteralAST *next = 0)
+ StringLiteralAST *StringLiteral(StringLiteralAST *next = nullptr)
{
StringLiteralAST *ast = new (&pool) StringLiteralAST;
ast->next = next;
return ast;
}
- SwitchStatementAST *SwitchStatement(ExpressionAST *condition = 0, StatementAST *statement = 0)
+ SwitchStatementAST *SwitchStatement(ExpressionAST *condition = nullptr, StatementAST *statement = nullptr)
{
SwitchStatementAST *ast = new (&pool) SwitchStatementAST;
ast->condition = condition;
@@ -821,7 +821,7 @@ public:
return ast;
}
- TemplateDeclarationAST *TemplateDeclaration(DeclarationListAST *template_parameter_list = 0, DeclarationAST *declaration = 0)
+ TemplateDeclarationAST *TemplateDeclaration(DeclarationListAST *template_parameter_list = nullptr, DeclarationAST *declaration = nullptr)
{
TemplateDeclarationAST *ast = new (&pool) TemplateDeclarationAST;
ast->template_parameter_list = template_parameter_list;
@@ -829,28 +829,28 @@ public:
return ast;
}
- ThrowExpressionAST *ThrowExpression(ExpressionAST *expression = 0)
+ ThrowExpressionAST *ThrowExpression(ExpressionAST *expression = nullptr)
{
ThrowExpressionAST *ast = new (&pool) ThrowExpressionAST;
ast->expression = expression;
return ast;
}
- NoExceptOperatorExpressionAST *NoExceptOperatorExpression(ExpressionAST *expression = 0)
+ NoExceptOperatorExpressionAST *NoExceptOperatorExpression(ExpressionAST *expression = nullptr)
{
NoExceptOperatorExpressionAST *ast = new (&pool) NoExceptOperatorExpressionAST;
ast->expression = expression;
return ast;
}
- TranslationUnitAST *TranslationUnit(DeclarationListAST *declaration_list = 0)
+ TranslationUnitAST *TranslationUnit(DeclarationListAST *declaration_list = nullptr)
{
TranslationUnitAST *ast = new (&pool) TranslationUnitAST;
ast->declaration_list = declaration_list;
return ast;
}
- TryBlockStatementAST *TryBlockStatement(StatementAST *statement = 0, CatchClauseListAST *catch_clause_list = 0)
+ TryBlockStatementAST *TryBlockStatement(StatementAST *statement = nullptr, CatchClauseListAST *catch_clause_list = nullptr)
{
TryBlockStatementAST *ast = new (&pool) TryBlockStatementAST;
ast->statement = statement;
@@ -858,7 +858,7 @@ public:
return ast;
}
- CatchClauseAST *CatchClause(ExceptionDeclarationAST *exception_declaration = 0, StatementAST *statement = 0)
+ CatchClauseAST *CatchClause(ExceptionDeclarationAST *exception_declaration = nullptr, StatementAST *statement = nullptr)
{
CatchClauseAST *ast = new (&pool) CatchClauseAST;
ast->exception_declaration = exception_declaration;
@@ -866,7 +866,7 @@ public:
return ast;
}
- TypeIdAST *TypeId(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0)
+ TypeIdAST *TypeId(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr)
{
TypeIdAST *ast = new (&pool) TypeIdAST;
ast->type_specifier_list = type_specifier_list;
@@ -874,7 +874,7 @@ public:
return ast;
}
- TypenameTypeParameterAST *TypenameTypeParameter(NameAST *name = 0, ExpressionAST *type_id = 0)
+ TypenameTypeParameterAST *TypenameTypeParameter(NameAST *name = nullptr, ExpressionAST *type_id = nullptr)
{
TypenameTypeParameterAST *ast = new (&pool) TypenameTypeParameterAST;
ast->name = name;
@@ -882,7 +882,7 @@ public:
return ast;
}
- TemplateTypeParameterAST *TemplateTypeParameter(DeclarationListAST *template_parameter_list = 0, NameAST *name = 0, ExpressionAST *type_id = 0)
+ TemplateTypeParameterAST *TemplateTypeParameter(DeclarationListAST *template_parameter_list = nullptr, NameAST *name = nullptr, ExpressionAST *type_id = nullptr)
{
TemplateTypeParameterAST *ast = new (&pool) TemplateTypeParameterAST;
ast->template_parameter_list = template_parameter_list;
@@ -891,28 +891,28 @@ public:
return ast;
}
- UnaryExpressionAST *UnaryExpression(ExpressionAST *expression = 0)
+ UnaryExpressionAST *UnaryExpression(ExpressionAST *expression = nullptr)
{
UnaryExpressionAST *ast = new (&pool) UnaryExpressionAST;
ast->expression = expression;
return ast;
}
- UsingAST *Using(NameAST *name = 0)
+ UsingAST *Using(NameAST *name = nullptr)
{
UsingAST *ast = new (&pool) UsingAST;
ast->name = name;
return ast;
}
- UsingDirectiveAST *UsingDirective(NameAST *name = 0)
+ UsingDirectiveAST *UsingDirective(NameAST *name = nullptr)
{
UsingDirectiveAST *ast = new (&pool) UsingDirectiveAST;
ast->name = name;
return ast;
}
- WhileStatementAST *WhileStatement(ExpressionAST *condition = 0, StatementAST *statement = 0)
+ WhileStatementAST *WhileStatement(ExpressionAST *condition = nullptr, StatementAST *statement = nullptr)
{
WhileStatementAST *ast = new (&pool) WhileStatementAST;
ast->condition = condition;
@@ -920,7 +920,7 @@ public:
return ast;
}
- ObjCClassForwardDeclarationAST *ObjCClassForwardDeclaration(SpecifierListAST *attribute_list = 0, NameListAST *identifier_list = 0)
+ ObjCClassForwardDeclarationAST *ObjCClassForwardDeclaration(SpecifierListAST *attribute_list = nullptr, NameListAST *identifier_list = nullptr)
{
ObjCClassForwardDeclarationAST *ast = new (&pool) ObjCClassForwardDeclarationAST;
ast->attribute_list = attribute_list;
@@ -928,7 +928,7 @@ public:
return ast;
}
- ObjCClassDeclarationAST *ObjCClassDeclaration(SpecifierListAST *attribute_list = 0, NameAST *class_name = 0, NameAST *category_name = 0, NameAST *superclass = 0, ObjCProtocolRefsAST *protocol_refs = 0, ObjCInstanceVariablesDeclarationAST *inst_vars_decl = 0, DeclarationListAST *member_declaration_list = 0)
+ ObjCClassDeclarationAST *ObjCClassDeclaration(SpecifierListAST *attribute_list = nullptr, NameAST *class_name = nullptr, NameAST *category_name = nullptr, NameAST *superclass = nullptr, ObjCProtocolRefsAST *protocol_refs = nullptr, ObjCInstanceVariablesDeclarationAST *inst_vars_decl = nullptr, DeclarationListAST *member_declaration_list = nullptr)
{
ObjCClassDeclarationAST *ast = new (&pool) ObjCClassDeclarationAST;
ast->attribute_list = attribute_list;
@@ -941,7 +941,7 @@ public:
return ast;
}
- ObjCProtocolForwardDeclarationAST *ObjCProtocolForwardDeclaration(SpecifierListAST *attribute_list = 0, NameListAST *identifier_list = 0)
+ ObjCProtocolForwardDeclarationAST *ObjCProtocolForwardDeclaration(SpecifierListAST *attribute_list = nullptr, NameListAST *identifier_list = nullptr)
{
ObjCProtocolForwardDeclarationAST *ast = new (&pool) ObjCProtocolForwardDeclarationAST;
ast->attribute_list = attribute_list;
@@ -949,7 +949,7 @@ public:
return ast;
}
- ObjCProtocolDeclarationAST *ObjCProtocolDeclaration(SpecifierListAST *attribute_list = 0, NameAST *name = 0, ObjCProtocolRefsAST *protocol_refs = 0, DeclarationListAST *member_declaration_list = 0)
+ ObjCProtocolDeclarationAST *ObjCProtocolDeclaration(SpecifierListAST *attribute_list = nullptr, NameAST *name = nullptr, ObjCProtocolRefsAST *protocol_refs = nullptr, DeclarationListAST *member_declaration_list = nullptr)
{
ObjCProtocolDeclarationAST *ast = new (&pool) ObjCProtocolDeclarationAST;
ast->attribute_list = attribute_list;
@@ -959,21 +959,21 @@ public:
return ast;
}
- ObjCProtocolRefsAST *ObjCProtocolRefs(NameListAST *identifier_list = 0)
+ ObjCProtocolRefsAST *ObjCProtocolRefs(NameListAST *identifier_list = nullptr)
{
ObjCProtocolRefsAST *ast = new (&pool) ObjCProtocolRefsAST;
ast->identifier_list = identifier_list;
return ast;
}
- ObjCMessageArgumentAST *ObjCMessageArgument(ExpressionAST *parameter_value_expression = 0)
+ ObjCMessageArgumentAST *ObjCMessageArgument(ExpressionAST *parameter_value_expression = nullptr)
{
ObjCMessageArgumentAST *ast = new (&pool) ObjCMessageArgumentAST;
ast->parameter_value_expression = parameter_value_expression;
return ast;
}
- ObjCMessageExpressionAST *ObjCMessageExpression(ExpressionAST *receiver_expression = 0, ObjCSelectorAST *selector = 0, ObjCMessageArgumentListAST *argument_list = 0)
+ ObjCMessageExpressionAST *ObjCMessageExpression(ExpressionAST *receiver_expression = nullptr, ObjCSelectorAST *selector = nullptr, ObjCMessageArgumentListAST *argument_list = nullptr)
{
ObjCMessageExpressionAST *ast = new (&pool) ObjCMessageExpressionAST;
ast->receiver_expression = receiver_expression;
@@ -988,28 +988,28 @@ public:
return ast;
}
- ObjCTypeNameAST *ObjCTypeName(ExpressionAST *type_id = 0)
+ ObjCTypeNameAST *ObjCTypeName(ExpressionAST *type_id = nullptr)
{
ObjCTypeNameAST *ast = new (&pool) ObjCTypeNameAST;
ast->type_id = type_id;
return ast;
}
- ObjCEncodeExpressionAST *ObjCEncodeExpression(ObjCTypeNameAST *type_name = 0)
+ ObjCEncodeExpressionAST *ObjCEncodeExpression(ObjCTypeNameAST *type_name = nullptr)
{
ObjCEncodeExpressionAST *ast = new (&pool) ObjCEncodeExpressionAST;
ast->type_name = type_name;
return ast;
}
- ObjCSelectorExpressionAST *ObjCSelectorExpression(ObjCSelectorAST *selector = 0)
+ ObjCSelectorExpressionAST *ObjCSelectorExpression(ObjCSelectorAST *selector = nullptr)
{
ObjCSelectorExpressionAST *ast = new (&pool) ObjCSelectorExpressionAST;
ast->selector = selector;
return ast;
}
- ObjCInstanceVariablesDeclarationAST *ObjCInstanceVariablesDeclaration(DeclarationListAST *instance_variable_list = 0)
+ ObjCInstanceVariablesDeclarationAST *ObjCInstanceVariablesDeclaration(DeclarationListAST *instance_variable_list = nullptr)
{
ObjCInstanceVariablesDeclarationAST *ast = new (&pool) ObjCInstanceVariablesDeclarationAST;
ast->instance_variable_list = instance_variable_list;
@@ -1022,14 +1022,14 @@ public:
return ast;
}
- ObjCPropertyAttributeAST *ObjCPropertyAttribute(ObjCSelectorAST *method_selector = 0)
+ ObjCPropertyAttributeAST *ObjCPropertyAttribute(ObjCSelectorAST *method_selector = nullptr)
{
ObjCPropertyAttributeAST *ast = new (&pool) ObjCPropertyAttributeAST;
ast->method_selector = method_selector;
return ast;
}
- ObjCPropertyDeclarationAST *ObjCPropertyDeclaration(SpecifierListAST *attribute_list = 0, ObjCPropertyAttributeListAST *property_attribute_list = 0, DeclarationAST *simple_declaration = 0)
+ ObjCPropertyDeclarationAST *ObjCPropertyDeclaration(SpecifierListAST *attribute_list = nullptr, ObjCPropertyAttributeListAST *property_attribute_list = nullptr, DeclarationAST *simple_declaration = nullptr)
{
ObjCPropertyDeclarationAST *ast = new (&pool) ObjCPropertyDeclarationAST;
ast->attribute_list = attribute_list;
@@ -1038,7 +1038,7 @@ public:
return ast;
}
- ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclaration(ObjCTypeNameAST *type_name = 0, SpecifierListAST *attribute_list = 0, NameAST *param_name = 0)
+ ObjCMessageArgumentDeclarationAST *ObjCMessageArgumentDeclaration(ObjCTypeNameAST *type_name = nullptr, SpecifierListAST *attribute_list = nullptr, NameAST *param_name = nullptr)
{
ObjCMessageArgumentDeclarationAST *ast = new (&pool) ObjCMessageArgumentDeclarationAST;
ast->type_name = type_name;
@@ -1047,7 +1047,7 @@ public:
return ast;
}
- ObjCMethodPrototypeAST *ObjCMethodPrototype(ObjCTypeNameAST *type_name = 0, ObjCSelectorAST *selector = 0, ObjCMessageArgumentDeclarationListAST *argument_list = 0, SpecifierListAST *attribute_list = 0)
+ ObjCMethodPrototypeAST *ObjCMethodPrototype(ObjCTypeNameAST *type_name = nullptr, ObjCSelectorAST *selector = nullptr, ObjCMessageArgumentDeclarationListAST *argument_list = nullptr, SpecifierListAST *attribute_list = nullptr)
{
ObjCMethodPrototypeAST *ast = new (&pool) ObjCMethodPrototypeAST;
ast->type_name = type_name;
@@ -1057,7 +1057,7 @@ public:
return ast;
}
- ObjCMethodDeclarationAST *ObjCMethodDeclaration(ObjCMethodPrototypeAST *method_prototype = 0, StatementAST *function_body = 0)
+ ObjCMethodDeclarationAST *ObjCMethodDeclaration(ObjCMethodPrototypeAST *method_prototype = nullptr, StatementAST *function_body = nullptr)
{
ObjCMethodDeclarationAST *ast = new (&pool) ObjCMethodDeclarationAST;
ast->method_prototype = method_prototype;
@@ -1071,21 +1071,21 @@ public:
return ast;
}
- ObjCSynthesizedPropertiesDeclarationAST *ObjCSynthesizedPropertiesDeclaration(ObjCSynthesizedPropertyListAST *property_identifier_list = 0)
+ ObjCSynthesizedPropertiesDeclarationAST *ObjCSynthesizedPropertiesDeclaration(ObjCSynthesizedPropertyListAST *property_identifier_list = nullptr)
{
ObjCSynthesizedPropertiesDeclarationAST *ast = new (&pool) ObjCSynthesizedPropertiesDeclarationAST;
ast->property_identifier_list = property_identifier_list;
return ast;
}
- ObjCDynamicPropertiesDeclarationAST *ObjCDynamicPropertiesDeclaration(NameListAST *property_identifier_list = 0)
+ ObjCDynamicPropertiesDeclarationAST *ObjCDynamicPropertiesDeclaration(NameListAST *property_identifier_list = nullptr)
{
ObjCDynamicPropertiesDeclarationAST *ast = new (&pool) ObjCDynamicPropertiesDeclarationAST;
ast->property_identifier_list = property_identifier_list;
return ast;
}
- ObjCFastEnumerationAST *ObjCFastEnumeration(SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0, ExpressionAST *initializer = 0, ExpressionAST *fast_enumeratable_expression = 0, StatementAST *statement = 0)
+ ObjCFastEnumerationAST *ObjCFastEnumeration(SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr, ExpressionAST *initializer = nullptr, ExpressionAST *fast_enumeratable_expression = nullptr, StatementAST *statement = nullptr)
{
ObjCFastEnumerationAST *ast = new (&pool) ObjCFastEnumerationAST;
ast->type_specifier_list = type_specifier_list;
@@ -1096,7 +1096,7 @@ public:
return ast;
}
- ObjCSynchronizedStatementAST *ObjCSynchronizedStatement(ExpressionAST *synchronized_object = 0, StatementAST *statement = 0)
+ ObjCSynchronizedStatementAST *ObjCSynchronizedStatement(ExpressionAST *synchronized_object = nullptr, StatementAST *statement = nullptr)
{
ObjCSynchronizedStatementAST *ast = new (&pool) ObjCSynchronizedStatementAST;
ast->synchronized_object = synchronized_object;
@@ -1104,7 +1104,7 @@ public:
return ast;
}
- LambdaExpressionAST *LambdaExpression(LambdaIntroducerAST *lambda_introducer = 0, LambdaDeclaratorAST *lambda_declarator = 0, StatementAST *statement = 0)
+ LambdaExpressionAST *LambdaExpression(LambdaIntroducerAST *lambda_introducer = nullptr, LambdaDeclaratorAST *lambda_declarator = nullptr, StatementAST *statement = nullptr)
{
LambdaExpressionAST *ast = new (&pool) LambdaExpressionAST;
ast->lambda_introducer = lambda_introducer;
@@ -1113,28 +1113,28 @@ public:
return ast;
}
- LambdaIntroducerAST *LambdaIntroducer(LambdaCaptureAST *lambda_capture = 0)
+ LambdaIntroducerAST *LambdaIntroducer(LambdaCaptureAST *lambda_capture = nullptr)
{
LambdaIntroducerAST *ast = new (&pool) LambdaIntroducerAST;
ast->lambda_capture = lambda_capture;
return ast;
}
- LambdaCaptureAST *LambdaCapture(CaptureListAST *capture_list = 0)
+ LambdaCaptureAST *LambdaCapture(CaptureListAST *capture_list = nullptr)
{
LambdaCaptureAST *ast = new (&pool) LambdaCaptureAST;
ast->capture_list = capture_list;
return ast;
}
- CaptureAST *Capture(NameAST *identifier = 0)
+ CaptureAST *Capture(NameAST *identifier = nullptr)
{
CaptureAST *ast = new (&pool) CaptureAST;
ast->identifier = identifier;
return ast;
}
- LambdaDeclaratorAST *LambdaDeclarator(ParameterDeclarationClauseAST *parameter_declaration_clause = 0, SpecifierListAST *attributes = 0, ExceptionSpecificationAST *exception_specification = 0, TrailingReturnTypeAST *trailing_return_type = 0)
+ LambdaDeclaratorAST *LambdaDeclarator(ParameterDeclarationClauseAST *parameter_declaration_clause = nullptr, SpecifierListAST *attributes = nullptr, ExceptionSpecificationAST *exception_specification = nullptr, TrailingReturnTypeAST *trailing_return_type = nullptr)
{
LambdaDeclaratorAST *ast = new (&pool) LambdaDeclaratorAST;
ast->parameter_declaration_clause = parameter_declaration_clause;
@@ -1144,7 +1144,7 @@ public:
return ast;
}
- TrailingReturnTypeAST *TrailingReturnType(SpecifierListAST *attributes = 0, SpecifierListAST *type_specifier_list = 0, DeclaratorAST *declarator = 0)
+ TrailingReturnTypeAST *TrailingReturnType(SpecifierListAST *attributes = nullptr, SpecifierListAST *type_specifier_list = nullptr, DeclaratorAST *declarator = nullptr)
{
TrailingReturnTypeAST *ast = new (&pool) TrailingReturnTypeAST;
ast->attributes = attributes;
@@ -1153,7 +1153,7 @@ public:
return ast;
}
- BracedInitializerAST *BracedInitializer(ExpressionListAST *expression_list = 0)
+ BracedInitializerAST *BracedInitializer(ExpressionListAST *expression_list = nullptr)
{
BracedInitializerAST *ast = new (&pool) BracedInitializerAST;
ast->expression_list = expression_list;
@@ -1166,14 +1166,14 @@ public:
return ast;
}
- BracketDesignatorAST *BracketDesignator(ExpressionAST *expression = 0)
+ BracketDesignatorAST *BracketDesignator(ExpressionAST *expression = nullptr)
{
BracketDesignatorAST *ast = new (&pool) BracketDesignatorAST;
ast->expression = expression;
return ast;
}
- DesignatedInitializerAST *DesignatedInitializer(DesignatorListAST *designator_list = 0, ExpressionAST *initializer = 0)
+ DesignatedInitializerAST *DesignatedInitializer(DesignatorListAST *designator_list = nullptr, ExpressionAST *initializer = nullptr)
{
DesignatedInitializerAST *ast = new (&pool) DesignatedInitializerAST;
ast->designator_list = designator_list;
@@ -1181,7 +1181,7 @@ public:
return ast;
}
- BaseSpecifierListAST *BaseSpecifierList(BaseSpecifierAST *value, BaseSpecifierListAST *next = 0)
+ BaseSpecifierListAST *BaseSpecifierList(BaseSpecifierAST *value, BaseSpecifierListAST *next = nullptr)
{
BaseSpecifierListAST *list = new (&pool) BaseSpecifierListAST;
list->next = next;
@@ -1189,7 +1189,7 @@ public:
return list;
}
- CaptureListAST *CaptureList(CaptureAST *value, CaptureListAST *next = 0)
+ CaptureListAST *CaptureList(CaptureAST *value, CaptureListAST *next = nullptr)
{
CaptureListAST *list = new (&pool) CaptureListAST;
list->next = next;
@@ -1197,7 +1197,7 @@ public:
return list;
}
- CatchClauseListAST *CatchClauseList(CatchClauseAST *value, CatchClauseListAST *next = 0)
+ CatchClauseListAST *CatchClauseList(CatchClauseAST *value, CatchClauseListAST *next = nullptr)
{
CatchClauseListAST *list = new (&pool) CatchClauseListAST;
list->next = next;
@@ -1205,7 +1205,7 @@ public:
return list;
}
- DeclarationListAST *DeclarationList(DeclarationAST *value, DeclarationListAST *next = 0)
+ DeclarationListAST *DeclarationList(DeclarationAST *value, DeclarationListAST *next = nullptr)
{
DeclarationListAST *list = new (&pool) DeclarationListAST;
list->next = next;
@@ -1213,7 +1213,7 @@ public:
return list;
}
- DeclaratorListAST *DeclaratorList(DeclaratorAST *value, DeclaratorListAST *next = 0)
+ DeclaratorListAST *DeclaratorList(DeclaratorAST *value, DeclaratorListAST *next = nullptr)
{
DeclaratorListAST *list = new (&pool) DeclaratorListAST;
list->next = next;
@@ -1221,7 +1221,7 @@ public:
return list;
}
- DesignatorListAST *DesignatorList(DesignatorAST *value, DesignatorListAST *next = 0)
+ DesignatorListAST *DesignatorList(DesignatorAST *value, DesignatorListAST *next = nullptr)
{
DesignatorListAST *list = new (&pool) DesignatorListAST;
list->next = next;
@@ -1229,7 +1229,7 @@ public:
return list;
}
- EnumeratorListAST *EnumeratorList(EnumeratorAST *value, EnumeratorListAST *next = 0)
+ EnumeratorListAST *EnumeratorList(EnumeratorAST *value, EnumeratorListAST *next = nullptr)
{
EnumeratorListAST *list = new (&pool) EnumeratorListAST;
list->next = next;
@@ -1237,7 +1237,7 @@ public:
return list;
}
- ExpressionListAST *ExpressionList(ExpressionAST *value, ExpressionListAST *next = 0)
+ ExpressionListAST *ExpressionList(ExpressionAST *value, ExpressionListAST *next = nullptr)
{
ExpressionListAST *list = new (&pool) ExpressionListAST;
list->next = next;
@@ -1245,7 +1245,7 @@ public:
return list;
}
- GnuAttributeListAST *GnuAttributeList(GnuAttributeAST *value, GnuAttributeListAST *next = 0)
+ GnuAttributeListAST *GnuAttributeList(GnuAttributeAST *value, GnuAttributeListAST *next = nullptr)
{
GnuAttributeListAST *list = new (&pool) GnuAttributeListAST;
list->next = next;
@@ -1253,7 +1253,7 @@ public:
return list;
}
- MemInitializerListAST *MemInitializerList(MemInitializerAST *value, MemInitializerListAST *next = 0)
+ MemInitializerListAST *MemInitializerList(MemInitializerAST *value, MemInitializerListAST *next = nullptr)
{
MemInitializerListAST *list = new (&pool) MemInitializerListAST;
list->next = next;
@@ -1261,7 +1261,7 @@ public:
return list;
}
- NameListAST *NameList(NameAST *value, NameListAST *next = 0)
+ NameListAST *NameList(NameAST *value, NameListAST *next = nullptr)
{
NameListAST *list = new (&pool) NameListAST;
list->next = next;
@@ -1269,7 +1269,7 @@ public:
return list;
}
- NestedNameSpecifierListAST *NestedNameSpecifierList(NestedNameSpecifierAST *value, NestedNameSpecifierListAST *next = 0)
+ NestedNameSpecifierListAST *NestedNameSpecifierList(NestedNameSpecifierAST *value, NestedNameSpecifierListAST *next = nullptr)
{
NestedNameSpecifierListAST *list = new (&pool) NestedNameSpecifierListAST;
list->next = next;
@@ -1277,7 +1277,7 @@ public:
return list;
}
- NewArrayDeclaratorListAST *NewArrayDeclaratorList(NewArrayDeclaratorAST *value, NewArrayDeclaratorListAST *next = 0)
+ NewArrayDeclaratorListAST *NewArrayDeclaratorList(NewArrayDeclaratorAST *value, NewArrayDeclaratorListAST *next = nullptr)
{
NewArrayDeclaratorListAST *list = new (&pool) NewArrayDeclaratorListAST;
list->next = next;
@@ -1285,7 +1285,7 @@ public:
return list;
}
- ObjCMessageArgumentDeclarationListAST *ObjCMessageArgumentDeclarationList(ObjCMessageArgumentDeclarationAST *value, ObjCMessageArgumentDeclarationListAST *next = 0)
+ ObjCMessageArgumentDeclarationListAST *ObjCMessageArgumentDeclarationList(ObjCMessageArgumentDeclarationAST *value, ObjCMessageArgumentDeclarationListAST *next = nullptr)
{
ObjCMessageArgumentDeclarationListAST *list = new (&pool) ObjCMessageArgumentDeclarationListAST;
list->next = next;
@@ -1293,7 +1293,7 @@ public:
return list;
}
- ObjCMessageArgumentListAST *ObjCMessageArgumentList(ObjCMessageArgumentAST *value, ObjCMessageArgumentListAST *next = 0)
+ ObjCMessageArgumentListAST *ObjCMessageArgumentList(ObjCMessageArgumentAST *value, ObjCMessageArgumentListAST *next = nullptr)
{
ObjCMessageArgumentListAST *list = new (&pool) ObjCMessageArgumentListAST;
list->next = next;
@@ -1301,7 +1301,7 @@ public:
return list;
}
- ObjCPropertyAttributeListAST *ObjCPropertyAttributeList(ObjCPropertyAttributeAST *value, ObjCPropertyAttributeListAST *next = 0)
+ ObjCPropertyAttributeListAST *ObjCPropertyAttributeList(ObjCPropertyAttributeAST *value, ObjCPropertyAttributeListAST *next = nullptr)
{
ObjCPropertyAttributeListAST *list = new (&pool) ObjCPropertyAttributeListAST;
list->next = next;
@@ -1309,7 +1309,7 @@ public:
return list;
}
- ObjCSelectorArgumentListAST *ObjCSelectorArgumentList(ObjCSelectorArgumentAST *value, ObjCSelectorArgumentListAST *next = 0)
+ ObjCSelectorArgumentListAST *ObjCSelectorArgumentList(ObjCSelectorArgumentAST *value, ObjCSelectorArgumentListAST *next = nullptr)
{
ObjCSelectorArgumentListAST *list = new (&pool) ObjCSelectorArgumentListAST;
list->next = next;
@@ -1317,7 +1317,7 @@ public:
return list;
}
- ObjCSynthesizedPropertyListAST *ObjCSynthesizedPropertyList(ObjCSynthesizedPropertyAST *value, ObjCSynthesizedPropertyListAST *next = 0)
+ ObjCSynthesizedPropertyListAST *ObjCSynthesizedPropertyList(ObjCSynthesizedPropertyAST *value, ObjCSynthesizedPropertyListAST *next = nullptr)
{
ObjCSynthesizedPropertyListAST *list = new (&pool) ObjCSynthesizedPropertyListAST;
list->next = next;
@@ -1325,7 +1325,7 @@ public:
return list;
}
- ParameterDeclarationListAST *ParameterDeclarationList(ParameterDeclarationAST *value, ParameterDeclarationListAST *next = 0)
+ ParameterDeclarationListAST *ParameterDeclarationList(ParameterDeclarationAST *value, ParameterDeclarationListAST *next = nullptr)
{
ParameterDeclarationListAST *list = new (&pool) ParameterDeclarationListAST;
list->next = next;
@@ -1333,7 +1333,7 @@ public:
return list;
}
- PostfixDeclaratorListAST *PostfixDeclaratorList(PostfixDeclaratorAST *value, PostfixDeclaratorListAST *next = 0)
+ PostfixDeclaratorListAST *PostfixDeclaratorList(PostfixDeclaratorAST *value, PostfixDeclaratorListAST *next = nullptr)
{
PostfixDeclaratorListAST *list = new (&pool) PostfixDeclaratorListAST;
list->next = next;
@@ -1341,7 +1341,7 @@ public:
return list;
}
- PtrOperatorListAST *PtrOperatorList(PtrOperatorAST *value, PtrOperatorListAST *next = 0)
+ PtrOperatorListAST *PtrOperatorList(PtrOperatorAST *value, PtrOperatorListAST *next = nullptr)
{
PtrOperatorListAST *list = new (&pool) PtrOperatorListAST;
list->next = next;
@@ -1349,7 +1349,7 @@ public:
return list;
}
- QtInterfaceNameListAST *QtInterfaceNameList(QtInterfaceNameAST *value, QtInterfaceNameListAST *next = 0)
+ QtInterfaceNameListAST *QtInterfaceNameList(QtInterfaceNameAST *value, QtInterfaceNameListAST *next = nullptr)
{
QtInterfaceNameListAST *list = new (&pool) QtInterfaceNameListAST;
list->next = next;
@@ -1357,7 +1357,7 @@ public:
return list;
}
- QtPropertyDeclarationItemListAST *QtPropertyDeclarationItemList(QtPropertyDeclarationItemAST *value, QtPropertyDeclarationItemListAST *next = 0)
+ QtPropertyDeclarationItemListAST *QtPropertyDeclarationItemList(QtPropertyDeclarationItemAST *value, QtPropertyDeclarationItemListAST *next = nullptr)
{
QtPropertyDeclarationItemListAST *list = new (&pool) QtPropertyDeclarationItemListAST;
list->next = next;
@@ -1365,7 +1365,7 @@ public:
return list;
}
- SpecifierListAST *SpecifierList(SpecifierAST *value, SpecifierListAST *next = 0)
+ SpecifierListAST *SpecifierList(SpecifierAST *value, SpecifierListAST *next = nullptr)
{
SpecifierListAST *list = new (&pool) SpecifierListAST;
list->next = next;
@@ -1373,7 +1373,7 @@ public:
return list;
}
- StatementListAST *StatementList(StatementAST *value, StatementListAST *next = 0)
+ StatementListAST *StatementList(StatementAST *value, StatementListAST *next = nullptr)
{
StatementListAST *list = new (&pool) StatementListAST;
list->next = next;
diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.cpp b/src/libs/3rdparty/cplusplus/ASTVisitor.cpp
index f4119e9ce1..efd5ff1d53 100644
--- a/src/libs/3rdparty/cplusplus/ASTVisitor.cpp
+++ b/src/libs/3rdparty/cplusplus/ASTVisitor.cpp
@@ -40,7 +40,7 @@ Control *ASTVisitor::control() const
if (_translationUnit)
return _translationUnit->control();
- return 0;
+ return nullptr;
}
TranslationUnit *ASTVisitor::translationUnit() const
@@ -49,44 +49,40 @@ TranslationUnit *ASTVisitor::translationUnit() const
void ASTVisitor::setTranslationUnit(TranslationUnit *translationUnit)
{ _translationUnit = translationUnit; }
-unsigned ASTVisitor::tokenCount() const
+int ASTVisitor::tokenCount() const
{ return translationUnit()->tokenCount(); }
-const Token &ASTVisitor::tokenAt(unsigned index) const
+const Token &ASTVisitor::tokenAt(int index) const
{ return translationUnit()->tokenAt(index); }
-int ASTVisitor::tokenKind(unsigned index) const
+int ASTVisitor::tokenKind(int index) const
{ return translationUnit()->tokenKind(index); }
-const char *ASTVisitor::spell(unsigned index) const
+const char *ASTVisitor::spell(int index) const
{ return translationUnit()->spell(index); }
-const Identifier *ASTVisitor::identifier(unsigned index) const
+const Identifier *ASTVisitor::identifier(int index) const
{ return translationUnit()->identifier(index); }
-const Literal *ASTVisitor::literal(unsigned index) const
+const Literal *ASTVisitor::literal(int index) const
{ return translationUnit()->literal(index); }
-const NumericLiteral *ASTVisitor::numericLiteral(unsigned index) const
+const NumericLiteral *ASTVisitor::numericLiteral(int index) const
{ return translationUnit()->numericLiteral(index); }
-const StringLiteral *ASTVisitor::stringLiteral(unsigned index) const
+const StringLiteral *ASTVisitor::stringLiteral(int index) const
{ return translationUnit()->stringLiteral(index); }
-void ASTVisitor::getPosition(unsigned offset,
- unsigned *line,
- unsigned *column,
+void ASTVisitor::getPosition(int offset, int *line, int *column,
const StringLiteral **fileName) const
{ translationUnit()->getPosition(offset, line, column, fileName); }
-void ASTVisitor::getTokenPosition(unsigned index,
- unsigned *line,
- unsigned *column,
+void ASTVisitor::getTokenPosition(int index, int *line, int *column,
const StringLiteral **fileName) const
{ translationUnit()->getTokenPosition(index, line, column, fileName); }
-void ASTVisitor::getTokenStartPosition(unsigned index, unsigned *line, unsigned *column) const
+void ASTVisitor::getTokenStartPosition(int index, int *line, int *column) const
{ getPosition(tokenAt(index).utf16charsBegin(), line, column); }
-void ASTVisitor::getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const
+void ASTVisitor::getTokenEndPosition(int index, int *line, int *column) const
{ getPosition(tokenAt(index).utf16charsEnd(), line, column); }
diff --git a/src/libs/3rdparty/cplusplus/ASTVisitor.h b/src/libs/3rdparty/cplusplus/ASTVisitor.h
index 46bfde340b..a1740e12cd 100644
--- a/src/libs/3rdparty/cplusplus/ASTVisitor.h
+++ b/src/libs/3rdparty/cplusplus/ASTVisitor.h
@@ -38,27 +38,27 @@ public:
void setTranslationUnit(TranslationUnit *translationUnit);
Control *control() const;
- unsigned tokenCount() const;
- const Token &tokenAt(unsigned index) const;
- int tokenKind(unsigned index) const;
- const char *spell(unsigned index) const;
- const Identifier *identifier(unsigned index) const;
- const Literal *literal(unsigned index) const;
- const NumericLiteral *numericLiteral(unsigned index) const;
- const StringLiteral *stringLiteral(unsigned index) const;
+ int tokenCount() const;
+ const Token &tokenAt(int index) const;
+ int tokenKind(int index) const;
+ const char *spell(int index) const;
+ const Identifier *identifier(int index) const;
+ const Literal *literal(int index) const;
+ const NumericLiteral *numericLiteral(int index) const;
+ const StringLiteral *stringLiteral(int index) const;
- void getPosition(unsigned offset,
- unsigned *line,
- unsigned *column = 0,
- const StringLiteral **fileName = 0) const;
+ void getPosition(int offset,
+ int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
- void getTokenPosition(unsigned index,
- unsigned *line,
- unsigned *column = 0,
- const StringLiteral **fileName = 0) const;
+ void getTokenPosition(int index,
+ int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
- void getTokenStartPosition(unsigned index, unsigned *line, unsigned *column) const;
- void getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const;
+ void getTokenStartPosition(int index, int *line, int *column) const;
+ void getTokenEndPosition(int index, int *line, int *column) const;
void accept(AST *ast);
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp
index 1f082a6ec8..053d4f1388 100644
--- a/src/libs/3rdparty/cplusplus/Bind.cpp
+++ b/src/libs/3rdparty/cplusplus/Bind.cpp
@@ -42,10 +42,10 @@ const int Bind::kMaxDepth(100);
Bind::Bind(TranslationUnit *unit)
: ASTVisitor(unit),
- _scope(0),
- _expression(0),
- _name(0),
- _declaratorId(0),
+ _scope(nullptr),
+ _expression(nullptr),
+ _name(nullptr),
+ _declaratorId(nullptr),
_visibility(Symbol::Public),
_objcVisibility(Symbol::Public),
_methodKey(Function::NormalMethod),
@@ -64,7 +64,7 @@ void Bind::setSkipFunctionBodies(bool skipFunctionBodies)
_skipFunctionBodies = skipFunctionBodies;
}
-unsigned Bind::location(DeclaratorAST *ast, unsigned defaultLocation) const
+int Bind::location(DeclaratorAST *ast, int defaultLocation) const
{
if (! ast)
return defaultLocation;
@@ -75,7 +75,7 @@ unsigned Bind::location(DeclaratorAST *ast, unsigned defaultLocation) const
return ast->firstToken();
}
-unsigned Bind::location(CoreDeclaratorAST *ast, unsigned defaultLocation) const
+int Bind::location(CoreDeclaratorAST *ast, int defaultLocation) const
{
if (! ast)
return defaultLocation;
@@ -89,7 +89,7 @@ unsigned Bind::location(CoreDeclaratorAST *ast, unsigned defaultLocation) const
return ast->firstToken();
}
-unsigned Bind::location(NameAST *name, unsigned defaultLocation) const
+int Bind::location(NameAST *name, int defaultLocation) const
{
if (! name)
return defaultLocation;
@@ -229,7 +229,7 @@ void Bind::declaration(DeclarationAST *ast)
const Name *Bind::name(NameAST *ast)
{
- const Name *value = 0;
+ const Name *value = nullptr;
std::swap(_name, value);
accept(ast);
std::swap(_name, value);
@@ -296,7 +296,7 @@ bool Bind::visit(ObjCSelectorArgumentAST *ast)
const Name *Bind::objCSelectorArgument(ObjCSelectorArgumentAST *ast, bool *hasArg)
{
if (! (ast && ast->name_token))
- return 0;
+ return nullptr;
if (ast->colon_token)
*hasArg = true;
@@ -316,7 +316,7 @@ void Bind::attribute(GnuAttributeAST *ast)
if (! ast)
return;
- // unsigned identifier_token = ast->identifier_token;
+ // int identifier_token = ast->identifier_token;
if (const Identifier *id = identifier(ast->identifier_token)) {
if (id == control()->deprecatedId())
_type.setDeprecated(true);
@@ -324,12 +324,12 @@ void Bind::attribute(GnuAttributeAST *ast)
_type.setUnavailable(true);
}
- // unsigned lparen_token = ast->lparen_token;
- // unsigned tag_token = ast->tag_token;
+ // int lparen_token = ast->lparen_token;
+ // int tag_token = ast->tag_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
ExpressionTy value = this->expression(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
}
bool Bind::visit(DeclaratorAST *ast)
@@ -413,12 +413,12 @@ bool Bind::visit(BaseSpecifierAST *ast)
return false;
}
-void Bind::baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *klass)
+void Bind::baseSpecifier(BaseSpecifierAST *ast, int colon_token, Class *klass)
{
if (! ast)
return;
- unsigned sourceLocation = location(ast->name, ast->firstToken());
+ int sourceLocation = location(ast->name, ast->firstToken());
if (! sourceLocation)
sourceLocation = std::max(colon_token, klass->sourceLocation());
@@ -448,11 +448,11 @@ void Bind::ctorInitializer(CtorInitializerAST *ast, Function *fun)
if (! ast)
return;
- // unsigned colon_token = ast->colon_token;
+ // int colon_token = ast->colon_token;
for (MemInitializerListAST *it = ast->member_initializer_list; it; it = it->next) {
this->memInitializer(it->value, fun);
}
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
}
bool Bind::visit(EnumeratorAST *ast)
@@ -508,7 +508,7 @@ void calculateConstantValue(const Symbol *symbol, EnumeratorDeclaration *e, Cont
const std::string buffer
= std::to_string(static_cast<long long>(constantValueAsInt));
e->setConstantValue(control->stringLiteral(buffer.c_str(),
- unsigned(buffer.size())));
+ int(buffer.size())));
}
}
}
@@ -531,7 +531,7 @@ const StringLiteral *valueOfEnumerator(const Enum *e, const Identifier *value) {
}
}
}
- return 0;
+ return nullptr;
}
} // anonymous namespace
@@ -543,8 +543,8 @@ void Bind::enumerator(EnumeratorAST *ast, Enum *symbol)
if (! ast)
return;
- // unsigned identifier_token = ast->identifier_token;
- // unsigned equal_token = ast->equal_token;
+ // int identifier_token = ast->identifier_token;
+ // int equal_token = ast->equal_token;
/*ExpressionTy expression =*/ this->expression(ast->expression);
if (ast->identifier_token) {
@@ -556,7 +556,7 @@ void Bind::enumerator(EnumeratorAST *ast, Enum *symbol)
const int firstToken = expr->firstToken();
const int lastToken = expr->lastToken();
const StringLiteral *constantValue = asStringLiteral(expr);
- const StringLiteral *resolvedValue = 0;
+ const StringLiteral *resolvedValue = nullptr;
if (lastToken - firstToken == 1) {
if (const Identifier *constantId = identifier(firstToken))
resolvedValue = valueOfEnumerator(symbol, constantId);
@@ -587,16 +587,16 @@ FullySpecifiedType Bind::exceptionSpecification(ExceptionSpecificationAST *ast,
return type;
if (DynamicExceptionSpecificationAST *dyn = ast->asDynamicExceptionSpecification()) {
- // unsigned throw_token = ast->throw_token;
- // unsigned lparen_token = ast->lparen_token;
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+ // int throw_token = ast->throw_token;
+ // int lparen_token = ast->lparen_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
for (ExpressionListAST *it = dyn->type_id_list; it; it = it->next) {
/*ExpressionTy value =*/ this->expression(it->value);
}
} else if (NoExceptSpecificationAST *no = ast->asNoExceptSpecification()) {
/*ExpressionTy value =*/ this->expression(no->expression);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return type;
}
@@ -629,7 +629,7 @@ bool Bind::visit(NestedNameSpecifierAST *ast)
const Name *Bind::nestedNameSpecifier(NestedNameSpecifierAST *ast)
{
if (! ast)
- return 0;
+ return nullptr;
const Name *class_or_namespace_name = this->name(ast->class_or_namespace_name);
return class_or_namespace_name;
@@ -637,11 +637,11 @@ const Name *Bind::nestedNameSpecifier(NestedNameSpecifierAST *ast)
bool Bind::visit(ExpressionListParenAST *ast)
{
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
/*ExpressionTy value =*/ this->expression(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
@@ -651,11 +651,11 @@ void Bind::newPlacement(ExpressionListParenAST *ast)
if (! ast)
return;
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
ExpressionTy value = this->expression(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
}
bool Bind::visit(NewArrayDeclaratorAST *ast)
@@ -672,9 +672,9 @@ FullySpecifiedType Bind::newArrayDeclarator(NewArrayDeclaratorAST *ast, const Fu
if (! ast)
return type;
- // unsigned lbracket_token = ast->lbracket_token;
+ // int lbracket_token = ast->lbracket_token;
ExpressionTy expression = this->expression(ast->expression);
- // unsigned rbracket_token = ast->rbracket_token;
+ // int rbracket_token = ast->rbracket_token;
return type;
}
@@ -719,9 +719,9 @@ OperatorNameId::Kind Bind::cppOperator(OperatorAST *ast)
if (! ast)
return kind;
- // unsigned op_token = ast->op_token;
- // unsigned open_token = ast->open_token;
- // unsigned close_token = ast->close_token;
+ // int op_token = ast->op_token;
+ // int open_token = ast->open_token;
+ // int close_token = ast->close_token;
switch (tokenKind(ast->op_token)) {
case T_NEW:
@@ -904,7 +904,7 @@ bool Bind::visit(ParameterDeclarationClauseAST *ast)
return false;
}
-void Bind::parameterDeclarationClause(ParameterDeclarationClauseAST *ast, unsigned lparen_token, Function *fun)
+void Bind::parameterDeclarationClause(ParameterDeclarationClauseAST *ast, int lparen_token, Function *fun)
{
if (! ast)
return;
@@ -992,7 +992,7 @@ FullySpecifiedType Bind::objCTypeName(ObjCTypeNameAST *ast)
if (! ast)
return FullySpecifiedType();
- // unsigned type_qualifier_token = ast->type_qualifier_token;
+ // int type_qualifier_token = ast->type_qualifier_token;
ExpressionTy type_id = this->expression(ast->type_id);
return type_id;
}
@@ -1011,11 +1011,11 @@ void Bind::objCInstanceVariablesDeclaration(ObjCInstanceVariablesDeclarationAST
if (! ast)
return;
- // unsigned lbrace_token = ast->lbrace_token;
+ // int lbrace_token = ast->lbrace_token;
for (DeclarationListAST *it = ast->instance_variable_list; it; it = it->next) {
this->declaration(it->value);
}
- // unsigned rbrace_token = ast->rbrace_token;
+ // int rbrace_token = ast->rbrace_token;
}
bool Bind::visit(ObjCPropertyAttributeAST *ast)
@@ -1030,8 +1030,8 @@ void Bind::objCPropertyAttribute(ObjCPropertyAttributeAST *ast)
if (! ast)
return;
- // unsigned attribute_identifier_token = ast->attribute_identifier_token;
- // unsigned equals_token = ast->equals_token;
+ // int attribute_identifier_token = ast->attribute_identifier_token;
+ // int equals_token = ast->equals_token;
/*const Name *method_selector =*/ this->name(ast->method_selector);
}
@@ -1070,13 +1070,13 @@ bool Bind::visit(ObjCMethodPrototypeAST *ast)
ObjCMethod *Bind::objCMethodPrototype(ObjCMethodPrototypeAST *ast)
{
if (! ast)
- return 0;
+ return nullptr;
- // unsigned method_type_token = ast->method_type_token;
+ // int method_type_token = ast->method_type_token;
FullySpecifiedType returnType = this->objCTypeName(ast->type_name);
const Name *selector = this->name(ast->selector);
- const unsigned sourceLocation = location(ast->selector, ast->firstToken());
+ const int sourceLocation = location(ast->selector, ast->firstToken());
ObjCMethod *method = control()->newObjCMethod(sourceLocation, selector);
// ### set the offsets
method->setReturnType(returnType);
@@ -1115,9 +1115,9 @@ void Bind::objCSynthesizedProperty(ObjCSynthesizedPropertyAST *ast)
if (! ast)
return;
- // unsigned property_identifier_token = ast->property_identifier_token;
- // unsigned equals_token = ast->equals_token;
- // unsigned alias_identifier_token = ast->alias_identifier_token;
+ // int property_identifier_token = ast->property_identifier_token;
+ // int equals_token = ast->equals_token;
+ // int alias_identifier_token = ast->alias_identifier_token;
}
bool Bind::visit(LambdaIntroducerAST *ast)
@@ -1132,9 +1132,9 @@ void Bind::lambdaIntroducer(LambdaIntroducerAST *ast)
if (! ast)
return;
- // unsigned lbracket_token = ast->lbracket_token;
+ // int lbracket_token = ast->lbracket_token;
this->lambdaCapture(ast->lambda_capture);
- // unsigned rbracket_token = ast->rbracket_token;
+ // int rbracket_token = ast->rbracket_token;
}
bool Bind::visit(LambdaCaptureAST *ast)
@@ -1149,7 +1149,7 @@ void Bind::lambdaCapture(LambdaCaptureAST *ast)
if (! ast)
return;
- // unsigned default_capture_token = ast->default_capture_token;
+ // int default_capture_token = ast->default_capture_token;
for (CaptureListAST *it = ast->capture_list; it; it = it->next) {
this->capture(it->value);
}
@@ -1180,9 +1180,9 @@ bool Bind::visit(LambdaDeclaratorAST *ast)
Function *Bind::lambdaDeclarator(LambdaDeclaratorAST *ast)
{
if (! ast)
- return 0;
+ return nullptr;
- Function *fun = control()->newFunction(0, 0);
+ Function *fun = control()->newFunction(0, nullptr);
fun->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin());
fun->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
@@ -1191,13 +1191,13 @@ Function *Bind::lambdaDeclarator(LambdaDeclaratorAST *ast)
type = this->trailingReturnType(ast->trailing_return_type, type);
ast->symbol = fun;
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
this->parameterDeclarationClause(ast->parameter_declaration_clause, ast->lparen_token, fun);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
for (SpecifierListAST *it = ast->attributes; it; it = it->next) {
type = this->specifier(it->value, type);
}
- // unsigned mutable_token = ast->mutable_token;
+ // int mutable_token = ast->mutable_token;
type = this->exceptionSpecification(ast->exception_specification, type);
if (!type.isValid())
@@ -1220,37 +1220,37 @@ FullySpecifiedType Bind::trailingReturnType(TrailingReturnTypeAST *ast, const Fu
if (! ast)
return type;
- // unsigned arrow_token = ast->arrow_token;
+ // int arrow_token = ast->arrow_token;
for (SpecifierListAST *it = ast->attributes; it; it = it->next) {
type = this->specifier(it->value, type);
}
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
return type;
}
const StringLiteral *Bind::asStringLiteral(const ExpressionAST *ast)
{
- CPP_ASSERT(ast, return 0);
- const unsigned firstToken = ast->firstToken();
- const unsigned lastToken = ast->lastToken();
+ CPP_ASSERT(ast, return nullptr);
+ const int firstToken = ast->firstToken();
+ const int lastToken = ast->lastToken();
std::string buffer;
- for (unsigned index = firstToken; index != lastToken; ++index) {
+ for (int index = firstToken; index != lastToken; ++index) {
const Token &tk = tokenAt(index);
if (index != firstToken && (tk.whitespace() || tk.newline()))
buffer += ' ';
buffer += tk.spell();
}
- return control()->stringLiteral(buffer.c_str(), unsigned(buffer.size()));
+ return control()->stringLiteral(buffer.c_str(), int(buffer.size()));
}
// StatementAST
bool Bind::visit(QtMemberDeclarationAST *ast)
{
- const Name *name = 0;
+ const Name *name = nullptr;
if (tokenKind(ast->q_token) == T_Q_D)
name = control()->identifier("d");
@@ -1266,7 +1266,7 @@ bool Bind::visit(QtMemberDeclarationAST *ast)
privateClass += nameId->identifier()->chars();
privateClass += "Private";
- const Name *privName = control()->identifier(privateClass.c_str(), unsigned(privateClass.size()));
+ const Name *privName = control()->identifier(privateClass.c_str(), int(privateClass.size()));
declTy.setType(control()->namedType(privName));
}
}
@@ -1289,7 +1289,7 @@ bool Bind::visit(CaseStatementAST *ast)
bool Bind::visit(CompoundStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- unsigned startScopeToken = ast->lbrace_token ? ast->lbrace_token : ast->firstToken();
+ int startScopeToken = ast->lbrace_token ? ast->lbrace_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
ast->symbol = block;
@@ -1325,14 +1325,14 @@ bool Bind::visit(ExpressionOrDeclarationStatementAST *ast)
bool Bind::visit(ExpressionStatementAST *ast)
{
ExpressionTy expression = this->expression(ast->expression);
- // unsigned semicolon_token = ast->semicolon_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
bool Bind::visit(ForeachStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1344,26 +1344,26 @@ bool Bind::visit(ForeachStatementAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
- const StringLiteral *initializer = 0;
+ const StringLiteral *initializer = nullptr;
if (type.isAuto() && translationUnit()->languageFeatures().cxx11Enabled) {
ExpressionTy exprType = this->expression(ast->expression);
- ArrayType* arrayType = 0;
+ ArrayType* arrayType = nullptr;
arrayType = exprType->asArrayType();
- if (arrayType != 0)
+ if (arrayType != nullptr)
type = arrayType->elementType();
- else if (ast->expression != 0) {
+ else if (ast->expression != nullptr) {
const StringLiteral *sl = asStringLiteral(ast->expression);
const std::string buff = std::string("*") + sl->chars() + ".begin()";
- initializer = control()->stringLiteral(buff.c_str(), unsigned(buff.size()));
+ initializer = control()->stringLiteral(buff.c_str(), int(buff.size()));
}
}
if (declaratorId && declaratorId->name) {
- unsigned sourceLocation = location(declaratorId->name, ast->firstToken());
+ int sourceLocation = location(declaratorId->name, ast->firstToken());
Declaration *decl = control()->newDeclaration(sourceLocation, declaratorId->name->name);
decl->setType(type);
decl->setInitializer(initializer);
@@ -1380,7 +1380,7 @@ bool Bind::visit(ForeachStatementAST *ast)
bool Bind::visit(RangeBasedForStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1392,26 +1392,26 @@ bool Bind::visit(RangeBasedForStatementAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
- const StringLiteral *initializer = 0;
+ const StringLiteral *initializer = nullptr;
if (type.isAuto() && translationUnit()->languageFeatures().cxx11Enabled) {
ExpressionTy exprType = this->expression(ast->expression);
- ArrayType* arrayType = 0;
+ ArrayType* arrayType = nullptr;
arrayType = exprType->asArrayType();
- if (arrayType != 0)
+ if (arrayType != nullptr)
type = arrayType->elementType();
- else if (ast->expression != 0) {
+ else if (ast->expression != nullptr) {
const StringLiteral *sl = asStringLiteral(ast->expression);
const std::string buff = std::string("*") + sl->chars() + ".begin()";
- initializer = control()->stringLiteral(buff.c_str(), unsigned(buff.size()));
+ initializer = control()->stringLiteral(buff.c_str(), int(buff.size()));
}
}
if (declaratorId && declaratorId->name) {
- unsigned sourceLocation = location(declaratorId->name, ast->firstToken());
+ int sourceLocation = location(declaratorId->name, ast->firstToken());
Declaration *decl = control()->newDeclaration(sourceLocation, declaratorId->name->name);
decl->setType(type);
decl->setInitializer(initializer);
@@ -1427,7 +1427,7 @@ bool Bind::visit(RangeBasedForStatementAST *ast)
bool Bind::visit(ForStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1436,9 +1436,9 @@ bool Bind::visit(ForStatementAST *ast)
Scope *previousScope = switchScope(block);
this->statement(ast->initializer);
/*ExpressionTy condition =*/ this->expression(ast->condition);
- // unsigned semicolon_token = ast->semicolon_token;
+ // int semicolon_token = ast->semicolon_token;
/*ExpressionTy expression =*/ this->expression(ast->expression);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
this->statement(ast->statement);
(void) switchScope(previousScope);
return false;
@@ -1447,7 +1447,7 @@ bool Bind::visit(ForStatementAST *ast)
bool Bind::visit(IfStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1463,8 +1463,8 @@ bool Bind::visit(IfStatementAST *ast)
bool Bind::visit(LabeledStatementAST *ast)
{
- // unsigned label_token = ast->label_token;
- // unsigned colon_token = ast->colon_token;
+ // int label_token = ast->label_token;
+ // int colon_token = ast->colon_token;
this->statement(ast->statement);
return false;
}
@@ -1472,25 +1472,25 @@ bool Bind::visit(LabeledStatementAST *ast)
bool Bind::visit(BreakStatementAST *ast)
{
(void) ast;
- // unsigned break_token = ast->break_token;
- // unsigned semicolon_token = ast->semicolon_token;
+ // int break_token = ast->break_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
bool Bind::visit(ContinueStatementAST *ast)
{
(void) ast;
- // unsigned continue_token = ast->continue_token;
- // unsigned semicolon_token = ast->semicolon_token;
+ // int continue_token = ast->continue_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
bool Bind::visit(GotoStatementAST *ast)
{
(void) ast;
- // unsigned goto_token = ast->goto_token;
- // unsigned identifier_token = ast->identifier_token;
- // unsigned semicolon_token = ast->semicolon_token;
+ // int goto_token = ast->goto_token;
+ // int identifier_token = ast->identifier_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
@@ -1503,7 +1503,7 @@ bool Bind::visit(ReturnStatementAST *ast)
bool Bind::visit(SwitchStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1518,7 +1518,7 @@ bool Bind::visit(SwitchStatementAST *ast)
bool Bind::visit(TryBlockStatementAST *ast)
{
- // unsigned try_token = ast->try_token;
+ // int try_token = ast->try_token;
this->statement(ast->statement);
for (CatchClauseListAST *it = ast->catch_clause_list; it; it = it->next) {
this->statement(it->value);
@@ -1529,7 +1529,7 @@ bool Bind::visit(TryBlockStatementAST *ast)
bool Bind::visit(CatchClauseAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1537,7 +1537,7 @@ bool Bind::visit(CatchClauseAST *ast)
Scope *previousScope = switchScope(block);
this->declaration(ast->exception_declaration);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
this->statement(ast->statement);
(void) switchScope(previousScope);
return false;
@@ -1546,7 +1546,7 @@ bool Bind::visit(CatchClauseAST *ast)
bool Bind::visit(WhileStatementAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1562,7 +1562,7 @@ bool Bind::visit(WhileStatementAST *ast)
bool Bind::visit(ObjCFastEnumerationAST *ast)
{
Block *block = control()->newBlock(ast->firstToken());
- const unsigned startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
+ const int startScopeToken = ast->lparen_token ? ast->lparen_token : ast->firstToken();
block->setStartOffset(tokenAt(startScopeToken).utf16charsEnd());
block->setEndOffset(tokenAt(ast->lastToken()).utf16charsBegin());
_scope->addMember(block);
@@ -1573,11 +1573,11 @@ bool Bind::visit(ObjCFastEnumerationAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
if (declaratorId && declaratorId->name) {
- unsigned sourceLocation = location(declaratorId->name, ast->firstToken());
+ int sourceLocation = location(declaratorId->name, ast->firstToken());
Declaration *decl = control()->newDeclaration(sourceLocation, declaratorId->name->name);
decl->setType(type);
block->addMember(decl);
@@ -1592,10 +1592,10 @@ bool Bind::visit(ObjCFastEnumerationAST *ast)
bool Bind::visit(ObjCSynchronizedStatementAST *ast)
{
- // unsigned synchronized_token = ast->synchronized_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int synchronized_token = ast->synchronized_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy synchronized_object = this->expression(ast->synchronized_object);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
this->statement(ast->statement);
return false;
}
@@ -1610,45 +1610,45 @@ bool Bind::visit(IdExpressionAST *ast)
bool Bind::visit(CompoundExpressionAST *ast)
{
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
this->statement(ast->statement);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(CompoundLiteralAST *ast)
{
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy type_id = this->expression(ast->type_id);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
ExpressionTy initializer = this->expression(ast->initializer);
return false;
}
bool Bind::visit(QtMethodAST *ast)
{
- // unsigned method_token = ast->method_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int method_token = ast->method_token;
+ // int lparen_token = ast->lparen_token;
FullySpecifiedType type;
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(BinaryExpressionAST *ast)
{
ExpressionTy left_expression = this->expression(ast->left_expression);
- // unsigned binary_op_token = ast->binary_op_token;
+ // int binary_op_token = ast->binary_op_token;
ExpressionTy right_expression = this->expression(ast->right_expression);
return false;
}
bool Bind::visit(CastExpressionAST *ast)
{
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy type_id = this->expression(ast->type_id);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
ExpressionTy expression = this->expression(ast->expression);
return false;
}
@@ -1659,11 +1659,11 @@ bool Bind::visit(ConditionAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
if (declaratorId && declaratorId->name) {
- unsigned sourceLocation = location(declaratorId->name, ast->firstToken());
+ int sourceLocation = location(declaratorId->name, ast->firstToken());
Declaration *decl = control()->newDeclaration(sourceLocation, declaratorId->name->name);
decl->setType(type);
@@ -1679,53 +1679,53 @@ bool Bind::visit(ConditionAST *ast)
bool Bind::visit(ConditionalExpressionAST *ast)
{
ExpressionTy condition = this->expression(ast->condition);
- // unsigned question_token = ast->question_token;
+ // int question_token = ast->question_token;
ExpressionTy left_expression = this->expression(ast->left_expression);
- // unsigned colon_token = ast->colon_token;
+ // int colon_token = ast->colon_token;
ExpressionTy right_expression = this->expression(ast->right_expression);
return false;
}
bool Bind::visit(CppCastExpressionAST *ast)
{
- // unsigned cast_token = ast->cast_token;
- // unsigned less_token = ast->less_token;
+ // int cast_token = ast->cast_token;
+ // int less_token = ast->less_token;
ExpressionTy type_id = this->expression(ast->type_id);
- // unsigned greater_token = ast->greater_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int greater_token = ast->greater_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy expression = this->expression(ast->expression);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(DeleteExpressionAST *ast)
{
- // unsigned scope_token = ast->scope_token;
- // unsigned delete_token = ast->delete_token;
- // unsigned lbracket_token = ast->lbracket_token;
- // unsigned rbracket_token = ast->rbracket_token;
+ // int scope_token = ast->scope_token;
+ // int delete_token = ast->delete_token;
+ // int lbracket_token = ast->lbracket_token;
+ // int rbracket_token = ast->rbracket_token;
ExpressionTy expression = this->expression(ast->expression);
return false;
}
bool Bind::visit(ArrayInitializerAST *ast)
{
- // unsigned lbrace_token = ast->lbrace_token;
+ // int lbrace_token = ast->lbrace_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
ExpressionTy value = this->expression(it->value);
}
- // unsigned rbrace_token = ast->rbrace_token;
+ // int rbrace_token = ast->rbrace_token;
return false;
}
bool Bind::visit(NewExpressionAST *ast)
{
- // unsigned scope_token = ast->scope_token;
- // unsigned new_token = ast->new_token;
+ // int scope_token = ast->scope_token;
+ // int new_token = ast->new_token;
this->newPlacement(ast->new_placement);
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy type_id = this->expression(ast->type_id);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
this->newTypeId(ast->new_type_id);
this->expression(ast->new_initializer);
return false;
@@ -1733,16 +1733,16 @@ bool Bind::visit(NewExpressionAST *ast)
bool Bind::visit(TypeidExpressionAST *ast)
{
- // unsigned typeid_token = ast->typeid_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int typeid_token = ast->typeid_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy expression = this->expression(ast->expression);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(TypenameCallExpressionAST *ast)
{
- // unsigned typename_token = ast->typename_token;
+ // int typename_token = ast->typename_token;
/*const Name *name =*/ this->name(ast->name);
this->expression(ast->expression);
return false;
@@ -1760,60 +1760,60 @@ bool Bind::visit(TypeConstructorCallAST *ast)
bool Bind::visit(SizeofExpressionAST *ast)
{
- // unsigned sizeof_token = ast->sizeof_token;
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int sizeof_token = ast->sizeof_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy expression = this->expression(ast->expression);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(PointerLiteralAST *ast)
{
(void) ast;
- // unsigned literal_token = ast->literal_token;
+ // int literal_token = ast->literal_token;
return false;
}
bool Bind::visit(NumericLiteralAST *ast)
{
(void) ast;
- // unsigned literal_token = ast->literal_token;
+ // int literal_token = ast->literal_token;
return false;
}
bool Bind::visit(BoolLiteralAST *ast)
{
(void) ast;
- // unsigned literal_token = ast->literal_token;
+ // int literal_token = ast->literal_token;
return false;
}
bool Bind::visit(ThisExpressionAST *ast)
{
(void) ast;
- // unsigned this_token = ast->this_token;
+ // int this_token = ast->this_token;
return false;
}
bool Bind::visit(NestedExpressionAST *ast)
{
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy expression = this->expression(ast->expression);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(StringLiteralAST *ast)
{
- // unsigned literal_token = ast->literal_token;
+ // int literal_token = ast->literal_token;
ExpressionTy next = this->expression(ast->next);
return false;
}
bool Bind::visit(ThrowExpressionAST *ast)
{
- // unsigned throw_token = ast->throw_token;
+ // int throw_token = ast->throw_token;
ExpressionTy expression = this->expression(ast->expression);
return false;
}
@@ -1824,7 +1824,7 @@ bool Bind::visit(TypeIdAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
_expression = type;
return false;
@@ -1832,46 +1832,46 @@ bool Bind::visit(TypeIdAST *ast)
bool Bind::visit(UnaryExpressionAST *ast)
{
- // unsigned unary_op_token = ast->unary_op_token;
+ // int unary_op_token = ast->unary_op_token;
ExpressionTy expression = this->expression(ast->expression);
return false;
}
bool Bind::visit(ObjCMessageExpressionAST *ast)
{
- // unsigned lbracket_token = ast->lbracket_token;
+ // int lbracket_token = ast->lbracket_token;
/*ExpressionTy receiver_expression =*/ this->expression(ast->receiver_expression);
/*const Name *selector =*/ this->name(ast->selector);
for (ObjCMessageArgumentListAST *it = ast->argument_list; it; it = it->next) {
this->objCMessageArgument(it->value);
}
- // unsigned rbracket_token = ast->rbracket_token;
+ // int rbracket_token = ast->rbracket_token;
return false;
}
bool Bind::visit(ObjCProtocolExpressionAST *ast)
{
(void) ast;
- // unsigned protocol_token = ast->protocol_token;
- // unsigned lparen_token = ast->lparen_token;
- // unsigned identifier_token = ast->identifier_token;
- // unsigned rparen_token = ast->rparen_token;
+ // int protocol_token = ast->protocol_token;
+ // int lparen_token = ast->lparen_token;
+ // int identifier_token = ast->identifier_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(ObjCEncodeExpressionAST *ast)
{
- // unsigned encode_token = ast->encode_token;
+ // int encode_token = ast->encode_token;
FullySpecifiedType type = this->objCTypeName(ast->type_name);
return false;
}
bool Bind::visit(ObjCSelectorExpressionAST *ast)
{
- // unsigned selector_token = ast->selector_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int selector_token = ast->selector_token;
+ // int lparen_token = ast->lparen_token;
/*const Name *selector =*/ this->name(ast->selector);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
@@ -1892,12 +1892,12 @@ bool Bind::visit(LambdaExpressionAST *ast)
bool Bind::visit(BracedInitializerAST *ast)
{
- // unsigned lbrace_token = ast->lbrace_token;
+ // int lbrace_token = ast->lbrace_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
/*ExpressionTy value =*/ this->expression(it->value);
}
- // unsigned comma_token = ast->comma_token;
- // unsigned rbrace_token = ast->rbrace_token;
+ // int comma_token = ast->comma_token;
+ // int rbrace_token = ast->rbrace_token;
return false;
}
@@ -1920,7 +1920,7 @@ bool Bind::visit(SimpleDeclarationAST *ast)
if (ast->qt_invokable_token)
methodKey = methodKeyForInvokableToken(tokenKind(ast->qt_invokable_token));
- // unsigned qt_invokable_token = ast->qt_invokable_token;
+ // int qt_invokable_token = ast->qt_invokable_token;
FullySpecifiedType type;
for (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
@@ -1929,13 +1929,13 @@ bool Bind::visit(SimpleDeclarationAST *ast)
List<Symbol *> **symbolTail = &ast->symbols;
if (! ast->declarator_list) {
- ElaboratedTypeSpecifierAST *elabTypeSpec = 0;
+ ElaboratedTypeSpecifierAST *elabTypeSpec = nullptr;
for (SpecifierListAST *it = ast->decl_specifier_list; ! elabTypeSpec && it; it = it->next)
elabTypeSpec = it->value->asElaboratedTypeSpecifier();
if (elabTypeSpec && tokenKind(elabTypeSpec->classkey_token) != T_TYPENAME) {
- unsigned sourceLocation = elabTypeSpec->firstToken();
- const Name *name = 0;
+ int sourceLocation = elabTypeSpec->firstToken();
+ const Name *name = nullptr;
if (elabTypeSpec->name) {
sourceLocation = location(elabTypeSpec->name, sourceLocation);
name = elabTypeSpec->name->name;
@@ -1953,11 +1953,11 @@ bool Bind::visit(SimpleDeclarationAST *ast)
}
for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) {
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
FullySpecifiedType declTy = this->declarator(it->value, type, &declaratorId);
- const Name *declName = 0;
- unsigned sourceLocation = location(it->value, ast->firstToken());
+ const Name *declName = nullptr;
+ int sourceLocation = location(it->value, ast->firstToken());
if (declaratorId && declaratorId->name)
declName = declaratorId->name->name;
@@ -2006,7 +2006,7 @@ bool Bind::visit(SimpleDeclarationAST *ast)
bool Bind::visit(EmptyDeclarationAST *ast)
{
(void) ast;
- unsigned semicolon_token = ast->semicolon_token;
+ int semicolon_token = ast->semicolon_token;
if (_scope && (_scope->isClass() || _scope->isNamespace())) {
const Token &tk = tokenAt(semicolon_token);
@@ -2034,25 +2034,25 @@ bool Bind::visit(AccessDeclarationAST *ast)
bool Bind::visit(QtObjectTagAST *ast)
{
(void) ast;
- // unsigned q_object_token = ast->q_object_token;
+ // int q_object_token = ast->q_object_token;
return false;
}
bool Bind::visit(QtPrivateSlotAST *ast)
{
- // unsigned q_private_slot_token = ast->q_private_slot_token;
- // unsigned lparen_token = ast->lparen_token;
- // unsigned dptr_token = ast->dptr_token;
- // unsigned dptr_lparen_token = ast->dptr_lparen_token;
- // unsigned dptr_rparen_token = ast->dptr_rparen_token;
- // unsigned comma_token = ast->comma_token;
+ // int q_private_slot_token = ast->q_private_slot_token;
+ // int lparen_token = ast->lparen_token;
+ // int dptr_token = ast->dptr_token;
+ // int dptr_lparen_token = ast->dptr_lparen_token;
+ // int dptr_rparen_token = ast->dptr_rparen_token;
+ // int comma_token = ast->comma_token;
FullySpecifiedType type;
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
@@ -2075,12 +2075,12 @@ static void qtPropertyAttribute(TranslationUnit *unit, ExpressionAST *expression
bool Bind::visit(QtPropertyDeclarationAST *ast)
{
- // unsigned property_specifier_token = ast->property_specifier_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int property_specifier_token = ast->property_specifier_token;
+ // int lparen_token = ast->lparen_token;
ExpressionTy type_id = this->expression(ast->type_id);
const Name *property_name = this->name(ast->property_name);
- unsigned sourceLocation = ast->firstToken();
+ int sourceLocation = ast->firstToken();
if (ast->property_name)
sourceLocation = ast->property_name->firstToken();
QtPropertyDeclaration *propertyDeclaration = control()->newQtPropertyDeclaration(sourceLocation, property_name);
@@ -2128,14 +2128,14 @@ bool Bind::visit(QtPropertyDeclarationAST *ast)
}
propertyDeclaration->setFlags(flags);
_scope->addMember(propertyDeclaration);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(QtEnumDeclarationAST *ast)
{
- // unsigned enum_specifier_token = ast->enum_specifier_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int enum_specifier_token = ast->enum_specifier_token;
+ // int lparen_token = ast->lparen_token;
for (NameListAST *it = ast->enumerator_list; it; it = it->next) {
const Name *value = this->name(it->value);
if (!value)
@@ -2144,29 +2144,29 @@ bool Bind::visit(QtEnumDeclarationAST *ast)
_scope->addMember(qtEnum);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(QtFlagsDeclarationAST *ast)
{
- // unsigned flags_specifier_token = ast->flags_specifier_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int flags_specifier_token = ast->flags_specifier_token;
+ // int lparen_token = ast->lparen_token;
for (NameListAST *it = ast->flag_enums_list; it; it = it->next) {
/*const Name *value =*/ this->name(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(QtInterfacesDeclarationAST *ast)
{
- // unsigned interfaces_token = ast->interfaces_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int interfaces_token = ast->interfaces_token;
+ // int lparen_token = ast->lparen_token;
for (QtInterfaceNameListAST *it = ast->interface_name_list; it; it = it->next) {
this->qtInterfaceName(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
@@ -2194,11 +2194,11 @@ bool Bind::visit(AliasDeclarationAST *ast)
bool Bind::visit(AsmDefinitionAST *ast)
{
(void) ast;
- // unsigned asm_token = ast->asm_token;
- // unsigned volatile_token = ast->volatile_token;
- // unsigned lparen_token = ast->lparen_token;
- // unsigned rparen_token = ast->rparen_token;
- // unsigned semicolon_token = ast->semicolon_token;
+ // int asm_token = ast->asm_token;
+ // int volatile_token = ast->volatile_token;
+ // int lparen_token = ast->lparen_token;
+ // int rparen_token = ast->rparen_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
@@ -2208,17 +2208,17 @@ bool Bind::visit(ExceptionDeclarationAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
- const Name *argName = 0;
+ const Name *argName = nullptr;
if (declaratorId && declaratorId->name)
argName = declaratorId->name->name;
Argument *arg = control()->newArgument(location(declaratorId, ast->firstToken()), argName);
arg->setType(type);
_scope->addMember(arg);
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
return false;
}
@@ -2233,7 +2233,7 @@ bool Bind::visit(FunctionDefinitionAST *ast)
for (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next) {
declSpecifiers = this->specifier(it->value, declSpecifiers);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
FullySpecifiedType type = this->declarator(ast->declarator, declSpecifiers.qualifiedType(), &declaratorId);
Function *fun = type->asFunctionType();
@@ -2270,33 +2270,33 @@ bool Bind::visit(FunctionDefinitionAST *ast)
bool Bind::visit(LinkageBodyAST *ast)
{
- // unsigned lbrace_token = ast->lbrace_token;
+ // int lbrace_token = ast->lbrace_token;
for (DeclarationListAST *it = ast->declaration_list; it; it = it->next) {
this->declaration(it->value);
}
- // unsigned rbrace_token = ast->rbrace_token;
+ // int rbrace_token = ast->rbrace_token;
return false;
}
bool Bind::visit(LinkageSpecificationAST *ast)
{
- // unsigned extern_token = ast->extern_token;
- // unsigned extern_type_token = ast->extern_type_token;
+ // int extern_token = ast->extern_token;
+ // int extern_type_token = ast->extern_type_token;
this->declaration(ast->declaration);
return false;
}
bool Bind::visit(NamespaceAST *ast)
{
- // unsigned namespace_token = ast->namespace_token;
- // unsigned identifier_token = ast->identifier_token;
+ // int namespace_token = ast->namespace_token;
+ // int identifier_token = ast->identifier_token;
FullySpecifiedType type;
for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- unsigned sourceLocation = ast->firstToken();
- const Name *namespaceName = 0;
+ int sourceLocation = ast->firstToken();
+ const Name *namespaceName = nullptr;
if (ast->identifier_token) {
sourceLocation = ast->identifier_token;
namespaceName = identifier(ast->identifier_token);
@@ -2317,8 +2317,8 @@ bool Bind::visit(NamespaceAST *ast)
bool Bind::visit(NamespaceAliasDefinitionAST *ast)
{
- unsigned sourceLocation = ast->firstToken();
- const Name *name = 0;
+ int sourceLocation = ast->firstToken();
+ const Name *name = nullptr;
if (ast->namespace_name_token) {
sourceLocation = ast->namespace_name_token;
name = identifier(ast->namespace_name_token);
@@ -2336,12 +2336,12 @@ bool Bind::visit(ParameterDeclarationAST *ast)
for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- DeclaratorIdAST *declaratorId = 0;
+ DeclaratorIdAST *declaratorId = nullptr;
type = this->declarator(ast->declarator, type, &declaratorId);
- // unsigned equal_token = ast->equal_token;
+ // int equal_token = ast->equal_token;
ExpressionTy expression = this->expression(ast->expression);
- const Name *argName = 0;
+ const Name *argName = nullptr;
if (declaratorId && declaratorId->name)
argName = declaratorId->name->name;
@@ -2359,7 +2359,7 @@ bool Bind::visit(ParameterDeclarationAST *ast)
bool Bind::visit(TemplateDeclarationAST *ast)
{
- Template *templ = control()->newTemplate(ast->firstToken(), 0);
+ Template *templ = control()->newTemplate(ast->firstToken(), nullptr);
templ->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin());
templ->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
ast->symbol = templ;
@@ -2368,7 +2368,7 @@ bool Bind::visit(TemplateDeclarationAST *ast)
for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) {
this->declaration(it->value);
}
- // unsigned greater_token = ast->greater_token;
+ // int greater_token = ast->greater_token;
this->declaration(ast->declaration);
(void) switchScope(previousScope);
@@ -2383,9 +2383,9 @@ bool Bind::visit(TemplateDeclarationAST *ast)
bool Bind::visit(TypenameTypeParameterAST *ast)
{
- unsigned sourceLocation = location(ast->name, ast->firstToken());
- // unsigned classkey_token = ast->classkey_token;
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+ int sourceLocation = location(ast->name, ast->firstToken());
+ // int classkey_token = ast->classkey_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
const Name *name = this->name(ast->name);
ExpressionTy type_id = this->expression(ast->type_id);
CPlusPlus::Kind classKey = translationUnit()->tokenKind(ast->classkey_token);
@@ -2400,19 +2400,19 @@ bool Bind::visit(TypenameTypeParameterAST *ast)
bool Bind::visit(TemplateTypeParameterAST *ast)
{
- unsigned sourceLocation = location(ast->name, ast->firstToken());
+ int sourceLocation = location(ast->name, ast->firstToken());
- // unsigned template_token = ast->template_token;
- // unsigned less_token = ast->less_token;
+ // int template_token = ast->template_token;
+ // int less_token = ast->less_token;
// ### process the template prototype
#if 0
for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) {
this->declaration(it->value);
}
#endif
- // unsigned greater_token = ast->greater_token;
- // unsigned class_token = ast->class_token;
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+ // int greater_token = ast->greater_token;
+ // int class_token = ast->class_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
const Name *name = this->name(ast->name);
ExpressionTy type_id = this->expression(ast->type_id);
@@ -2428,7 +2428,7 @@ bool Bind::visit(TemplateTypeParameterAST *ast)
bool Bind::visit(UsingAST *ast)
{
- unsigned sourceLocation = location(ast->name, ast->firstToken());
+ int sourceLocation = location(ast->name, ast->firstToken());
const Name *name = this->name(ast->name);
UsingDeclaration *symbol = control()->newUsingDeclaration(sourceLocation, name);
@@ -2439,7 +2439,7 @@ bool Bind::visit(UsingAST *ast)
bool Bind::visit(UsingDirectiveAST *ast)
{
- unsigned sourceLocation = location(ast->name, ast->firstToken());
+ int sourceLocation = location(ast->name, ast->firstToken());
const Name *name = this->name(ast->name);
UsingNamespaceDirective *symbol = control()->newUsingNamespaceDirective(sourceLocation, name);
ast->symbol = symbol;
@@ -2456,11 +2456,11 @@ bool Bind::visit(ObjCClassForwardDeclarationAST *ast)
List<ObjCForwardClassDeclaration *> **symbolTail = &ast->symbols;
- // unsigned class_token = ast->class_token;
+ // int class_token = ast->class_token;
for (NameListAST *it = ast->identifier_list; it; it = it->next) {
const Name *name = this->name(it->value);
- const unsigned sourceLocation = location(it->value, ast->firstToken());
+ const int sourceLocation = location(it->value, ast->firstToken());
ObjCForwardClassDeclaration *fwd = control()->newObjCForwardClassDeclaration(sourceLocation, name);
setDeclSpecifiers(fwd, declSpecifiers);
_scope->addMember(fwd);
@@ -2472,18 +2472,18 @@ bool Bind::visit(ObjCClassForwardDeclarationAST *ast)
return false;
}
-unsigned Bind::calculateScopeStart(ObjCClassDeclarationAST *ast) const
+int Bind::calculateScopeStart(ObjCClassDeclarationAST *ast) const
{
if (ast->inst_vars_decl)
- if (unsigned pos = ast->inst_vars_decl->lbrace_token)
+ if (int pos = ast->inst_vars_decl->lbrace_token)
return tokenAt(pos).utf16charsEnd();
if (ast->protocol_refs)
- if (unsigned pos = ast->protocol_refs->lastToken())
+ if (int pos = ast->protocol_refs->lastToken())
return tokenAt(pos - 1).utf16charsEnd();
if (ast->superclass)
- if (unsigned pos = ast->superclass->lastToken())
+ if (int pos = ast->superclass->lastToken())
return tokenAt(pos - 1).utf16charsEnd();
if (ast->colon_token)
@@ -2493,14 +2493,14 @@ unsigned Bind::calculateScopeStart(ObjCClassDeclarationAST *ast) const
return tokenAt(ast->rparen_token).utf16charsEnd();
if (ast->category_name)
- if (unsigned pos = ast->category_name->lastToken())
+ if (int pos = ast->category_name->lastToken())
return tokenAt(pos - 1).utf16charsEnd();
if (ast->lparen_token)
return tokenAt(ast->lparen_token).utf16charsEnd();
if (ast->class_name)
- if (unsigned pos = ast->class_name->lastToken())
+ if (int pos = ast->class_name->lastToken())
return tokenAt(pos - 1).utf16charsEnd();
return tokenAt(ast->firstToken()).utf16charsBegin();
@@ -2515,7 +2515,7 @@ bool Bind::visit(ObjCClassDeclarationAST *ast)
const Name *class_name = this->name(ast->class_name);
const Name *category_name = this->name(ast->category_name);
- const unsigned sourceLocation = location(ast->class_name, ast->firstToken());
+ const int sourceLocation = location(ast->class_name, ast->firstToken());
ObjCClass *klass = control()->newObjCClass(sourceLocation, class_name);
ast->symbol = klass;
_scope->addMember(klass);
@@ -2560,11 +2560,11 @@ bool Bind::visit(ObjCProtocolForwardDeclarationAST *ast)
List<ObjCForwardProtocolDeclaration *> **symbolTail = &ast->symbols;
- // unsigned class_token = ast->class_token;
+ // int class_token = ast->class_token;
for (NameListAST *it = ast->identifier_list; it; it = it->next) {
const Name *name = this->name(it->value);
- const unsigned sourceLocation = location(it->value, ast->firstToken());
+ const int sourceLocation = location(it->value, ast->firstToken());
ObjCForwardProtocolDeclaration *fwd = control()->newObjCForwardProtocolDeclaration(sourceLocation, name);
setDeclSpecifiers(fwd, declSpecifiers);
_scope->addMember(fwd);
@@ -2576,13 +2576,13 @@ bool Bind::visit(ObjCProtocolForwardDeclarationAST *ast)
return false;
}
-unsigned Bind::calculateScopeStart(ObjCProtocolDeclarationAST *ast) const
+int Bind::calculateScopeStart(ObjCProtocolDeclarationAST *ast) const
{
if (ast->protocol_refs)
- if (unsigned pos = ast->protocol_refs->lastToken())
+ if (int pos = ast->protocol_refs->lastToken())
return tokenAt(pos - 1).utf16charsEnd();
if (ast->name)
- if (unsigned pos = ast->name->lastToken())
+ if (int pos = ast->name->lastToken())
return tokenAt(pos - 1).utf16charsEnd();
return tokenAt(ast->firstToken()).utf16charsBegin();
@@ -2594,10 +2594,10 @@ bool Bind::visit(ObjCProtocolDeclarationAST *ast)
for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- // unsigned protocol_token = ast->protocol_token;
+ // int protocol_token = ast->protocol_token;
const Name *name = this->name(ast->name);
- const unsigned sourceLocation = location(ast->name, ast->firstToken());
+ const int sourceLocation = location(ast->name, ast->firstToken());
ObjCProtocol *protocol = control()->newObjCProtocol(sourceLocation, name);
protocol->setStartOffset(calculateScopeStart(ast));
protocol->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
@@ -2630,12 +2630,12 @@ bool Bind::visit(ObjCPropertyDeclarationAST *ast)
for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
type = this->specifier(it->value, type);
}
- // unsigned property_token = ast->property_token;
- // unsigned lparen_token = ast->lparen_token;
+ // int property_token = ast->property_token;
+ // int lparen_token = ast->lparen_token;
for (ObjCPropertyAttributeListAST *it = ast->property_attribute_list; it; it = it->next) {
this->objCPropertyAttribute(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
this->declaration(ast->simple_declaration);
// List<ObjCPropertyDeclaration *> *symbols = ast->symbols;
return false;
@@ -2647,7 +2647,7 @@ bool Bind::visit(ObjCMethodDeclarationAST *ast)
if (! ast->function_body) {
const Name *name = method->name();
- unsigned sourceLocation = ast->firstToken();
+ int sourceLocation = ast->firstToken();
Declaration *decl = control()->newDeclaration(sourceLocation, name);
decl->setType(method);
_scope->addMember(decl);
@@ -2665,21 +2665,21 @@ bool Bind::visit(ObjCMethodDeclarationAST *ast)
bool Bind::visit(ObjCSynthesizedPropertiesDeclarationAST *ast)
{
- // unsigned synthesized_token = ast->synthesized_token;
+ // int synthesized_token = ast->synthesized_token;
for (ObjCSynthesizedPropertyListAST *it = ast->property_identifier_list; it; it = it->next) {
this->objCSynthesizedProperty(it->value);
}
- // unsigned semicolon_token = ast->semicolon_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
bool Bind::visit(ObjCDynamicPropertiesDeclarationAST *ast)
{
- // unsigned dynamic_token = ast->dynamic_token;
+ // int dynamic_token = ast->dynamic_token;
for (NameListAST *it = ast->property_identifier_list; it; it = it->next) {
/*const Name *value =*/ this->name(it->value);
}
- // unsigned semicolon_token = ast->semicolon_token;
+ // int semicolon_token = ast->semicolon_token;
return false;
}
@@ -2696,7 +2696,7 @@ bool Bind::visit(ObjCSelectorAST *ast) // ### review
}
if (! arguments.empty()) {
- _name = control()->selectorNameId(&arguments[0], unsigned(arguments.size()), hasArgs);
+ _name = control()->selectorNameId(&arguments[0], int(arguments.size()), hasArgs);
ast->name = _name;
}
@@ -2781,7 +2781,7 @@ bool Bind::visit(TemplateIdAST *ast)
_name = control()->templateNameId(id, isSpecialization);
else
_name = control()->templateNameId(id, isSpecialization, &templateArguments[0],
- unsigned(templateArguments.size()));
+ int(templateArguments.size()));
ast->name = _name;
return false;
@@ -3003,14 +3003,14 @@ bool Bind::visit(AlignmentSpecifierAST *ast)
bool Bind::visit(GnuAttributeSpecifierAST *ast)
{
- // unsigned attribute_token = ast->attribute_token;
- // unsigned first_lparen_token = ast->first_lparen_token;
- // unsigned second_lparen_token = ast->second_lparen_token;
+ // int attribute_token = ast->attribute_token;
+ // int first_lparen_token = ast->first_lparen_token;
+ // int second_lparen_token = ast->second_lparen_token;
for (GnuAttributeListAST *it = ast->attribute_list; it; it = it->next) {
this->attribute(it->value);
}
- // unsigned first_rparen_token = ast->first_rparen_token;
- // unsigned second_rparen_token = ast->second_rparen_token;
+ // int first_rparen_token = ast->first_rparen_token;
+ // int second_rparen_token = ast->second_rparen_token;
return false;
}
@@ -3029,9 +3029,9 @@ bool Bind::visit(DecltypeSpecifierAST *ast)
bool Bind::visit(ClassSpecifierAST *ast)
{
- // unsigned classkey_token = ast->classkey_token;
- unsigned sourceLocation = ast->firstToken();
- unsigned startScopeOffset = tokenAt(sourceLocation).utf16charsEnd(); // at the end of the class key
+ // int classkey_token = ast->classkey_token;
+ int sourceLocation = ast->firstToken();
+ int startScopeOffset = tokenAt(sourceLocation).utf16charsEnd(); // at the end of the class key
for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
_type = this->specifier(it->value, _type);
@@ -3062,7 +3062,7 @@ bool Bind::visit(ClassSpecifierAST *ast)
klass->setVisibility(_visibility);
// set the class key
- unsigned classKey = tokenKind(ast->classkey_token);
+ int classKey = tokenKind(ast->classkey_token);
if (classKey == T_CLASS)
klass->setClassKey(Class::ClassKey);
else if (classKey == T_STRUCT)
@@ -3079,7 +3079,7 @@ bool Bind::visit(ClassSpecifierAST *ast)
for (BaseSpecifierListAST *it = ast->base_clause_list; it; it = it->next) {
this->baseSpecifier(it->value, ast->colon_token, klass);
}
- // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+ // int dot_dot_dot_token = ast->dot_dot_dot_token;
for (DeclarationListAST *it = ast->member_specifier_list; it; it = it->next) {
this->declaration(it->value);
}
@@ -3100,7 +3100,7 @@ bool Bind::visit(NamedTypeSpecifierAST *ast)
bool Bind::visit(ElaboratedTypeSpecifierAST *ast)
{
- // unsigned classkey_token = ast->classkey_token;
+ // int classkey_token = ast->classkey_token;
for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
_type = this->specifier(it->value, _type);
}
@@ -3110,7 +3110,7 @@ bool Bind::visit(ElaboratedTypeSpecifierAST *ast)
bool Bind::visit(EnumSpecifierAST *ast)
{
- unsigned sourceLocation = location(ast->name, ast->firstToken());
+ int sourceLocation = location(ast->name, ast->firstToken());
const Name *enumName = this->name(ast->name);
Enum *e = control()->newEnum(sourceLocation, enumName);
@@ -3136,7 +3136,7 @@ bool Bind::visit(EnumSpecifierAST *ast)
// PtrOperatorAST
bool Bind::visit(PointerToMemberAST *ast)
{
- const Name *memberName = 0;
+ const Name *memberName = nullptr;
for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
const Name *class_or_namespace_name = this->nestedNameSpecifier(it->value);
@@ -3184,35 +3184,35 @@ bool Bind::visit(ReferenceAST *ast)
bool Bind::visit(CallAST *ast)
{
/*ExpressionTy base_expression =*/ this->expression(ast->base_expression);
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
/*ExpressionTy value =*/ this->expression(it->value);
}
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
return false;
}
bool Bind::visit(ArrayAccessAST *ast)
{
/*ExpressionTy base_expression =*/ this->expression(ast->base_expression);
- // unsigned lbracket_token = ast->lbracket_token;
+ // int lbracket_token = ast->lbracket_token;
/*ExpressionTy expression =*/ this->expression(ast->expression);
- // unsigned rbracket_token = ast->rbracket_token;
+ // int rbracket_token = ast->rbracket_token;
return false;
}
bool Bind::visit(PostIncrDecrAST *ast)
{
ExpressionTy base_expression = this->expression(ast->base_expression);
- // unsigned incr_decr_token = ast->incr_decr_token;
+ // int incr_decr_token = ast->incr_decr_token;
return false;
}
bool Bind::visit(MemberAccessAST *ast)
{
ExpressionTy base_expression = this->expression(ast->base_expression);
- // unsigned access_token = ast->access_token;
- // unsigned template_token = ast->template_token;
+ // int access_token = ast->access_token;
+ // int template_token = ast->template_token;
/*const Name *member_name =*/ this->name(ast->member_name);
return false;
}
@@ -3236,16 +3236,16 @@ bool Bind::visit(NestedDeclaratorAST *ast)
// PostfixDeclaratorAST
bool Bind::visit(FunctionDeclaratorAST *ast)
{
- Function *fun = control()->newFunction(0, 0);
+ Function *fun = control()->newFunction(0, nullptr);
fun->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin());
fun->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
if (ast->trailing_return_type)
_type = this->trailingReturnType(ast->trailing_return_type, _type);
fun->setReturnType(_type);
- // unsigned lparen_token = ast->lparen_token;
+ // int lparen_token = ast->lparen_token;
this->parameterDeclarationClause(ast->parameter_declaration_clause, ast->lparen_token, fun);
- // unsigned rparen_token = ast->rparen_token;
+ // int rparen_token = ast->rparen_token;
FullySpecifiedType type(fun);
for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
type = this->specifier(it->value, type);
@@ -3266,7 +3266,7 @@ bool Bind::visit(FunctionDeclaratorAST *ast)
}
this->exceptionSpecification(ast->exception_specification, type);
- if (ast->as_cpp_initializer != 0) {
+ if (ast->as_cpp_initializer != nullptr) {
fun->setAmbiguous(true);
/*ExpressionTy as_cpp_initializer =*/ this->expression(ast->as_cpp_initializer);
}
@@ -3283,7 +3283,7 @@ bool Bind::visit(ArrayDeclaratorAST *ast)
return false;
}
-void Bind::ensureValidClassName(const Name **name, unsigned sourceLocation)
+void Bind::ensureValidClassName(const Name **name, int sourceLocation)
{
if (!*name)
return;
diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h
index 741043fdea..0898722964 100644
--- a/src/libs/3rdparty/cplusplus/Bind.h
+++ b/src/libs/3rdparty/cplusplus/Bind.h
@@ -43,9 +43,9 @@ public:
protected:
using ASTVisitor::translationUnit;
- unsigned location(DeclaratorAST *ast, unsigned defaultLocation) const;
- unsigned location(CoreDeclaratorAST *ast, unsigned defaultLocation) const;
- unsigned location(NameAST *name, unsigned defaultLocation) const;
+ int location(DeclaratorAST *ast, int defaultLocation) const;
+ int location(CoreDeclaratorAST *ast, int defaultLocation) const;
+ int location(NameAST *name, int defaultLocation) const;
static int visibilityForAccessSpecifier(int tokenKind);
static int visibilityForClassKey(int tokenKind);
@@ -72,14 +72,14 @@ protected:
int switchMethodKey(int methodKey);
int switchObjCVisibility(int visibility);
- unsigned calculateScopeStart(ObjCClassDeclarationAST *ast) const;
- unsigned calculateScopeStart(ObjCProtocolDeclarationAST *ast) const;
+ int calculateScopeStart(ObjCClassDeclarationAST *ast) const;
+ int calculateScopeStart(ObjCProtocolDeclarationAST *ast) const;
const Name *objCSelectorArgument(ObjCSelectorArgumentAST *ast, bool *hasArg);
void attribute(GnuAttributeAST *ast);
FullySpecifiedType declarator(DeclaratorAST *ast, const FullySpecifiedType &init, DeclaratorIdAST **declaratorId);
void qtInterfaceName(QtInterfaceNameAST *ast);
- void baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *klass);
+ void baseSpecifier(BaseSpecifierAST *ast, int colon_token, Class *klass);
void ctorInitializer(CtorInitializerAST *ast, Function *fun);
void enumerator(EnumeratorAST *ast, Enum *symbol);
FullySpecifiedType exceptionSpecification(ExceptionSpecificationAST *ast, const FullySpecifiedType &init);
@@ -89,7 +89,7 @@ protected:
FullySpecifiedType newArrayDeclarator(NewArrayDeclaratorAST *ast, const FullySpecifiedType &init);
FullySpecifiedType newTypeId(NewTypeIdAST *ast);
OperatorNameId::Kind cppOperator(OperatorAST *ast);
- void parameterDeclarationClause(ParameterDeclarationClauseAST *ast, unsigned lparen_token, Function *fun);
+ void parameterDeclarationClause(ParameterDeclarationClauseAST *ast, int lparen_token, Function *fun);
void translationUnit(TranslationUnitAST *ast);
void objCProtocolRefs(ObjCProtocolRefsAST *ast, Symbol *objcClassOrProtocol);
void objCMessageArgument(ObjCMessageArgumentAST *ast);
@@ -282,7 +282,7 @@ protected:
private:
static const int kMaxDepth;
- void ensureValidClassName(const Name **name, unsigned sourceLocation);
+ void ensureValidClassName(const Name **name, int sourceLocation);
Scope *_scope;
ExpressionTy _expression;
diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp
index a5601bf620..2bbe00c293 100644
--- a/src/libs/3rdparty/cplusplus/Control.cpp
+++ b/src/libs/3rdparty/cplusplus/Control.cpp
@@ -209,21 +209,21 @@ class Control::Data
public:
Data(Control *control)
: control(control)
- , translationUnit(0)
- , diagnosticClient(0)
- , deprecatedId(0)
- , unavailableId(0)
- , objcGetterId(0)
- , objcSetterId(0)
- , objcReadwriteId(0)
- , objcReadonlyId(0)
- , objcAssignId(0)
- , objcRetainId(0)
- , objcCopyId(0)
- , objcNonatomicId(0)
- , cpp11Override(0)
- , cpp11Final(0)
- , processor(0)
+ , translationUnit(nullptr)
+ , diagnosticClient(nullptr)
+ , deprecatedId(nullptr)
+ , unavailableId(nullptr)
+ , objcGetterId(nullptr)
+ , objcSetterId(nullptr)
+ , objcReadwriteId(nullptr)
+ , objcReadonlyId(nullptr)
+ , objcAssignId(nullptr)
+ , objcRetainId(nullptr)
+ , objcCopyId(nullptr)
+ , objcNonatomicId(nullptr)
+ , cpp11Override(nullptr)
+ , cpp11Final(nullptr)
+ , processor(nullptr)
{}
~Data()
@@ -574,20 +574,20 @@ const OperatorNameId *Control::findOperatorNameId(OperatorNameId::Kind operatorI
{
Table<OperatorNameId>::const_iterator i = d->operatorNameIds.find(operatorId);
if (i == d->operatorNameIds.end())
- return 0;
+ return nullptr;
else
return &*i;
}
-const Identifier *Control::findIdentifier(const char *chars, unsigned size) const
+const Identifier *Control::findIdentifier(const char *chars, int size) const
{ return d->identifiers.findLiteral(chars, size); }
-const Identifier *Control::identifier(const char *chars, unsigned size)
+const Identifier *Control::identifier(const char *chars, int size)
{ return d->identifiers.findOrInsertLiteral(chars, size); }
const Identifier *Control::identifier(const char *chars)
{
- const unsigned length = unsigned(std::strlen(chars));
+ const int length = int(std::strlen(chars));
return identifier(chars, length);
}
@@ -609,28 +609,28 @@ Control::NumericLiteralIterator Control::firstNumericLiteral() const
Control::NumericLiteralIterator Control::lastNumericLiteral() const
{ return d->numericLiterals.end(); }
-const StringLiteral *Control::stringLiteral(const char *chars, unsigned size)
+const StringLiteral *Control::stringLiteral(const char *chars, int size)
{ return d->stringLiterals.findOrInsertLiteral(chars, size); }
const StringLiteral *Control::stringLiteral(const char *chars)
{
- const unsigned length = unsigned(std::strlen(chars));
+ const int length = int(std::strlen(chars));
return stringLiteral(chars, length);
}
-const NumericLiteral *Control::numericLiteral(const char *chars, unsigned size)
+const NumericLiteral *Control::numericLiteral(const char *chars, int size)
{ return d->numericLiterals.findOrInsertLiteral(chars, size); }
const NumericLiteral *Control::numericLiteral(const char *chars)
{
- const unsigned length = unsigned(std::strlen(chars));
+ const int length = int(std::strlen(chars));
return numericLiteral(chars, length);
}
const TemplateNameId *Control::templateNameId(const Identifier *id,
bool isSpecialization,
const FullySpecifiedType *const args,
- unsigned argv)
+ int argv)
{
return d->findOrInsertTemplateNameId(id, isSpecialization, args, args + argv);
}
@@ -650,7 +650,7 @@ const QualifiedNameId *Control::qualifiedNameId(const Name *base, const Name *na
}
const SelectorNameId *Control::selectorNameId(const Name *const *names,
- unsigned nameCount,
+ int nameCount,
bool hasArguments)
{
return d->findOrInsertSelectorNameId(names, names + nameCount, hasArguments);
@@ -675,88 +675,88 @@ PointerType *Control::pointerType(const FullySpecifiedType &elementType)
ReferenceType *Control::referenceType(const FullySpecifiedType &elementType, bool rvalueRef)
{ return d->findOrInsertReferenceType(elementType, rvalueRef); }
-ArrayType *Control::arrayType(const FullySpecifiedType &elementType, unsigned size)
+ArrayType *Control::arrayType(const FullySpecifiedType &elementType, int size)
{ return d->findOrInsertArrayType(elementType, size); }
NamedType *Control::namedType(const Name *name)
{ return d->findOrInsertNamedType(name); }
-Argument *Control::newArgument(unsigned sourceLocation, const Name *name)
+Argument *Control::newArgument(int sourceLocation, const Name *name)
{ return d->newArgument(sourceLocation, name); }
-TypenameArgument *Control::newTypenameArgument(unsigned sourceLocation, const Name *name)
+TypenameArgument *Control::newTypenameArgument(int sourceLocation, const Name *name)
{ return d->newTypenameArgument(sourceLocation, name); }
-Function *Control::newFunction(unsigned sourceLocation, const Name *name)
+Function *Control::newFunction(int sourceLocation, const Name *name)
{ return d->newFunction(sourceLocation, name); }
-Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name)
+Namespace *Control::newNamespace(int sourceLocation, const Name *name)
{ return d->newNamespace(sourceLocation, name); }
-Template *Control::newTemplate(unsigned sourceLocation, const Name *name)
+Template *Control::newTemplate(int sourceLocation, const Name *name)
{ return d->newTemplate(sourceLocation, name); }
-NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name)
+NamespaceAlias *Control::newNamespaceAlias(int sourceLocation, const Name *name)
{ return d->newNamespaceAlias(sourceLocation, name); }
-BaseClass *Control::newBaseClass(unsigned sourceLocation, const Name *name)
+BaseClass *Control::newBaseClass(int sourceLocation, const Name *name)
{ return d->newBaseClass(sourceLocation, name); }
-Class *Control::newClass(unsigned sourceLocation, const Name *name)
+Class *Control::newClass(int sourceLocation, const Name *name)
{ return d->newClass(sourceLocation, name); }
-Enum *Control::newEnum(unsigned sourceLocation, const Name *name)
+Enum *Control::newEnum(int sourceLocation, const Name *name)
{ return d->newEnum(sourceLocation, name); }
-Block *Control::newBlock(unsigned sourceLocation)
+Block *Control::newBlock(int sourceLocation)
{ return d->newBlock(sourceLocation); }
-Declaration *Control::newDeclaration(unsigned sourceLocation, const Name *name)
+Declaration *Control::newDeclaration(int sourceLocation, const Name *name)
{ return d->newDeclaration(sourceLocation, name); }
-EnumeratorDeclaration *Control::newEnumeratorDeclaration(unsigned sourceLocation, const Name *name)
+EnumeratorDeclaration *Control::newEnumeratorDeclaration(int sourceLocation, const Name *name)
{ return d->newEnumeratorDeclaration(sourceLocation, name); }
-UsingNamespaceDirective *Control::newUsingNamespaceDirective(unsigned sourceLocation,
+UsingNamespaceDirective *Control::newUsingNamespaceDirective(int sourceLocation,
const Name *name)
{ return d->newUsingNamespaceDirective(sourceLocation, name); }
-UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, const Name *name)
+UsingDeclaration *Control::newUsingDeclaration(int sourceLocation, const Name *name)
{ return d->newUsingDeclaration(sourceLocation, name); }
-ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLocation,
+ForwardClassDeclaration *Control::newForwardClassDeclaration(int sourceLocation,
const Name *name)
{ return d->newForwardClassDeclaration(sourceLocation, name); }
-QtPropertyDeclaration *Control::newQtPropertyDeclaration(unsigned sourceLocation,
+QtPropertyDeclaration *Control::newQtPropertyDeclaration(int sourceLocation,
const Name *name)
{ return d->newQtPropertyDeclaration(sourceLocation, name); }
-QtEnum *Control::newQtEnum(unsigned sourceLocation, const Name *name)
+QtEnum *Control::newQtEnum(int sourceLocation, const Name *name)
{ return d->newQtEnum(sourceLocation, name); }
-ObjCBaseClass *Control::newObjCBaseClass(unsigned sourceLocation, const Name *name)
+ObjCBaseClass *Control::newObjCBaseClass(int sourceLocation, const Name *name)
{ return d->newObjCBaseClass(sourceLocation, name); }
-ObjCBaseProtocol *Control::newObjCBaseProtocol(unsigned sourceLocation, const Name *name)
+ObjCBaseProtocol *Control::newObjCBaseProtocol(int sourceLocation, const Name *name)
{ return d->newObjCBaseProtocol(sourceLocation, name); }
-ObjCClass *Control::newObjCClass(unsigned sourceLocation, const Name *name)
+ObjCClass *Control::newObjCClass(int sourceLocation, const Name *name)
{ return d->newObjCClass(sourceLocation, name); }
-ObjCForwardClassDeclaration *Control::newObjCForwardClassDeclaration(unsigned sourceLocation, const Name *name)
+ObjCForwardClassDeclaration *Control::newObjCForwardClassDeclaration(int sourceLocation, const Name *name)
{ return d->newObjCForwardClassDeclaration(sourceLocation, name); }
-ObjCProtocol *Control::newObjCProtocol(unsigned sourceLocation, const Name *name)
+ObjCProtocol *Control::newObjCProtocol(int sourceLocation, const Name *name)
{ return d->newObjCProtocol(sourceLocation, name); }
-ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsigned sourceLocation, const Name *name)
+ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(int sourceLocation, const Name *name)
{ return d->newObjCForwardProtocolDeclaration(sourceLocation, name); }
-ObjCMethod *Control::newObjCMethod(unsigned sourceLocation, const Name *name)
+ObjCMethod *Control::newObjCMethod(int sourceLocation, const Name *name)
{ return d->newObjCMethod(sourceLocation, name); }
-ObjCPropertyDeclaration *Control::newObjCPropertyDeclaration(unsigned sourceLocation, const Name *name)
+ObjCPropertyDeclaration *Control::newObjCPropertyDeclaration(int sourceLocation, const Name *name)
{ return d->newObjCPropertyDeclaration(sourceLocation, name); }
const Identifier *Control::deprecatedId() const
@@ -798,7 +798,7 @@ const Identifier *Control::cpp11Final() const
Symbol **Control::firstSymbol() const
{
if (d->symbols.empty())
- return 0;
+ return nullptr;
return &*d->symbols.begin();
}
@@ -806,12 +806,12 @@ Symbol **Control::firstSymbol() const
Symbol **Control::lastSymbol() const
{
if (d->symbols.empty())
- return 0;
+ return nullptr;
return &*d->symbols.begin() + d->symbols.size();
}
-unsigned Control::symbolCount() const
+int Control::symbolCount() const
{
return unsigned(d->symbols.size());
}
diff --git a/src/libs/3rdparty/cplusplus/Control.h b/src/libs/3rdparty/cplusplus/Control.h
index 97c1503833..348864a402 100644
--- a/src/libs/3rdparty/cplusplus/Control.h
+++ b/src/libs/3rdparty/cplusplus/Control.h
@@ -54,8 +54,8 @@ public:
/// Returns the canonical template name id.
const TemplateNameId *templateNameId(const Identifier *id,
bool isSpecialization,
- const FullySpecifiedType *const args = 0,
- unsigned argc = 0);
+ const FullySpecifiedType *const args = nullptr,
+ int argc = 0);
/// Returns the canonical destructor name id.
const DestructorNameId *destructorNameId(const Name *name);
@@ -70,7 +70,7 @@ public:
const QualifiedNameId *qualifiedNameId(const Name *base, const Name *name);
const SelectorNameId *selectorNameId(const Name *const *names,
- unsigned nameCount,
+ int nameCount,
bool hasArguments);
/// Returns a Type object of type VoidType.
@@ -93,82 +93,82 @@ public:
ReferenceType *referenceType(const FullySpecifiedType &elementType, bool rvalueRef);
/// Retruns a Type object of type ArrayType.
- ArrayType *arrayType(const FullySpecifiedType &elementType, unsigned size = 0);
+ ArrayType *arrayType(const FullySpecifiedType &elementType, int size = 0);
/// Returns a Type object of type NamedType.
NamedType *namedType(const Name *name);
/// Creates a new Declaration symbol.
- Declaration *newDeclaration(unsigned sourceLocation, const Name *name);
+ Declaration *newDeclaration(int sourceLocation, const Name *name);
/// Creates a new EnumeratorDeclaration symbol.
- EnumeratorDeclaration *newEnumeratorDeclaration(unsigned sourceLocation, const Name *name);
+ EnumeratorDeclaration *newEnumeratorDeclaration(int sourceLocation, const Name *name);
/// Creates a new Argument symbol.
- Argument *newArgument(unsigned sourceLocation, const Name *name = 0);
+ Argument *newArgument(int sourceLocation, const Name *name = nullptr);
/// Creates a new Argument symbol.
- TypenameArgument *newTypenameArgument(unsigned sourceLocation, const Name *name = 0);
+ TypenameArgument *newTypenameArgument(int sourceLocation, const Name *name = nullptr);
/// Creates a new Function symbol.
- Function *newFunction(unsigned sourceLocation, const Name *name = 0);
+ Function *newFunction(int sourceLocation, const Name *name = nullptr);
/// Creates a new Namespace symbol.
- Namespace *newNamespace(unsigned sourceLocation, const Name *name = 0);
+ Namespace *newNamespace(int sourceLocation, const Name *name = nullptr);
/// Creates a new Template symbol.
- Template *newTemplate(unsigned sourceLocation, const Name *name = 0);
+ Template *newTemplate(int sourceLocation, const Name *name = nullptr);
/// Creates a new Namespace symbol.
- NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0);
+ NamespaceAlias *newNamespaceAlias(int sourceLocation, const Name *name = nullptr);
/// Creates a new BaseClass symbol.
- BaseClass *newBaseClass(unsigned sourceLocation, const Name *name = 0);
+ BaseClass *newBaseClass(int sourceLocation, const Name *name = nullptr);
/// Creates a new Class symbol.
- Class *newClass(unsigned sourceLocation, const Name *name = 0);
+ Class *newClass(int sourceLocation, const Name *name = nullptr);
/// Creates a new Enum symbol.
- Enum *newEnum(unsigned sourceLocation, const Name *name = 0);
+ Enum *newEnum(int sourceLocation, const Name *name = nullptr);
/// Creates a new Block symbol.
- Block *newBlock(unsigned sourceLocation);
+ Block *newBlock(int sourceLocation);
/// Creates a new UsingNamespaceDirective symbol.
- UsingNamespaceDirective *newUsingNamespaceDirective(unsigned sourceLocation, const Name *name = 0);
+ UsingNamespaceDirective *newUsingNamespaceDirective(int sourceLocation, const Name *name = nullptr);
/// Creates a new UsingDeclaration symbol.
- UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, const Name *name = 0);
+ UsingDeclaration *newUsingDeclaration(int sourceLocation, const Name *name = nullptr);
/// Creates a new ForwardClassDeclaration symbol.
- ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, const Name *name = 0);
+ ForwardClassDeclaration *newForwardClassDeclaration(int sourceLocation, const Name *name = nullptr);
/// Creates a new QtPropertyDeclaration symbol.
- QtPropertyDeclaration *newQtPropertyDeclaration(unsigned sourceLocation, const Name *name = 0);
+ QtPropertyDeclaration *newQtPropertyDeclaration(int sourceLocation, const Name *name = nullptr);
/// Creates a new QtEnum symbol.
- QtEnum *newQtEnum(unsigned sourceLocation, const Name *name = 0);
+ QtEnum *newQtEnum(int sourceLocation, const Name *name = nullptr);
- ObjCBaseClass *newObjCBaseClass(unsigned sourceLocation, const Name *name);
- ObjCBaseProtocol *newObjCBaseProtocol(unsigned sourceLocation, const Name *name);
+ ObjCBaseClass *newObjCBaseClass(int sourceLocation, const Name *name);
+ ObjCBaseProtocol *newObjCBaseProtocol(int sourceLocation, const Name *name);
/// Creates a new Objective-C class symbol.
- ObjCClass *newObjCClass(unsigned sourceLocation, const Name *name = 0);
+ ObjCClass *newObjCClass(int sourceLocation, const Name *name = nullptr);
/// Creates a new Objective-C class forward declaration symbol.
- ObjCForwardClassDeclaration *newObjCForwardClassDeclaration(unsigned sourceLocation, const Name *name = 0);
+ ObjCForwardClassDeclaration *newObjCForwardClassDeclaration(int sourceLocation, const Name *name = nullptr);
/// Creates a new Objective-C protocol symbol.
- ObjCProtocol *newObjCProtocol(unsigned sourceLocation, const Name *name = 0);
+ ObjCProtocol *newObjCProtocol(int sourceLocation, const Name *name = nullptr);
/// Creates a new Objective-C protocol forward declaration symbol.
- ObjCForwardProtocolDeclaration *newObjCForwardProtocolDeclaration(unsigned sourceLocation, const Name *name = 0);
+ ObjCForwardProtocolDeclaration *newObjCForwardProtocolDeclaration(int sourceLocation, const Name *name = nullptr);
/// Creates a new Objective-C method symbol.
- ObjCMethod *newObjCMethod(unsigned sourceLocation, const Name *name = 0);
+ ObjCMethod *newObjCMethod(int sourceLocation, const Name *name = nullptr);
/// Creates a new Objective-C @property declaration symbol.
- ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, const Name *name);
+ ObjCPropertyDeclaration *newObjCPropertyDeclaration(int sourceLocation, const Name *name);
const Identifier *deprecatedId() const;
const Identifier *unavailableId() const;
@@ -187,8 +187,8 @@ public:
const OperatorNameId *findOperatorNameId(OperatorNameId::Kind operatorId) const;
- const Identifier *findIdentifier(const char *chars, unsigned size) const;
- const Identifier *identifier(const char *chars, unsigned size);
+ const Identifier *findIdentifier(const char *chars, int size) const;
+ const Identifier *identifier(const char *chars, int size);
const Identifier *identifier(const char *chars);
typedef const Identifier *const *IdentifierIterator;
@@ -204,15 +204,15 @@ public:
NumericLiteralIterator firstNumericLiteral() const;
NumericLiteralIterator lastNumericLiteral() const;
- const StringLiteral *stringLiteral(const char *chars, unsigned size);
+ const StringLiteral *stringLiteral(const char *chars, int size);
const StringLiteral *stringLiteral(const char *chars);
- const NumericLiteral *numericLiteral(const char *chars, unsigned size);
+ const NumericLiteral *numericLiteral(const char *chars, int size);
const NumericLiteral *numericLiteral(const char *chars);
Symbol **firstSymbol() const;
Symbol **lastSymbol() const;
- unsigned symbolCount() const;
+ int symbolCount() const;
bool hasSymbol(Symbol *symbol) const;
void addSymbol(Symbol *symbol);
diff --git a/src/libs/3rdparty/cplusplus/DiagnosticClient.h b/src/libs/3rdparty/cplusplus/DiagnosticClient.h
index 108133b97e..b009074ebd 100644
--- a/src/libs/3rdparty/cplusplus/DiagnosticClient.h
+++ b/src/libs/3rdparty/cplusplus/DiagnosticClient.h
@@ -42,7 +42,7 @@ public:
virtual void report(int level,
const StringLiteral *fileName,
- unsigned line, unsigned column,
+ int line, int column,
const char *format, va_list ap) = 0;
};
diff --git a/src/libs/3rdparty/cplusplus/FullySpecifiedType.h b/src/libs/3rdparty/cplusplus/FullySpecifiedType.h
index 5a7e33a2db..aa983ada10 100644
--- a/src/libs/3rdparty/cplusplus/FullySpecifiedType.h
+++ b/src/libs/3rdparty/cplusplus/FullySpecifiedType.h
@@ -28,7 +28,7 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT FullySpecifiedType
{
public:
- FullySpecifiedType(Type *type = 0);
+ FullySpecifiedType(Type *type = nullptr);
~FullySpecifiedType();
bool isValid() const;
@@ -103,7 +103,7 @@ public:
bool operator != (const FullySpecifiedType &other) const;
bool operator < (const FullySpecifiedType &other) const;
- bool match(const FullySpecifiedType &otherTy, Matcher *matcher = 0) const;
+ bool match(const FullySpecifiedType &otherTy, Matcher *matcher = nullptr) const;
FullySpecifiedType simplified() const;
diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp
index 079ae0ca6e..dc24f5e96c 100644
--- a/src/libs/3rdparty/cplusplus/Lexer.cpp
+++ b/src/libs/3rdparty/cplusplus/Lexer.cpp
@@ -64,8 +64,8 @@ Lexer::Lexer(TranslationUnit *unit)
}
Lexer::Lexer(const char *firstChar, const char *lastChar)
- : _translationUnit(0),
- _control(0),
+ : _translationUnit(nullptr),
+ _control(nullptr),
_state(0),
_flags(0),
_currentLine(1)
@@ -747,7 +747,7 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
const char *yytext = _currentChar;
int delimLength = -1;
- const char *closingDelimCandidate = 0;
+ const char *closingDelimCandidate = nullptr;
bool closed = false;
while (_yychar) {
if (_yychar == '(' && delimLength == -1) {
@@ -781,7 +781,7 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
// Make sure this continues to be a valid candidate.
if (_yychar != *(yytext + (_currentChar - closingDelimCandidate)))
- closingDelimCandidate = 0;
+ closingDelimCandidate = nullptr;
yyinp();
}
@@ -954,7 +954,8 @@ void Lexer::scanNumericLiteral(Token *tok)
yyinp();
while (std::isdigit(_yychar) ||
(_yychar >= 'a' && _yychar <= 'f') ||
- (_yychar >= 'A' && _yychar <= 'F')) {
+ (_yychar >= 'A' && _yychar <= 'F') ||
+ ((_yychar == '\'') && _languageFeatures.cxx14Enabled)) {
yyinp();
}
if (!scanOptionalIntegerSuffix())
@@ -962,7 +963,8 @@ void Lexer::scanNumericLiteral(Token *tok)
goto theEnd;
} else if (_yychar == 'b' || _yychar == 'B') { // see n3472
yyinp();
- while (_yychar == '0' || _yychar == '1')
+ while (_yychar == '0' || _yychar == '1' ||
+ ((_yychar == '\'') && _languageFeatures.cxx14Enabled))
yyinp();
if (!scanOptionalIntegerSuffix())
scanOptionalUserDefinedLiteral(tok);
@@ -970,7 +972,8 @@ void Lexer::scanNumericLiteral(Token *tok)
} else if (_yychar >= '0' && _yychar <= '7') {
do {
yyinp();
- } while (_yychar >= '0' && _yychar <= '7');
+ } while ((_yychar >= '0' && _yychar <= '7') ||
+ ((_yychar == '\'') && _languageFeatures.cxx14Enabled));
if (!scanOptionalIntegerSuffix())
scanOptionalUserDefinedLiteral(tok);
goto theEnd;
@@ -989,7 +992,8 @@ void Lexer::scanNumericLiteral(Token *tok)
if (scanExponentPart() && !scanOptionalFloatingSuffix())
scanOptionalUserDefinedLiteral(tok);
break;
- } else if (std::isdigit(_yychar)) {
+ } else if (std::isdigit(_yychar) ||
+ ((_yychar == '\'') && _languageFeatures.cxx14Enabled)) {
yyinp();
} else {
if (!scanOptionalIntegerSuffix())
diff --git a/src/libs/3rdparty/cplusplus/LiteralTable.h b/src/libs/3rdparty/cplusplus/LiteralTable.h
index 5a3f1e9042..494bc928bd 100644
--- a/src/libs/3rdparty/cplusplus/LiteralTable.h
+++ b/src/libs/3rdparty/cplusplus/LiteralTable.h
@@ -36,8 +36,8 @@ public:
public:
LiteralTable()
- : _literals(0),
- _buckets(0),
+ : _literals(nullptr),
+ _buckets(nullptr),
_allocatedLiterals(0),
_literalCount(-1),
_allocatedBuckets(0)
@@ -59,8 +59,8 @@ public:
if (_buckets)
std::free(_buckets);
- _literals = 0;
- _buckets = 0;
+ _literals = nullptr;
+ _buckets = nullptr;
_allocatedLiterals = 0;
_literalCount = -1;
_allocatedBuckets = 0;
@@ -69,10 +69,10 @@ public:
bool empty() const
{ return _literalCount == -1; }
- unsigned size() const
+ int size() const
{ return _literalCount + 1; }
- const Literal *at(unsigned index) const
+ const Literal *at(int index) const
{ return _literals[index]; }
iterator begin() const
@@ -81,7 +81,7 @@ public:
iterator end() const
{ return _literals + _literalCount + 1; }
- const Literal *findLiteral(const char *chars, unsigned size) const
+ const Literal *findLiteral(const char *chars, int size) const
{
if (_buckets) {
unsigned h = Literal::hashCode(chars, size);
@@ -92,10 +92,10 @@ public:
}
}
- return 0;
+ return nullptr;
}
- const Literal *findOrInsertLiteral(const char *chars, unsigned size)
+ const Literal *findOrInsertLiteral(const char *chars, int size)
{
if (_buckets) {
unsigned h = Literal::hashCode(chars, size);
diff --git a/src/libs/3rdparty/cplusplus/Literals.cpp b/src/libs/3rdparty/cplusplus/Literals.cpp
index 19c92e49bb..d778c2f0cc 100644
--- a/src/libs/3rdparty/cplusplus/Literals.cpp
+++ b/src/libs/3rdparty/cplusplus/Literals.cpp
@@ -28,8 +28,8 @@
using namespace CPlusPlus;
////////////////////////////////////////////////////////////////////////////////
-Literal::Literal(const char *chars, unsigned size)
- : _next(0), _index(0)
+Literal::Literal(const char *chars, int size)
+ : _next(nullptr), _index(0)
{
_chars = new char[size + 1];
@@ -79,7 +79,7 @@ unsigned Literal::hashCode(const char *chars, unsigned size)
}
////////////////////////////////////////////////////////////////////////////////
-NumericLiteral::NumericLiteral(const char *chars, unsigned size)
+NumericLiteral::NumericLiteral(const char *chars, int size)
: Literal(chars, size), _flags(0)
{
f._type = NumericLiteralIsInt;
diff --git a/src/libs/3rdparty/cplusplus/Literals.h b/src/libs/3rdparty/cplusplus/Literals.h
index 19255b619b..8a4f4332ac 100644
--- a/src/libs/3rdparty/cplusplus/Literals.h
+++ b/src/libs/3rdparty/cplusplus/Literals.h
@@ -36,15 +36,15 @@ public:
typedef iterator const_iterator;
public:
- Literal(const char *chars, unsigned size);
+ Literal(const char *chars, int size);
virtual ~Literal();
iterator begin() const { return _chars; }
iterator end() const { return _chars + _size; }
- char at(unsigned index) const { return _chars[index]; }
+ char at(int index) const { return _chars[index]; }
const char *chars() const { return _chars; }
- unsigned size() const { return _size; }
+ int size() const { return _size; }
unsigned hashCode() const { return _hashCode; }
static unsigned hashCode(const char *chars, unsigned size);
@@ -73,7 +73,7 @@ public:
class CPLUSPLUS_EXPORT NumericLiteral: public Literal
{
public:
- NumericLiteral(const char *chars, unsigned size);
+ NumericLiteral(const char *chars, int size);
enum {
NumericLiteralIsInt,
@@ -108,7 +108,7 @@ private:
class CPLUSPLUS_EXPORT Identifier: public Literal, public Name
{
public:
- Identifier(const char *chars, unsigned size)
+ Identifier(const char *chars, int size)
: Literal(chars, size)
{ }
diff --git a/src/libs/3rdparty/cplusplus/Matcher.cpp b/src/libs/3rdparty/cplusplus/Matcher.cpp
index ffb852a67c..8ef26017c6 100644
--- a/src/libs/3rdparty/cplusplus/Matcher.cpp
+++ b/src/libs/3rdparty/cplusplus/Matcher.cpp
@@ -293,7 +293,7 @@ bool Matcher::match(const ObjCMethod *type, const ObjCMethod *otherType)
else if (! type->returnType().match(otherType->returnType(), this))
return false;
- for (unsigned i = 0; i < type->argumentCount(); ++i) {
+ for (int i = 0; i < type->argumentCount(); ++i) {
Symbol *l = type->argumentAt(i);
Symbol *r = otherType->argumentAt(i);
if (! l->type().match(r->type(), this))
@@ -356,10 +356,10 @@ bool Matcher::match(const QualifiedNameId *name, const QualifiedNameId *otherNam
bool Matcher::match(const SelectorNameId *name, const SelectorNameId *otherName)
{
- const unsigned nc = name->nameCount();
+ const int nc = name->nameCount();
if (name->hasArguments() != otherName->hasArguments() || nc != otherName->nameCount())
return false;
- for (unsigned i = 0; i < nc; ++i)
+ for (int i = 0; i < nc; ++i)
if (! Matcher::match(name->nameAt(i), otherName->nameAt(i), this))
return false;
return true;
diff --git a/src/libs/3rdparty/cplusplus/Matcher.h b/src/libs/3rdparty/cplusplus/Matcher.h
index 6a8da9a7b7..4fc3fb1054 100644
--- a/src/libs/3rdparty/cplusplus/Matcher.h
+++ b/src/libs/3rdparty/cplusplus/Matcher.h
@@ -38,8 +38,8 @@ public:
Matcher();
virtual ~Matcher();
- static bool match(const Type *type, const Type *otherType, Matcher *matcher = 0);
- static bool match(const Name *name, const Name *otherName, Matcher *matcher = 0);
+ static bool match(const Type *type, const Type *otherType, Matcher *matcher = nullptr);
+ static bool match(const Name *name, const Name *otherName, Matcher *matcher = nullptr);
virtual bool match(const UndefinedType *type, const UndefinedType *otherType);
virtual bool match(const VoidType *type, const VoidType *otherType);
diff --git a/src/libs/3rdparty/cplusplus/MemoryPool.cpp b/src/libs/3rdparty/cplusplus/MemoryPool.cpp
index bcd5154b72..af6f7ebddb 100644
--- a/src/libs/3rdparty/cplusplus/MemoryPool.cpp
+++ b/src/libs/3rdparty/cplusplus/MemoryPool.cpp
@@ -27,11 +27,11 @@
using namespace CPlusPlus;
MemoryPool::MemoryPool()
- : _blocks(0),
+ : _blocks(nullptr),
_allocatedBlocks(0),
_blockCount(-1),
- _ptr(0),
- _end(0)
+ _ptr(nullptr),
+ _end(nullptr)
{ }
MemoryPool::~MemoryPool()
@@ -49,7 +49,7 @@ MemoryPool::~MemoryPool()
void MemoryPool::reset()
{
_blockCount = -1;
- _ptr = _end = 0;
+ _ptr = _end = nullptr;
}
void *MemoryPool::allocate_helper(size_t size)
@@ -65,7 +65,7 @@ void *MemoryPool::allocate_helper(size_t size)
_blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index)
- _blocks[index] = 0;
+ _blocks[index] = nullptr;
}
char *&block = _blocks[_blockCount];
diff --git a/src/libs/3rdparty/cplusplus/Name.cpp b/src/libs/3rdparty/cplusplus/Name.cpp
index 1016586c89..815b74bbed 100644
--- a/src/libs/3rdparty/cplusplus/Name.cpp
+++ b/src/libs/3rdparty/cplusplus/Name.cpp
@@ -35,28 +35,28 @@ Name::~Name()
{ }
bool Name::isNameId() const
-{ return asNameId() != 0; }
+{ return asNameId() != nullptr; }
bool Name::isAnonymousNameId() const
-{ return asAnonymousNameId() != 0; }
+{ return asAnonymousNameId() != nullptr; }
bool Name::isTemplateNameId() const
-{ return asTemplateNameId() != 0; }
+{ return asTemplateNameId() != nullptr; }
bool Name::isDestructorNameId() const
-{ return asDestructorNameId() != 0; }
+{ return asDestructorNameId() != nullptr; }
bool Name::isOperatorNameId() const
-{ return asOperatorNameId() != 0; }
+{ return asOperatorNameId() != nullptr; }
bool Name::isConversionNameId() const
-{ return asConversionNameId() != 0; }
+{ return asConversionNameId() != nullptr; }
bool Name::isQualifiedNameId() const
-{ return asQualifiedNameId() != 0; }
+{ return asQualifiedNameId() != nullptr; }
bool Name::isSelectorNameId() const
-{ return asSelectorNameId() != 0; }
+{ return asSelectorNameId() != nullptr; }
void Name::accept(NameVisitor *visitor) const
{
@@ -79,9 +79,9 @@ bool Name::match(const Name *other, Matcher *matcher) const
bool Name::Compare::operator()(const Name *name, const Name *other) const
{
- if (name == 0)
- return other != 0;
- if (other == 0)
+ if (name == nullptr)
+ return other != nullptr;
+ if (other == nullptr)
return false;
if (name == other)
return false;
@@ -89,9 +89,9 @@ bool Name::Compare::operator()(const Name *name, const Name *other) const
const Identifier *id = name->identifier();
const Identifier *otherId = other->identifier();
- if (id == 0)
- return otherId != 0;
- if (otherId == 0)
+ if (id == nullptr)
+ return otherId != nullptr;
+ if (otherId == nullptr)
return false;
return std::strcmp(id->chars(), otherId->chars()) < 0;
diff --git a/src/libs/3rdparty/cplusplus/Name.h b/src/libs/3rdparty/cplusplus/Name.h
index 460f0bca11..7a4a159ffe 100644
--- a/src/libs/3rdparty/cplusplus/Name.h
+++ b/src/libs/3rdparty/cplusplus/Name.h
@@ -44,19 +44,19 @@ public:
bool isQualifiedNameId() const;
bool isSelectorNameId() const;
- virtual const Identifier *asNameId() const { return 0; }
- virtual const AnonymousNameId *asAnonymousNameId() const { return 0; }
- virtual const TemplateNameId *asTemplateNameId() const { return 0; }
- virtual const DestructorNameId *asDestructorNameId() const { return 0; }
- virtual const OperatorNameId *asOperatorNameId() const { return 0; }
- virtual const ConversionNameId *asConversionNameId() const { return 0; }
- virtual const QualifiedNameId *asQualifiedNameId() const { return 0; }
- virtual const SelectorNameId *asSelectorNameId() const { return 0; }
+ virtual const Identifier *asNameId() const { return nullptr; }
+ virtual const AnonymousNameId *asAnonymousNameId() const { return nullptr; }
+ virtual const TemplateNameId *asTemplateNameId() const { return nullptr; }
+ virtual const DestructorNameId *asDestructorNameId() const { return nullptr; }
+ virtual const OperatorNameId *asOperatorNameId() const { return nullptr; }
+ virtual const ConversionNameId *asConversionNameId() const { return nullptr; }
+ virtual const QualifiedNameId *asQualifiedNameId() const { return nullptr; }
+ virtual const SelectorNameId *asSelectorNameId() const { return nullptr; }
void accept(NameVisitor *visitor) const;
static void accept(const Name *name, NameVisitor *visitor);
- bool match(const Name *other, Matcher *matcher = 0) const;
+ bool match(const Name *other, Matcher *matcher = nullptr) const;
public:
struct Compare {
diff --git a/src/libs/3rdparty/cplusplus/Names.cpp b/src/libs/3rdparty/cplusplus/Names.cpp
index 10bbf389d2..6bcc988f37 100644
--- a/src/libs/3rdparty/cplusplus/Names.cpp
+++ b/src/libs/3rdparty/cplusplus/Names.cpp
@@ -45,7 +45,7 @@ const Identifier *QualifiedNameId::identifier() const
if (const Name *u = name())
return u->identifier();
- return 0;
+ return nullptr;
}
const Name *QualifiedNameId::base() const
@@ -93,18 +93,18 @@ bool TemplateNameId::match0(const Name *otherName, Matcher *matcher) const
const Identifier *TemplateNameId::identifier() const
{ return _identifier; }
-unsigned TemplateNameId::templateArgumentCount() const
-{ return unsigned(_templateArguments.size()); }
+int TemplateNameId::templateArgumentCount() const
+{ return int(_templateArguments.size()); }
-const FullySpecifiedType &TemplateNameId::templateArgumentAt(unsigned index) const
+const FullySpecifiedType &TemplateNameId::templateArgumentAt(int index) const
{ return _templateArguments[index]; }
bool TemplateNameId::Compare::operator()(const TemplateNameId *name,
const TemplateNameId *other) const
{
- if (name == 0)
- return other != 0;
- if (other == 0)
+ if (name == nullptr)
+ return other != nullptr;
+ if (other == nullptr)
return false;
if (name == other)
return false;
@@ -112,9 +112,9 @@ bool TemplateNameId::Compare::operator()(const TemplateNameId *name,
const Identifier *id = name->identifier();
const Identifier *otherId = other->identifier();
- if (id == 0)
- return otherId != 0;
- if (otherId == 0)
+ if (id == nullptr)
+ return otherId != nullptr;
+ if (otherId == nullptr)
return false;
const int c = std::strcmp(id->chars(), otherId->chars());
@@ -154,7 +154,7 @@ OperatorNameId::Kind OperatorNameId::kind() const
{ return _kind; }
const Identifier *OperatorNameId::identifier() const
-{ return 0; }
+{ return nullptr; }
ConversionNameId::ConversionNameId(const FullySpecifiedType &type)
: _type(type)
@@ -177,7 +177,7 @@ FullySpecifiedType ConversionNameId::type() const
{ return _type; }
const Identifier *ConversionNameId::identifier() const
-{ return 0; }
+{ return nullptr; }
SelectorNameId::~SelectorNameId()
{ }
@@ -195,28 +195,28 @@ bool SelectorNameId::match0(const Name *otherName, Matcher *matcher) const
const Identifier *SelectorNameId::identifier() const
{
if (_names.empty())
- return 0;
+ return nullptr;
return nameAt(0)->identifier();
}
-unsigned SelectorNameId::nameCount() const
-{ return unsigned(_names.size()); }
+int SelectorNameId::nameCount() const
+{ return int(_names.size()); }
-const Name *SelectorNameId::nameAt(unsigned index) const
+const Name *SelectorNameId::nameAt(int index) const
{ return _names[index]; }
bool SelectorNameId::hasArguments() const
{ return _hasArguments; }
-AnonymousNameId::AnonymousNameId(unsigned classTokenIndex)
+AnonymousNameId::AnonymousNameId(int classTokenIndex)
: _classTokenIndex(classTokenIndex)
{ }
AnonymousNameId::~AnonymousNameId()
{ }
-unsigned AnonymousNameId::classTokenIndex() const
+int AnonymousNameId::classTokenIndex() const
{
return _classTokenIndex;
}
@@ -232,4 +232,4 @@ bool AnonymousNameId::match0(const Name *otherName, Matcher *matcher) const
}
const Identifier *AnonymousNameId::identifier() const
-{ return 0; }
+{ return nullptr; }
diff --git a/src/libs/3rdparty/cplusplus/Names.h b/src/libs/3rdparty/cplusplus/Names.h
index b8d090da2f..cea93911c6 100644
--- a/src/libs/3rdparty/cplusplus/Names.h
+++ b/src/libs/3rdparty/cplusplus/Names.h
@@ -88,8 +88,8 @@ public:
virtual const Identifier *identifier() const;
// ### find a better name
- unsigned templateArgumentCount() const;
- const FullySpecifiedType &templateArgumentAt(unsigned index) const;
+ int templateArgumentCount() const;
+ const FullySpecifiedType &templateArgumentAt(int index) const;
virtual const TemplateNameId *asTemplateNameId() const
{ return this; }
@@ -224,8 +224,8 @@ public:
virtual const Identifier *identifier() const;
- unsigned nameCount() const;
- const Name *nameAt(unsigned index) const;
+ int nameCount() const;
+ const Name *nameAt(int index) const;
bool hasArguments() const;
virtual const SelectorNameId *asSelectorNameId() const
@@ -248,10 +248,10 @@ private:
class CPLUSPLUS_EXPORT AnonymousNameId: public Name
{
public:
- AnonymousNameId(unsigned classTokenIndex);
+ AnonymousNameId(int classTokenIndex);
virtual ~AnonymousNameId();
- unsigned classTokenIndex() const;
+ int classTokenIndex() const;
virtual const Identifier *identifier() const;
@@ -263,7 +263,7 @@ protected:
virtual bool match0(const Name *otherName, Matcher *matcher) const;
private:
- unsigned _classTokenIndex;
+ int _classTokenIndex;
};
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index 6bee0fa972..fd7b963a87 100644
--- a/src/libs/3rdparty/cplusplus/Parser.cpp
+++ b/src/libs/3rdparty/cplusplus/Parser.cpp
@@ -49,7 +49,7 @@ class DebugRule {
public:
static int depth;
- DebugRule(const char *name, const char *spell, unsigned idx, bool blocked)
+ DebugRule(const char *name, const char *spell, int idx, bool blocked)
{
for (int i = 0; i <= depth; ++i)
fputc('-', stderr);
@@ -170,20 +170,20 @@ public:
};
struct CacheKey {
- CacheKey(unsigned initialCursor, ASTKind astKind)
+ CacheKey(int initialCursor, ASTKind astKind)
: initialCursor(initialCursor)
, astKind(astKind)
{}
- const unsigned initialCursor;
+ const int initialCursor;
const ASTKind astKind;
};
public:
ASTCache() {}
- void insert(ASTKind astKind, unsigned tokenIndexBeforeParsing,
- AST *resultingAST, unsigned resultingTokenIndex, bool resultingReturnValue)
+ void insert(ASTKind astKind, int tokenIndexBeforeParsing,
+ AST *resultingAST, int resultingTokenIndex, bool resultingReturnValue)
{
const auto key = std::make_pair(astKind, tokenIndexBeforeParsing);
@@ -195,14 +195,14 @@ public:
_cache.insert(keyValue);
}
- AST *find(ASTKind astKind, unsigned tokenIndex,
- unsigned *resultingTokenIndex, bool *foundInCache, bool *returnValue) const
+ AST *find(ASTKind astKind, int tokenIndex,
+ int *resultingTokenIndex, bool *foundInCache, bool *returnValue) const
{
const auto key = std::make_pair(astKind, tokenIndex);
const auto it = _cache.find(key);
if (it == _cache.end()) {
*foundInCache = false;
- return 0;
+ return nullptr;
} else {
*foundInCache = true;
*resultingTokenIndex = it->second.resultingTokenIndex;
@@ -224,11 +224,11 @@ private:
struct ParseFunctionResult {
AST *resultingAST;
- unsigned resultingTokenIndex;
+ int resultingTokenIndex;
bool returnValue;
};
- typedef std::pair<int, unsigned> ASTKindAndTokenIndex;
+ typedef std::pair<int, int> ASTKindAndTokenIndex;
std::unordered_map<ASTKindAndTokenIndex, ParseFunctionResult, KeyHasher> _cache;
};
@@ -251,7 +251,7 @@ inline void debugPrintCheckCache(bool) {}
#define CHECK_CACHE(ASTKind, ASTType) \
do { \
bool foundInCache; \
- unsigned newTokenIndex; \
+ int newTokenIndex; \
bool returnValue; \
if (AST *ast = _astCache->find(ASTKind, cursor(), \
&newTokenIndex, &foundInCache, &returnValue)) { \
@@ -486,7 +486,7 @@ int Parser::find(int token, int stopAt)
return 0;
}
-void Parser::match(int kind, unsigned *token)
+void Parser::match(int kind, int *token)
{
if (LA() == kind)
*token = consumeToken();
@@ -501,7 +501,7 @@ bool Parser::parseClassOrNamespaceName(NameAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_IDENTIFIER && (LA(2) == T_COLON_COLON || LA(2) == T_LESS)) {
- unsigned identifier_token = cursor();
+ int identifier_token = cursor();
if (LA(2) == T_LESS) {
bool blocked = blockErrors(true);
@@ -521,7 +521,7 @@ bool Parser::parseClassOrNamespaceName(NameAST *&node)
return true;
}
} else if (LA() == T_TEMPLATE) {
- unsigned template_token = consumeToken();
+ int template_token = consumeToken();
if (parseTemplateId(node, template_token) && LA() == T_COLON_COLON)
return true;
rewind(template_token);
@@ -529,12 +529,12 @@ bool Parser::parseClassOrNamespaceName(NameAST *&node)
return false;
}
-bool Parser::parseTemplateId(NameAST *&node, unsigned template_token)
+bool Parser::parseTemplateId(NameAST *&node, int template_token)
{
DEBUG_THIS_RULE();
CHECK_CACHE(ASTCache::TemplateId, NameAST);
- const unsigned start = cursor();
+ const int start = cursor();
if (LA() == T_IDENTIFIER && LA(2) == T_LESS) {
TemplateIdAST *ast = new (_pool) TemplateIdAST;
@@ -554,7 +554,7 @@ bool Parser::parseTemplateId(NameAST *&node, unsigned template_token)
}
const bool result = false;
- _astCache->insert(ASTCache::TemplateId, start, 0, cursor(), result);
+ _astCache->insert(ASTCache::TemplateId, start, nullptr, cursor(), result);
rewind(start);
return result;
}
@@ -564,9 +564,9 @@ bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node,
{
DEBUG_THIS_RULE();
NestedNameSpecifierListAST **nested_name_specifier = &node;
- NameAST *class_or_namespace_name = 0;
+ NameAST *class_or_namespace_name = nullptr;
if (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
- unsigned scope_token = consumeToken();
+ int scope_token = consumeToken();
NestedNameSpecifierAST *name = new (_pool) NestedNameSpecifierAST;
name->class_or_namespace_name = class_or_namespace_name;
@@ -598,7 +598,7 @@ bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node,
bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
+ int start = cursor();
if (! parseNestedNameSpecifier(name, acceptTemplateId))
rewind(start);
return true;
@@ -607,7 +607,7 @@ bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool
bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
{
DEBUG_THIS_RULE();
- unsigned global_scope_token = 0;
+ int global_scope_token = 0;
switch (LA()) {
case T_COLON_COLON:
@@ -623,13 +623,13 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
if (LA() == T_COLON_COLON)
global_scope_token = consumeToken();
- NestedNameSpecifierListAST *nested_name_specifier = 0;
+ NestedNameSpecifierListAST *nested_name_specifier = nullptr;
parseNestedNameSpecifierOpt(nested_name_specifier,
/*acceptTemplateId=*/ true);
- NameAST *unqualified_name = 0;
+ NameAST *unqualified_name = nullptr;
if (parseUnqualifiedName(unqualified_name,
- /*acceptTemplateId=*/ acceptTemplateId || nested_name_specifier != 0)) {
+ /*acceptTemplateId=*/ acceptTemplateId || nested_name_specifier != nullptr)) {
if (! global_scope_token && ! nested_name_specifier) {
node = unqualified_name;
return true;
@@ -653,9 +653,9 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
DeclarationListAST **decl = &ast->declaration_list;
while (LA()) {
- unsigned start_declaration = cursor();
+ int start_declaration = cursor();
- DeclarationAST *declaration = 0;
+ DeclarationAST *declaration = nullptr;
if (parseDeclaration(declaration)) {
*decl = new (_pool) DeclarationListAST;
@@ -729,15 +729,15 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
case T_Q_DECLARE_INTERFACE:
{
consumeToken();
- unsigned lparen_token = 0;
+ int lparen_token = 0;
match(T_LPAREN, &lparen_token);
- NameAST *name = 0;
+ NameAST *name = nullptr;
parseName(name);
- unsigned comma_token = 0;
+ int comma_token = 0;
match(T_COMMA, &comma_token);
- unsigned string_literal = 0;
+ int string_literal = 0;
match(T_STRING_LITERAL, &string_literal);
- unsigned rparen_token = 0;
+ int rparen_token = 0;
match(T_RPAREN, &rparen_token);
} return true;
@@ -759,8 +759,8 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
default: {
if (_languageFeatures.objCEnabled && LA() == T___ATTRIBUTE__) {
- const unsigned start = cursor();
- SpecifierListAST *attributes = 0, **attr = &attributes;
+ const int start = cursor();
+ SpecifierListAST *attributes = nullptr, **attr = &attributes;
while (parseGnuAttributeSpecifier(*attr))
attr = &(*attr)->next;
if (LA() == T_AT_INTERFACE)
@@ -817,8 +817,8 @@ bool Parser::parseLinkageBody(DeclarationAST *&node)
if (tk == T_RBRACE)
break;
- unsigned start_declaration = cursor();
- DeclarationAST *declaration = 0;
+ int start_declaration = cursor();
+ DeclarationAST *declaration = nullptr;
if (parseDeclaration(declaration)) {
*declaration_ptr = new (_pool) DeclarationListAST;
(*declaration_ptr)->value = declaration;
@@ -865,11 +865,11 @@ bool Parser::parseNamespace(DeclarationAST *&node)
&& !isNestedNamespace())
return false;
- unsigned inline_token = 0;
+ int inline_token = 0;
if (_languageFeatures.cxx11Enabled && LA() == T_INLINE)
inline_token = consumeToken();
- unsigned namespace_token = consumeToken();
+ int namespace_token = consumeToken();
if (LA() == T_IDENTIFIER && LA(2) == T_EQUAL) {
if (inline_token)
@@ -896,7 +896,7 @@ bool Parser::parseNamespace(DeclarationAST *&node)
} else if (LA() == T_LBRACE) {
parseLinkageBody(ast->linkage_body);
} else { // attempt to do error recovery
- unsigned pos = cursor();
+ int pos = cursor();
for (;LA() != T_EOF_SYMBOL; consumeToken()) {
switch (LA()) {
case T_IDENTIFIER:
@@ -932,7 +932,7 @@ bool Parser::isNestedNamespace() const
bool Parser::parseNestedNamespace(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
- DeclarationAST *ast = 0;
+ DeclarationAST *ast = nullptr;
if (isNestedNamespace() && parseNamespace(ast)) {
node = ast;
return true;
@@ -1003,7 +1003,7 @@ bool Parser::parseAliasDeclaration(DeclarationAST *&node)
alias->equal_token = consumeToken();
- ExpressionAST *expr = 0;
+ ExpressionAST *expr = nullptr;
parseTypeId(expr);
if (expr)
alias->typeId = expr->asTypeId();
@@ -1019,11 +1019,11 @@ bool Parser::parseConversionFunctionId(NameAST *&node)
DEBUG_THIS_RULE();
if (LA() != T_OPERATOR)
return false;
- unsigned operator_token = consumeToken();
- SpecifierListAST *type_specifier = 0;
+ int operator_token = consumeToken();
+ SpecifierListAST *type_specifier = nullptr;
if (! parseTypeSpecifier(type_specifier))
return false;
- PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
+ PtrOperatorListAST *ptr_operators = nullptr, **ptr_operators_tail = &ptr_operators;
while (parsePtrOperator(*ptr_operators_tail))
ptr_operators_tail = &(*ptr_operators_tail)->next;
@@ -1040,9 +1040,9 @@ bool Parser::parseOperatorFunctionId(NameAST *&node)
DEBUG_THIS_RULE();
if (LA() != T_OPERATOR)
return false;
- unsigned operator_token = consumeToken();
+ int operator_token = consumeToken();
- OperatorAST *op = 0;
+ OperatorAST *op = nullptr;
if (! parseOperator(op))
return false;
@@ -1053,13 +1053,13 @@ bool Parser::parseOperatorFunctionId(NameAST *&node)
return true;
}
-Parser::TemplateArgumentListEntry *Parser::templateArgumentListEntry(unsigned tokenIndex)
+Parser::TemplateArgumentListEntry *Parser::templateArgumentListEntry(int tokenIndex)
{
- std::map<unsigned, TemplateArgumentListEntry>::iterator it =_templateArgumentList.find(tokenIndex);
+ std::map<int, TemplateArgumentListEntry>::iterator it =_templateArgumentList.find(tokenIndex);
if (it != _templateArgumentList.end())
return &it->second;
- return 0;
+ return nullptr;
}
bool Parser::parseTemplateArgumentList(ExpressionListAST *&node)
@@ -1069,13 +1069,13 @@ bool Parser::parseTemplateArgumentList(ExpressionListAST *&node)
if (TemplateArgumentListEntry *entry = templateArgumentListEntry(cursor())) {
rewind(entry->cursor);
node = entry->ast;
- return entry->ast != 0;
+ return entry->ast != nullptr;
}
- unsigned start = cursor();
+ int start = cursor();
ExpressionListAST **template_argument_ptr = &node;
- ExpressionAST *template_argument = 0;
+ ExpressionAST *template_argument = nullptr;
const bool cxx11Enabled = _languageFeatures.cxx11Enabled;
if (parseTemplateArgument(template_argument)) {
*template_argument_ptr = new (_pool) ExpressionListAST;
@@ -1103,14 +1103,14 @@ bool Parser::parseTemplateArgumentList(ExpressionListAST *&node)
ExpressionListAST *template_argument_list = node;
for (ExpressionListAST *iter = template_argument_list, **ast_iter = &node;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
- *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
+ *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : nullptr);
}
_templateArgumentList.insert(std::make_pair(start, TemplateArgumentListEntry(start, cursor(), node)));
return true;
}
- _templateArgumentList.insert(std::make_pair(start, TemplateArgumentListEntry(start, cursor(), 0)));
+ _templateArgumentList.insert(std::make_pair(start, TemplateArgumentListEntry(start, cursor(), nullptr)));
return false;
}
@@ -1127,7 +1127,7 @@ bool Parser::parseAsmDefinition(DeclarationAST *&node)
ast->volatile_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
- unsigned string_literal_token = 0;
+ int string_literal_token = 0;
match(T_STRING_LITERAL, &string_literal_token);
while (LA() == T_STRING_LITERAL) {
consumeToken();
@@ -1181,19 +1181,19 @@ bool Parser::parseAsmOperandList()
bool Parser::parseAsmOperand()
{
DEBUG_THIS_RULE();
- unsigned string_literal_token = 0;
+ int string_literal_token = 0;
match(T_STRING_LITERAL, &string_literal_token);
if (LA() == T_LBRACKET) {
- /*unsigned lbracket_token = */ consumeToken();
+ /*int lbracket_token = */ consumeToken();
match(T_STRING_LITERAL, &string_literal_token);
- unsigned rbracket_token = 0;
+ int rbracket_token = 0;
match(T_RBRACKET, &rbracket_token);
}
- unsigned lparen_token = 0, rparen_token = 0;
+ int lparen_token = 0, rparen_token = 0;
match(T_LPAREN, &lparen_token);
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
parseExpression(expression);
match(T_RPAREN, &rparen_token);
return true;
@@ -1205,7 +1205,7 @@ bool Parser::parseAsmClobberList()
if (LA() != T_STRING_LITERAL)
return false;
- unsigned string_literal_token = consumeToken();
+ int string_literal_token = consumeToken();
while (LA() == T_COMMA) {
consumeToken();
@@ -1236,9 +1236,9 @@ bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
}
while (LA()) {
- unsigned start_declaration = cursor();
+ int start_declaration = cursor();
- ast->declaration = 0;
+ ast->declaration = nullptr;
if (parseDeclaration(ast->declaration))
break;
@@ -1335,7 +1335,7 @@ bool Parser::parseCvQualifiers(SpecifierListAST *&node)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
+ int start = cursor();
SpecifierListAST **ast = &node;
while (*ast)
@@ -1357,7 +1357,7 @@ bool Parser::parseCvQualifiers(SpecifierListAST *&node)
return start != cursor();
}
-bool Parser::parseRefQualifier(unsigned &ref_qualifier)
+bool Parser::parseRefQualifier(int &ref_qualifier)
{
DEBUG_THIS_RULE();
@@ -1382,7 +1382,7 @@ bool Parser::parseOverrideFinalQualifiers(SpecifierListAST *&node)
if (!_languageFeatures.cxx11Enabled)
return false;
- unsigned start = cursor();
+ int start = cursor();
SpecifierListAST **ast = &node;
while (*ast)
@@ -1421,13 +1421,13 @@ bool Parser::parsePtrOperator(PtrOperatorListAST *&node)
node = new (_pool) PtrOperatorListAST(ast);
return true;
} else if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER) {
- unsigned scope_or_identifier_token = cursor();
+ int scope_or_identifier_token = cursor();
- unsigned global_scope_token = 0;
+ int global_scope_token = 0;
if (LA() == T_COLON_COLON)
global_scope_token = consumeToken();
- NestedNameSpecifierListAST *nested_name_specifiers = 0;
+ NestedNameSpecifierListAST *nested_name_specifiers = nullptr;
bool has_nested_name_specifier = parseNestedNameSpecifier(nested_name_specifiers, true);
if (has_nested_name_specifier && LA() == T_STAR) {
PointerToMemberAST *ast = new (_pool) PointerToMemberAST;
@@ -1446,7 +1446,7 @@ bool Parser::parsePtrOperator(PtrOperatorListAST *&node)
bool Parser::parseTemplateArgument(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
+ int start = cursor();
if (parseTypeId(node)) {
int index = 1;
@@ -1482,7 +1482,7 @@ bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq,
{
DEBUG_THIS_RULE();
bool has_type_specifier = false;
- NameAST *named_type_specifier = 0;
+ NameAST *named_type_specifier = nullptr;
SpecifierListAST **decl_specifier_seq_ptr = &decl_specifier_seq;
for (;;) {
if (! noStorageSpecifiers && ! onlySimpleTypeSpecifiers && lookAtStorageClassSpecifier()) {
@@ -1515,7 +1515,7 @@ bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq,
} else if (! onlySimpleTypeSpecifiers && ! has_type_specifier &&
(LA() == T_TYPENAME || LA() == T_ENUM || lookAtClassKey())) {
// typename-specifier, elaborated-type-specifier
- unsigned startOfElaboratedTypeSpecifier = cursor();
+ int startOfElaboratedTypeSpecifier = cursor();
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) {
error(startOfElaboratedTypeSpecifier, "expected an elaborated type specifier");
break;
@@ -1526,13 +1526,13 @@ bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq,
break;
}
- return decl_specifier_seq != 0;
+ return decl_specifier_seq != nullptr;
}
bool Parser::parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
+ int start = cursor();
bool blocked = blockErrors(true);
if (parseDeclarator(node, decl_specifier_list)) {
blockErrors(blocked);
@@ -1546,23 +1546,23 @@ bool Parser::parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, Specifier
bool Parser::parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
- SpecifierListAST *attributes = 0;
+ int start = cursor();
+ SpecifierListAST *attributes = nullptr;
parseOptionalAttributeSpecifierSequence(attributes);
- PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
+ PtrOperatorListAST *ptr_operators = nullptr, **ptr_operators_tail = &ptr_operators;
while (parsePtrOperator(*ptr_operators_tail))
ptr_operators_tail = &(*ptr_operators_tail)->next;
if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER || LA() == T_TILDE || LA() == T_OPERATOR
|| (_languageFeatures.cxx11Enabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COLON_COLON || LA(2) == T_IDENTIFIER))) {
- unsigned dot_dot_dot_token = 0;
+ int dot_dot_dot_token = 0;
if (LA() == T_DOT_DOT_DOT)
dot_dot_dot_token = consumeToken();
- NameAST *name = 0;
+ NameAST *name = nullptr;
if (parseName(name)) {
DeclaratorIdAST *declarator_id = new (_pool) DeclaratorIdAST;
declarator_id->dot_dot_dot_token = dot_dot_dot_token;
@@ -1578,8 +1578,8 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
if (attributes)
warning(attributes->firstToken(), "unexpected attribtues");
- unsigned lparen_token = consumeToken();
- DeclaratorAST *declarator = 0;
+ int lparen_token = consumeToken();
+ DeclaratorAST *declarator = nullptr;
if (parseDeclarator(declarator, decl_specifier_list) && LA() == T_RPAREN) {
NestedDeclaratorAST *nested_declarator = new (_pool) NestedDeclaratorAST;
nested_declarator->lparen_token = lparen_token;
@@ -1623,17 +1623,17 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
PostfixDeclaratorListAST **postfix_ptr = &node->postfix_declarator_list;
for (;;) {
- unsigned startOfPostDeclarator = cursor();
+ int startOfPostDeclarator = cursor();
if (LA() == T_LPAREN) {
if (! declaringClass && LA(2) != T_RPAREN && maybeCppInitializer(node)) {
- unsigned lparen_token = cursor();
- ExpressionAST *initializer = 0;
+ int lparen_token = cursor();
+ ExpressionAST *initializer = nullptr;
bool blocked = blockErrors(true);
if (parseInitializer(initializer, &node->equal_token)) {
// maybe the initializer also parses as a FunctionDeclarator?
- ExpressionListParenAST *expr = 0;
+ ExpressionListParenAST *expr = nullptr;
if (initializer)
expr = initializer->asExpressionListParen();
if (expr) {
@@ -1643,9 +1643,9 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
// check for ambiguous declarators.
consumeToken();
- ParameterDeclarationClauseAST *parameter_declaration_clause = 0;
+ ParameterDeclarationClauseAST *parameter_declaration_clause = nullptr;
if (parseParameterDeclarationClause(parameter_declaration_clause) && LA() == T_RPAREN) {
- unsigned rparen_token = consumeToken();
+ int rparen_token = consumeToken();
FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
ast->lparen_token = lparen_token;
@@ -1730,15 +1730,15 @@ bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node, SpecifierListAST
{
DEBUG_THIS_RULE();
- PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
+ PtrOperatorListAST *ptr_operators = nullptr, **ptr_operators_tail = &ptr_operators;
while (parsePtrOperator(*ptr_operators_tail))
ptr_operators_tail = &(*ptr_operators_tail)->next;
- unsigned after_ptr_operators = cursor();
+ int after_ptr_operators = cursor();
if (LA() == T_LPAREN && LA(2) != T_RPAREN) {
- unsigned lparen_token = consumeToken();
- DeclaratorAST *declarator = 0;
+ int lparen_token = consumeToken();
+ DeclaratorAST *declarator = nullptr;
if (parseAbstractDeclarator(declarator, decl_specifier_list) && LA() == T_RPAREN) {
NestedDeclaratorAST *nested_declarator = new (_pool) NestedDeclaratorAST;
nested_declarator->lparen_token = lparen_token;
@@ -1768,7 +1768,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *dec
if (! parseAbstractCoreDeclarator(node, decl_specifier_list))
return false;
- PostfixDeclaratorListAST *postfix_declarators = 0,
+ PostfixDeclaratorListAST *postfix_declarators = nullptr,
**postfix_ptr = &postfix_declarators;
for (;;) {
@@ -1844,7 +1844,7 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
}
if (LA() == T_LBRACE) {
ast->lbrace_token = consumeToken();
- unsigned comma_token = 0;
+ int comma_token = 0;
EnumeratorListAST **enumerator_ptr = &ast->enumerator_list;
while (int tk = LA()) {
if (tk == T_RBRACE)
@@ -1879,7 +1879,7 @@ bool Parser::parseTemplateParameterList(DeclarationListAST *&node)
{
DEBUG_THIS_RULE();
DeclarationListAST **template_parameter_ptr = &node;
- DeclarationAST *declaration = 0;
+ DeclarationAST *declaration = nullptr;
if (parseTemplateParameter(declaration)) {
*template_parameter_ptr = new (_pool) DeclarationListAST;
(*template_parameter_ptr)->value = declaration;
@@ -1888,7 +1888,7 @@ bool Parser::parseTemplateParameterList(DeclarationListAST *&node)
while (LA() == T_COMMA) {
consumeToken(); // XXX Store this token somewhere
- declaration = 0;
+ declaration = nullptr;
if (parseTemplateParameter(declaration)) {
*template_parameter_ptr = new (_pool) DeclarationListAST;
(*template_parameter_ptr)->value = declaration;
@@ -1906,7 +1906,7 @@ bool Parser::parseTemplateParameter(DeclarationAST *&node)
if (parseTypeParameter(node))
return true;
bool previousTemplateArguments = switchTemplateArguments(true);
- ParameterDeclarationAST *ast = 0;
+ ParameterDeclarationAST *ast = nullptr;
bool parsed = parseParameterDeclaration(ast);
node = ast;
(void) switchTemplateArguments(previousTemplateArguments);
@@ -2005,7 +2005,7 @@ bool Parser::parseTypeId(ExpressionAST *&node)
DEBUG_THIS_RULE();
CHECK_CACHE(ASTCache::TypeId, ExpressionAST);
- SpecifierListAST *type_specifier = 0;
+ SpecifierListAST *type_specifier = nullptr;
if (parseTypeSpecifier(type_specifier)) {
TypeIdAST *ast = new (_pool) TypeIdAST;
ast->type_specifier_list = type_specifier;
@@ -2022,11 +2022,11 @@ bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&nod
if (LA() == T_RPAREN)
return true; // nothing to do
CHECK_CACHE(ASTCache::ParameterDeclarationClause, ParameterDeclarationClauseAST);
- const unsigned initialCursor = cursor();
+ const int initialCursor = cursor();
- ParameterDeclarationListAST *parameter_declarations = 0;
+ ParameterDeclarationListAST *parameter_declarations = nullptr;
- unsigned dot_dot_dot_token = 0;
+ int dot_dot_dot_token = 0;
if (LA() == T_DOT_DOT_DOT)
dot_dot_dot_token = consumeToken();
else {
@@ -2059,7 +2059,7 @@ bool Parser::parseParameterDeclarationList(ParameterDeclarationListAST *&node)
return false; // nothing to do.
ParameterDeclarationListAST **parameter_declaration_ptr = &node;
- ParameterDeclarationAST *declaration = 0;
+ ParameterDeclarationAST *declaration = nullptr;
if (parseParameterDeclaration(declaration)) {
*parameter_declaration_ptr = new (_pool) ParameterDeclarationListAST;
(*parameter_declaration_ptr)->value = declaration;
@@ -2070,7 +2070,7 @@ bool Parser::parseParameterDeclarationList(ParameterDeclarationListAST *&node)
if (LA() == T_DOT_DOT_DOT)
break;
- declaration = 0;
+ declaration = nullptr;
if (parseParameterDeclaration(declaration)) {
*parameter_declaration_ptr = new (_pool) ParameterDeclarationListAST;
(*parameter_declaration_ptr)->value = declaration;
@@ -2085,7 +2085,7 @@ bool Parser::parseParameterDeclarationList(ParameterDeclarationListAST *&node)
bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
{
DEBUG_THIS_RULE();
- SpecifierListAST *decl_specifier_seq = 0;
+ SpecifierListAST *decl_specifier_seq = nullptr;
if (parseDeclSpecifierSeq(decl_specifier_seq)) {
ParameterDeclarationAST *ast = new (_pool) ParameterDeclarationAST;
ast->type_specifier_list = decl_specifier_seq;
@@ -2107,7 +2107,7 @@ bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
const Identifier *Parser::className(ClassSpecifierAST *ast) const
{
if (! ast)
- return 0;
+ return nullptr;
return identifier(ast->name);
}
@@ -2115,7 +2115,7 @@ const Identifier *Parser::className(ClassSpecifierAST *ast) const
const Identifier *Parser::identifier(NameAST *name) const
{
if (! name)
- return 0;
+ return nullptr;
if (QualifiedNameAST *q = name->asQualifiedName())
name = q->unqualified_name;
@@ -2127,7 +2127,7 @@ const Identifier *Parser::identifier(NameAST *name) const
return _translationUnit->identifier(template_id->identifier_token);
}
- return 0;
+ return nullptr;
}
bool Parser::parseClassSpecifier(SpecifierListAST *&node)
@@ -2136,9 +2136,9 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
if (! lookAtClassKey())
return false;
- unsigned classkey_token = consumeToken();
+ int classkey_token = consumeToken();
- SpecifierListAST *attributes = 0;
+ SpecifierListAST *attributes = nullptr;
parseOptionalAttributeSpecifierSequence(attributes);
if (LA(1) == T_IDENTIFIER && LA(2) == T_IDENTIFIER) {
@@ -2150,7 +2150,7 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
}
}
- NameAST *name = 0;
+ NameAST *name = nullptr;
parseName(name);
bool parsed = false;
@@ -2158,9 +2158,9 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
const bool previousInFunctionBody = _inFunctionBody;
_inFunctionBody = false;
- unsigned colon_token = 0;
- unsigned dot_dot_dot_token = 0;
- unsigned final_token = 0;
+ int colon_token = 0;
+ int dot_dot_dot_token = 0;
+ int final_token = 0;
if (LA() == T_IDENTIFIER) {
const Identifier *id = tok().identifier;
@@ -2175,7 +2175,7 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
name = ast;
}
- BaseSpecifierListAST *base_clause_list = 0;
+ BaseSpecifierListAST *base_clause_list = nullptr;
if (LA() == T_COLON) {
colon_token = cursor();
@@ -2188,7 +2188,7 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
if (LA() != T_LBRACE) {
error(cursor(), "expected `{' before `%s'", tok().spell());
- const unsigned saved = cursor();
+ const int saved = cursor();
for (int n = 0; n < 3 && LA() != T_EOF_SYMBOL; ++n, consumeToken()) {
if (LA() == T_LBRACE)
@@ -2219,8 +2219,8 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
break;
}
- unsigned start_declaration = cursor();
- DeclarationAST *declaration = 0;
+ int start_declaration = cursor();
+ DeclarationAST *declaration = nullptr;
if (parseMemberSpecification(declaration, ast)) {
if (declaration) { // paranoia check
*declaration_ptr = new (_pool) DeclarationListAST;
@@ -2325,7 +2325,7 @@ bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node)
node = ast;
break;
} else if (LA() == T_IDENTIFIER) {
- QtPropertyDeclarationItemAST *item = 0;
+ QtPropertyDeclarationItemAST *item = nullptr;
switch (peekAtQtContextKeyword()) {
case Token_READ:
case Token_WRITE:
@@ -2337,8 +2337,8 @@ bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node)
case Token_SCRIPTABLE:
case Token_STORED:
case Token_USER: {
- unsigned item_name_token = consumeToken();
- ExpressionAST *expr = 0;
+ int item_name_token = consumeToken();
+ ExpressionAST *expr = nullptr;
if (parsePostfixExpression(expr)) {
QtPropertyDeclarationItemAST *bItem =
new (_pool) QtPropertyDeclarationItemAST;
@@ -2403,7 +2403,7 @@ bool Parser::parseQtEnumDeclaration(DeclarationAST *&node)
ast->enum_specifier_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
for (NameListAST **iter = &ast->enumerator_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
- NameAST *name_ast = 0;
+ NameAST *name_ast = nullptr;
if (!parseName(name_ast))
break;
*iter = new (_pool) NameListAST;
@@ -2436,7 +2436,7 @@ bool Parser::parseQtFlags(DeclarationAST *&node)
ast->flags_specifier_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
for (NameListAST **iter = &ast->flag_enums_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
- NameAST *name_ast = 0;
+ NameAST *name_ast = nullptr;
if (!parseName(name_ast))
break;
*iter = new (_pool) NameListAST;
@@ -2486,15 +2486,15 @@ bool Parser::parseQtInterfaces(DeclarationAST *&node)
ast->interfaces_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
for (QtInterfaceNameListAST **iter = &ast->interface_name_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
- NameAST *name_ast = 0;
+ NameAST *name_ast = nullptr;
if (!parseName(name_ast))
break;
*iter = new (_pool) QtInterfaceNameListAST;
(*iter)->value = new (_pool) QtInterfaceNameAST;
(*iter)->value->interface_name = name_ast;
for (NameListAST **iter2 = &(*iter)->value->constraint_list; LA() && LA() == T_COLON; iter2 = &(*iter2)->next) {
- /*unsigned colon_token =*/ consumeToken();
- NameAST *name_ast2 = 0;
+ /*int colon_token =*/ consumeToken();
+ NameAST *name_ast2 = nullptr;
if (!parseName(name_ast2))
break;
*iter2 = new (_pool) NameListAST;
@@ -2595,7 +2595,7 @@ bool Parser::parseCtorInitializer(CtorInitializerAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_COLON) {
- unsigned colon_token = consumeToken();
+ int colon_token = consumeToken();
CtorInitializerAST *ast = new (_pool) CtorInitializerAST;
ast->colon_token = colon_token;
@@ -2615,11 +2615,11 @@ bool Parser::parseElaboratedTypeSpecifier(SpecifierListAST *&node)
{
DEBUG_THIS_RULE();
if (lookAtClassKey() || LA() == T_ENUM || LA() == T_TYPENAME) {
- unsigned classkey_token = consumeToken();
+ int classkey_token = consumeToken();
- SpecifierListAST *attributes = 0;
+ SpecifierListAST *attributes = nullptr;
parseOptionalAttributeSpecifierSequence(attributes);
- NameAST *name = 0;
+ NameAST *name = nullptr;
if (parseName(name)) {
ElaboratedTypeSpecifierAST *ast = new (_pool) ElaboratedTypeSpecifierAST;
ast->classkey_token = classkey_token;
@@ -2706,8 +2706,8 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
&& node->postfix_declarator_list->lastValue()->asFunctionDeclarator();
if (declaringClass && LA() == T_COLON
&& (! node || ! node->postfix_declarator_list)) {
- unsigned colon_token = consumeToken();
- ExpressionAST *expression = 0;
+ int colon_token = consumeToken();
+ ExpressionAST *expression = nullptr;
if (parseConstantExpression(expression) && (LA() == T_COMMA ||
LA() == T_SEMICOLON)) {
// recognized a bitfielddeclarator.
@@ -2760,14 +2760,14 @@ bool Parser::parseBaseClause(BaseSpecifierListAST *&node)
return false;
}
-bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token)
+bool Parser::parseInitializer(ExpressionAST *&node, int *equals_token)
{
DEBUG_THIS_RULE();
return parseInitializer0x(node, equals_token);
}
-bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token)
+bool Parser::parseInitializer0x(ExpressionAST *&node, int *equals_token)
{
DEBUG_THIS_RULE();
@@ -2835,7 +2835,7 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node)
{
DEBUG_THIS_RULE();
ExpressionListAST **expression_list_ptr = &node;
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
_initializerClauseDepth.push(1);
@@ -2941,7 +2941,7 @@ bool Parser::parseMemInitializerList(MemInitializerListAST *&node)
bool Parser::parseMemInitializer(MemInitializerListAST *&node)
{
DEBUG_THIS_RULE();
- NameAST *name = 0;
+ NameAST *name = nullptr;
if (! parseName(name))
return false;
@@ -2969,7 +2969,7 @@ bool Parser::parseTypeIdList(ExpressionListAST *&node)
{
DEBUG_THIS_RULE();
ExpressionListAST **expression_list_ptr = &node;
- ExpressionAST *typeId = 0;
+ ExpressionAST *typeId = nullptr;
if (parseTypeId(typeId)) {
*expression_list_ptr = new (_pool) ExpressionListAST;
(*expression_list_ptr)->value = typeId;
@@ -3000,7 +3000,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node)
{
DEBUG_THIS_RULE();
CHECK_CACHE(ASTCache::ExpressionList, ExpressionListAST);
- unsigned initialCursor = cursor();
+ int initialCursor = cursor();
if (_languageFeatures.cxx11Enabled) {
const bool result = parseInitializerList0x(node);
@@ -3009,7 +3009,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node)
}
ExpressionListAST **expression_list_ptr = &node;
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
if (parseAssignmentExpression(expression)) {
*expression_list_ptr = new (_pool) ExpressionListAST;
(*expression_list_ptr)->value = expression;
@@ -3029,7 +3029,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node)
}
const bool result = false;
- _astCache->insert(ASTCache::ExpressionList, initialCursor, 0, cursor(), result);
+ _astCache->insert(ASTCache::ExpressionList, initialCursor, nullptr, cursor(), result);
return result;
}
@@ -3071,14 +3071,14 @@ bool Parser::parseInitializerList(ExpressionListAST *&node)
{
DEBUG_THIS_RULE();
ExpressionListAST **initializer_ptr = &node;
- ExpressionAST *initializer = 0;
+ ExpressionAST *initializer = nullptr;
if (parseInitializerClause(initializer)) {
*initializer_ptr = new (_pool) ExpressionListAST;
(*initializer_ptr)->value = initializer;
initializer_ptr = &(*initializer_ptr)->next;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
- initializer = 0;
+ initializer = nullptr;
parseInitializerClause(initializer);
*initializer_ptr = new (_pool) ExpressionListAST;
(*initializer_ptr)->value = initializer;
@@ -3116,13 +3116,13 @@ bool Parser::parseUnqualifiedName(NameAST *&node, bool acceptTemplateId)
node = ast;
return true;
} else if (LA() == T_OPERATOR) {
- unsigned operator_token = cursor();
+ int operator_token = cursor();
if (parseOperatorFunctionId(node))
return true;
rewind(operator_token);
return parseConversionFunctionId(node);
} else if (LA() == T_IDENTIFIER) {
- unsigned identifier_token = cursor();
+ int identifier_token = cursor();
if (acceptTemplateId && LA(2) == T_LESS) {
bool blocked = blockErrors(true);
if (parseTemplateId(node)
@@ -3141,7 +3141,7 @@ bool Parser::parseUnqualifiedName(NameAST *&node, bool acceptTemplateId)
node = ast;
return true;
} else if (LA() == T_TEMPLATE) {
- unsigned template_token = consumeToken();
+ int template_token = consumeToken();
if (parseTemplateId(node, template_token))
return true;
rewind(template_token);
@@ -3205,7 +3205,7 @@ bool Parser::parseExpressionStatement(StatementAST *&node)
bool parsed = false;
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
if (parseExpression(expression)) {
ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST;
if (expression)
@@ -3253,7 +3253,7 @@ bool Parser::parseStatement(StatementAST *&node, bool blockLabeledStatement)
return parseSwitchStatement(node);
case T_TRY:
- return parseTryBlockStatement(node, 0);
+ return parseTryBlockStatement(node, nullptr);
case T_CASE:
case T_DEFAULT:
@@ -3314,7 +3314,7 @@ bool Parser::parseStatement(StatementAST *&node, bool blockLabeledStatement)
// Simply skip the emit token and parse as an expression statement - no strong
// reason to have an specific ast type.
consumeToken();
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
if (parsePostfixExpression(expression)) {
ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
ast->expression = expression;
@@ -3397,13 +3397,13 @@ bool Parser::parseReturnStatement(StatementAST *&node)
bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast, StatementAST *&node)
{
- const unsigned start = ast->firstToken();
- const unsigned end = ast->lastToken();
+ const int start = ast->firstToken();
+ const int end = ast->lastToken();
const bool blocked = blockErrors(true);
bool maybeAmbiguous = false;
- StatementAST *stmt = 0;
+ StatementAST *stmt = nullptr;
if (parseExpressionStatement(stmt)) {
if (stmt->firstToken() == start && stmt->lastToken() == end) {
maybeAmbiguous = true;
@@ -3423,7 +3423,7 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
if (LA() == T_SEMICOLON)
return parseExpressionStatement(node);
- const unsigned start = cursor();
+ const int start = cursor();
if (lookAtCVQualifier()
|| lookAtStorageClassSpecifier()
@@ -3438,13 +3438,13 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
if (LA() == T_IDENTIFIER || (LA() == T_COLON_COLON && LA(2) == T_IDENTIFIER)) {
const bool blocked = blockErrors(true);
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
const bool hasExpression = parseExpression(expression);
- const unsigned afterExpression = cursor();
+ const int afterExpression = cursor();
if (hasExpression/* && LA() == T_SEMICOLON*/) {
- //const unsigned semicolon_token = consumeToken();
- unsigned semicolon_token = 0;
+ //const int semicolon_token = consumeToken();
+ int semicolon_token = 0;
if (LA() == T_SEMICOLON)
semicolon_token = cursor();
@@ -3467,7 +3467,7 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
}
}
} else if (CallAST *call = expression->asCall()) {
- if (call->base_expression->asIdExpression() != 0) {
+ if (call->base_expression->asIdExpression() != nullptr) {
(void) blockErrors(blocked);
node = as_expression;
match(T_SEMICOLON, &as_expression->semicolon_token);
@@ -3477,14 +3477,14 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
rewind(start);
- DeclarationAST *declaration = 0;
+ DeclarationAST *declaration = nullptr;
if (parseSimpleDeclaration(declaration)) {
DeclarationStatementAST *as_declaration = new (_pool) DeclarationStatementAST;
as_declaration->declaration = declaration;
SimpleDeclarationAST *simple = declaration->asSimpleDeclaration();
if (! semicolon_token || invalidAssignment || semicolon_token != simple->semicolon_token ||
- (simple->decl_specifier_list != 0 && simple->declarator_list != 0)) {
+ (simple->decl_specifier_list != nullptr && simple->declarator_list != nullptr)) {
node = as_declaration;
(void) blockErrors(blocked);
return true;
@@ -3518,13 +3518,13 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
bool Parser::parseCondition(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
+ int start = cursor();
bool blocked = blockErrors(true);
- SpecifierListAST *type_specifier = 0;
+ SpecifierListAST *type_specifier = nullptr;
if (parseTypeSpecifier(type_specifier)) {
- DeclaratorAST *declarator = 0;
- if (parseInitDeclarator(declarator, type_specifier, /*declaringClass=*/ 0)) {
+ DeclaratorAST *declarator = nullptr;
+ if (parseInitDeclarator(declarator, type_specifier, /*declaringClass=*/ nullptr)) {
if (declarator->initializer && declarator->equal_token) {
ConditionAST *ast = new (_pool) ConditionAST;
ast->type_specifier_list = type_specifier;
@@ -3583,15 +3583,15 @@ bool Parser::parseForeachStatement(StatementAST *&node)
ast->foreach_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
- unsigned startOfTypeSpecifier = cursor();
+ int startOfTypeSpecifier = cursor();
bool blocked = blockErrors(true);
if (parseTypeSpecifier(ast->type_specifier_list))
parseDeclarator(ast->declarator, ast->type_specifier_list);
if (! ast->type_specifier_list || ! ast->declarator) {
- ast->type_specifier_list = 0;
- ast->declarator = 0;
+ ast->type_specifier_list = nullptr;
+ ast->declarator = nullptr;
blockErrors(blocked);
rewind(startOfTypeSpecifier);
@@ -3617,11 +3617,11 @@ bool Parser::parseForStatement(StatementAST *&node)
if (LA() != T_FOR)
return false;
- unsigned for_token = consumeToken();
- unsigned lparen_token = 0;
+ int for_token = consumeToken();
+ int lparen_token = 0;
match(T_LPAREN, &lparen_token);
- unsigned startOfTypeSpecifier = cursor();
+ int startOfTypeSpecifier = cursor();
bool blocked = blockErrors(true);
if (_languageFeatures.objCEnabled) {
@@ -3634,16 +3634,16 @@ bool Parser::parseForStatement(StatementAST *&node)
if ((ast->type_specifier_list || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) {
// woops, probably parsed too much: "in" got parsed as a declarator. Let's redo it:
- ast->type_specifier_list = 0;
- ast->declarator = 0;
+ ast->type_specifier_list = nullptr;
+ ast->declarator = nullptr;
rewind(startOfTypeSpecifier);
parseDeclarator(ast->declarator, ast->type_specifier_list);
}
if (! ast->type_specifier_list || ! ast->declarator) {
- ast->type_specifier_list = 0;
- ast->declarator = 0;
+ ast->type_specifier_list = nullptr;
+ ast->declarator = nullptr;
rewind(startOfTypeSpecifier);
parseAssignmentExpression(ast->initializer);
@@ -3736,8 +3736,8 @@ bool Parser::parseCompoundStatement(StatementAST *&node)
if (tk == T_RBRACE)
break;
- unsigned start_statement = cursor();
- StatementAST *statement = 0;
+ int start_statement = cursor();
+ StatementAST *statement = nullptr;
if (! parseStatement(statement)) {
rewind(start_statement + 1);
skipUntilStatement();
@@ -3876,8 +3876,8 @@ bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node)
bool Parser::parseDeclarationStatement(StatementAST *&node)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
- DeclarationAST *declaration = 0;
+ int start = cursor();
+ DeclarationAST *declaration = nullptr;
if (! parseBlockDeclaration(declaration))
return false;
@@ -3998,7 +3998,7 @@ bool Parser::parseAttributeSpecifier(SpecifierListAST *&attribute_list)
ast->align_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
- const unsigned saved = cursor();
+ const int saved = cursor();
if (!parseTypeId(ast->typeIdExprOrAlignmentExpr) ||
(LA() != T_RPAREN &&
(LA(1) != T_DOT_DOT_DOT || LA(2) != T_RPAREN))) {
@@ -4087,7 +4087,7 @@ bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node)
TypeofSpecifierAST *ast = new (_pool) TypeofSpecifierAST;
ast->typeof_token = consumeToken();
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
+ int lparen_token = consumeToken();
if (parseTypeId(ast->expression) && LA() == T_RPAREN) {
ast->lparen_token = lparen_token;
ast->rparen_token = consumeToken();
@@ -4122,7 +4122,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
const ASTCache::CacheKey cacheKey(cursor(), ASTCache::Declaration);
CHECK_CACHE(cacheKey.astKind, DeclarationAST);
- unsigned qt_invokable_token = 0;
+ int qt_invokable_token = 0;
if (declaringClass && (LA() == T_Q_SIGNAL || LA() == T_Q_SLOT || LA() == T_Q_INVOKABLE))
qt_invokable_token = consumeToken();
@@ -4130,9 +4130,9 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
// or a contructor declaration.
bool has_type_specifier = false;
bool has_complex_type_specifier = false;
- unsigned startOfNamedTypeSpecifier = 0;
- NameAST *named_type_specifier = 0;
- SpecifierListAST *decl_specifier_seq = 0,
+ int startOfNamedTypeSpecifier = 0;
+ NameAST *named_type_specifier = nullptr;
+ SpecifierListAST *decl_specifier_seq = nullptr,
**decl_specifier_seq_ptr = &decl_specifier_seq;
for (;;) {
if (lookAtCVQualifier() || lookAtFunctionSpecifier()
@@ -4174,7 +4174,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
break;
}
} else if (! has_type_specifier && LA() == T_ENUM) {
- unsigned startOfTypeSpecifier = cursor();
+ int startOfTypeSpecifier = cursor();
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)
|| LA() == T_LBRACE
|| (_languageFeatures.cxx11Enabled && LA() == T_COLON)) {
@@ -4188,7 +4188,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
has_type_specifier = true;
} else if (! has_type_specifier && LA() == T_TYPENAME) {
- unsigned startOfElaboratedTypeSpecifier = cursor();
+ int startOfElaboratedTypeSpecifier = cursor();
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) {
error(startOfElaboratedTypeSpecifier, "expected an elaborated type specifier");
break;
@@ -4196,7 +4196,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
has_type_specifier = true;
} else if (! has_type_specifier && lookAtClassKey()) {
- unsigned startOfTypeSpecifier = cursor();
+ int startOfTypeSpecifier = cursor();
if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) ||
(LA() == T_COLON || LA() == T_LBRACE
|| (LA(0) == T_IDENTIFIER && LA(1) == T_IDENTIFIER // MACRO Name followed by : or {
@@ -4216,22 +4216,22 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
break;
}
- DeclaratorListAST *declarator_list = 0,
+ DeclaratorListAST *declarator_list = nullptr,
**declarator_ptr = &declarator_list;
- DeclaratorAST *declarator = 0;
+ DeclaratorAST *declarator = nullptr;
if (LA() != T_SEMICOLON) {
const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier);
bool didParseInitDeclarator = parseInitDeclarator(declarator, decl_specifier_seq, declaringClass);
if ((! didParseInitDeclarator && maybeCtor) || (didParseInitDeclarator && maybeCtor && LA() == T_COLON)){
rewind(startOfNamedTypeSpecifier);
- named_type_specifier = 0;
+ named_type_specifier = nullptr;
// pop the named type specifier from the decl-specifier-seq
SpecifierListAST **spec_ptr = &decl_specifier_seq;
for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) {
if (! (*spec_ptr)->next) {
- *spec_ptr = 0;
+ *spec_ptr = nullptr;
break;
}
}
@@ -4258,7 +4258,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
- declarator = 0;
+ declarator = nullptr;
if (parseInitDeclarator(declarator, decl_specifier_seq, declaringClass)) {
*declarator_ptr = new (_pool) DeclaratorListAST;
(*declarator_ptr)->value = declarator;
@@ -4282,7 +4282,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
node = ast;
CACHE_AND_RETURN(cacheKey, true); // recognized a function definition.
} else {
- CtorInitializerAST *ctor_initializer = 0;
+ CtorInitializerAST *ctor_initializer = nullptr;
bool hasCtorInitializer = false;
if (LA() == T_COLON) {
@@ -4290,7 +4290,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *de
parseCtorInitializer(ctor_initializer);
if (LA() != T_LBRACE) {
- const unsigned pos = cursor();
+ const int pos = cursor();
for (int n = 0; n < 3 && LA(); consumeToken(), ++n)
if (LA() == T_LBRACE)
@@ -4339,7 +4339,7 @@ bool Parser::maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq
spec->asEnumSpecifier() ||
spec->asClassSpecifier()) {
for (it = it->next; it; it = it->next)
- if (it->value->asAttributeSpecifier() == 0)
+ if (it->value->asAttributeSpecifier() == nullptr)
return false;
return true;
}
@@ -4353,7 +4353,7 @@ bool Parser::parseFunctionBody(StatementAST *&node)
{
DEBUG_THIS_RULE();
if (_translationUnit->skipFunctionBody()) {
- unsigned token_lbrace = 0;
+ int token_lbrace = 0;
match(T_LBRACE, &token_lbrace);
if (! token_lbrace)
return false;
@@ -4361,7 +4361,7 @@ bool Parser::parseFunctionBody(StatementAST *&node)
const Token &tk = _translationUnit->tokenAt(token_lbrace);
if (tk.close_brace)
rewind(tk.close_brace);
- unsigned token_rbrace = 0;
+ int token_rbrace = 0;
match(T_RBRACE, &token_rbrace);
return true;
}
@@ -4391,12 +4391,12 @@ bool Parser::parseTryBlockStatement(StatementAST *&node, CtorInitializerAST **pl
ast->try_token = consumeToken();
// [ctor-initializer]
if (LA() == T_COLON) {
- const unsigned colonPos = cursor();
- CtorInitializerAST *ctor_initializer = 0;
+ const int colonPos = cursor();
+ CtorInitializerAST *ctor_initializer = nullptr;
parseCtorInitializer(ctor_initializer);
if (LA() != T_LBRACE) {
- const unsigned pos = cursor();
+ const int pos = cursor();
for (int n = 0; n < 3 && LA(); consumeToken(), ++n)
if (LA() == T_LBRACE)
@@ -4451,7 +4451,7 @@ bool Parser::parseExceptionDeclaration(ExceptionDeclarationAST *&node)
return true;
}
- SpecifierListAST *type_specifier = 0;
+ SpecifierListAST *type_specifier = nullptr;
if (parseTypeSpecifier(type_specifier)) {
ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST;
ast->type_specifier_list = type_specifier;
@@ -4554,7 +4554,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
// GNU extension: '(' '{' statement-list '}' ')'
CompoundExpressionAST *ast = new (_pool) CompoundExpressionAST;
ast->lparen_token = consumeToken();
- StatementAST *statement = 0;
+ StatementAST *statement = nullptr;
parseCompoundStatement(statement);
ast->statement = statement->asCompoundStatement();
match(T_RPAREN, &ast->rparen_token);
@@ -4569,7 +4569,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
return parseQtMethod(node);
case T_LBRACKET: {
- const unsigned lbracket_token = cursor();
+ const int lbracket_token = cursor();
if (_languageFeatures.cxx11Enabled) {
if (parseLambdaExpression(node))
@@ -4589,7 +4589,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
return parseObjCExpression(node);
default: {
- NameAST *name = 0;
+ NameAST *name = nullptr;
if (parseNameId(name)) {
IdExpressionAST *ast = new (_pool) IdExpressionAST;
ast->name = name;
@@ -4667,15 +4667,15 @@ bool Parser::parseObjCTryStatement(StatementAST *& /*node*/)
parseCompoundStatement(body_statment);
while (LA() == T_AT_CATCH) {
/*catch_token =*/ consumeToken();
- unsigned lparen_token;
+ int lparen_token;
match(T_LPAREN, &lparen_token);
if (LA() == T_DOT_DOT_DOT) {
- /*unsigned ellipsis_token =*/ consumeToken();
+ /*int ellipsis_token =*/ consumeToken();
} else {
ParameterDeclarationAST *exception_decl;
parseParameterDeclaration(exception_decl);
}
- unsigned rparen_token;
+ int rparen_token;
match(T_RPAREN, &rparen_token);
StatementAST *catch_statement;
parseCompoundStatement(catch_statement);
@@ -4720,7 +4720,7 @@ bool Parser::parseObjCThrowStatement(StatementAST *&/*node*/)
/*throw_token =*/ consumeToken();
ExpressionAST *thrown_expression;
parseExpression(thrown_expression);
- unsigned semicolon_token;
+ int semicolon_token;
match(T_SEMICOLON, &semicolon_token);
return true;
@@ -4764,7 +4764,7 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
ast->selector_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
- unsigned identifier_token = 0;
+ int identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
if (LA() == T_COLON) {
ObjCSelectorAST *args = new (_pool) ObjCSelectorAST;
@@ -4807,12 +4807,12 @@ bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
if (LA() != T_LBRACKET)
return false;
- unsigned start = cursor();
+ int start = cursor();
- unsigned lbracket_token = consumeToken();
- ExpressionAST *receiver_expression = 0;
- ObjCSelectorAST *selector = 0;
- ObjCMessageArgumentListAST *argument_list = 0;
+ int lbracket_token = consumeToken();
+ ExpressionAST *receiver_expression = nullptr;
+ ObjCSelectorAST *selector = nullptr;
+ ObjCMessageArgumentListAST *argument_list = nullptr;
if (parseObjCMessageReceiver(receiver_expression) &&
parseObjCMessageArguments(selector, argument_list)) {
@@ -4845,10 +4845,10 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
if (LA() == T_RBRACKET)
return false; // nothing to do.
- unsigned start = cursor();
+ int start = cursor();
- ObjCSelectorArgumentAST *selectorArgument = 0;
- ObjCMessageArgumentAST *messageArgument = 0;
+ ObjCSelectorArgumentAST *selectorArgument = nullptr;
+ ObjCMessageArgumentAST *messageArgument = nullptr;
if (parseObjCSelectorArg(selectorArgument, messageArgument)) {
ObjCSelectorArgumentListAST *selAst = new (_pool) ObjCSelectorArgumentListAST;
@@ -4890,7 +4890,7 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
return true;
} else {
rewind(start);
- unsigned name_token = 0;
+ int name_token = 0;
if (!parseObjCSelector(name_token))
return false;
ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
@@ -4898,7 +4898,7 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
sel->selector_argument_list->value->name_token = name_token;
selNode = sel;
- argNode = 0;
+ argNode = nullptr;
return true;
}
@@ -4908,7 +4908,7 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg
bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessageArgumentAST *&argNode)
{
DEBUG_THIS_RULE();
- unsigned selector_token = 0;
+ int selector_token = 0;
if (!parseObjCSelector(selector_token))
return false;
@@ -4921,7 +4921,7 @@ bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessage
argNode = new (_pool) ObjCMessageArgumentAST;
ExpressionAST **expr = &argNode->parameter_value_expression;
- unsigned expressionStart = cursor();
+ int expressionStart = cursor();
if (parseAssignmentExpression(*expr) && LA() == T_COLON && (*expr)->asCastExpression()) {
rewind(expressionStart);
parseUnaryExpression(*expr);
@@ -4933,7 +4933,7 @@ bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessage
bool Parser::parseNameId(NameAST *&name)
{
DEBUG_THIS_RULE();
- unsigned start = cursor();
+ int start = cursor();
if (! parseName(name))
return false;
@@ -4942,7 +4942,7 @@ bool Parser::parseNameId(NameAST *&name)
QualifiedNameAST *qualified_name_id = name->asQualifiedName();
- TemplateIdAST *template_id = 0;
+ TemplateIdAST *template_id = nullptr;
if (qualified_name_id) {
if (NameAST *unqualified_name = qualified_name_id->unqualified_name)
template_id = unqualified_name->asTemplateId();
@@ -4959,8 +4959,8 @@ bool Parser::parseNameId(NameAST *&name)
if (! template_arguments->next && template_arguments->value &&
template_arguments->value->asBinaryExpression()) {
- unsigned saved = cursor();
- ExpressionAST *expr = 0;
+ int saved = cursor();
+ ExpressionAST *expr = nullptr;
bool blocked = blockErrors(true);
bool lookAtCastExpression = parseCastExpression(expr);
@@ -4972,7 +4972,7 @@ bool Parser::parseNameId(NameAST *&name)
&& cast_expression->type_id && cast_expression->expression) {
rewind(start);
- name = 0;
+ name = nullptr;
return parseName(name, false);
}
}
@@ -5013,10 +5013,10 @@ bool Parser::parseNestedExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
+ int lparen_token = consumeToken();
bool previousTemplateArguments = switchTemplateArguments(false);
- ExpressionAST *expression = 0;
+ ExpressionAST *expression = nullptr;
if (parseExpression(expression) && LA() == T_RPAREN) {
NestedExpressionAST *ast = new (_pool) NestedExpressionAST;
ast->lparen_token = lparen_token;
@@ -5056,8 +5056,8 @@ bool Parser::parseTypenameCallExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_TYPENAME) {
- unsigned typename_token = consumeToken();
- NameAST *name = 0;
+ int typename_token = consumeToken();
+ NameAST *name = nullptr;
if (parseName(name)
&& (LA() == T_LPAREN || (_languageFeatures.cxx11Enabled && LA() == T_LBRACE))) {
TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST;
@@ -5085,7 +5085,7 @@ bool Parser::parseTypeidExpression(ExpressionAST *&node)
ast->typeid_token = consumeToken();
if (LA() == T_LPAREN)
ast->lparen_token = consumeToken();
- unsigned saved = cursor();
+ int saved = cursor();
if (! (parseTypeId(ast->expression) && LA() == T_RPAREN)) {
rewind(saved);
parseExpression(ast->expression);
@@ -5115,13 +5115,13 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
return parseTypeidExpression(node);
default: {
- unsigned start = cursor();
- SpecifierListAST *type_specifier = 0;
+ int start = cursor();
+ SpecifierListAST *type_specifier = nullptr;
bool blocked = blockErrors(true);
if (lookAtBuiltinTypeSpecifier() &&
parseSimpleTypeSpecifier(type_specifier) &&
(LA() == T_LPAREN || (_languageFeatures.cxx11Enabled && LA() == T_LBRACE))) {
- ExpressionAST *expr = 0;
+ ExpressionAST *expr = nullptr;
if (LA() == T_LPAREN) {
parseExpressionListParen(expr);
} else { // T_LBRACE
@@ -5138,10 +5138,10 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
// look for compound literals
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
- ExpressionAST *type_id = 0;
+ int lparen_token = consumeToken();
+ ExpressionAST *type_id = nullptr;
if (parseTypeId(type_id) && LA() == T_RPAREN) {
- unsigned rparen_token = consumeToken();
+ int rparen_token = consumeToken();
if (LA() == T_LBRACE) {
blockErrors(blocked);
@@ -5223,7 +5223,7 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
case T_PLUS:
case T_MINUS:
case T_EXCLAIM: {
- unsigned op = cursor();
+ int op = cursor();
UnaryExpressionAST *ast = new (_pool) UnaryExpressionAST;
ast->unary_op_token = consumeToken();
if (! parseCastExpression(ast->expression))
@@ -5253,7 +5253,7 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
ast->dot_dot_dot_token = consumeToken();
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
+ int lparen_token = consumeToken();
const bool blocked = blockErrors(true);
const bool hasTypeId = parseTypeId(ast->expression);
(void) blockErrors(blocked);
@@ -5281,7 +5281,7 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
ast->alignof_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
- ExpressionAST *temp = 0;
+ ExpressionAST *temp = nullptr;
parseTypeId(temp);
if (temp)
ast->typeId = temp->asTypeId();
@@ -5318,10 +5318,10 @@ bool Parser::parseExpressionListParen(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
- ExpressionListAST *expression_list = 0;
+ int lparen_token = consumeToken();
+ ExpressionListAST *expression_list = nullptr;
if (parseExpressionList(expression_list) && LA() == T_RPAREN) {
- unsigned rparen_token = consumeToken();
+ int rparen_token = consumeToken();
ExpressionListParenAST *ast = new (_pool) ExpressionListParenAST;
ast->lparen_token = lparen_token;
ast->expression_list = expression_list;
@@ -5351,12 +5351,12 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
ast->new_token = consumeToken();
- ExpressionAST *parenExpressionList = 0;
+ ExpressionAST *parenExpressionList = nullptr;
if (parseExpressionListParen(parenExpressionList)) {
- unsigned after_new_placement = cursor();
+ int after_new_placement = cursor();
- NewTypeIdAST *new_type_id = 0;
+ NewTypeIdAST *new_type_id = nullptr;
if (parseNewTypeId(new_type_id)) {
ast->new_placement = parenExpressionList->asExpressionListParen();
ast->new_type_id = new_type_id;
@@ -5368,8 +5368,8 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
rewind(after_new_placement);
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
- ExpressionAST *type_id = 0;
+ int lparen_token = consumeToken();
+ ExpressionAST *type_id = nullptr;
if (parseTypeId(type_id) && LA() == T_RPAREN) {
ast->new_placement = parenExpressionList->asExpressionListParen();
ast->lparen_token = lparen_token;
@@ -5385,8 +5385,8 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
rewind(ast->new_token + 1);
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
- ExpressionAST *type_id = 0;
+ int lparen_token = consumeToken();
+ ExpressionAST *type_id = nullptr;
if (parseTypeId(type_id) && LA() == T_RPAREN) {
ast->lparen_token = lparen_token;
ast->type_id = type_id;
@@ -5406,7 +5406,7 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
bool Parser::parseNewTypeId(NewTypeIdAST *&node)
{
DEBUG_THIS_RULE();
- SpecifierListAST *typeSpec = 0;
+ SpecifierListAST *typeSpec = nullptr;
if (! parseTypeSpecifier(typeSpec))
return false;
@@ -5479,9 +5479,9 @@ bool Parser::parseCastExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_LPAREN) {
- unsigned lparen_token = consumeToken();
- unsigned initialCursor = cursor();
- ExpressionAST *type_id = 0;
+ int lparen_token = consumeToken();
+ int initialCursor = cursor();
+ ExpressionAST *type_id = nullptr;
if (parseTypeId(type_id) && LA() == T_RPAREN) {
if (TypeIdAST *tid = type_id->asTypeId()) {
@@ -5493,10 +5493,10 @@ bool Parser::parseCastExpression(ExpressionAST *&node)
case T_PLUS_PLUS:
case T_MINUS_MINUS: {
- const unsigned rparen_token = consumeToken();
+ const int rparen_token = consumeToken();
const bool blocked = blockErrors(true);
- ExpressionAST *unary = 0;
+ ExpressionAST *unary = nullptr;
bool followedByUnaryExpression = parseUnaryExpression(unary);
blockErrors(blocked);
rewind(rparen_token);
@@ -5505,7 +5505,7 @@ bool Parser::parseCastExpression(ExpressionAST *&node)
if (! unary)
followedByUnaryExpression = false;
else if (UnaryExpressionAST *u = unary->asUnaryExpression())
- followedByUnaryExpression = u->expression != 0;
+ followedByUnaryExpression = u->expression != nullptr;
}
if (! followedByUnaryExpression)
@@ -5521,8 +5521,8 @@ bool Parser::parseCastExpression(ExpressionAST *&node)
}
}
- unsigned rparen_token = consumeToken();
- ExpressionAST *expression = 0;
+ int rparen_token = consumeToken();
+ ExpressionAST *expression = nullptr;
if (parseCastExpression(expression)) {
CastExpressionAST *ast = new (_pool) CastExpressionAST;
ast->lparen_token = lparen_token;
@@ -5535,7 +5535,7 @@ bool Parser::parseCastExpression(ExpressionAST *&node)
}
parse_as_unary_expression:
- _astCache->insert(ASTCache::TypeId, initialCursor, 0, cursor(), false);
+ _astCache->insert(ASTCache::TypeId, initialCursor, nullptr, cursor(), false);
rewind(lparen_token);
}
@@ -5618,7 +5618,7 @@ bool Parser::parseQtMethod(ExpressionAST *&node)
QtMethodAST *ast = new (_pool) QtMethodAST;
ast->method_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
- if (! parseDeclarator(ast->declarator, /*decl_specifier_seq =*/ 0))
+ if (! parseDeclarator(ast->declarator, /*decl_specifier_seq =*/ nullptr))
error(cursor(), "expected a function declarator before token `%s'", tok().spell());
match(T_RPAREN, &ast->rparen_token);
node = ast;
@@ -5637,7 +5637,7 @@ bool Parser::parseExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
CHECK_CACHE(ASTCache::Expression, ExpressionAST);
- unsigned initialCursor = cursor();
+ int initialCursor = cursor();
if (_expressionDepth > MAX_EXPRESSION_DEPTH)
return false;
@@ -5654,7 +5654,7 @@ void Parser::parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minP
{
DEBUG_THIS_RULE();
- unsigned iterations = 0;
+ int iterations = 0;
while (precedence(tok().kind(), _templateArguments) >= minPrecedence) {
if (++iterations > MAX_EXPRESSION_DEPTH) {
warning(cursor(), "Reached parse limit for expression");
@@ -5664,21 +5664,21 @@ void Parser::parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minP
const int operPrecedence = precedence(tok().kind(), _templateArguments);
const int oper = consumeToken();
- ConditionalExpressionAST *condExpr = 0;
+ ConditionalExpressionAST *condExpr = nullptr;
if (operPrecedence == Prec::Conditional) {
condExpr = new (_pool) ConditionalExpressionAST;
condExpr->question_token = oper;
if (tok().kind() == T_COLON) {
// GNU extension:
// logical-or-expression '?' ':' conditional-expression
- condExpr->left_expression = 0;
+ condExpr->left_expression = nullptr;
} else {
parseExpression(condExpr->left_expression);
}
match(T_COLON, &condExpr->colon_token);
}
- ExpressionAST *rhs = 0;
+ ExpressionAST *rhs = nullptr;
const bool isCPlusPlus = true;
if (operPrecedence <= Prec::Conditional && isCPlusPlus) {
// in C++ you can put a throw in the right-most expression of a conditional expression,
@@ -5783,8 +5783,8 @@ bool Parser::parseDesignatedInitializer(ExpressionAST *&node)
DesignatedInitializerAST *ast = new (_pool) DesignatedInitializerAST;
DesignatorListAST **designator_list_ptr = &ast->designator_list;
- DesignatorAST *designator = 0;
- const unsigned start = cursor();
+ DesignatorAST *designator = nullptr;
+ const int start = cursor();
while (parseDesignator(designator)) {
*designator_list_ptr = new (_pool) DesignatorListAST;
(*designator_list_ptr)->value = designator;
@@ -5817,7 +5817,7 @@ bool Parser::parseDesignatedInitializer(ExpressionAST *&node)
bool Parser::parseDesignator(DesignatorAST *&node)
{
DEBUG_THIS_RULE();
- const unsigned start = cursor();
+ const int start = cursor();
if (LA() == T_DOT) {
DotDesignatorAST *ast = new (_pool) DotDesignatorAST;
ast->dot_token = consumeToken();
@@ -5849,7 +5849,7 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
ObjCClassForwardDeclarationAST *ast = new (_pool) ObjCClassForwardDeclarationAST;
ast->class_token = consumeToken();
- unsigned identifier_token = 0;
+ int identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
ast->identifier_list = new (_pool) NameListAST;
@@ -5902,8 +5902,8 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
if (LA() != T_AT_INTERFACE)
return false;
- unsigned objc_interface_token = consumeToken();
- unsigned identifier_token = 0;
+ int objc_interface_token = consumeToken();
+ int identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
if (LA() == T_LPAREN) {
@@ -5931,7 +5931,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
parseObjCProtocolRefs(ast->protocol_refs);
DeclarationListAST **nextMembers = &ast->member_declaration_list;
- DeclarationAST *declaration = 0;
+ DeclarationAST *declaration = nullptr;
while (parseObjCInterfaceMemberDeclaration(declaration)) {
*nextMembers = new (_pool) DeclarationListAST;
(*nextMembers)->value = declaration;
@@ -5962,7 +5962,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
parseObjClassInstanceVariables(ast->inst_vars_decl);
DeclarationListAST **nextMembers = &ast->member_declaration_list;
- DeclarationAST *declaration = 0;
+ DeclarationAST *declaration = nullptr;
while (parseObjCInterfaceMemberDeclaration(declaration)) {
*nextMembers = new (_pool) DeclarationListAST;
(*nextMembers)->value = declaration;
@@ -5991,8 +5991,8 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
if (LA() != T_AT_PROTOCOL)
return false;
- unsigned protocol_token = consumeToken();
- unsigned identifier_token = 0;
+ int protocol_token = consumeToken();
+ int identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
if (LA() == T_COMMA || LA() == T_SEMICOLON) {
@@ -6033,7 +6033,7 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
parseObjCProtocolRefs(ast->protocol_refs);
DeclarationListAST **nextMembers = &ast->member_declaration_list;
- DeclarationAST *declaration = 0;
+ DeclarationAST *declaration = nullptr;
while (parseObjCInterfaceMemberDeclaration(declaration)) {
*nextMembers = new (_pool) DeclarationListAST;
(*nextMembers)->value = declaration;
@@ -6057,8 +6057,8 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
if (LA() != T_AT_IMPLEMENTATION)
return false;
- unsigned implementation_token = consumeToken();
- unsigned identifier_token = 0;
+ int implementation_token = consumeToken();
+ int identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
if (LA() == T_LPAREN) {
@@ -6110,8 +6110,8 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
DeclarationListAST **next = &node;
while (LA() && LA() != T_AT_END) {
- unsigned start = cursor();
- DeclarationAST *declaration = 0;
+ int start = cursor();
+ DeclarationAST *declaration = nullptr;
switch (LA()) {
case T_PLUS:
@@ -6213,7 +6213,7 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
bool Parser::parseObjCMethodDefinition(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
- ObjCMethodPrototypeAST *method_prototype = 0;
+ ObjCMethodPrototypeAST *method_prototype = nullptr;
if (! parseObjCMethodPrototype(method_prototype))
return false;
@@ -6245,7 +6245,7 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
match(T_LESS, &ast->less_token);
- unsigned identifier_token = 0;
+ int identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
ast->identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
@@ -6286,7 +6286,7 @@ bool Parser::parseObjClassInstanceVariables(ObjCInstanceVariablesDeclarationAST
if (LA() == T_RBRACE)
break;
- const unsigned start = cursor();
+ const int start = cursor();
*next = new (_pool) DeclarationListAST;
parseObjCInstanceVariableDeclaration((*next)->value);
@@ -6393,7 +6393,7 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAS
if (LA() == T_LPAREN) {
match(T_LPAREN, &ast->lparen_token);
- ObjCPropertyAttributeAST *property_attribute = 0;
+ ObjCPropertyAttributeAST *property_attribute = nullptr;
if (parseObjCPropertyAttribute(property_attribute)) {
ast->property_attribute_list = new (_pool) ObjCPropertyAttributeListAST;
ast->property_attribute_list->value = property_attribute;
@@ -6439,8 +6439,8 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
parseObjCTypeName(ast->type_name);
if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) {
- ObjCSelectorArgumentAST *argument = 0;
- ObjCMessageArgumentDeclarationAST *declaration = 0;
+ ObjCSelectorArgumentAST *argument = nullptr;
+ ObjCMessageArgumentDeclarationAST *declaration = nullptr;
parseObjCKeywordDeclaration(argument, declaration);
ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
@@ -6472,7 +6472,7 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
}
// TODO: Is this still valid, and if so, should it be stored in the AST? (EV)
- ParameterDeclarationAST *parameter_declaration = 0;
+ ParameterDeclarationAST *parameter_declaration = nullptr;
parseParameterDeclaration(parameter_declaration);
}
} else if (lookAtObjCSelector()) {
@@ -6568,7 +6568,7 @@ bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node)
// objc-selector ::= T_IDENTIFIER | keyword
//
-bool Parser::parseObjCSelector(unsigned &selector_token)
+bool Parser::parseObjCSelector(int &selector_token)
{
DEBUG_THIS_RULE();
if (! lookAtObjCSelector())
@@ -6605,7 +6605,7 @@ bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, Obj
return true;
}
-bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
+bool Parser::parseObjCTypeQualifiers(int &type_qualifier)
{
DEBUG_THIS_RULE();
if (LA() != T_IDENTIFIER)
@@ -6636,7 +6636,7 @@ bool Parser::peekAtObjCContextKeyword(int kind)
return k == kind;
}
-bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token)
+bool Parser::parseObjCContextKeyword(int kind, int &in_token)
{
DEBUG_THIS_RULE();
@@ -6661,7 +6661,7 @@ bool Parser::parseLambdaExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
- LambdaIntroducerAST *lambda_introducer = 0;
+ LambdaIntroducerAST *lambda_introducer = nullptr;
if (parseLambdaIntroducer(lambda_introducer)) {
LambdaExpressionAST *ast = new (_pool) LambdaExpressionAST;
ast->lambda_introducer = lambda_introducer;
@@ -6703,8 +6703,8 @@ bool Parser::parseLambdaCapture(LambdaCaptureAST *&node)
DEBUG_THIS_RULE();
bool startsWithDefaultCapture = false;
- unsigned default_capture = 0;
- CaptureListAST *capture_list = 0;
+ int default_capture = 0;
+ CaptureListAST *capture_list = nullptr;
if (LA() == T_AMPER || LA() == T_EQUAL) {
if (LA(2) == T_COMMA || LA(2) == T_RBRACKET) {
@@ -6758,7 +6758,7 @@ bool Parser::parseCaptureList(CaptureListAST *&node)
{
DEBUG_THIS_RULE();
- CaptureAST *capture = 0;
+ CaptureAST *capture = nullptr;
if (parseCapture(capture)) {
node = new (_pool) CaptureListAST;
@@ -6767,7 +6767,7 @@ bool Parser::parseCaptureList(CaptureListAST *&node)
CaptureListAST **l = &node->next;
while (LA() == T_COMMA) {
consumeToken(); // consume `,'
- CaptureAST *capture = 0;
+ CaptureAST *capture = nullptr;
parseCapture(capture);
if (capture) {
*l = new (_pool) CaptureListAST;
@@ -6828,21 +6828,21 @@ bool Parser::parseTrailingReturnType(TrailingReturnTypeAST *&node)
return true;
}
-void Parser::rewind(unsigned cursor)
+void Parser::rewind(int cursor)
{
#ifndef CPLUSPLUS_NO_DEBUG_RULE
if (cursor != _tokenIndex)
fprintf(stderr, "! rewinding from token %d to token %d\n", _tokenIndex, cursor);
#endif
- const unsigned n = _translationUnit->tokenCount();
+ const int n = _translationUnit->tokenCount();
if (cursor < n)
_tokenIndex = cursor;
else
_tokenIndex = n - 1;
}
-void Parser::warning(unsigned index, const char *format, ...)
+void Parser::warning(int index, const char *format, ...)
{
va_list args, ap;
va_start(args, format);
@@ -6852,7 +6852,7 @@ void Parser::warning(unsigned index, const char *format, ...)
va_end(args);
}
-void Parser::error(unsigned index, const char *format, ...)
+void Parser::error(int index, const char *format, ...)
{
va_list args, ap;
va_start(args, format);
@@ -6862,7 +6862,7 @@ void Parser::error(unsigned index, const char *format, ...)
va_end(args);
}
-void Parser::fatal(unsigned index, const char *format, ...)
+void Parser::fatal(int index, const char *format, ...)
{
va_list args, ap;
va_start(args, format);
diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h
index 110bb29d2b..750c590b40 100644
--- a/src/libs/3rdparty/cplusplus/Parser.h
+++ b/src/libs/3rdparty/cplusplus/Parser.h
@@ -72,14 +72,14 @@ public:
bool parseConstantExpression(ExpressionAST *&node);
bool parseCtorInitializer(CtorInitializerAST *&node);
bool parseCvQualifiers(SpecifierListAST *&node);
- bool parseRefQualifier(unsigned &ref_qualifier);
+ bool parseRefQualifier(int &ref_qualifier);
bool parseOverrideFinalQualifiers(SpecifierListAST *&node);
bool parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list);
bool parseDeclaration(DeclarationAST *&node);
- bool parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *declaringClass = 0);
+ bool parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *declaringClass = nullptr);
bool parseDeclarationStatement(StatementAST *&node);
bool parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass);
- bool parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass = 0);
+ bool parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass = nullptr);
bool parseDeleteExpression(ExpressionAST *&node);
bool parseDoStatement(StatementAST *&node);
bool parseElaboratedTypeSpecifier(SpecifierListAST *&node);
@@ -100,7 +100,7 @@ public:
bool parseInclusiveOrExpression(ExpressionAST *&node);
bool parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass);
bool parseInitializerList(ExpressionListAST *&node);
- bool parseInitializer(ExpressionAST *&node, unsigned *equals_token);
+ bool parseInitializer(ExpressionAST *&node, int *equals_token);
bool parseInitializerClause(ExpressionAST *&node);
bool parseLabeledStatement(StatementAST *&node);
bool parseLinkageBody(DeclarationAST *&node);
@@ -111,7 +111,7 @@ public:
bool parseMemInitializerList(MemInitializerListAST *&node);
bool parseMemberSpecification(DeclarationAST *&node, ClassSpecifierAST *declaringClass);
bool parseMultiplicativeExpression(ExpressionAST *&node);
- bool parseTemplateId(NameAST *&node, unsigned template_token = 0);
+ bool parseTemplateId(NameAST *&node, int template_token = 0);
bool parseClassOrNamespaceName(NameAST *&node);
bool parseNameId(NameAST *&node);
bool parseName(NameAST *&node, bool acceptTemplateId = true);
@@ -195,7 +195,7 @@ public:
bool parseQtMethod(ExpressionAST *&node);
// C++0x
- bool parseInitializer0x(ExpressionAST *&node, unsigned *equals_token);
+ bool parseInitializer0x(ExpressionAST *&node, int *equals_token);
bool parseBraceOrEqualInitializer0x(ExpressionAST *&node);
bool parseInitializerClause0x(ExpressionAST *&node);
bool parseInitializerList0x(ExpressionListAST *&node);
@@ -213,9 +213,9 @@ public:
bool parseObjCExpression(ExpressionAST *&node);
bool parseObjCClassForwardDeclaration(DeclarationAST *&node);
bool parseObjCInterface(DeclarationAST *&node,
- SpecifierListAST *attributes = 0);
+ SpecifierListAST *attributes = nullptr);
bool parseObjCProtocol(DeclarationAST *&node,
- SpecifierListAST *attributes = 0);
+ SpecifierListAST *attributes = nullptr);
bool parseObjCTryStatement(StatementAST *&node);
bool parseObjCSynchronizedStatement(StatementAST *&node);
@@ -236,16 +236,16 @@ public:
bool parseObjCInterfaceMemberDeclaration(DeclarationAST *&node);
bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node);
bool parseObjCPropertyDeclaration(DeclarationAST *&node,
- SpecifierListAST *attributes = 0);
+ SpecifierListAST *attributes = nullptr);
bool parseObjCImplementation(DeclarationAST *&node);
bool parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node);
bool parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node);
bool parseObjCTypeName(ObjCTypeNameAST *&node);
- bool parseObjCSelector(unsigned &selector_token);
+ bool parseObjCSelector(int &selector_token);
bool parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, ObjCMessageArgumentDeclarationAST *&node);
- bool parseObjCTypeQualifiers(unsigned &type_qualifier);
+ bool parseObjCTypeQualifiers(int &type_qualifier);
bool peekAtObjCContextKeyword(int kind);
- bool parseObjCContextKeyword(int kind, unsigned &in_token);
+ bool parseObjCContextKeyword(int kind, int &in_token);
bool lookAtObjCSelector() const;
@@ -269,7 +269,7 @@ public:
const Identifier *className(ClassSpecifierAST *ast) const;
const Identifier *identifier(NameAST *name) const;
- void match(int kind, unsigned *token);
+ void match(int kind, int *token);
bool maybeAmbiguousStatement(DeclarationStatementAST *ast, StatementAST *&node);
bool maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const;
@@ -280,9 +280,9 @@ public:
bool maybeSplitGreaterGreaterToken(int n = 1);
bool blockErrors(bool block) { return _translationUnit->blockErrors(block); }
- void warning(unsigned index, const char *format, ...);
- void error(unsigned index, const char *format, ...);
- void fatal(unsigned index, const char *format, ...);
+ void warning(int index, const char *format, ...);
+ void error(int index, const char *format, ...);
+ void fatal(int index, const char *format, ...);
inline const Token &tok(int i = 1) const
{ return _translationUnit->tokenAt(_tokenIndex + i - 1); }
@@ -293,21 +293,21 @@ public:
inline int consumeToken()
{ return _tokenIndex++; }
- inline unsigned cursor() const
+ inline int cursor() const
{ return _tokenIndex; }
- void rewind(unsigned cursor);
+ void rewind(int cursor);
struct TemplateArgumentListEntry {
- unsigned index;
- unsigned cursor;
+ int index;
+ int cursor;
ExpressionListAST *ast;
- TemplateArgumentListEntry(unsigned index = 0, unsigned cursor = 0, ExpressionListAST *ast = 0)
+ TemplateArgumentListEntry(int index = 0, int cursor = 0, ExpressionListAST *ast = nullptr)
: index(index), cursor(cursor), ast(ast) {}
};
- TemplateArgumentListEntry *templateArgumentListEntry(unsigned tokenIndex);
+ TemplateArgumentListEntry *templateArgumentListEntry(int tokenIndex);
void clearTemplateArgumentList() { _templateArgumentList.clear(); }
private:
@@ -315,7 +315,7 @@ private:
Control *_control;
MemoryPool *_pool;
LanguageFeatures _languageFeatures;
- unsigned _tokenIndex;
+ int _tokenIndex;
bool _templateArguments: 1;
bool _inFunctionBody: 1;
bool _inExpressionStatement: 1;
@@ -324,7 +324,7 @@ private:
std::stack<int> _initializerClauseDepth;
MemoryPool _expressionStatementTempPool;
- std::map<unsigned, TemplateArgumentListEntry> _templateArgumentList;
+ std::map<int, TemplateArgumentListEntry> _templateArgumentList;
class ASTCache;
ASTCache *_astCache;
diff --git a/src/libs/3rdparty/cplusplus/Scope.cpp b/src/libs/3rdparty/cplusplus/Scope.cpp
index 406a794c7e..43d8c98965 100644
--- a/src/libs/3rdparty/cplusplus/Scope.cpp
+++ b/src/libs/3rdparty/cplusplus/Scope.cpp
@@ -40,7 +40,7 @@ public:
public:
/// Constructs an empty Scope.
- SymbolTable(Scope *owner = 0);
+ SymbolTable(Scope *owner = nullptr);
/// Destroy this scope.
~SymbolTable();
@@ -58,10 +58,10 @@ public:
bool isEmpty() const;
/// Returns the number of symbols is in the scope.
- unsigned symbolCount() const;
+ int symbolCount() const;
/// Returns the Symbol at the given position.
- Symbol *symbolAt(unsigned index) const;
+ Symbol *symbolAt(int index) const;
/// Returns the first Symbol in the scope.
iterator firstSymbol() const;
@@ -92,8 +92,8 @@ private:
SymbolTable::SymbolTable(Scope *owner)
: _owner(owner),
- _symbols(0),
- _hash(0),
+ _symbols(nullptr),
+ _hash(nullptr),
_allocatedSymbols(0),
_symbolCount(-1),
_hashSize(0)
@@ -136,7 +136,7 @@ void SymbolTable::enterSymbol(Symbol *symbol)
Symbol *SymbolTable::lookat(const Identifier *id) const
{
if (! _hash || ! id)
- return 0;
+ return nullptr;
const unsigned h = id->hashCode() % _hashSize;
Symbol *symbol = _hash[h];
@@ -154,7 +154,7 @@ Symbol *SymbolTable::lookat(const Identifier *id) const
if (d->identifier()->match(id))
break;
} else if (identity->isQualifiedNameId()) {
- return 0;
+ return nullptr;
} else if (const SelectorNameId *selectorNameId = identity->asSelectorNameId()) {
if (selectorNameId->identifier()->match(id))
break;
@@ -166,7 +166,7 @@ Symbol *SymbolTable::lookat(const Identifier *id) const
Symbol *SymbolTable::lookat(OperatorNameId::Kind operatorId) const
{
if (! _hash)
- return 0;
+ return nullptr;
const unsigned h = operatorId % _hashSize;
Symbol *symbol = _hash[h];
@@ -210,13 +210,13 @@ unsigned SymbolTable::hashValue(Symbol *symbol) const
bool SymbolTable::isEmpty() const
{ return _symbolCount == -1; }
-unsigned SymbolTable::symbolCount() const
+int SymbolTable::symbolCount() const
{ return _symbolCount + 1; }
-Symbol *SymbolTable::symbolAt(unsigned index) const
+Symbol *SymbolTable::symbolAt(int index) const
{
if (! _symbols)
- return 0;
+ return nullptr;
return _symbols[index];
}
@@ -226,16 +226,16 @@ SymbolTable::iterator SymbolTable::firstSymbol() const
SymbolTable::iterator SymbolTable::lastSymbol() const
{ return _symbols + _symbolCount + 1; }
-Scope::Scope(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Scope::Scope(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name),
- _members(0),
+ _members(nullptr),
_startOffset(0),
_endOffset(0)
{ }
Scope::Scope(Clone *clone, Subst *subst, Scope *original)
: Symbol(clone, subst, original)
- , _members(0)
+ , _members(nullptr)
, _startOffset(original->_startOffset)
, _endOffset(original->_endOffset)
{
@@ -260,39 +260,39 @@ bool Scope::isEmpty() const
{ return _members ? _members->isEmpty() : true; }
/// Returns the number of symbols is in the scope.
-unsigned Scope::memberCount() const
+int Scope::memberCount() const
{ return _members ? _members->symbolCount() : 0; }
/// Returns the Symbol at the given position.
-Symbol *Scope::memberAt(unsigned index) const
-{ return _members ? _members->symbolAt(index) : 0; }
+Symbol *Scope::memberAt(int index) const
+{ return _members ? _members->symbolAt(index) : nullptr; }
/// Returns the first Symbol in the scope.
Scope::iterator Scope::memberBegin() const
-{ return _members ? _members->firstSymbol() : 0; }
+{ return _members ? _members->firstSymbol() : nullptr; }
/// Returns the last Symbol in the scope.
Scope::iterator Scope::memberEnd() const
-{ return _members ? _members->lastSymbol() : 0; }
+{ return _members ? _members->lastSymbol() : nullptr; }
Symbol *Scope::find(const Identifier *id) const
-{ return _members ? _members->lookat(id) : 0; }
+{ return _members ? _members->lookat(id) : nullptr; }
Symbol *Scope::find(OperatorNameId::Kind operatorId) const
-{ return _members ? _members->lookat(operatorId) : 0; }
+{ return _members ? _members->lookat(operatorId) : nullptr; }
/// Set the start offset of the scope
-unsigned Scope::startOffset() const
+int Scope::startOffset() const
{ return _startOffset; }
-void Scope::setStartOffset(unsigned offset)
+void Scope::setStartOffset(int offset)
{ _startOffset = offset; }
/// Set the end offset of the scope
-unsigned Scope::endOffset() const
+int Scope::endOffset() const
{ return _endOffset; }
-void Scope::setEndOffset(unsigned offset)
+void Scope::setEndOffset(int offset)
{ _endOffset = offset; }
} // namespace CPlusPlus
diff --git a/src/libs/3rdparty/cplusplus/Scope.h b/src/libs/3rdparty/cplusplus/Scope.h
index 01a5b7450d..c3b2a6ca37 100644
--- a/src/libs/3rdparty/cplusplus/Scope.h
+++ b/src/libs/3rdparty/cplusplus/Scope.h
@@ -29,7 +29,7 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT Scope: public Symbol
{
public:
- Scope(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Scope(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Scope(Clone *clone, Subst *subst, Scope *original);
virtual ~Scope();
@@ -40,10 +40,10 @@ public:
bool isEmpty() const;
/// Returns the number of symbols is in the scope.
- unsigned memberCount() const;
+ int memberCount() const;
/// Returns the Symbol at the given position.
- Symbol *memberAt(unsigned index) const;
+ Symbol *memberAt(int index) const;
typedef Symbol **iterator;
@@ -57,12 +57,12 @@ public:
Symbol *find(OperatorNameId::Kind operatorId) const;
/// Set the start offset of the scope
- unsigned startOffset() const;
- void setStartOffset(unsigned offset);
+ int startOffset() const;
+ void setStartOffset(int offset);
/// Set the end offset of the scope
- unsigned endOffset() const;
- void setEndOffset(unsigned offset);
+ int endOffset() const;
+ void setEndOffset(int offset);
virtual const Scope *asScope() const
{ return this; }
@@ -72,8 +72,8 @@ public:
private:
SymbolTable *_members;
- unsigned _startOffset;
- unsigned _endOffset;
+ int _startOffset;
+ int _endOffset;
};
} // namespace CPlusPlus
diff --git a/src/libs/3rdparty/cplusplus/Symbol.cpp b/src/libs/3rdparty/cplusplus/Symbol.cpp
index e9c7edb0dc..62100474b4 100644
--- a/src/libs/3rdparty/cplusplus/Symbol.cpp
+++ b/src/libs/3rdparty/cplusplus/Symbol.cpp
@@ -86,11 +86,11 @@ private:
unsigned _value;
};
-Symbol::Symbol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
- : _name(0),
- _enclosingScope(0),
- _next(0),
- _fileId(0),
+Symbol::Symbol(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
+ : _name(nullptr),
+ _enclosingScope(nullptr),
+ _next(nullptr),
+ _fileId(nullptr),
_sourceLocation(0),
_hashCode(0),
_storage(Symbol::NoStorage),
@@ -108,8 +108,8 @@ Symbol::Symbol(TranslationUnit *translationUnit, unsigned sourceLocation, const
Symbol::Symbol(Clone *clone, Subst *subst, Symbol *original)
: _name(clone->name(original->_name, subst)),
- _enclosingScope(0),
- _next(0),
+ _enclosingScope(nullptr),
+ _next(nullptr),
_fileId(clone->control()->stringLiteral(original->fileName(), original->fileNameLength())),
_sourceLocation(original->_sourceLocation),
_hashCode(original->_hashCode),
@@ -142,7 +142,7 @@ void Symbol::visitSymbol(Symbol *symbol, SymbolVisitor *visitor)
symbol->visitSymbol(visitor);
}
-unsigned Symbol::sourceLocation() const
+int Symbol::sourceLocation() const
{ return _sourceLocation; }
bool Symbol::isGenerated() const
@@ -160,7 +160,7 @@ bool Symbol::isUnavailable() const
void Symbol::setUnavailable(bool isUnavailable)
{ _isUnavailable = isUnavailable; }
-void Symbol::setSourceLocation(unsigned sourceLocation, TranslationUnit *translationUnit)
+void Symbol::setSourceLocation(int sourceLocation, TranslationUnit *translationUnit)
{
_sourceLocation = sourceLocation;
@@ -172,16 +172,16 @@ void Symbol::setSourceLocation(unsigned sourceLocation, TranslationUnit *transla
_isGenerated = false;
_line = 0;
_column = 0;
- _fileId = 0;
+ _fileId = nullptr;
}
}
-unsigned Symbol::line() const
+int Symbol::line() const
{
return _line;
}
-unsigned Symbol::column() const
+int Symbol::column() const
{
return _column;
}
@@ -194,13 +194,13 @@ const StringLiteral *Symbol::fileId() const
const char *Symbol::fileName() const
{ return _fileId ? _fileId->chars() : ""; }
-unsigned Symbol::fileNameLength() const
+int Symbol::fileNameLength() const
{ return _fileId ? _fileId->size() : 0; }
const Name *Symbol::unqualifiedName() const
{
if (! _name)
- return 0;
+ return nullptr;
else if (const QualifiedNameId *q = _name->asQualifiedNameId())
return q->name();
@@ -228,7 +228,7 @@ const Identifier *Symbol::identifier() const
if (_name)
return _name->identifier();
- return 0;
+ return nullptr;
}
Scope *Symbol::enclosingScope() const
@@ -242,7 +242,7 @@ void Symbol::setEnclosingScope(Scope *scope)
void Symbol::resetEnclosingScope()
{
- _enclosingScope = 0;
+ _enclosingScope = nullptr;
}
Namespace *Symbol::enclosingNamespace() const
@@ -251,7 +251,7 @@ Namespace *Symbol::enclosingNamespace() const
if (Namespace *ns = s->asNamespace())
return ns;
}
- return 0;
+ return nullptr;
}
Template *Symbol::enclosingTemplate() const
@@ -260,7 +260,7 @@ Template *Symbol::enclosingTemplate() const
if (Template *templ = s->asTemplate())
return templ;
}
- return 0;
+ return nullptr;
}
Class *Symbol::enclosingClass() const
@@ -269,7 +269,7 @@ Class *Symbol::enclosingClass() const
if (Class *klass = s->asClass())
return klass;
}
- return 0;
+ return nullptr;
}
Enum *Symbol::enclosingEnum() const
@@ -278,7 +278,7 @@ Enum *Symbol::enclosingEnum() const
if (Enum *e = s->asEnum())
return e;
}
- return 0;
+ return nullptr;
}
Function *Symbol::enclosingFunction() const
@@ -287,7 +287,7 @@ Function *Symbol::enclosingFunction() const
if (Function *fun = s->asFunction())
return fun;
}
- return 0;
+ return nullptr;
}
Block *Symbol::enclosingBlock() const
@@ -296,7 +296,7 @@ Block *Symbol::enclosingBlock() const
if (Block *block = s->asBlock())
return block;
}
- return 0;
+ return nullptr;
}
unsigned Symbol::index() const
@@ -348,76 +348,76 @@ bool Symbol::isPrivate() const
{ return _visibility == Private; }
bool Symbol::isScope() const
-{ return asScope() != 0; }
+{ return asScope() != nullptr; }
bool Symbol::isEnum() const
-{ return asEnum() != 0; }
+{ return asEnum() != nullptr; }
bool Symbol::isFunction() const
-{ return asFunction() != 0; }
+{ return asFunction() != nullptr; }
bool Symbol::isNamespace() const
-{ return asNamespace() != 0; }
+{ return asNamespace() != nullptr; }
bool Symbol::isTemplate() const
-{ return asTemplate() != 0; }
+{ return asTemplate() != nullptr; }
bool Symbol::isClass() const
-{ return asClass() != 0; }
+{ return asClass() != nullptr; }
bool Symbol::isForwardClassDeclaration() const
-{ return asForwardClassDeclaration() != 0; }
+{ return asForwardClassDeclaration() != nullptr; }
bool Symbol::isQtPropertyDeclaration() const
-{ return asQtPropertyDeclaration() != 0; }
+{ return asQtPropertyDeclaration() != nullptr; }
bool Symbol::isQtEnum() const
-{ return asQtEnum() != 0; }
+{ return asQtEnum() != nullptr; }
bool Symbol::isBlock() const
-{ return asBlock() != 0; }
+{ return asBlock() != nullptr; }
bool Symbol::isUsingNamespaceDirective() const
-{ return asUsingNamespaceDirective() != 0; }
+{ return asUsingNamespaceDirective() != nullptr; }
bool Symbol::isUsingDeclaration() const
-{ return asUsingDeclaration() != 0; }
+{ return asUsingDeclaration() != nullptr; }
bool Symbol::isDeclaration() const
-{ return asDeclaration() != 0; }
+{ return asDeclaration() != nullptr; }
bool Symbol::isArgument() const
-{ return asArgument() != 0; }
+{ return asArgument() != nullptr; }
bool Symbol::isTypenameArgument() const
-{ return asTypenameArgument() != 0; }
+{ return asTypenameArgument() != nullptr; }
bool Symbol::isBaseClass() const
-{ return asBaseClass() != 0; }
+{ return asBaseClass() != nullptr; }
bool Symbol::isObjCBaseClass() const
-{ return asObjCBaseClass() != 0; }
+{ return asObjCBaseClass() != nullptr; }
bool Symbol::isObjCBaseProtocol() const
-{ return asObjCBaseProtocol() != 0; }
+{ return asObjCBaseProtocol() != nullptr; }
bool Symbol::isObjCClass() const
-{ return asObjCClass() != 0; }
+{ return asObjCClass() != nullptr; }
bool Symbol::isObjCForwardClassDeclaration() const
-{ return asObjCForwardClassDeclaration() != 0; }
+{ return asObjCForwardClassDeclaration() != nullptr; }
bool Symbol::isObjCProtocol() const
-{ return asObjCProtocol() != 0; }
+{ return asObjCProtocol() != nullptr; }
bool Symbol::isObjCForwardProtocolDeclaration() const
-{ return asObjCForwardProtocolDeclaration() != 0; }
+{ return asObjCForwardProtocolDeclaration() != nullptr; }
bool Symbol::isObjCMethod() const
-{ return asObjCMethod() != 0; }
+{ return asObjCMethod() != nullptr; }
bool Symbol::isObjCPropertyDeclaration() const
-{ return asObjCPropertyDeclaration() != 0; }
+{ return asObjCPropertyDeclaration() != nullptr; }
void Symbol::copy(Symbol *other)
{
@@ -439,10 +439,10 @@ void Symbol::copy(Symbol *other)
Utils::Link Symbol::toLink() const
{
- const QString filename = QString::fromUtf8(fileName(), static_cast<int>(fileNameLength()));
+ const QString filename = QString::fromUtf8(fileName(), fileNameLength());
- int line = static_cast<int>(this->line());
- int column = static_cast<int>(this->column());
+ int line = this->line();
+ int column = this->column();
if (column)
--column;
diff --git a/src/libs/3rdparty/cplusplus/Symbol.h b/src/libs/3rdparty/cplusplus/Symbol.h
index e4c8eea152..ae441b339b 100644
--- a/src/libs/3rdparty/cplusplus/Symbol.h
+++ b/src/libs/3rdparty/cplusplus/Symbol.h
@@ -54,20 +54,20 @@ public:
public:
/// Constructs a Symbol with the given source location, name and translation unit.
- Symbol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Symbol(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Symbol(Clone *clone, Subst *subst, Symbol *original);
/// Destroy this Symbol.
virtual ~Symbol();
/// Returns this Symbol's source location.
- unsigned sourceLocation() const;
+ int sourceLocation() const;
/// \returns this Symbol's line number. The line number is 1-based.
- unsigned line() const;
+ int line() const;
/// \returns this Symbol's column number. The column number is 1-based.
- unsigned column() const;
+ int column() const;
/// Returns this Symbol's file name.
const StringLiteral *fileId() const;
@@ -76,7 +76,7 @@ public:
const char *fileName() const;
/// Returns this Symbol's file name length.
- unsigned fileNameLength() const;
+ int fileNameLength() const;
/// Returns this Symbol's name.
const Name *name() const;
@@ -200,57 +200,57 @@ public:
Utils::Link toLink() const;
- virtual const Scope *asScope() const { return 0; }
- virtual const Enum *asEnum() const { return 0; }
- virtual const Function *asFunction() const { return 0; }
- virtual const Namespace *asNamespace() const { return 0; }
- virtual const Template *asTemplate() const { return 0; }
- virtual const NamespaceAlias *asNamespaceAlias() const { return 0; }
- virtual const Class *asClass() const { return 0; }
- virtual const Block *asBlock() const { return 0; }
- virtual const UsingNamespaceDirective *asUsingNamespaceDirective() const { return 0; }
- virtual const UsingDeclaration *asUsingDeclaration() const { return 0; }
- virtual const Declaration *asDeclaration() const { return 0; }
- virtual const Argument *asArgument() const { return 0; }
- virtual const TypenameArgument *asTypenameArgument() const { return 0; }
- virtual const BaseClass *asBaseClass() const { return 0; }
- virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return 0; }
- virtual const QtPropertyDeclaration *asQtPropertyDeclaration() const { return 0; }
- virtual const QtEnum *asQtEnum() const { return 0; }
- virtual const ObjCBaseClass *asObjCBaseClass() const { return 0; }
- virtual const ObjCBaseProtocol *asObjCBaseProtocol() const { return 0; }
- virtual const ObjCClass *asObjCClass() const { return 0; }
- virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const { return 0; }
- virtual const ObjCProtocol *asObjCProtocol() const { return 0; }
- virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return 0; }
- virtual const ObjCMethod *asObjCMethod() const { return 0; }
- virtual const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const { return 0; }
-
- virtual Scope *asScope() { return 0; }
- virtual Enum *asEnum() { return 0; }
- virtual Function *asFunction() { return 0; }
- virtual Namespace *asNamespace() { return 0; }
- virtual Template *asTemplate() { return 0; }
- virtual NamespaceAlias *asNamespaceAlias() { return 0; }
- virtual Class *asClass() { return 0; }
- virtual Block *asBlock() { return 0; }
- virtual UsingNamespaceDirective *asUsingNamespaceDirective() { return 0; }
- virtual UsingDeclaration *asUsingDeclaration() { return 0; }
- virtual Declaration *asDeclaration() { return 0; }
- virtual Argument *asArgument() { return 0; }
- virtual TypenameArgument *asTypenameArgument() { return 0; }
- virtual BaseClass *asBaseClass() { return 0; }
- virtual ForwardClassDeclaration *asForwardClassDeclaration() { return 0; }
- virtual QtPropertyDeclaration *asQtPropertyDeclaration() { return 0; }
- virtual QtEnum *asQtEnum() { return 0; }
- virtual ObjCBaseClass *asObjCBaseClass() { return 0; }
- virtual ObjCBaseProtocol *asObjCBaseProtocol() { return 0; }
- virtual ObjCClass *asObjCClass() { return 0; }
- virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() { return 0; }
- virtual ObjCProtocol *asObjCProtocol() { return 0; }
- virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return 0; }
- virtual ObjCMethod *asObjCMethod() { return 0; }
- virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() { return 0; }
+ virtual const Scope *asScope() const { return nullptr; }
+ virtual const Enum *asEnum() const { return nullptr; }
+ virtual const Function *asFunction() const { return nullptr; }
+ virtual const Namespace *asNamespace() const { return nullptr; }
+ virtual const Template *asTemplate() const { return nullptr; }
+ virtual const NamespaceAlias *asNamespaceAlias() const { return nullptr; }
+ virtual const Class *asClass() const { return nullptr; }
+ virtual const Block *asBlock() const { return nullptr; }
+ virtual const UsingNamespaceDirective *asUsingNamespaceDirective() const { return nullptr; }
+ virtual const UsingDeclaration *asUsingDeclaration() const { return nullptr; }
+ virtual const Declaration *asDeclaration() const { return nullptr; }
+ virtual const Argument *asArgument() const { return nullptr; }
+ virtual const TypenameArgument *asTypenameArgument() const { return nullptr; }
+ virtual const BaseClass *asBaseClass() const { return nullptr; }
+ virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return nullptr; }
+ virtual const QtPropertyDeclaration *asQtPropertyDeclaration() const { return nullptr; }
+ virtual const QtEnum *asQtEnum() const { return nullptr; }
+ virtual const ObjCBaseClass *asObjCBaseClass() const { return nullptr; }
+ virtual const ObjCBaseProtocol *asObjCBaseProtocol() const { return nullptr; }
+ virtual const ObjCClass *asObjCClass() const { return nullptr; }
+ virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const { return nullptr; }
+ virtual const ObjCProtocol *asObjCProtocol() const { return nullptr; }
+ virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return nullptr; }
+ virtual const ObjCMethod *asObjCMethod() const { return nullptr; }
+ virtual const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const { return nullptr; }
+
+ virtual Scope *asScope() { return nullptr; }
+ virtual Enum *asEnum() { return nullptr; }
+ virtual Function *asFunction() { return nullptr; }
+ virtual Namespace *asNamespace() { return nullptr; }
+ virtual Template *asTemplate() { return nullptr; }
+ virtual NamespaceAlias *asNamespaceAlias() { return nullptr; }
+ virtual Class *asClass() { return nullptr; }
+ virtual Block *asBlock() { return nullptr; }
+ virtual UsingNamespaceDirective *asUsingNamespaceDirective() { return nullptr; }
+ virtual UsingDeclaration *asUsingDeclaration() { return nullptr; }
+ virtual Declaration *asDeclaration() { return nullptr; }
+ virtual Argument *asArgument() { return nullptr; }
+ virtual TypenameArgument *asTypenameArgument() { return nullptr; }
+ virtual BaseClass *asBaseClass() { return nullptr; }
+ virtual ForwardClassDeclaration *asForwardClassDeclaration() { return nullptr; }
+ virtual QtPropertyDeclaration *asQtPropertyDeclaration() { return nullptr; }
+ virtual QtEnum *asQtEnum() { return nullptr; }
+ virtual ObjCBaseClass *asObjCBaseClass() { return nullptr; }
+ virtual ObjCBaseProtocol *asObjCBaseProtocol() { return nullptr; }
+ virtual ObjCClass *asObjCClass() { return nullptr; }
+ virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() { return nullptr; }
+ virtual ObjCProtocol *asObjCProtocol() { return nullptr; }
+ virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return nullptr; }
+ virtual ObjCMethod *asObjCMethod() { return nullptr; }
+ virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() { return nullptr; }
/// Returns this Symbol's type.
virtual FullySpecifiedType type() const = 0;
@@ -294,7 +294,7 @@ public:
void setEnclosingScope(Scope *enclosingScope); // ### make me private
void resetEnclosingScope(); // ### make me private
- void setSourceLocation(unsigned sourceLocation, TranslationUnit *translationUnit); // ### make me private
+ void setSourceLocation(int sourceLocation, TranslationUnit *translationUnit); // ### make me private
void visitSymbol(SymbolVisitor *visitor);
static void visitSymbol(Symbol *symbol, SymbolVisitor *visitor);
@@ -309,13 +309,13 @@ private:
Scope *_enclosingScope;
Symbol *_next;
const StringLiteral *_fileId;
- unsigned _sourceLocation;
+ int _sourceLocation;
unsigned _hashCode;
int _storage;
int _visibility;
- unsigned _index;
- unsigned _line;
- unsigned _column;
+ int _index;
+ int _line;
+ int _column;
bool _isGenerated: 1;
bool _isDeprecated: 1;
diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp
index 8ce7cb8a73..a895f7ed6c 100644
--- a/src/libs/3rdparty/cplusplus/Symbols.cpp
+++ b/src/libs/3rdparty/cplusplus/Symbols.cpp
@@ -34,7 +34,7 @@
using namespace CPlusPlus;
UsingNamespaceDirective::UsingNamespaceDirective(TranslationUnit *translationUnit,
- unsigned sourceLocation, const Name *name)
+ int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
{ }
@@ -52,8 +52,8 @@ void UsingNamespaceDirective::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
NamespaceAlias::NamespaceAlias(TranslationUnit *translationUnit,
- unsigned sourceLocation, const Name *name)
- : Symbol(translationUnit, sourceLocation, name), _namespaceName(0)
+ int sourceLocation, const Name *name)
+ : Symbol(translationUnit, sourceLocation, name), _namespaceName(nullptr)
{ }
NamespaceAlias::NamespaceAlias(Clone *clone, Subst *subst, NamespaceAlias *original)
@@ -78,7 +78,7 @@ void NamespaceAlias::visitSymbol0(SymbolVisitor *visitor)
UsingDeclaration::UsingDeclaration(TranslationUnit *translationUnit,
- unsigned sourceLocation, const Name *name)
+ int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
{ }
@@ -95,9 +95,9 @@ FullySpecifiedType UsingDeclaration::type() const
void UsingDeclaration::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-Declaration::Declaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Declaration::Declaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
- , _initializer(0)
+ , _initializer(nullptr)
{ }
Declaration::Declaration(Clone *clone, Subst *subst, Declaration *original)
@@ -158,7 +158,7 @@ Declaration::Declaration(Clone *clone, Subst *subst, Declaration *original)
std::strcmp(enNamespaceNameId, "__cxx11") == 0) {
if (std::strcmp(enClassNameId, "unique_ptr") == 0) {
if (std::strcmp(nameId, "pointer") == 0) {
- newType = clone->type(subst->apply(firstTemplParamName), 0);
+ newType = clone->type(subst->apply(firstTemplParamName), nullptr);
newType = FullySpecifiedType(clone->control()->pointerType(newType));
}
} else if (std::strcmp(enClassNameId, "list") == 0 ||
@@ -172,12 +172,12 @@ Declaration::Declaration(Clone *clone, Subst *subst, Declaration *original)
std::strcmp(enClassNameId, "array") == 0) {
if (std::strcmp(nameId, "reference") == 0 ||
std::strcmp(nameId, "const_reference") == 0) {
- newType = clone->type(subst->apply(firstTemplParamName), 0);
+ newType = clone->type(subst->apply(firstTemplParamName), nullptr);
} else if (std::strcmp(nameId, "iterator") == 0 ||
std::strcmp(nameId, "reverse_iterator") == 0 ||
std::strcmp(nameId, "const_reverse_iterator") == 0 ||
std::strcmp(nameId, "const_iterator") == 0) {
- newType = clone->type(subst->apply(firstTemplParamName), 0);
+ newType = clone->type(subst->apply(firstTemplParamName), nullptr);
newType = FullySpecifiedType(clone->control()->pointerType(newType));
}
} else if (std::strcmp(enClassNameId, "_Hash") == 0 ||
@@ -186,12 +186,12 @@ Declaration::Declaration(Clone *clone, Subst *subst, Declaration *original)
std::strcmp(nameId, "reverse_iterator") == 0 ||
std::strcmp(nameId, "const_reverse_iterator") == 0 ||
std::strcmp(nameId, "const_iterator") == 0) {
- FullySpecifiedType clonedType = clone->type(subst->apply(firstTemplParamName), 0);
+ FullySpecifiedType clonedType = clone->type(subst->apply(firstTemplParamName), nullptr);
if (NamedType *namedType = clonedType.type()->asNamedType()) {
if (const TemplateNameId * templateNameId =
namedType->name()->asTemplateNameId()) {
if (templateNameId->templateArgumentCount()) {
- newType = clone->type(templateNameId->templateArgumentAt(0), 0);
+ newType = clone->type(templateNameId->templateArgumentAt(0), nullptr);
newType = FullySpecifiedType(clone->control()->pointerType(newType));
}
}
@@ -226,9 +226,9 @@ const StringLiteral *Declaration::getInitializer() const
void Declaration::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-EnumeratorDeclaration::EnumeratorDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+EnumeratorDeclaration::EnumeratorDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Declaration(translationUnit, sourceLocation, name)
- , _constantValue(0)
+ , _constantValue(nullptr)
{}
EnumeratorDeclaration::~EnumeratorDeclaration()
@@ -240,9 +240,9 @@ const StringLiteral *EnumeratorDeclaration::constantValue() const
void EnumeratorDeclaration::setConstantValue(const StringLiteral *constantValue)
{ _constantValue = constantValue; }
-Argument::Argument(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Argument::Argument(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name),
- _initializer(0)
+ _initializer(nullptr)
{ }
Argument::Argument(Clone *clone, Subst *subst, Argument *original)
@@ -255,7 +255,7 @@ Argument::~Argument()
{ }
bool Argument::hasInitializer() const
-{ return _initializer != 0; }
+{ return _initializer != nullptr; }
const StringLiteral *Argument::initializer() const
{ return _initializer; }
@@ -272,7 +272,7 @@ FullySpecifiedType Argument::type() const
void Argument::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-TypenameArgument::TypenameArgument(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+TypenameArgument::TypenameArgument(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
, _isClassDeclarator(false)
{ }
@@ -295,7 +295,7 @@ FullySpecifiedType TypenameArgument::type() const
void TypenameArgument::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-Function::Function(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Function::Function(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name),
_flags(0)
{ }
@@ -338,10 +338,10 @@ bool Function::isSignatureEqualTo(const Function *other, Matcher *matcher) const
else if (! Matcher::match(unqualifiedName(), other->unqualifiedName(), matcher))
return false;
- const unsigned argc = argumentCount();
+ const int argc = argumentCount();
if (argc != other->argumentCount())
return false;
- for (unsigned i = 0; i < argc; ++i) {
+ for (int i = 0; i < argc; ++i) {
Symbol *l = argumentAt(i);
Symbol *r = other->argumentAt(i);
if (! l->type().match(r->type(), matcher)) {
@@ -395,24 +395,24 @@ bool Function::hasReturnType() const
return ty.isValid() || ty.isSigned() || ty.isUnsigned();
}
-unsigned Function::argumentCount() const
+int Function::argumentCount() const
{
- const unsigned memCnt = memberCount();
+ const int memCnt = memberCount();
if (memCnt > 0 && memberAt(0)->type()->isVoidType())
return 0;
// Definitions with function-try-blocks will have more than a block, and
// arguments with a lambda as default argument will also have more blocks.
- unsigned argc = 0;
- for (unsigned it = 0; it < memCnt; ++it)
+ int argc = 0;
+ for (int it = 0; it < memCnt; ++it)
if (memberAt(it)->isArgument())
++argc;
return argc;
}
-Symbol *Function::argumentAt(unsigned index) const
+Symbol *Function::argumentAt(int index) const
{
- for (unsigned it = 0, eit = memberCount(); it < eit; ++it) {
+ for (int it = 0, eit = memberCount(); it < eit; ++it) {
if (Argument *arg = memberAt(it)->asArgument()) {
if (index == 0)
return arg;
@@ -421,20 +421,20 @@ Symbol *Function::argumentAt(unsigned index) const
}
}
- return 0;
+ return nullptr;
}
bool Function::hasArguments() const
{
- unsigned argc = argumentCount();
+ int argc = argumentCount();
return ! (argc == 0 || (argc == 1 && argumentAt(0)->type()->isVoidType()));
}
-unsigned Function::minimumArgumentCount() const
+int Function::minimumArgumentCount() const
{
- unsigned index = 0;
+ int index = 0;
- for (unsigned ei = argumentCount(); index < ei; ++index) {
+ for (int ei = argumentCount(); index < ei; ++index) {
if (Argument *arg = argumentAt(index)->asArgument()) {
if (arg->hasInitializer())
break;
@@ -501,16 +501,16 @@ void Function::setAmbiguous(bool isAmbiguous)
void Function::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
}
-bool Function::maybeValidPrototype(unsigned actualArgumentCount) const
+bool Function::maybeValidPrototype(int actualArgumentCount) const
{
- const unsigned argc = argumentCount();
- unsigned minNumberArguments = 0;
+ const int argc = argumentCount();
+ int minNumberArguments = 0;
for (; minNumberArguments < argc; ++minNumberArguments) {
Argument *arg = argumentAt(minNumberArguments)->asArgument();
@@ -535,8 +535,8 @@ bool Function::maybeValidPrototype(unsigned actualArgumentCount) const
}
-Block::Block(TranslationUnit *translationUnit, unsigned sourceLocation)
- : Scope(translationUnit, sourceLocation, /*name = */ 0)
+Block::Block(TranslationUnit *translationUnit, int sourceLocation)
+ : Scope(translationUnit, sourceLocation, /*name = */ nullptr)
{ }
Block::Block(Clone *clone, Subst *subst, Block *original)
@@ -552,13 +552,13 @@ FullySpecifiedType Block::type() const
void Block::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
}
-Enum::Enum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Enum::Enum(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name)
, _isScoped(false)
{ }
@@ -598,13 +598,13 @@ bool Enum::match0(const Type *otherType, Matcher *matcher) const
void Enum::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
}
-Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Template::Template(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name)
{ }
@@ -615,21 +615,21 @@ Template::Template(Clone *clone, Subst *subst, Template *original)
Template::~Template()
{ }
-unsigned Template::templateParameterCount() const
+int Template::templateParameterCount() const
{
- if (declaration() != 0)
+ if (declaration() != nullptr)
return memberCount() - 1;
return 0;
}
-Symbol *Template::templateParameterAt(unsigned index) const
+Symbol *Template::templateParameterAt(int index) const
{ return memberAt(index); }
Symbol *Template::declaration() const
{
if (isEmpty())
- return 0;
+ return nullptr;
if (Symbol *s = memberAt(memberCount() - 1)) {
if (s->isClass() || s->isForwardClassDeclaration() ||
@@ -637,7 +637,7 @@ Symbol *Template::declaration() const
return s;
}
- return 0;
+ return nullptr;
}
FullySpecifiedType Template::type() const
@@ -646,7 +646,7 @@ FullySpecifiedType Template::type() const
void Template::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
@@ -662,7 +662,7 @@ bool Template::match0(const Type *otherType, Matcher *matcher) const
return false;
}
-Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Namespace::Namespace(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name)
, _isInline(false)
{ }
@@ -689,7 +689,7 @@ bool Namespace::match0(const Type *otherType, Matcher *matcher) const
void Namespace::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
@@ -698,7 +698,7 @@ void Namespace::visitSymbol0(SymbolVisitor *visitor)
FullySpecifiedType Namespace::type() const
{ return FullySpecifiedType(const_cast<Namespace *>(this)); }
-BaseClass::BaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+BaseClass::BaseClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name),
_isVirtual(false)
{ }
@@ -734,7 +734,7 @@ void BaseClass::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
ForwardClassDeclaration::ForwardClassDeclaration(TranslationUnit *translationUnit,
- unsigned sourceLocation, const Name *name)
+ int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
{ }
@@ -762,7 +762,7 @@ bool ForwardClassDeclaration::match0(const Type *otherType, Matcher *matcher) co
return false;
}
-Class::Class(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+Class::Class(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name),
_key(ClassKey)
{ }
@@ -804,10 +804,10 @@ bool Class::match0(const Type *otherType, Matcher *matcher) const
return false;
}
-unsigned Class::baseClassCount() const
-{ return unsigned(_baseClasses.size()); }
+int Class::baseClassCount() const
+{ return int(_baseClasses.size()); }
-BaseClass *Class::baseClassAt(unsigned index) const
+BaseClass *Class::baseClassAt(int index) const
{ return _baseClasses.at(index); }
void Class::addBaseClass(BaseClass *baseClass)
@@ -819,17 +819,17 @@ FullySpecifiedType Class::type() const
void Class::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < _baseClasses.size(); ++i) {
+ for (int i = 0; i < int(_baseClasses.size()); ++i) {
visitSymbol(_baseClasses.at(i), visitor);
}
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
}
-QtPropertyDeclaration::QtPropertyDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+QtPropertyDeclaration::QtPropertyDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
, _flags(NoFlags)
{ }
@@ -859,7 +859,7 @@ void QtPropertyDeclaration::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-QtEnum::QtEnum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+QtEnum::QtEnum(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
{ }
@@ -877,7 +877,7 @@ void QtEnum::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-ObjCBaseClass::ObjCBaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+ObjCBaseClass::ObjCBaseClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
{ }
@@ -894,7 +894,7 @@ FullySpecifiedType ObjCBaseClass::type() const
void ObjCBaseClass::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-ObjCBaseProtocol::ObjCBaseProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+ObjCBaseProtocol::ObjCBaseProtocol(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Symbol(translationUnit, sourceLocation, name)
{ }
@@ -911,17 +911,17 @@ FullySpecifiedType ObjCBaseProtocol::type() const
void ObjCBaseProtocol::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
-ObjCClass::ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name):
+ObjCClass::ObjCClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name):
Scope(translationUnit, sourceLocation, name),
- _categoryName(0),
- _baseClass(0),
+ _categoryName(nullptr),
+ _baseClass(nullptr),
_isInterface(false)
{ }
ObjCClass::ObjCClass(Clone *clone, Subst *subst, ObjCClass *original)
: Scope(clone, subst, original)
, _categoryName(clone->name(original->_categoryName, subst))
- , _baseClass(0)
+ , _baseClass(nullptr)
, _isInterface(original->_isInterface)
{
if (original->_baseClass)
@@ -940,7 +940,7 @@ void ObjCClass::setInterface(bool isInterface)
{ _isInterface = isInterface; }
bool ObjCClass::isCategory() const
-{ return _categoryName != 0; }
+{ return _categoryName != nullptr; }
const Name *ObjCClass::categoryName() const
{ return _categoryName; }
@@ -954,10 +954,10 @@ ObjCBaseClass *ObjCClass::baseClass() const
void ObjCClass::setBaseClass(ObjCBaseClass *baseClass)
{ _baseClass = baseClass; }
-unsigned ObjCClass::protocolCount() const
-{ return unsigned(_protocols.size()); }
+int ObjCClass::protocolCount() const
+{ return int(_protocols.size()); }
-ObjCBaseProtocol *ObjCClass::protocolAt(unsigned index) const
+ObjCBaseProtocol *ObjCClass::protocolAt(int index) const
{ return _protocols.at(index); }
void ObjCClass::addProtocol(ObjCBaseProtocol *protocol)
@@ -972,10 +972,10 @@ void ObjCClass::visitSymbol0(SymbolVisitor *visitor)
if (_baseClass)
visitSymbol(_baseClass, visitor);
- for (unsigned i = 0; i < _protocols.size(); ++i)
+ for (int i = 0; i < int(_protocols.size()); ++i)
visitSymbol(_protocols.at(i), visitor);
- for (unsigned i = 0; i < memberCount(); ++i)
+ for (int i = 0; i < memberCount(); ++i)
visitSymbol(memberAt(i), visitor);
}
}
@@ -991,7 +991,7 @@ bool ObjCClass::match0(const Type *otherType, Matcher *matcher) const
return false;
}
-ObjCProtocol::ObjCProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name):
+ObjCProtocol::ObjCProtocol(TranslationUnit *translationUnit, int sourceLocation, const Name *name):
Scope(translationUnit, sourceLocation, name)
{
}
@@ -1006,10 +1006,10 @@ ObjCProtocol::ObjCProtocol(Clone *clone, Subst *subst, ObjCProtocol *original)
ObjCProtocol::~ObjCProtocol()
{}
-unsigned ObjCProtocol::protocolCount() const
-{ return unsigned(_protocols.size()); }
+int ObjCProtocol::protocolCount() const
+{ return int(_protocols.size()); }
-ObjCBaseProtocol *ObjCProtocol::protocolAt(unsigned index) const
+ObjCBaseProtocol *ObjCProtocol::protocolAt(int index) const
{ return _protocols.at(index); }
void ObjCProtocol::addProtocol(ObjCBaseProtocol *protocol)
@@ -1021,7 +1021,7 @@ FullySpecifiedType ObjCProtocol::type() const
void ObjCProtocol::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < _protocols.size(); ++i)
+ for (int i = 0; i < int(_protocols.size()); ++i)
visitSymbol(_protocols.at(i), visitor);
}
}
@@ -1037,7 +1037,7 @@ bool ObjCProtocol::match0(const Type *otherType, Matcher *matcher) const
return false;
}
-ObjCForwardClassDeclaration::ObjCForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation,
+ObjCForwardClassDeclaration::ObjCForwardClassDeclaration(TranslationUnit *translationUnit, int sourceLocation,
const Name *name):
Symbol(translationUnit, sourceLocation, name)
{
@@ -1067,7 +1067,7 @@ bool ObjCForwardClassDeclaration::match0(const Type *otherType, Matcher *matcher
return false;
}
-ObjCForwardProtocolDeclaration::ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation,
+ObjCForwardProtocolDeclaration::ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, int sourceLocation,
const Name *name):
Symbol(translationUnit, sourceLocation, name)
{
@@ -1097,7 +1097,7 @@ bool ObjCForwardProtocolDeclaration::match0(const Type *otherType, Matcher *matc
return false;
}
-ObjCMethod::ObjCMethod(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
+ObjCMethod::ObjCMethod(TranslationUnit *translationUnit, int sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name),
_flags(0)
{ }
@@ -1137,15 +1137,15 @@ bool ObjCMethod::hasReturnType() const
return ty.isValid() || ty.isSigned() || ty.isUnsigned();
}
-unsigned ObjCMethod::argumentCount() const
+int ObjCMethod::argumentCount() const
{
- const unsigned c = memberCount();
+ const int c = memberCount();
if (c > 0 && memberAt(c - 1)->isBlock())
return c - 1;
return c;
}
-Symbol *ObjCMethod::argumentAt(unsigned index) const
+Symbol *ObjCMethod::argumentAt(int index) const
{
return memberAt(index);
}
@@ -1165,18 +1165,18 @@ void ObjCMethod::setVariadic(bool isVariadic)
void ObjCMethod::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
- for (unsigned i = 0; i < memberCount(); ++i) {
+ for (int i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
}
ObjCPropertyDeclaration::ObjCPropertyDeclaration(TranslationUnit *translationUnit,
- unsigned sourceLocation,
+ int sourceLocation,
const Name *name):
Symbol(translationUnit, sourceLocation, name),
- _getterName(0),
- _setterName(0),
+ _getterName(nullptr),
+ _setterName(nullptr),
_propertyAttributes(None)
{}
diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h
index e29f78bf01..fd9417984e 100644
--- a/src/libs/3rdparty/cplusplus/Symbols.h
+++ b/src/libs/3rdparty/cplusplus/Symbols.h
@@ -32,7 +32,7 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT UsingNamespaceDirective: public Symbol
{
public:
- UsingNamespaceDirective(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ UsingNamespaceDirective(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
UsingNamespaceDirective(Clone *clone, Subst *subst, UsingNamespaceDirective *original);
virtual ~UsingNamespaceDirective();
@@ -52,7 +52,7 @@ protected:
class CPLUSPLUS_EXPORT UsingDeclaration: public Symbol
{
public:
- UsingDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ UsingDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
UsingDeclaration(Clone *clone, Subst *subst, UsingDeclaration *original);
virtual ~UsingDeclaration();
@@ -72,7 +72,7 @@ protected:
class CPLUSPLUS_EXPORT NamespaceAlias: public Symbol
{
public:
- NamespaceAlias(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ NamespaceAlias(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
NamespaceAlias(Clone *clone, Subst *subst, NamespaceAlias *original);
virtual ~NamespaceAlias();
@@ -98,7 +98,7 @@ private:
class CPLUSPLUS_EXPORT Declaration: public Symbol
{
public:
- Declaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Declaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Declaration(Clone *clone, Subst *subst, Declaration *original);
virtual ~Declaration();
@@ -116,10 +116,10 @@ public:
{ return this; }
virtual EnumeratorDeclaration *asEnumeratorDeclarator()
- { return 0; }
+ { return nullptr; }
virtual const EnumeratorDeclaration *asEnumeratorDeclarator() const
- { return 0; }
+ { return nullptr; }
protected:
virtual void visitSymbol0(SymbolVisitor *visitor);
@@ -132,7 +132,7 @@ private:
class CPLUSPLUS_EXPORT EnumeratorDeclaration: public Declaration
{
public:
- EnumeratorDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ EnumeratorDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
virtual ~EnumeratorDeclaration();
const StringLiteral *constantValue() const;
@@ -151,7 +151,7 @@ private:
class CPLUSPLUS_EXPORT Argument: public Symbol
{
public:
- Argument(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Argument(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Argument(Clone *clone, Subst *subst, Argument *original);
virtual ~Argument();
@@ -182,7 +182,7 @@ private:
class CPLUSPLUS_EXPORT TypenameArgument: public Symbol
{
public:
- TypenameArgument(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ TypenameArgument(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
TypenameArgument(Clone *clone, Subst *subst, TypenameArgument *original);
virtual ~TypenameArgument();
@@ -210,7 +210,7 @@ private:
class CPLUSPLUS_EXPORT Block: public Scope
{
public:
- Block(TranslationUnit *translationUnit, unsigned sourceLocation);
+ Block(TranslationUnit *translationUnit, int sourceLocation);
Block(Clone *clone, Subst *subst, Block *original);
virtual ~Block();
@@ -230,7 +230,7 @@ protected:
class CPLUSPLUS_EXPORT ForwardClassDeclaration: public Symbol, public Type
{
public:
- ForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ForwardClassDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ForwardClassDeclaration(Clone *clone, Subst *subst, ForwardClassDeclaration *original);
virtual ~ForwardClassDeclaration();
@@ -259,7 +259,7 @@ protected:
class CPLUSPLUS_EXPORT Enum: public Scope, public Type
{
public:
- Enum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Enum(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Enum(Clone *clone, Subst *subst, Enum *original);
virtual ~Enum();
@@ -308,7 +308,7 @@ public:
};
public:
- Function(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Function(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Function(Clone *clone, Subst *subst, Function *original);
virtual ~Function();
@@ -325,12 +325,12 @@ public:
/** Convenience function that returns whether the function returns something (including void). */
bool hasReturnType() const;
- unsigned argumentCount() const;
- Symbol *argumentAt(unsigned index) const;
+ int argumentCount() const;
+ Symbol *argumentAt(int index) const;
/** Convenience function that returns whether the function receives any arguments. */
bool hasArguments() const;
- unsigned minimumArgumentCount() const;
+ int minimumArgumentCount() const;
bool isVirtual() const;
void setVirtual(bool isVirtual);
@@ -356,12 +356,12 @@ public:
RefQualifier refQualifier() const;
void setRefQualifier(RefQualifier refQualifier);
- bool isSignatureEqualTo(const Function *other, Matcher *matcher = 0) const;
+ bool isSignatureEqualTo(const Function *other, Matcher *matcher = nullptr) const;
bool isAmbiguous() const; // internal
void setAmbiguous(bool isAmbiguous); // internal
- bool maybeValidPrototype(unsigned actualArgumentCount) const;
+ bool maybeValidPrototype(int actualArgumentCount) const;
// Symbol's interface
virtual FullySpecifiedType type() const;
@@ -407,12 +407,12 @@ private:
class CPLUSPLUS_EXPORT Template: public Scope, public Type
{
public:
- Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Template(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Template(Clone *clone, Subst *subst, Template *original);
virtual ~Template();
- unsigned templateParameterCount() const;
- Symbol *templateParameterAt(unsigned index) const;
+ int templateParameterCount() const;
+ Symbol *templateParameterAt(int index) const;
Symbol *declaration() const;
// Symbol's interface
@@ -441,7 +441,7 @@ protected:
class CPLUSPLUS_EXPORT Namespace: public Scope, public Type
{
public:
- Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Namespace(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Namespace(Clone *clone, Subst *subst, Namespace *original);
virtual ~Namespace();
@@ -479,7 +479,7 @@ private:
class CPLUSPLUS_EXPORT BaseClass: public Symbol
{
public:
- BaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ BaseClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
BaseClass(Clone *clone, Subst *subst, BaseClass *original);
virtual ~BaseClass();
@@ -511,7 +511,7 @@ private:
class CPLUSPLUS_EXPORT Class: public Scope, public Type
{
public:
- Class(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ Class(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
Class(Clone *clone, Subst *subst, Class *original);
virtual ~Class();
@@ -527,8 +527,8 @@ public:
Key classKey() const;
void setClassKey(Key key);
- unsigned baseClassCount() const;
- BaseClass *baseClassAt(unsigned index) const;
+ int baseClassCount() const;
+ BaseClass *baseClassAt(int index) const;
void addBaseClass(BaseClass *baseClass);
// Symbol's interface
@@ -580,7 +580,7 @@ public:
};
public:
- QtPropertyDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ QtPropertyDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
QtPropertyDeclaration(Clone *clone, Subst *subst, QtPropertyDeclaration *original);
virtual ~QtPropertyDeclaration();
@@ -609,7 +609,7 @@ private:
class CPLUSPLUS_EXPORT QtEnum: public Symbol
{
public:
- QtEnum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ QtEnum(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
QtEnum(Clone *clone, Subst *subst, QtEnum *original);
virtual ~QtEnum();
@@ -629,7 +629,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCBaseClass: public Symbol
{
public:
- ObjCBaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCBaseClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCBaseClass(Clone *clone, Subst *subst, ObjCBaseClass *original);
virtual ~ObjCBaseClass();
@@ -649,7 +649,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCBaseProtocol: public Symbol
{
public:
- ObjCBaseProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCBaseProtocol(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCBaseProtocol(Clone *clone, Subst *subst, ObjCBaseProtocol *original);
virtual ~ObjCBaseProtocol();
@@ -669,7 +669,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCForwardProtocolDeclaration: public Symbol, public Type
{
public:
- ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCForwardProtocolDeclaration(Clone *clone, Subst *subst, ObjCForwardProtocolDeclaration *original);
virtual ~ObjCForwardProtocolDeclaration();
@@ -698,12 +698,12 @@ protected:
class CPLUSPLUS_EXPORT ObjCProtocol: public Scope, public Type
{
public:
- ObjCProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCProtocol(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCProtocol(Clone *clone, Subst *subst, ObjCProtocol *original);
virtual ~ObjCProtocol();
- unsigned protocolCount() const;
- ObjCBaseProtocol *protocolAt(unsigned index) const;
+ int protocolCount() const;
+ ObjCBaseProtocol *protocolAt(int index) const;
void addProtocol(ObjCBaseProtocol *protocol);
// Symbol's interface
@@ -734,7 +734,7 @@ private:
class CPLUSPLUS_EXPORT ObjCForwardClassDeclaration: public Symbol, public Type
{
public:
- ObjCForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCForwardClassDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCForwardClassDeclaration(Clone *clone, Subst *subst, ObjCForwardClassDeclaration *original);
virtual ~ObjCForwardClassDeclaration();
@@ -763,7 +763,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCClass: public Scope, public Type
{
public:
- ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCClass(Clone *clone, Subst *subst, ObjCClass *original);
virtual ~ObjCClass();
@@ -777,8 +777,8 @@ public:
ObjCBaseClass *baseClass() const;
void setBaseClass(ObjCBaseClass *baseClass);
- unsigned protocolCount() const;
- ObjCBaseProtocol *protocolAt(unsigned index) const;
+ int protocolCount() const;
+ ObjCBaseProtocol *protocolAt(int index) const;
void addProtocol(ObjCBaseProtocol *protocol);
// Symbol's interface
@@ -812,7 +812,7 @@ private:
class CPLUSPLUS_EXPORT ObjCMethod: public Scope, public Type
{
public:
- ObjCMethod(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
+ ObjCMethod(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
ObjCMethod(Clone *clone, Subst *subst, ObjCMethod *original);
virtual ~ObjCMethod();
@@ -822,8 +822,8 @@ public:
/** Convenience function that returns whether the function returns something (including void). */
bool hasReturnType() const;
- unsigned argumentCount() const;
- Symbol *argumentAt(unsigned index) const;
+ int argumentCount() const;
+ Symbol *argumentAt(int index) const;
/** Convenience function that returns whether the function receives any arguments. */
bool hasArguments() const;
@@ -883,7 +883,7 @@ public:
public:
ObjCPropertyDeclaration(TranslationUnit *translationUnit,
- unsigned sourceLocation,
+ int sourceLocation,
const Name *name);
ObjCPropertyDeclaration(Clone *clone, Subst *subst, ObjCPropertyDeclaration *original);
virtual ~ObjCPropertyDeclaration();
diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp
index 61c6e612ae..75ee4e95fa 100644
--- a/src/libs/3rdparty/cplusplus/Templates.cpp
+++ b/src/libs/3rdparty/cplusplus/Templates.cpp
@@ -34,7 +34,7 @@ using namespace CPlusPlus;
CloneType::CloneType(Clone *clone)
: _clone(clone)
, _control(clone->control())
- , _subst(0)
+ , _subst(nullptr)
{
}
@@ -102,7 +102,7 @@ void CloneType::visit(NamedType *type)
const Name *name = _clone->name(type->name(), _subst);
FullySpecifiedType ty;
if (_subst)
- ty = _clone->type(_subst->apply(name), 0);
+ ty = _clone->type(_subst->apply(name), nullptr);
if (! ty.isValid())
ty = _control->namedType(name);
_type.setType(ty.type());
@@ -177,15 +177,15 @@ void CloneType::visit(ObjCForwardProtocolDeclaration *type)
CloneSymbol::CloneSymbol(Clone *clone)
: _clone(clone)
, _control(clone->control())
- , _subst(0)
- , _symbol(0)
+ , _subst(nullptr)
+ , _symbol(nullptr)
{
}
Symbol *CloneSymbol::cloneSymbol(Symbol *symbol, Subst *subst)
{
if (! symbol)
- return 0;
+ return nullptr;
SymbolSubstPair symbolSubstPair = std::make_pair(symbol, subst);
auto it = _cache.find(symbolSubstPair);
@@ -194,14 +194,14 @@ Symbol *CloneSymbol::cloneSymbol(Symbol *symbol, Subst *subst)
return it->second;
}
- Symbol *r = 0;
+ Symbol *r = nullptr;
std::swap(_subst, subst);
std::swap(_symbol, r);
accept(symbol);
std::swap(_symbol, r);
std::swap(_subst, subst);
- CPP_CHECK(r != 0);
+ CPP_CHECK(r != nullptr);
_cache[symbolSubstPair] = r;
return r;
}
@@ -401,28 +401,28 @@ bool CloneSymbol::visit(ObjCPropertyDeclaration *symbol)
CloneName::CloneName(Clone *clone)
: _clone(clone)
, _control(clone->control())
- , _subst(0)
- , _name(0)
+ , _subst(nullptr)
+ , _name(nullptr)
{
}
const Name *CloneName::cloneName(const Name *name, Subst *subst)
{
if (! name)
- return 0;
+ return nullptr;
NameSubstPair nameSubstPair = std::make_pair(name, subst);
auto it = _cache.find(nameSubstPair);
if (it != _cache.end())
return it->second;
- const Name *r = 0;
+ const Name *r = nullptr;
std::swap(_subst, subst);
std::swap(_name, r);
accept(name);
std::swap(_name, r);
std::swap(_subst, subst);
- CPP_CHECK(r != 0);
+ CPP_CHECK(r != nullptr);
_cache[nameSubstPair] = r;
return r;
}
@@ -440,13 +440,13 @@ void CloneName::visit(const AnonymousNameId *name)
void CloneName::visit(const TemplateNameId *name)
{
std::vector<FullySpecifiedType> args(name->templateArgumentCount());
- for (unsigned i = 0; i < args.size(); ++i)
+ for (int i = 0; i < int(args.size()); ++i)
args[i] = _clone->type(name->templateArgumentAt(i), _subst);
if (args.empty())
_name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization());
else
_name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization(),
- &args[0], unsigned(args.size()));
+ &args[0], int(args.size()));
}
void CloneName::visit(const DestructorNameId *name)
@@ -474,9 +474,9 @@ void CloneName::visit(const SelectorNameId *name)
{
CPP_CHECK(name->nameCount() > 0);
std::vector<const Name *> names(name->nameCount());
- for (unsigned i = 0; i < names.size(); ++i)
+ for (int i = 0; i < int(names.size()); ++i)
names[i] = _clone->name(name->nameAt(i), _subst);
- _name = _control->selectorNameId(&names[0], unsigned(names.size()), name->hasArguments());
+ _name = _control->selectorNameId(&names[0], int(names.size()), name->hasArguments());
}
@@ -490,17 +490,17 @@ Clone::Clone(Control *control)
const StringLiteral *Clone::stringLiteral(const StringLiteral *literal)
{
- return literal ? _control->stringLiteral(literal->chars(), literal->size()) : 0;
+ return literal ? _control->stringLiteral(literal->chars(), literal->size()) : nullptr;
}
const NumericLiteral *Clone::numericLiteral(const NumericLiteral *literal)
{
- return literal ? _control->numericLiteral(literal->chars(), literal->size()) : 0;
+ return literal ? _control->numericLiteral(literal->chars(), literal->size()) : nullptr;
}
const Identifier *Clone::identifier(const Identifier *id)
{
- return id ? _control->identifier(id->chars(), id->size()) : 0;
+ return id ? _control->identifier(id->chars(), id->size()) : nullptr;
}
FullySpecifiedType Clone::type(const FullySpecifiedType &type, Subst *subst)
@@ -518,16 +518,16 @@ Symbol *Clone::symbol(Symbol *symbol, Subst *subst)
return _symbol(symbol, subst);
}
-Symbol *Clone::instantiate(Template *templ, const FullySpecifiedType *const args, unsigned argc, Subst *s)
+Symbol *Clone::instantiate(Template *templ, const FullySpecifiedType *const args, int argc, Subst *s)
{
Subst subst(_control, s);
- for (unsigned i = 0, e = std::min(templ->templateParameterCount(), argc); i < e; ++i) {
+ for (int i = 0, e = std::min(templ->templateParameterCount(), argc); i < e; ++i) {
Symbol *formal = templ->templateParameterAt(i);
FullySpecifiedType actual = args[i];
- subst.bind(name(formal->name(), 0), actual);
+ subst.bind(name(formal->name(), nullptr), actual);
}
if (argc < templ->templateParameterCount()) {
- for (unsigned i = argc; i < templ->templateParameterCount(); ++i) {
+ for (int i = argc; i < templ->templateParameterCount(); ++i) {
Symbol *formal = templ->templateParameterAt(i);
if (TypenameArgument *tn = formal->asTypenameArgument())
subst.bind(name(formal->name(), &subst), type(tn->type(), &subst));
@@ -537,7 +537,7 @@ Symbol *Clone::instantiate(Template *templ, const FullySpecifiedType *const args
inst->setEnclosingScope(templ->enclosingScope());
return inst;
}
- return 0;
+ return nullptr;
}
//
@@ -564,7 +564,7 @@ FullySpecifiedType Subst::apply(const Name *name) const
return control()->namedType(control()->qualifiedNameId(qualifiedBase,
qualifiedName));
}
- else if(baseNamedType->name()->identifier() != 0) {
+ else if(baseNamedType->name()->identifier() != nullptr) {
const QualifiedNameId *clonedQualifiedNameId
= control()->qualifiedNameId(baseNamedType->name()->identifier(),
unqualified->name());
diff --git a/src/libs/3rdparty/cplusplus/Templates.h b/src/libs/3rdparty/cplusplus/Templates.h
index 67b57a6296..b1da4ef4d0 100644
--- a/src/libs/3rdparty/cplusplus/Templates.h
+++ b/src/libs/3rdparty/cplusplus/Templates.h
@@ -40,7 +40,7 @@ class CPLUSPLUS_EXPORT Subst
Subst &operator = (const Subst &other);
public:
- Subst(Control *control, Subst *previous = 0)
+ Subst(Control *control, Subst *previous = nullptr)
: _control(control)
, _previous(previous)
{ }
@@ -196,8 +196,8 @@ public:
Symbol *symbol(Symbol *symbol, Subst *subst);
Symbol *instantiate(Template *templ,
- const FullySpecifiedType *const args, unsigned argc,
- Subst *subst = 0);
+ const FullySpecifiedType *const args, int argc,
+ Subst *subst = nullptr);
private:
CloneType _type;
diff --git a/src/libs/3rdparty/cplusplus/Token.cpp b/src/libs/3rdparty/cplusplus/Token.cpp
index ecc7a8487b..0159b1ed7d 100644
--- a/src/libs/3rdparty/cplusplus/Token.cpp
+++ b/src/libs/3rdparty/cplusplus/Token.cpp
@@ -247,7 +247,7 @@ void Token::reset()
flags = 0;
byteOffset = 0;
utf16charOffset = 0;
- ptr = 0;
+ ptr = nullptr;
}
const char *Token::name(int kind)
diff --git a/src/libs/3rdparty/cplusplus/Token.h b/src/libs/3rdparty/cplusplus/Token.h
index 67378b28a3..0f0f76d3cf 100644
--- a/src/libs/3rdparty/cplusplus/Token.h
+++ b/src/libs/3rdparty/cplusplus/Token.h
@@ -298,7 +298,7 @@ enum Kind {
class CPLUSPLUS_EXPORT Token
{
public:
- Token() : flags(0), byteOffset(0), utf16charOffset(0), ptr(0) {}
+ Token() : flags(0), byteOffset(0), utf16charOffset(0), ptr(nullptr) {}
inline bool is(unsigned k) const { return f.kind == k; }
inline bool isNot(unsigned k) const { return f.kind != k; }
@@ -313,13 +313,13 @@ public:
inline bool generated() const { return f.generated; }
inline bool userDefinedLiteral() const { return f.userDefinedLiteral; }
- inline unsigned bytes() const { return f.bytes; }
- inline unsigned bytesBegin() const { return byteOffset; }
- inline unsigned bytesEnd() const { return byteOffset + f.bytes; }
+ inline int bytes() const { return f.bytes; }
+ inline int bytesBegin() const { return byteOffset; }
+ inline int bytesEnd() const { return byteOffset + f.bytes; }
- inline unsigned utf16chars() const { return f.utf16chars; }
- inline unsigned utf16charsBegin() const { return utf16charOffset; }
- inline unsigned utf16charsEnd() const { return utf16charOffset + f.utf16chars; }
+ inline int utf16chars() const { return f.utf16chars; }
+ inline int utf16charsBegin() const { return utf16charOffset; }
+ inline int utf16charsEnd() const { return utf16charOffset + f.utf16chars; }
inline bool isLiteral() const
{ return f.kind >= T_FIRST_LITERAL && f.kind <= T_LAST_LITERAL; }
@@ -405,7 +405,7 @@ public:
const StringLiteral *string;
const Identifier *identifier;
unsigned close_brace;
- unsigned lineno;
+ int lineno;
};
};
@@ -437,6 +437,7 @@ struct LanguageFeatures
unsigned int qtKeywordsEnabled : 1; // If Qt is used but QT_NO_KEYWORDS defined
unsigned int cxxEnabled : 1;
unsigned int cxx11Enabled : 1;
+ unsigned int cxx14Enabled : 1;
unsigned int objCEnabled : 1;
unsigned int c99Enabled : 1;
};
diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp
index 2da8ad563e..d5f299750e 100644
--- a/src/libs/3rdparty/cplusplus/TranslationUnit.cpp
+++ b/src/libs/3rdparty/cplusplus/TranslationUnit.cpp
@@ -43,10 +43,10 @@ const Token TranslationUnit::nullToken;
TranslationUnit::TranslationUnit(Control *control, const StringLiteral *fileId)
: _control(control),
_fileId(fileId),
- _firstSourceChar(0),
- _lastSourceChar(0),
- _pool(0),
- _ast(0),
+ _firstSourceChar(nullptr),
+ _lastSourceChar(nullptr),
+ _pool(nullptr),
+ _ast(nullptr),
_flags(0)
{
_tokens = new std::vector<Token>();
@@ -70,7 +70,7 @@ const StringLiteral *TranslationUnit::fileId() const
const char *TranslationUnit::fileName() const
{ return _fileId->chars(); }
-unsigned TranslationUnit::fileNameLength() const
+int TranslationUnit::fileNameLength() const
{ return _fileId->size(); }
const char *TranslationUnit::firstSourceChar() const
@@ -79,42 +79,42 @@ const char *TranslationUnit::firstSourceChar() const
const char *TranslationUnit::lastSourceChar() const
{ return _lastSourceChar; }
-unsigned TranslationUnit::sourceLength() const
+int TranslationUnit::sourceLength() const
{ return _lastSourceChar - _firstSourceChar; }
-void TranslationUnit::setSource(const char *source, unsigned size)
+void TranslationUnit::setSource(const char *source, int size)
{
_firstSourceChar = source;
_lastSourceChar = source + size;
}
-const char *TranslationUnit::spell(unsigned index) const
+const char *TranslationUnit::spell(int index) const
{
if (! index)
- return 0;
+ return nullptr;
return tokenAt(index).spell();
}
-unsigned TranslationUnit::commentCount() const
-{ return unsigned(_comments->size()); }
+int TranslationUnit::commentCount() const
+{ return int(_comments->size()); }
-const Token &TranslationUnit::commentAt(unsigned index) const
+const Token &TranslationUnit::commentAt(int index) const
{ return _comments->at(index); }
-const Identifier *TranslationUnit::identifier(unsigned index) const
+const Identifier *TranslationUnit::identifier(int index) const
{ return tokenAt(index).identifier; }
-const Literal *TranslationUnit::literal(unsigned index) const
+const Literal *TranslationUnit::literal(int index) const
{ return tokenAt(index).literal; }
-const StringLiteral *TranslationUnit::stringLiteral(unsigned index) const
+const StringLiteral *TranslationUnit::stringLiteral(int index) const
{ return tokenAt(index).string; }
-const NumericLiteral *TranslationUnit::numericLiteral(unsigned index) const
+const NumericLiteral *TranslationUnit::numericLiteral(int index) const
{ return tokenAt(index).number; }
-unsigned TranslationUnit::matchingBrace(unsigned index) const
+int TranslationUnit::matchingBrace(int index) const
{ return tokenAt(index).close_brace; }
MemoryPool *TranslationUnit::memoryPool() const
@@ -140,7 +140,7 @@ void TranslationUnit::tokenize()
lex.setLanguageFeatures(_languageFeatures);
lex.setScanCommentTokens(true);
- std::stack<unsigned> braces;
+ std::stack<int> braces;
_tokens->push_back(nullToken); // the first token needs to be invalid!
pushLineOffset(0);
@@ -153,8 +153,8 @@ void TranslationUnit::tokenize()
// We need to track information about the expanded tokens. A vector with an addition
// explicit index control is used instead of queue mainly for performance reasons.
- std::vector<std::pair<unsigned, unsigned> > lineColumn;
- unsigned lineColumnIdx = 0;
+ std::vector<std::pair<int, int> > lineColumn;
+ int lineColumnIdx = 0;
Token tk;
do {
@@ -162,7 +162,7 @@ void TranslationUnit::tokenize()
recognize:
if (tk.is(T_POUND) && tk.newline()) {
- const unsigned utf16CharOffset = tk.utf16charOffset;
+ const int utf16CharOffset = tk.utf16charOffset;
lex(&tk);
if (! tk.newline() && tk.is(T_IDENTIFIER) && tk.identifier == expansionId) {
@@ -175,10 +175,10 @@ recognize:
lex(&tk);
// Gather where the expansion happens and its length.
- //unsigned macroOffset = static_cast<unsigned>(strtoul(tk.spell(), 0, 0));
+ //int macroOffset = static_cast<int>(strtoul(tk.spell(), 0, 0));
lex(&tk);
lex(&tk); // Skip the separating comma
- //unsigned macroLength = static_cast<unsigned>(strtoul(tk.spell(), 0, 0));
+ //int macroLength = static_cast<int>(strtoul(tk.spell(), 0, 0));
lex(&tk);
// NOTE: We are currently not using the macro offset and length. They
@@ -198,7 +198,7 @@ recognize:
// Get the total number of generated tokens and specify "null"
// information for them.
unsigned totalGenerated =
- static_cast<unsigned>(strtoul(tk.spell(), 0, 0));
+ static_cast<int>(strtoul(tk.spell(), nullptr, 0));
const std::size_t previousSize = lineColumn.size();
lineColumn.resize(previousSize + totalGenerated);
std::fill(lineColumn.begin() + previousSize,
@@ -207,10 +207,10 @@ recognize:
lex(&tk);
} else if (tk.is(T_NUMERIC_LITERAL)) {
- unsigned line = static_cast<unsigned>(strtoul(tk.spell(), 0, 0));
+ int line = static_cast<int>(strtoul(tk.spell(), nullptr, 0));
lex(&tk);
lex(&tk); // Skip the separating colon
- unsigned column = static_cast<unsigned>(strtoul(tk.spell(), 0, 0));
+ int column = static_cast<int>(strtoul(tk.spell(), nullptr, 0));
// Store line and column for this non-generated token.
lineColumn.push_back(std::make_pair(line, column));
@@ -230,7 +230,7 @@ recognize:
if (! tk.newline() && tk.is(T_IDENTIFIER) && tk.identifier == lineId)
lex(&tk);
if (! tk.newline() && tk.is(T_NUMERIC_LITERAL)) {
- unsigned line = (unsigned) strtoul(tk.spell(), 0, 0);
+ int line = static_cast<int>(strtol(tk.spell(), nullptr, 0));
lex(&tk);
if (! tk.newline() && tk.is(T_STRING_LITERAL)) {
const StringLiteral *fileName =
@@ -244,12 +244,12 @@ recognize:
}
goto recognize;
} else if (tk.kind() == T_LBRACE) {
- braces.push(unsigned(_tokens->size()));
+ braces.push(int(_tokens->size()));
} else if (tk.kind() == T_RBRACE && ! braces.empty()) {
- const unsigned open_brace_index = braces.top();
+ const int open_brace_index = braces.top();
braces.pop();
if (open_brace_index < tokenCount())
- (*_tokens)[open_brace_index].close_brace = unsigned(_tokens->size());
+ (*_tokens)[open_brace_index].close_brace = int(_tokens->size());
} else if (tk.isComment()) {
_comments->push_back(tk);
continue; // comments are not in the regular token stream
@@ -258,9 +258,9 @@ recognize:
bool currentExpanded = false;
bool currentGenerated = false;
- if (!lineColumn.empty() && lineColumnIdx < lineColumn.size()) {
+ if (!lineColumn.empty() && lineColumnIdx < static_cast<int>(lineColumn.size())) {
currentExpanded = true;
- const std::pair<unsigned, unsigned> &p = lineColumn[lineColumnIdx];
+ const std::pair<int, int> &p = lineColumn[lineColumnIdx];
if (p.first)
_expandedLineColumn.insert(std::make_pair(tk.utf16charsBegin(), p));
else
@@ -276,8 +276,8 @@ recognize:
} while (tk.kind());
for (; ! braces.empty(); braces.pop()) {
- unsigned open_brace_index = braces.top();
- (*_tokens)[open_brace_index].close_brace = unsigned(_tokens->size());
+ int open_brace_index = braces.top();
+ (*_tokens)[open_brace_index].close_brace = int(_tokens->size());
}
}
@@ -302,31 +302,31 @@ bool TranslationUnit::parse(ParseMode mode)
switch (mode) {
case ParseTranlationUnit: {
- TranslationUnitAST *node = 0;
+ TranslationUnitAST *node = nullptr;
parsed = parser.parseTranslationUnit(node);
_ast = node;
} break;
case ParseDeclaration: {
- DeclarationAST *node = 0;
+ DeclarationAST *node = nullptr;
parsed = parser.parseDeclaration(node);
_ast = node;
} break;
case ParseExpression: {
- ExpressionAST *node = 0;
+ ExpressionAST *node = nullptr;
parsed = parser.parseExpression(node);
_ast = node;
} break;
case ParseDeclarator: {
- DeclaratorAST *node = 0;
- parsed = parser.parseDeclarator(node, /*decl_specifier_list =*/ 0);
+ DeclaratorAST *node = nullptr;
+ parsed = parser.parseDeclarator(node, /*decl_specifier_list =*/ nullptr);
_ast = node;
} break;
case ParseStatement: {
- StatementAST *node = 0;
+ StatementAST *node = nullptr;
parsed = parser.parseStatement(node);
_ast = node;
} break;
@@ -338,17 +338,17 @@ bool TranslationUnit::parse(ParseMode mode)
return parsed;
}
-void TranslationUnit::pushLineOffset(unsigned offset)
+void TranslationUnit::pushLineOffset(int offset)
{ _lineOffsets.push_back(offset); }
-void TranslationUnit::pushPreprocessorLine(unsigned utf16charOffset,
- unsigned line,
+void TranslationUnit::pushPreprocessorLine(int utf16charOffset,
+ int line,
const StringLiteral *fileName)
{ _ppLines.push_back(PPLine(utf16charOffset, line, fileName)); }
-unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const
+int TranslationUnit::findLineNumber(int utf16charOffset) const
{
- std::vector<unsigned>::const_iterator it =
+ std::vector<int>::const_iterator it =
std::lower_bound(_lineOffsets.begin(), _lineOffsets.end(), utf16charOffset);
if (it != _lineOffsets.begin())
@@ -357,7 +357,7 @@ unsigned TranslationUnit::findLineNumber(unsigned utf16charOffset) const
return it - _lineOffsets.begin();
}
-TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(unsigned utf16charOffset) const
+TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(int utf16charOffset) const
{
std::vector<PPLine>::const_iterator it =
std::lower_bound(_ppLines.begin(), _ppLines.end(), PPLine(utf16charOffset));
@@ -368,7 +368,7 @@ TranslationUnit::PPLine TranslationUnit::findPreprocessorLine(unsigned utf16char
return *it;
}
-unsigned TranslationUnit::findColumnNumber(unsigned utf16CharOffset, unsigned lineNumber) const
+int TranslationUnit::findColumnNumber(int utf16CharOffset, int lineNumber) const
{
if (! utf16CharOffset)
return 0;
@@ -376,30 +376,30 @@ unsigned TranslationUnit::findColumnNumber(unsigned utf16CharOffset, unsigned li
return utf16CharOffset - _lineOffsets[lineNumber];
}
-void TranslationUnit::getTokenPosition(unsigned index,
- unsigned *line,
- unsigned *column,
+void TranslationUnit::getTokenPosition(int index,
+ int *line,
+ int *column,
const StringLiteral **fileName) const
{ return getPosition(tokenAt(index).utf16charsBegin(), line, column, fileName); }
-void TranslationUnit::getTokenStartPosition(unsigned index, unsigned *line,
- unsigned *column,
+void TranslationUnit::getTokenStartPosition(int index, int *line,
+ int *column,
const StringLiteral **fileName) const
{ return getPosition(tokenAt(index).utf16charsBegin(), line, column, fileName); }
-void TranslationUnit::getTokenEndPosition(unsigned index, unsigned *line,
- unsigned *column,
+void TranslationUnit::getTokenEndPosition(int index, int *line,
+ int *column,
const StringLiteral **fileName) const
{ return getPosition(tokenAt(index).utf16charsEnd(), line, column, fileName); }
-void TranslationUnit::getPosition(unsigned utf16charOffset,
- unsigned *line,
- unsigned *column,
+void TranslationUnit::getPosition(int utf16charOffset,
+ int *line,
+ int *column,
const StringLiteral **fileName) const
{
- unsigned lineNumber = 0;
- unsigned columnNumber = 0;
- const StringLiteral *file = 0;
+ int lineNumber = 0;
+ int columnNumber = 0;
+ const StringLiteral *file = nullptr;
// If this token is expanded we already have the information directly from the expansion
// section header. Otherwise, we need to calculate it.
@@ -433,22 +433,22 @@ void TranslationUnit::getPosition(unsigned utf16charOffset,
*fileName = file;
}
-void TranslationUnit::message(DiagnosticClient::Level level, unsigned index, const char *format, va_list args)
+void TranslationUnit::message(DiagnosticClient::Level level, int index, const char *format, va_list args)
{
if (f._blockErrors)
return;
index = std::min(index, tokenCount() - 1);
- unsigned line = 0, column = 0;
- const StringLiteral *fileName = 0;
+ int line = 0, column = 0;
+ const StringLiteral *fileName = nullptr;
getTokenPosition(index, &line, &column, &fileName);
if (DiagnosticClient *client = control()->diagnosticClient())
client->report(level, fileName, line, column, format, args);
}
-void TranslationUnit::warning(unsigned index, const char *format, ...)
+void TranslationUnit::warning(int index, const char *format, ...)
{
if (f._blockErrors)
return;
@@ -461,7 +461,7 @@ void TranslationUnit::warning(unsigned index, const char *format, ...)
va_end(args);
}
-void TranslationUnit::error(unsigned index, const char *format, ...)
+void TranslationUnit::error(int index, const char *format, ...)
{
if (f._blockErrors)
return;
@@ -474,7 +474,7 @@ void TranslationUnit::error(unsigned index, const char *format, ...)
va_end(args);
}
-void TranslationUnit::fatal(unsigned index, const char *format, ...)
+void TranslationUnit::fatal(int index, const char *format, ...)
{
if (f._blockErrors)
return;
@@ -487,13 +487,13 @@ void TranslationUnit::fatal(unsigned index, const char *format, ...)
va_end(args);
}
-unsigned TranslationUnit::findPreviousLineOffset(unsigned tokenIndex) const
+int TranslationUnit::findPreviousLineOffset(int tokenIndex) const
{
- unsigned lineOffset = _lineOffsets[findLineNumber(tokenAt(tokenIndex).utf16charsBegin())];
+ int lineOffset = _lineOffsets[findLineNumber(tokenAt(tokenIndex).utf16charsBegin())];
return lineOffset;
}
-bool TranslationUnit::maybeSplitGreaterGreaterToken(unsigned tokenIndex)
+bool TranslationUnit::maybeSplitGreaterGreaterToken(int tokenIndex)
{
if (tokenIndex >= tokenCount())
return false;
@@ -529,16 +529,16 @@ bool TranslationUnit::maybeSplitGreaterGreaterToken(unsigned tokenIndex)
void TranslationUnit::releaseTokensAndComments()
{
delete _tokens;
- _tokens = 0;
+ _tokens = nullptr;
delete _comments;
- _comments = 0;
+ _comments = nullptr;
}
void TranslationUnit::resetAST()
{
delete _pool;
- _pool = 0;
- _ast = 0;
+ _pool = nullptr;
+ _ast = nullptr;
}
void TranslationUnit::release()
diff --git a/src/libs/3rdparty/cplusplus/TranslationUnit.h b/src/libs/3rdparty/cplusplus/TranslationUnit.h
index 7def1a65a3..7422885a7e 100644
--- a/src/libs/3rdparty/cplusplus/TranslationUnit.h
+++ b/src/libs/3rdparty/cplusplus/TranslationUnit.h
@@ -43,29 +43,29 @@ public:
const StringLiteral *fileId() const;
const char *fileName() const;
- unsigned fileNameLength() const;
+ int fileNameLength() const;
const char *firstSourceChar() const;
const char *lastSourceChar() const;
- unsigned sourceLength() const;
+ int sourceLength() const;
- void setSource(const char *source, unsigned size);
+ void setSource(const char *source, int size);
- unsigned tokenCount() const { return _tokens ? unsigned(_tokens->size()) : unsigned(0); }
- const Token &tokenAt(unsigned index) const
+ int tokenCount() const { return _tokens ? int(_tokens->size()) : 0; }
+ const Token &tokenAt(int index) const
{ return _tokens && index < tokenCount() ? (*_tokens)[index] : nullToken; }
- Kind tokenKind(unsigned index) const { return tokenAt(index).kind(); }
- const char *spell(unsigned index) const;
+ Kind tokenKind(int index) const { return tokenAt(index).kind(); }
+ const char *spell(int index) const;
- unsigned commentCount() const;
- const Token &commentAt(unsigned index) const;
+ int commentCount() const;
+ const Token &commentAt(int index) const;
- unsigned matchingBrace(unsigned index) const;
- const Identifier *identifier(unsigned index) const;
- const Literal *literal(unsigned index) const;
- const StringLiteral *stringLiteral(unsigned index) const;
- const NumericLiteral *numericLiteral(unsigned index) const;
+ int matchingBrace(int index) const;
+ const Identifier *identifier(int index) const;
+ const Literal *literal(int index) const;
+ const StringLiteral *stringLiteral(int index) const;
+ const NumericLiteral *numericLiteral(int index) const;
MemoryPool *memoryPool() const;
AST *ast() const;
@@ -78,11 +78,11 @@ public:
return previous;
}
- void warning(unsigned index, const char *fmt, ...);
- void error(unsigned index, const char *fmt, ...);
- void fatal(unsigned index, const char *fmt, ...);
+ void warning(int index, const char *fmt, ...);
+ void error(int index, const char *fmt, ...);
+ void fatal(int index, const char *fmt, ...);
- void message(DiagnosticClient::Level level, unsigned index,
+ void message(DiagnosticClient::Level level, int index,
const char *format, va_list ap);
bool isTokenized() const;
@@ -106,45 +106,45 @@ public:
void resetAST();
void release();
- void getTokenStartPosition(unsigned index, unsigned *line,
- unsigned *column = 0,
- const StringLiteral **fileName = 0) const;
+ void getTokenStartPosition(int index, int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
- void getTokenEndPosition(unsigned index, unsigned *line,
- unsigned *column = 0,
- const StringLiteral **fileName = 0) const;
+ void getTokenEndPosition(int index, int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
- void getPosition(unsigned utf16charOffset,
- unsigned *line,
- unsigned *column = 0,
- const StringLiteral **fileName = 0) const;
+ void getPosition(int utf16charOffset,
+ int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
- void getTokenPosition(unsigned index,
- unsigned *line,
- unsigned *column = 0,
- const StringLiteral **fileName = 0) const;
+ void getTokenPosition(int index,
+ int *line,
+ int *column = nullptr,
+ const StringLiteral **fileName = nullptr) const;
- void pushLineOffset(unsigned offset);
- void pushPreprocessorLine(unsigned utf16charOffset,
- unsigned line,
+ void pushLineOffset(int offset);
+ void pushPreprocessorLine(int utf16charOffset,
+ int line,
const StringLiteral *fileName);
- unsigned findPreviousLineOffset(unsigned tokenIndex) const;
+ int findPreviousLineOffset(int tokenIndex) const;
- bool maybeSplitGreaterGreaterToken(unsigned tokenIndex);
+ bool maybeSplitGreaterGreaterToken(int tokenIndex);
LanguageFeatures languageFeatures() const { return _languageFeatures; }
void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; }
private:
struct PPLine {
- unsigned utf16charOffset;
- unsigned line;
+ int utf16charOffset;
+ int line;
const StringLiteral *fileName;
- PPLine(unsigned utf16charOffset = 0,
- unsigned line = 0,
- const StringLiteral *fileName = 0)
+ PPLine(int utf16charOffset = 0,
+ int line = 0,
+ const StringLiteral *fileName = nullptr)
: utf16charOffset(utf16charOffset), line(line), fileName(fileName)
{ }
@@ -159,9 +159,9 @@ private:
};
void releaseTokensAndComments();
- unsigned findLineNumber(unsigned utf16charOffset) const;
- unsigned findColumnNumber(unsigned utf16CharOffset, unsigned lineNumber) const;
- PPLine findPreprocessorLine(unsigned utf16charOffset) const;
+ int findLineNumber(int utf16charOffset) const;
+ int findColumnNumber(int utf16CharOffset, int lineNumber) const;
+ PPLine findPreprocessorLine(int utf16charOffset) const;
static const Token nullToken;
@@ -171,9 +171,9 @@ private:
const char *_lastSourceChar;
std::vector<Token> *_tokens;
std::vector<Token> *_comments;
- std::vector<unsigned> _lineOffsets;
+ std::vector<int> _lineOffsets;
std::vector<PPLine> _ppLines;
- typedef std::unordered_map<unsigned, std::pair<unsigned, unsigned> > TokenLineColumn;
+ typedef std::unordered_map<unsigned, std::pair<int, int> > TokenLineColumn;
TokenLineColumn _expandedLineColumn;
MemoryPool *_pool;
AST *_ast;
diff --git a/src/libs/3rdparty/cplusplus/Type.cpp b/src/libs/3rdparty/cplusplus/Type.cpp
index bad4d42eeb..e9b0f2d3c1 100644
--- a/src/libs/3rdparty/cplusplus/Type.cpp
+++ b/src/libs/3rdparty/cplusplus/Type.cpp
@@ -36,61 +36,61 @@ bool Type::isUndefinedType() const
{ return this == UndefinedType::instance(); }
bool Type::isVoidType() const
-{ return asVoidType() != 0; }
+{ return asVoidType() != nullptr; }
bool Type::isIntegerType() const
-{ return asIntegerType() != 0; }
+{ return asIntegerType() != nullptr; }
bool Type::isFloatType() const
-{ return asFloatType() != 0; }
+{ return asFloatType() != nullptr; }
bool Type::isPointerType() const
-{ return asPointerType() != 0; }
+{ return asPointerType() != nullptr; }
bool Type::isPointerToMemberType() const
-{ return asPointerToMemberType() != 0; }
+{ return asPointerToMemberType() != nullptr; }
bool Type::isReferenceType() const
-{ return asReferenceType() != 0; }
+{ return asReferenceType() != nullptr; }
bool Type::isArrayType() const
-{ return asArrayType() != 0; }
+{ return asArrayType() != nullptr; }
bool Type::isNamedType() const
-{ return asNamedType() != 0; }
+{ return asNamedType() != nullptr; }
bool Type::isFunctionType() const
-{ return asFunctionType() != 0; }
+{ return asFunctionType() != nullptr; }
bool Type::isNamespaceType() const
-{ return asNamespaceType() != 0; }
+{ return asNamespaceType() != nullptr; }
bool Type::isTemplateType() const
-{ return asTemplateType() != 0; }
+{ return asTemplateType() != nullptr; }
bool Type::isClassType() const
-{ return asClassType() != 0; }
+{ return asClassType() != nullptr; }
bool Type::isEnumType() const
-{ return asEnumType() != 0; }
+{ return asEnumType() != nullptr; }
bool Type::isForwardClassDeclarationType() const
-{ return asForwardClassDeclarationType() != 0; }
+{ return asForwardClassDeclarationType() != nullptr; }
bool Type::isObjCClassType() const
-{ return asObjCClassType() != 0; }
+{ return asObjCClassType() != nullptr; }
bool Type::isObjCProtocolType() const
-{ return asObjCProtocolType() != 0; }
+{ return asObjCProtocolType() != nullptr; }
bool Type::isObjCMethodType() const
-{ return asObjCMethodType() != 0; }
+{ return asObjCMethodType() != nullptr; }
bool Type::isObjCForwardClassDeclarationType() const
-{ return asObjCForwardClassDeclarationType() != 0; }
+{ return asObjCForwardClassDeclarationType() != nullptr; }
bool Type::isObjCForwardProtocolDeclarationType() const
-{ return asObjCForwardProtocolDeclarationType() != 0; }
+{ return asObjCForwardProtocolDeclarationType() != nullptr; }
void Type::accept(TypeVisitor *visitor)
{
diff --git a/src/libs/3rdparty/cplusplus/Type.h b/src/libs/3rdparty/cplusplus/Type.h
index 25f260c2cd..72116daf37 100644
--- a/src/libs/3rdparty/cplusplus/Type.h
+++ b/src/libs/3rdparty/cplusplus/Type.h
@@ -51,52 +51,52 @@ public:
bool isObjCForwardClassDeclarationType() const;
bool isObjCForwardProtocolDeclarationType() const;
- virtual const UndefinedType *asUndefinedType() const { return 0; }
- virtual const VoidType *asVoidType() const { return 0; }
- virtual const IntegerType *asIntegerType() const { return 0; }
- virtual const FloatType *asFloatType() const { return 0; }
- virtual const PointerType *asPointerType() const { return 0; }
- virtual const PointerToMemberType *asPointerToMemberType() const { return 0; }
- virtual const ReferenceType *asReferenceType() const { return 0; }
- virtual const ArrayType *asArrayType() const { return 0; }
- virtual const NamedType *asNamedType() const { return 0; }
- virtual const Function *asFunctionType() const { return 0; }
- virtual const Namespace *asNamespaceType() const { return 0; }
- virtual const Template *asTemplateType() const { return 0; }
- virtual const Class *asClassType() const { return 0; }
- virtual const Enum *asEnumType() const { return 0; }
- virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
- virtual const ObjCClass *asObjCClassType() const { return 0; }
- virtual const ObjCProtocol *asObjCProtocolType() const { return 0; }
- virtual const ObjCMethod *asObjCMethodType() const { return 0; }
- virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const { return 0; }
- virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const { return 0; }
+ virtual const UndefinedType *asUndefinedType() const { return nullptr; }
+ virtual const VoidType *asVoidType() const { return nullptr; }
+ virtual const IntegerType *asIntegerType() const { return nullptr; }
+ virtual const FloatType *asFloatType() const { return nullptr; }
+ virtual const PointerType *asPointerType() const { return nullptr; }
+ virtual const PointerToMemberType *asPointerToMemberType() const { return nullptr; }
+ virtual const ReferenceType *asReferenceType() const { return nullptr; }
+ virtual const ArrayType *asArrayType() const { return nullptr; }
+ virtual const NamedType *asNamedType() const { return nullptr; }
+ virtual const Function *asFunctionType() const { return nullptr; }
+ virtual const Namespace *asNamespaceType() const { return nullptr; }
+ virtual const Template *asTemplateType() const { return nullptr; }
+ virtual const Class *asClassType() const { return nullptr; }
+ virtual const Enum *asEnumType() const { return nullptr; }
+ virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return nullptr; }
+ virtual const ObjCClass *asObjCClassType() const { return nullptr; }
+ virtual const ObjCProtocol *asObjCProtocolType() const { return nullptr; }
+ virtual const ObjCMethod *asObjCMethodType() const { return nullptr; }
+ virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const { return nullptr; }
+ virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const { return nullptr; }
- virtual UndefinedType *asUndefinedType() { return 0; }
- virtual VoidType *asVoidType() { return 0; }
- virtual IntegerType *asIntegerType() { return 0; }
- virtual FloatType *asFloatType() { return 0; }
- virtual PointerType *asPointerType() { return 0; }
- virtual PointerToMemberType *asPointerToMemberType() { return 0; }
- virtual ReferenceType *asReferenceType() { return 0; }
- virtual ArrayType *asArrayType() { return 0; }
- virtual NamedType *asNamedType() { return 0; }
- virtual Function *asFunctionType() { return 0; }
- virtual Namespace *asNamespaceType() { return 0; }
- virtual Template *asTemplateType() { return 0; }
- virtual Class *asClassType() { return 0; }
- virtual Enum *asEnumType() { return 0; }
- virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }
- virtual ObjCClass *asObjCClassType() { return 0; }
- virtual ObjCProtocol *asObjCProtocolType() { return 0; }
- virtual ObjCMethod *asObjCMethodType() { return 0; }
- virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() { return 0; }
- virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() { return 0; }
+ virtual UndefinedType *asUndefinedType() { return nullptr; }
+ virtual VoidType *asVoidType() { return nullptr; }
+ virtual IntegerType *asIntegerType() { return nullptr; }
+ virtual FloatType *asFloatType() { return nullptr; }
+ virtual PointerType *asPointerType() { return nullptr; }
+ virtual PointerToMemberType *asPointerToMemberType() { return nullptr; }
+ virtual ReferenceType *asReferenceType() { return nullptr; }
+ virtual ArrayType *asArrayType() { return nullptr; }
+ virtual NamedType *asNamedType() { return nullptr; }
+ virtual Function *asFunctionType() { return nullptr; }
+ virtual Namespace *asNamespaceType() { return nullptr; }
+ virtual Template *asTemplateType() { return nullptr; }
+ virtual Class *asClassType() { return nullptr; }
+ virtual Enum *asEnumType() { return nullptr; }
+ virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return nullptr; }
+ virtual ObjCClass *asObjCClassType() { return nullptr; }
+ virtual ObjCProtocol *asObjCProtocolType() { return nullptr; }
+ virtual ObjCMethod *asObjCMethodType() { return nullptr; }
+ virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() { return nullptr; }
+ virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() { return nullptr; }
void accept(TypeVisitor *visitor);
static void accept(Type *type, TypeVisitor *visitor);
- bool match(const Type *other, Matcher *matcher = 0) const;
+ bool match(const Type *other, Matcher *matcher = nullptr) const;
protected:
virtual void accept0(TypeVisitor *visitor) = 0;
diff --git a/src/libs/3rdparty/json/json.hpp b/src/libs/3rdparty/json/json.hpp
new file mode 100644
index 0000000000..c66d8243ad
--- /dev/null
+++ b/src/libs/3rdparty/json/json.hpp
@@ -0,0 +1,20842 @@
+/*
+ __ _____ _____ _____
+ __| | __| | | | JSON for Modern C++
+| | |__ | | | | | | version 3.6.1
+|_____|_____|_____|_|___| https://github.com/nlohmann/json
+
+Licensed under the MIT License <http://opensource.org/licenses/MIT>.
+SPDX-License-Identifier: MIT
+Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef INCLUDE_NLOHMANN_JSON_HPP_
+#define INCLUDE_NLOHMANN_JSON_HPP_
+
+#define NLOHMANN_JSON_VERSION_MAJOR 3
+#define NLOHMANN_JSON_VERSION_MINOR 6
+#define NLOHMANN_JSON_VERSION_PATCH 1
+
+#include <algorithm> // all_of, find, for_each
+#include <cassert> // assert
+#include <ciso646> // and, not, or
+#include <cstddef> // nullptr_t, ptrdiff_t, size_t
+#include <functional> // hash, less
+#include <initializer_list> // initializer_list
+#include <iosfwd> // istream, ostream
+#include <iterator> // random_access_iterator_tag
+#include <memory> // unique_ptr
+#include <numeric> // accumulate
+#include <string> // string, stoi, to_string
+#include <utility> // declval, forward, move, pair, swap
+#include <vector> // vector
+
+// #include <nlohmann/adl_serializer.hpp>
+
+
+#include <utility>
+
+// #include <nlohmann/detail/conversions/from_json.hpp>
+
+
+#include <algorithm> // transform
+#include <array> // array
+#include <ciso646> // and, not
+#include <forward_list> // forward_list
+#include <iterator> // inserter, front_inserter, end
+#include <map> // map
+#include <string> // string
+#include <tuple> // tuple, make_tuple
+#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
+#include <unordered_map> // unordered_map
+#include <utility> // pair, declval
+#include <valarray> // valarray
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+
+#include <exception> // exception
+#include <stdexcept> // runtime_error
+#include <string> // to_string
+
+// #include <nlohmann/detail/input/position_t.hpp>
+
+
+#include <cstddef> // size_t
+
+namespace nlohmann
+{
+namespace detail
+{
+/// struct to capture the start position of the current token
+struct position_t
+{
+ /// the total number of characters read
+ std::size_t chars_read_total = 0;
+ /// the number of characters read in the current line
+ std::size_t chars_read_current_line = 0;
+ /// the number of lines read
+ std::size_t lines_read = 0;
+
+ /// conversion to size_t to preserve SAX interface
+ constexpr operator size_t() const
+ {
+ return chars_read_total;
+ }
+};
+
+} // namespace detail
+} // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+////////////////
+// exceptions //
+////////////////
+
+/*!
+@brief general exception of the @ref basic_json class
+
+This class is an extension of `std::exception` objects with a member @a id for
+exception ids. It is used as the base class for all exceptions thrown by the
+@ref basic_json class. This class can hence be used as "wildcard" to catch
+exceptions.
+
+Subclasses:
+- @ref parse_error for exceptions indicating a parse error
+- @ref invalid_iterator for exceptions indicating errors with iterators
+- @ref type_error for exceptions indicating executing a member function with
+ a wrong type
+- @ref out_of_range for exceptions indicating access out of the defined range
+- @ref other_error for exceptions indicating other library errors
+
+@internal
+@note To have nothrow-copy-constructible exceptions, we internally use
+ `std::runtime_error` which can cope with arbitrary-length error messages.
+ Intermediate strings are built with static functions and then passed to
+ the actual constructor.
+@endinternal
+
+@liveexample{The following code shows how arbitrary library exceptions can be
+caught.,exception}
+
+@since version 3.0.0
+*/
+class exception : public std::exception
+{
+ public:
+ /// returns the explanatory string
+ const char* what() const noexcept override
+ {
+ return m.what();
+ }
+
+ /// the id of the exception
+ const int id;
+
+ protected:
+ exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
+
+ static std::string name(const std::string& ename, int id_)
+ {
+ return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
+ }
+
+ private:
+ /// an exception object as storage for error messages
+ std::runtime_error m;
+};
+
+/*!
+@brief exception indicating a parse error
+
+This exception is thrown by the library when a parse error occurs. Parse errors
+can occur during the deserialization of JSON text, CBOR, MessagePack, as well
+as when using JSON Patch.
+
+Member @a byte holds the byte index of the last read character in the input
+file.
+
+Exceptions have ids 1xx.
+
+name / id | example message | description
+------------------------------ | --------------- | -------------------------
+json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
+json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
+json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
+json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
+json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
+json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
+json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
+json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
+json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
+json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
+json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
+json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
+json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
+
+@note For an input with n bytes, 1 is the index of the first character and n+1
+ is the index of the terminating null byte or the end of file. This also
+ holds true when reading a byte vector (CBOR or MessagePack).
+
+@liveexample{The following code shows how a `parse_error` exception can be
+caught.,parse_error}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref type_error for exceptions indicating executing a member function with
+ a wrong type
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class parse_error : public exception
+{
+ public:
+ /*!
+ @brief create a parse error exception
+ @param[in] id_ the id of the exception
+ @param[in] pos the position where the error occurred (or with
+ chars_read_total=0 if the position cannot be
+ determined)
+ @param[in] what_arg the explanatory string
+ @return parse_error object
+ */
+ static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
+ {
+ std::string w = exception::name("parse_error", id_) + "parse error" +
+ position_string(pos) + ": " + what_arg;
+ return parse_error(id_, pos.chars_read_total, w.c_str());
+ }
+
+ static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
+ {
+ std::string w = exception::name("parse_error", id_) + "parse error" +
+ (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
+ ": " + what_arg;
+ return parse_error(id_, byte_, w.c_str());
+ }
+
+ /*!
+ @brief byte index of the parse error
+
+ The byte index of the last read character in the input file.
+
+ @note For an input with n bytes, 1 is the index of the first character and
+ n+1 is the index of the terminating null byte or the end of file.
+ This also holds true when reading a byte vector (CBOR or MessagePack).
+ */
+ const std::size_t byte;
+
+ private:
+ parse_error(int id_, std::size_t byte_, const char* what_arg)
+ : exception(id_, what_arg), byte(byte_) {}
+
+ static std::string position_string(const position_t& pos)
+ {
+ return " at line " + std::to_string(pos.lines_read + 1) +
+ ", column " + std::to_string(pos.chars_read_current_line);
+ }
+};
+
+/*!
+@brief exception indicating errors with iterators
+
+This exception is thrown if iterators passed to a library function do not match
+the expected semantics.
+
+Exceptions have ids 2xx.
+
+name / id | example message | description
+----------------------------------- | --------------- | -------------------------
+json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
+json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
+json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
+json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
+json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
+json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
+json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
+json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
+json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
+json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
+json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
+json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
+json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
+json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
+
+@liveexample{The following code shows how an `invalid_iterator` exception can be
+caught.,invalid_iterator}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref type_error for exceptions indicating executing a member function with
+ a wrong type
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class invalid_iterator : public exception
+{
+ public:
+ static invalid_iterator create(int id_, const std::string& what_arg)
+ {
+ std::string w = exception::name("invalid_iterator", id_) + what_arg;
+ return invalid_iterator(id_, w.c_str());
+ }
+
+ private:
+ invalid_iterator(int id_, const char* what_arg)
+ : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating executing a member function with a wrong type
+
+This exception is thrown in case of a type error; that is, a library function is
+executed on a JSON value whose type does not match the expected semantics.
+
+Exceptions have ids 3xx.
+
+name / id | example message | description
+----------------------------- | --------------- | -------------------------
+json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
+json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
+json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
+json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
+json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
+json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
+json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
+json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
+json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
+json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
+json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
+json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
+json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
+json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
+json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
+json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
+json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
+
+@liveexample{The following code shows how a `type_error` exception can be
+caught.,type_error}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class type_error : public exception
+{
+ public:
+ static type_error create(int id_, const std::string& what_arg)
+ {
+ std::string w = exception::name("type_error", id_) + what_arg;
+ return type_error(id_, w.c_str());
+ }
+
+ private:
+ type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating access out of the defined range
+
+This exception is thrown in case a library function is called on an input
+parameter that exceeds the expected range, for instance in case of array
+indices or nonexisting object keys.
+
+Exceptions have ids 4xx.
+
+name / id | example message | description
+------------------------------- | --------------- | -------------------------
+json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
+json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
+json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
+json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
+json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
+json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
+json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
+json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
+json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
+
+@liveexample{The following code shows how an `out_of_range` exception can be
+caught.,out_of_range}
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref type_error for exceptions indicating executing a member function with
+ a wrong type
+@sa - @ref other_error for exceptions indicating other library errors
+
+@since version 3.0.0
+*/
+class out_of_range : public exception
+{
+ public:
+ static out_of_range create(int id_, const std::string& what_arg)
+ {
+ std::string w = exception::name("out_of_range", id_) + what_arg;
+ return out_of_range(id_, w.c_str());
+ }
+
+ private:
+ out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+
+/*!
+@brief exception indicating other library errors
+
+This exception is thrown in case of errors that cannot be classified with the
+other exception types.
+
+Exceptions have ids 5xx.
+
+name / id | example message | description
+------------------------------ | --------------- | -------------------------
+json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
+
+@sa - @ref exception for the base class of the library exceptions
+@sa - @ref parse_error for exceptions indicating a parse error
+@sa - @ref invalid_iterator for exceptions indicating errors with iterators
+@sa - @ref type_error for exceptions indicating executing a member function with
+ a wrong type
+@sa - @ref out_of_range for exceptions indicating access out of the defined range
+
+@liveexample{The following code shows how an `other_error` exception can be
+caught.,other_error}
+
+@since version 3.0.0
+*/
+class other_error : public exception
+{
+ public:
+ static other_error create(int id_, const std::string& what_arg)
+ {
+ std::string w = exception::name("other_error", id_) + what_arg;
+ return other_error(id_, w.c_str());
+ }
+
+ private:
+ other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+#include <utility> // pair
+
+// This file contains all internal macro definitions
+// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
+
+// exclude unsupported compilers
+#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
+ #if defined(__clang__)
+ #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
+ #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
+ #endif
+ #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
+ #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
+ #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
+ #endif
+ #endif
+#endif
+
+// disable float-equal warnings on GCC/clang
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+// disable documentation warnings on clang
+#if defined(__clang__)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdocumentation"
+#endif
+
+// allow for portable deprecation warnings
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+ #define JSON_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+ #define JSON_DEPRECATED __declspec(deprecated)
+#else
+ #define JSON_DEPRECATED
+#endif
+
+// allow for portable nodiscard warnings
+#if defined(__has_cpp_attribute)
+ #if __has_cpp_attribute(nodiscard)
+ #define JSON_NODISCARD [[nodiscard]]
+ #elif __has_cpp_attribute(gnu::warn_unused_result)
+ #define JSON_NODISCARD [[gnu::warn_unused_result]]
+ #else
+ #define JSON_NODISCARD
+ #endif
+#else
+ #define JSON_NODISCARD
+#endif
+
+// allow to disable exceptions
+#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
+ #define JSON_THROW(exception) throw exception
+ #define JSON_TRY try
+ #define JSON_CATCH(exception) catch(exception)
+ #define JSON_INTERNAL_CATCH(exception) catch(exception)
+#else
+ #include <cstdlib>
+ #define JSON_THROW(exception) std::abort()
+ #define JSON_TRY if (true)
+ #define JSON_CATCH(exception) if (false)
+ #define JSON_INTERNAL_CATCH(exception) if (false)
+#endif
+
+// override exception macros
+#if defined(JSON_THROW_USER)
+ #undef JSON_THROW
+ #define JSON_THROW JSON_THROW_USER
+#endif
+#if defined(JSON_TRY_USER)
+ #undef JSON_TRY
+ #define JSON_TRY JSON_TRY_USER
+#endif
+#if defined(JSON_CATCH_USER)
+ #undef JSON_CATCH
+ #define JSON_CATCH JSON_CATCH_USER
+ #undef JSON_INTERNAL_CATCH
+ #define JSON_INTERNAL_CATCH JSON_CATCH_USER
+#endif
+#if defined(JSON_INTERNAL_CATCH_USER)
+ #undef JSON_INTERNAL_CATCH
+ #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
+#endif
+
+// manual branch prediction
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+ #define JSON_LIKELY(x) __builtin_expect(x, 1)
+ #define JSON_UNLIKELY(x) __builtin_expect(x, 0)
+#else
+ #define JSON_LIKELY(x) x
+ #define JSON_UNLIKELY(x) x
+#endif
+
+// C++ language standard detection
+#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
+ #define JSON_HAS_CPP_17
+ #define JSON_HAS_CPP_14
+#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
+ #define JSON_HAS_CPP_14
+#endif
+
+/*!
+@brief macro to briefly define a mapping between an enum and JSON
+@def NLOHMANN_JSON_SERIALIZE_ENUM
+@since version 3.4.0
+*/
+#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
+ template<typename BasicJsonType> \
+ inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
+ { \
+ static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
+ static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
+ auto it = std::find_if(std::begin(m), std::end(m), \
+ [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
+ { \
+ return ej_pair.first == e; \
+ }); \
+ j = ((it != std::end(m)) ? it : std::begin(m))->second; \
+ } \
+ template<typename BasicJsonType> \
+ inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
+ { \
+ static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
+ static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
+ auto it = std::find_if(std::begin(m), std::end(m), \
+ [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
+ { \
+ return ej_pair.second == j; \
+ }); \
+ e = ((it != std::end(m)) ? it : std::begin(m))->first; \
+ }
+
+// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
+// may be removed in the future once the class is split.
+
+#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
+ template<template<typename, typename, typename...> class ObjectType, \
+ template<typename, typename...> class ArrayType, \
+ class StringType, class BooleanType, class NumberIntegerType, \
+ class NumberUnsignedType, class NumberFloatType, \
+ template<typename> class AllocatorType, \
+ template<typename, typename = void> class JSONSerializer>
+
+#define NLOHMANN_BASIC_JSON_TPL \
+ basic_json<ObjectType, ArrayType, StringType, BooleanType, \
+ NumberIntegerType, NumberUnsignedType, NumberFloatType, \
+ AllocatorType, JSONSerializer>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+
+#include <ciso646> // not
+#include <cstddef> // size_t
+#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
+
+namespace nlohmann
+{
+namespace detail
+{
+// alias templates to reduce boilerplate
+template<bool B, typename T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+template<typename T>
+using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+// implementation of C++14 index_sequence and affiliates
+// source: https://stackoverflow.com/a/32223343
+template<std::size_t... Ints>
+struct index_sequence
+{
+ using type = index_sequence;
+ using value_type = std::size_t;
+ static constexpr std::size_t size() noexcept
+ {
+ return sizeof...(Ints);
+ }
+};
+
+template<class Sequence1, class Sequence2>
+struct merge_and_renumber;
+
+template<std::size_t... I1, std::size_t... I2>
+struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
+ : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
+
+template<std::size_t N>
+struct make_index_sequence
+ : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
+ typename make_index_sequence < N - N / 2 >::type > {};
+
+template<> struct make_index_sequence<0> : index_sequence<> {};
+template<> struct make_index_sequence<1> : index_sequence<0> {};
+
+template<typename... Ts>
+using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
+
+// dispatch utility (taken from ranges-v3)
+template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
+template<> struct priority_tag<0> {};
+
+// taken from ranges-v3
+template<typename T>
+struct static_const
+{
+ static constexpr T value{};
+};
+
+template<typename T>
+constexpr T static_const<T>::value;
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+
+#include <ciso646> // not
+#include <limits> // numeric_limits
+#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
+#include <utility> // declval
+
+// #include <nlohmann/detail/iterators/iterator_traits.hpp>
+
+
+#include <iterator> // random_access_iterator_tag
+
+// #include <nlohmann/detail/meta/void_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template <typename ...Ts> struct make_void
+{
+ using type = void;
+};
+template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template <typename It, typename = void>
+struct iterator_types {};
+
+template <typename It>
+struct iterator_types <
+ It,
+ void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
+ typename It::reference, typename It::iterator_category >>
+{
+ using difference_type = typename It::difference_type;
+ using value_type = typename It::value_type;
+ using pointer = typename It::pointer;
+ using reference = typename It::reference;
+ using iterator_category = typename It::iterator_category;
+};
+
+// This is required as some compilers implement std::iterator_traits in a way that
+// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
+template <typename T, typename = void>
+struct iterator_traits
+{
+};
+
+template <typename T>
+struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
+ : iterator_types<T>
+{
+};
+
+template <typename T>
+struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
+{
+ using iterator_category = std::random_access_iterator_tag;
+ using value_type = T;
+ using difference_type = ptrdiff_t;
+ using pointer = T*;
+ using reference = T&;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/detected.hpp>
+
+
+#include <type_traits>
+
+// #include <nlohmann/detail/meta/void_t.hpp>
+
+
+// http://en.cppreference.com/w/cpp/experimental/is_detected
+namespace nlohmann
+{
+namespace detail
+{
+struct nonesuch
+{
+ nonesuch() = delete;
+ ~nonesuch() = delete;
+ nonesuch(nonesuch const&) = delete;
+ nonesuch(nonesuch const&&) = delete;
+ void operator=(nonesuch const&) = delete;
+ void operator=(nonesuch&&) = delete;
+};
+
+template <class Default,
+ class AlwaysVoid,
+ template <class...> class Op,
+ class... Args>
+struct detector
+{
+ using value_t = std::false_type;
+ using type = Default;
+};
+
+template <class Default, template <class...> class Op, class... Args>
+struct detector<Default, void_t<Op<Args...>>, Op, Args...>
+{
+ using value_t = std::true_type;
+ using type = Op<Args...>;
+};
+
+template <template <class...> class Op, class... Args>
+using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
+
+template <template <class...> class Op, class... Args>
+using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
+
+template <class Default, template <class...> class Op, class... Args>
+using detected_or = detector<Default, void, Op, Args...>;
+
+template <class Default, template <class...> class Op, class... Args>
+using detected_or_t = typename detected_or<Default, Op, Args...>::type;
+
+template <class Expected, template <class...> class Op, class... Args>
+using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
+
+template <class To, template <class...> class Op, class... Args>
+using is_detected_convertible =
+ std::is_convertible<detected_t<Op, Args...>, To>;
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/json_fwd.hpp>
+#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
+#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
+
+#include <cstdint> // int64_t, uint64_t
+#include <map> // map
+#include <memory> // allocator
+#include <string> // string
+#include <vector> // vector
+
+/*!
+@brief namespace for Niels Lohmann
+@see https://github.com/nlohmann
+@since version 1.0.0
+*/
+namespace nlohmann
+{
+/*!
+@brief default JSONSerializer template argument
+
+This serializer ignores the template arguments and uses ADL
+([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
+for serialization.
+*/
+template<typename T = void, typename SFINAE = void>
+struct adl_serializer;
+
+template<template<typename U, typename V, typename... Args> class ObjectType =
+ std::map,
+ template<typename U, typename... Args> class ArrayType = std::vector,
+ class StringType = std::string, class BooleanType = bool,
+ class NumberIntegerType = std::int64_t,
+ class NumberUnsignedType = std::uint64_t,
+ class NumberFloatType = double,
+ template<typename U> class AllocatorType = std::allocator,
+ template<typename T, typename SFINAE = void> class JSONSerializer =
+ adl_serializer>
+class basic_json;
+
+/*!
+@brief JSON Pointer
+
+A JSON pointer defines a string syntax for identifying a specific value
+within a JSON document. It can be used with functions `at` and
+`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
+
+@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
+
+@since version 2.0.0
+*/
+template<typename BasicJsonType>
+class json_pointer;
+
+/*!
+@brief default JSON class
+
+This type is the default specialization of the @ref basic_json class which
+uses the standard template types.
+
+@since version 1.0.0
+*/
+using json = basic_json<>;
+} // namespace nlohmann
+
+#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
+
+
+namespace nlohmann
+{
+/*!
+@brief detail namespace with internal helper functions
+
+This namespace collects functions that should not be exposed,
+implementations of some @ref basic_json methods, and meta-programming helpers.
+
+@since version 2.1.0
+*/
+namespace detail
+{
+/////////////
+// helpers //
+/////////////
+
+// Note to maintainers:
+//
+// Every trait in this file expects a non CV-qualified type.
+// The only exceptions are in the 'aliases for detected' section
+// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
+//
+// In this case, T has to be properly CV-qualified to constraint the function arguments
+// (e.g. to_json(BasicJsonType&, const T&))
+
+template<typename> struct is_basic_json : std::false_type {};
+
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
+
+//////////////////////////
+// aliases for detected //
+//////////////////////////
+
+template <typename T>
+using mapped_type_t = typename T::mapped_type;
+
+template <typename T>
+using key_type_t = typename T::key_type;
+
+template <typename T>
+using value_type_t = typename T::value_type;
+
+template <typename T>
+using difference_type_t = typename T::difference_type;
+
+template <typename T>
+using pointer_t = typename T::pointer;
+
+template <typename T>
+using reference_t = typename T::reference;
+
+template <typename T>
+using iterator_category_t = typename T::iterator_category;
+
+template <typename T>
+using iterator_t = typename T::iterator;
+
+template <typename T, typename... Args>
+using to_json_function = decltype(T::to_json(std::declval<Args>()...));
+
+template <typename T, typename... Args>
+using from_json_function = decltype(T::from_json(std::declval<Args>()...));
+
+template <typename T, typename U>
+using get_template_function = decltype(std::declval<T>().template get<U>());
+
+// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
+template <typename BasicJsonType, typename T, typename = void>
+struct has_from_json : std::false_type {};
+
+template <typename BasicJsonType, typename T>
+struct has_from_json<BasicJsonType, T,
+ enable_if_t<not is_basic_json<T>::value>>
+{
+ using serializer = typename BasicJsonType::template json_serializer<T, void>;
+
+ static constexpr bool value =
+ is_detected_exact<void, from_json_function, serializer,
+ const BasicJsonType&, T&>::value;
+};
+
+// This trait checks if JSONSerializer<T>::from_json(json const&) exists
+// this overload is used for non-default-constructible user-defined-types
+template <typename BasicJsonType, typename T, typename = void>
+struct has_non_default_from_json : std::false_type {};
+
+template<typename BasicJsonType, typename T>
+struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
+{
+ using serializer = typename BasicJsonType::template json_serializer<T, void>;
+
+ static constexpr bool value =
+ is_detected_exact<T, from_json_function, serializer,
+ const BasicJsonType&>::value;
+};
+
+// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
+// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
+template <typename BasicJsonType, typename T, typename = void>
+struct has_to_json : std::false_type {};
+
+template <typename BasicJsonType, typename T>
+struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
+{
+ using serializer = typename BasicJsonType::template json_serializer<T, void>;
+
+ static constexpr bool value =
+ is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
+ T>::value;
+};
+
+
+///////////////////
+// is_ functions //
+///////////////////
+
+template <typename T, typename = void>
+struct is_iterator_traits : std::false_type {};
+
+template <typename T>
+struct is_iterator_traits<iterator_traits<T>>
+{
+ private:
+ using traits = iterator_traits<T>;
+
+ public:
+ static constexpr auto value =
+ is_detected<value_type_t, traits>::value &&
+ is_detected<difference_type_t, traits>::value &&
+ is_detected<pointer_t, traits>::value &&
+ is_detected<iterator_category_t, traits>::value &&
+ is_detected<reference_t, traits>::value;
+};
+
+// source: https://stackoverflow.com/a/37193089/4116453
+
+template <typename T, typename = void>
+struct is_complete_type : std::false_type {};
+
+template <typename T>
+struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
+
+template <typename BasicJsonType, typename CompatibleObjectType,
+ typename = void>
+struct is_compatible_object_type_impl : std::false_type {};
+
+template <typename BasicJsonType, typename CompatibleObjectType>
+struct is_compatible_object_type_impl <
+ BasicJsonType, CompatibleObjectType,
+ enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
+ is_detected<key_type_t, CompatibleObjectType>::value >>
+{
+
+ using object_t = typename BasicJsonType::object_t;
+
+ // macOS's is_constructible does not play well with nonesuch...
+ static constexpr bool value =
+ std::is_constructible<typename object_t::key_type,
+ typename CompatibleObjectType::key_type>::value and
+ std::is_constructible<typename object_t::mapped_type,
+ typename CompatibleObjectType::mapped_type>::value;
+};
+
+template <typename BasicJsonType, typename CompatibleObjectType>
+struct is_compatible_object_type
+ : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
+
+template <typename BasicJsonType, typename ConstructibleObjectType,
+ typename = void>
+struct is_constructible_object_type_impl : std::false_type {};
+
+template <typename BasicJsonType, typename ConstructibleObjectType>
+struct is_constructible_object_type_impl <
+ BasicJsonType, ConstructibleObjectType,
+ enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
+ is_detected<key_type_t, ConstructibleObjectType>::value >>
+{
+ using object_t = typename BasicJsonType::object_t;
+
+ static constexpr bool value =
+ (std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
+ std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
+ (has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value or
+ has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type >::value);
+};
+
+template <typename BasicJsonType, typename ConstructibleObjectType>
+struct is_constructible_object_type
+ : is_constructible_object_type_impl<BasicJsonType,
+ ConstructibleObjectType> {};
+
+template <typename BasicJsonType, typename CompatibleStringType,
+ typename = void>
+struct is_compatible_string_type_impl : std::false_type {};
+
+template <typename BasicJsonType, typename CompatibleStringType>
+struct is_compatible_string_type_impl <
+ BasicJsonType, CompatibleStringType,
+ enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
+ value_type_t, CompatibleStringType>::value >>
+{
+ static constexpr auto value =
+ std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
+};
+
+template <typename BasicJsonType, typename ConstructibleStringType>
+struct is_compatible_string_type
+ : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
+
+template <typename BasicJsonType, typename ConstructibleStringType,
+ typename = void>
+struct is_constructible_string_type_impl : std::false_type {};
+
+template <typename BasicJsonType, typename ConstructibleStringType>
+struct is_constructible_string_type_impl <
+ BasicJsonType, ConstructibleStringType,
+ enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
+ value_type_t, ConstructibleStringType>::value >>
+{
+ static constexpr auto value =
+ std::is_constructible<ConstructibleStringType,
+ typename BasicJsonType::string_t>::value;
+};
+
+template <typename BasicJsonType, typename ConstructibleStringType>
+struct is_constructible_string_type
+ : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
+
+template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
+struct is_compatible_array_type_impl : std::false_type {};
+
+template <typename BasicJsonType, typename CompatibleArrayType>
+struct is_compatible_array_type_impl <
+ BasicJsonType, CompatibleArrayType,
+ enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
+ is_detected<iterator_t, CompatibleArrayType>::value and
+// This is needed because json_reverse_iterator has a ::iterator type...
+// Therefore it is detected as a CompatibleArrayType.
+// The real fix would be to have an Iterable concept.
+ not is_iterator_traits<
+ iterator_traits<CompatibleArrayType>>::value >>
+{
+ static constexpr bool value =
+ std::is_constructible<BasicJsonType,
+ typename CompatibleArrayType::value_type>::value;
+};
+
+template <typename BasicJsonType, typename CompatibleArrayType>
+struct is_compatible_array_type
+ : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
+
+template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
+struct is_constructible_array_type_impl : std::false_type {};
+
+template <typename BasicJsonType, typename ConstructibleArrayType>
+struct is_constructible_array_type_impl <
+ BasicJsonType, ConstructibleArrayType,
+ enable_if_t<std::is_same<ConstructibleArrayType,
+ typename BasicJsonType::value_type>::value >>
+ : std::true_type {};
+
+template <typename BasicJsonType, typename ConstructibleArrayType>
+struct is_constructible_array_type_impl <
+ BasicJsonType, ConstructibleArrayType,
+ enable_if_t<not std::is_same<ConstructibleArrayType,
+ typename BasicJsonType::value_type>::value and
+ is_detected<value_type_t, ConstructibleArrayType>::value and
+ is_detected<iterator_t, ConstructibleArrayType>::value and
+ is_complete_type<
+ detected_t<value_type_t, ConstructibleArrayType>>::value >>
+{
+ static constexpr bool value =
+ // This is needed because json_reverse_iterator has a ::iterator type,
+ // furthermore, std::back_insert_iterator (and other iterators) have a base class `iterator`...
+ // Therefore it is detected as a ConstructibleArrayType.
+ // The real fix would be to have an Iterable concept.
+ not is_iterator_traits <
+ iterator_traits<ConstructibleArrayType >>::value and
+
+ (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
+ has_from_json<BasicJsonType,
+ typename ConstructibleArrayType::value_type>::value or
+ has_non_default_from_json <
+ BasicJsonType, typename ConstructibleArrayType::value_type >::value);
+};
+
+template <typename BasicJsonType, typename ConstructibleArrayType>
+struct is_constructible_array_type
+ : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
+
+template <typename RealIntegerType, typename CompatibleNumberIntegerType,
+ typename = void>
+struct is_compatible_integer_type_impl : std::false_type {};
+
+template <typename RealIntegerType, typename CompatibleNumberIntegerType>
+struct is_compatible_integer_type_impl <
+ RealIntegerType, CompatibleNumberIntegerType,
+ enable_if_t<std::is_integral<RealIntegerType>::value and
+ std::is_integral<CompatibleNumberIntegerType>::value and
+ not std::is_same<bool, CompatibleNumberIntegerType>::value >>
+{
+ // is there an assert somewhere on overflows?
+ using RealLimits = std::numeric_limits<RealIntegerType>;
+ using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
+
+ static constexpr auto value =
+ std::is_constructible<RealIntegerType,
+ CompatibleNumberIntegerType>::value and
+ CompatibleLimits::is_integer and
+ RealLimits::is_signed == CompatibleLimits::is_signed;
+};
+
+template <typename RealIntegerType, typename CompatibleNumberIntegerType>
+struct is_compatible_integer_type
+ : is_compatible_integer_type_impl<RealIntegerType,
+ CompatibleNumberIntegerType> {};
+
+template <typename BasicJsonType, typename CompatibleType, typename = void>
+struct is_compatible_type_impl: std::false_type {};
+
+template <typename BasicJsonType, typename CompatibleType>
+struct is_compatible_type_impl <
+ BasicJsonType, CompatibleType,
+ enable_if_t<is_complete_type<CompatibleType>::value >>
+{
+ static constexpr bool value =
+ has_to_json<BasicJsonType, CompatibleType>::value;
+};
+
+template <typename BasicJsonType, typename CompatibleType>
+struct is_compatible_type
+ : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+#include <array> // array
+#include <ciso646> // and
+#include <cstddef> // size_t
+#include <cstdint> // uint8_t
+#include <string> // string
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////////////
+// JSON type enumeration //
+///////////////////////////
+
+/*!
+@brief the JSON type enumeration
+
+This enumeration collects the different JSON types. It is internally used to
+distinguish the stored values, and the functions @ref basic_json::is_null(),
+@ref basic_json::is_object(), @ref basic_json::is_array(),
+@ref basic_json::is_string(), @ref basic_json::is_boolean(),
+@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
+@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
+@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
+@ref basic_json::is_structured() rely on it.
+
+@note There are three enumeration entries (number_integer, number_unsigned, and
+number_float), because the library distinguishes these three types for numbers:
+@ref basic_json::number_unsigned_t is used for unsigned integers,
+@ref basic_json::number_integer_t is used for signed integers, and
+@ref basic_json::number_float_t is used for floating-point numbers or to
+approximate integers which do not fit in the limits of their respective type.
+
+@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
+value with the default value for a given type
+
+@since version 1.0.0
+*/
+enum class value_t : std::uint8_t
+{
+ null, ///< null value
+ object, ///< object (unordered set of name/value pairs)
+ array, ///< array (ordered collection of values)
+ string, ///< string value
+ boolean, ///< boolean value
+ number_integer, ///< number value (signed integer)
+ number_unsigned, ///< number value (unsigned integer)
+ number_float, ///< number value (floating-point)
+ discarded ///< discarded by the the parser callback function
+};
+
+/*!
+@brief comparison operator for JSON types
+
+Returns an ordering that is similar to Python:
+- order: null < boolean < number < object < array < string
+- furthermore, each type is not smaller than itself
+- discarded values are not comparable
+
+@since version 1.0.0
+*/
+inline bool operator<(const value_t lhs, const value_t rhs) noexcept
+{
+ static constexpr std::array<std::uint8_t, 8> order = {{
+ 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
+ 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
+ }
+ };
+
+ const auto l_index = static_cast<std::size_t>(lhs);
+ const auto r_index = static_cast<std::size_t>(rhs);
+ return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
+}
+} // namespace detail
+} // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
+{
+ if (JSON_UNLIKELY(not j.is_null()))
+ {
+ JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
+ }
+ n = nullptr;
+}
+
+// overloads for basic_json template parameters
+template<typename BasicJsonType, typename ArithmeticType,
+ enable_if_t<std::is_arithmetic<ArithmeticType>::value and
+ not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+ int> = 0>
+void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
+{
+ switch (static_cast<value_t>(j))
+ {
+ case value_t::number_unsigned:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
+ break;
+ }
+ case value_t::number_integer:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
+ break;
+ }
+ case value_t::number_float:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
+ break;
+ }
+
+ default:
+ JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
+ }
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
+{
+ if (JSON_UNLIKELY(not j.is_boolean()))
+ {
+ JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
+ }
+ b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
+{
+ if (JSON_UNLIKELY(not j.is_string()))
+ {
+ JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
+ }
+ s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
+}
+
+template <
+ typename BasicJsonType, typename ConstructibleStringType,
+ enable_if_t <
+ is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
+ not std::is_same<typename BasicJsonType::string_t,
+ ConstructibleStringType>::value,
+ int > = 0 >
+void from_json(const BasicJsonType& j, ConstructibleStringType& s)
+{
+ if (JSON_UNLIKELY(not j.is_string()))
+ {
+ JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
+ }
+
+ s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
+{
+ get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
+{
+ get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType>
+void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
+{
+ get_arithmetic_value(j, val);
+}
+
+template<typename BasicJsonType, typename EnumType,
+ enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void from_json(const BasicJsonType& j, EnumType& e)
+{
+ typename std::underlying_type<EnumType>::type val;
+ get_arithmetic_value(j, val);
+ e = static_cast<EnumType>(val);
+}
+
+// forward_list doesn't have an insert method
+template<typename BasicJsonType, typename T, typename Allocator,
+ enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
+{
+ if (JSON_UNLIKELY(not j.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+ }
+ std::transform(j.rbegin(), j.rend(),
+ std::front_inserter(l), [](const BasicJsonType & i)
+ {
+ return i.template get<T>();
+ });
+}
+
+// valarray doesn't have an insert method
+template<typename BasicJsonType, typename T,
+ enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
+void from_json(const BasicJsonType& j, std::valarray<T>& l)
+{
+ if (JSON_UNLIKELY(not j.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+ }
+ l.resize(j.size());
+ std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
+}
+
+template<typename BasicJsonType>
+void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
+{
+ arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
+}
+
+template <typename BasicJsonType, typename T, std::size_t N>
+auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
+ priority_tag<2> /*unused*/)
+-> decltype(j.template get<T>(), void())
+{
+ for (std::size_t i = 0; i < N; ++i)
+ {
+ arr[i] = j.at(i).template get<T>();
+ }
+}
+
+template<typename BasicJsonType, typename ConstructibleArrayType>
+auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
+-> decltype(
+ arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
+ j.template get<typename ConstructibleArrayType::value_type>(),
+ void())
+{
+ using std::end;
+
+ arr.reserve(j.size());
+ std::transform(j.begin(), j.end(),
+ std::inserter(arr, end(arr)), [](const BasicJsonType & i)
+ {
+ // get<BasicJsonType>() returns *this, this won't call a from_json
+ // method when value_type is BasicJsonType
+ return i.template get<typename ConstructibleArrayType::value_type>();
+ });
+}
+
+template <typename BasicJsonType, typename ConstructibleArrayType>
+void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
+ priority_tag<0> /*unused*/)
+{
+ using std::end;
+
+ std::transform(
+ j.begin(), j.end(), std::inserter(arr, end(arr)),
+ [](const BasicJsonType & i)
+ {
+ // get<BasicJsonType>() returns *this, this won't call a from_json
+ // method when value_type is BasicJsonType
+ return i.template get<typename ConstructibleArrayType::value_type>();
+ });
+}
+
+template <typename BasicJsonType, typename ConstructibleArrayType,
+ enable_if_t <
+ is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
+ not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
+ not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
+ not is_basic_json<ConstructibleArrayType>::value,
+ int > = 0 >
+
+auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
+-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
+j.template get<typename ConstructibleArrayType::value_type>(),
+void())
+{
+ if (JSON_UNLIKELY(not j.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " +
+ std::string(j.type_name())));
+ }
+
+ from_json_array_impl(j, arr, priority_tag<3> {});
+}
+
+template<typename BasicJsonType, typename ConstructibleObjectType,
+ enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
+void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
+{
+ if (JSON_UNLIKELY(not j.is_object()))
+ {
+ JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
+ }
+
+ auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
+ using value_type = typename ConstructibleObjectType::value_type;
+ std::transform(
+ inner_object->begin(), inner_object->end(),
+ std::inserter(obj, obj.begin()),
+ [](typename BasicJsonType::object_t::value_type const & p)
+ {
+ return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
+ });
+}
+
+// overload for arithmetic types, not chosen for basic_json template arguments
+// (BooleanType, etc..); note: Is it really necessary to provide explicit
+// overloads for boolean_t etc. in case of a custom BooleanType which is not
+// an arithmetic type?
+template<typename BasicJsonType, typename ArithmeticType,
+ enable_if_t <
+ std::is_arithmetic<ArithmeticType>::value and
+ not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
+ not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
+ not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
+ not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
+ int> = 0>
+void from_json(const BasicJsonType& j, ArithmeticType& val)
+{
+ switch (static_cast<value_t>(j))
+ {
+ case value_t::number_unsigned:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
+ break;
+ }
+ case value_t::number_integer:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
+ break;
+ }
+ case value_t::number_float:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
+ break;
+ }
+ case value_t::boolean:
+ {
+ val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
+ break;
+ }
+
+ default:
+ JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
+ }
+}
+
+template<typename BasicJsonType, typename A1, typename A2>
+void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
+{
+ p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
+{
+ t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
+}
+
+template<typename BasicJsonType, typename... Args>
+void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
+{
+ from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
+}
+
+template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
+ typename = enable_if_t<not std::is_constructible<
+ typename BasicJsonType::string_t, Key>::value>>
+void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
+{
+ if (JSON_UNLIKELY(not j.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+ }
+ for (const auto& p : j)
+ {
+ if (JSON_UNLIKELY(not p.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
+ }
+ m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
+ }
+}
+
+template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
+ typename = enable_if_t<not std::is_constructible<
+ typename BasicJsonType::string_t, Key>::value>>
+void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
+{
+ if (JSON_UNLIKELY(not j.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
+ }
+ for (const auto& p : j)
+ {
+ if (JSON_UNLIKELY(not p.is_array()))
+ {
+ JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
+ }
+ m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
+ }
+}
+
+struct from_json_fn
+{
+ template<typename BasicJsonType, typename T>
+ auto operator()(const BasicJsonType& j, T& val) const
+ noexcept(noexcept(from_json(j, val)))
+ -> decltype(from_json(j, val), void())
+ {
+ return from_json(j, val);
+ }
+};
+} // namespace detail
+
+/// namespace to hold default `from_json` function
+/// to see why this is required:
+/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
+namespace
+{
+constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
+} // namespace
+} // namespace nlohmann
+
+// #include <nlohmann/detail/conversions/to_json.hpp>
+
+
+#include <algorithm> // copy
+#include <ciso646> // or, and, not
+#include <iterator> // begin, end
+#include <string> // string
+#include <tuple> // tuple, get
+#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
+#include <utility> // move, forward, declval, pair
+#include <valarray> // valarray
+#include <vector> // vector
+
+// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
+
+
+#include <cstddef> // size_t
+#include <iterator> // input_iterator_tag
+#include <string> // string, to_string
+#include <tuple> // tuple_size, get, tuple_element
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template <typename IteratorType> class iteration_proxy_value
+{
+ public:
+ using difference_type = std::ptrdiff_t;
+ using value_type = iteration_proxy_value;
+ using pointer = value_type * ;
+ using reference = value_type & ;
+ using iterator_category = std::input_iterator_tag;
+
+ private:
+ /// the iterator
+ IteratorType anchor;
+ /// an index for arrays (used to create key names)
+ std::size_t array_index = 0;
+ /// last stringified array index
+ mutable std::size_t array_index_last = 0;
+ /// a string representation of the array index
+ mutable std::string array_index_str = "0";
+ /// an empty string (to return a reference for primitive values)
+ const std::string empty_str = "";
+
+ public:
+ explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
+
+ /// dereference operator (needed for range-based for)
+ iteration_proxy_value& operator*()
+ {
+ return *this;
+ }
+
+ /// increment operator (needed for range-based for)
+ iteration_proxy_value& operator++()
+ {
+ ++anchor;
+ ++array_index;
+
+ return *this;
+ }
+
+ /// equality operator (needed for InputIterator)
+ bool operator==(const iteration_proxy_value& o) const
+ {
+ return anchor == o.anchor;
+ }
+
+ /// inequality operator (needed for range-based for)
+ bool operator!=(const iteration_proxy_value& o) const
+ {
+ return anchor != o.anchor;
+ }
+
+ /// return key of the iterator
+ const std::string& key() const
+ {
+ assert(anchor.m_object != nullptr);
+
+ switch (anchor.m_object->type())
+ {
+ // use integer array index as key
+ case value_t::array:
+ {
+ if (array_index != array_index_last)
+ {
+ array_index_str = std::to_string(array_index);
+ array_index_last = array_index;
+ }
+ return array_index_str;
+ }
+
+ // use key from the object
+ case value_t::object:
+ return anchor.key();
+
+ // use an empty key for all primitive types
+ default:
+ return empty_str;
+ }
+ }
+
+ /// return value of the iterator
+ typename IteratorType::reference value() const
+ {
+ return anchor.value();
+ }
+};
+
+/// proxy class for the items() function
+template<typename IteratorType> class iteration_proxy
+{
+ private:
+ /// the container to iterate
+ typename IteratorType::reference container;
+
+ public:
+ /// construct iteration proxy from a container
+ explicit iteration_proxy(typename IteratorType::reference cont) noexcept
+ : container(cont) {}
+
+ /// return iterator begin (needed for range-based for)
+ iteration_proxy_value<IteratorType> begin() noexcept
+ {
+ return iteration_proxy_value<IteratorType>(container.begin());
+ }
+
+ /// return iterator end (needed for range-based for)
+ iteration_proxy_value<IteratorType> end() noexcept
+ {
+ return iteration_proxy_value<IteratorType>(container.end());
+ }
+};
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
+{
+ return i.key();
+}
+// Structured Bindings Support
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
+auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
+{
+ return i.value();
+}
+} // namespace detail
+} // namespace nlohmann
+
+// The Addition to the STD Namespace is required to add
+// Structured Bindings Support to the iteration_proxy_value class
+// For further reference see https://blog.tartanllama.xyz/structured-bindings/
+// And see https://github.com/nlohmann/json/pull/1391
+namespace std
+{
+#if defined(__clang__)
+ // Fix: https://github.com/nlohmann/json/issues/1401
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wmismatched-tags"
+#endif
+template <typename IteratorType>
+class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
+ : public std::integral_constant<std::size_t, 2> {};
+
+template <std::size_t N, typename IteratorType>
+class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
+{
+ public:
+ using type = decltype(
+ get<N>(std::declval <
+ ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
+};
+#if defined(__clang__)
+ #pragma clang diagnostic pop
+#endif
+} // namespace std
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+//////////////////
+// constructors //
+//////////////////
+
+template<value_t> struct external_constructor;
+
+template<>
+struct external_constructor<value_t::boolean>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
+ {
+ j.m_type = value_t::boolean;
+ j.m_value = b;
+ j.assert_invariant();
+ }
+};
+
+template<>
+struct external_constructor<value_t::string>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
+ {
+ j.m_type = value_t::string;
+ j.m_value = s;
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
+ {
+ j.m_type = value_t::string;
+ j.m_value = std::move(s);
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType, typename CompatibleStringType,
+ enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
+ int> = 0>
+ static void construct(BasicJsonType& j, const CompatibleStringType& str)
+ {
+ j.m_type = value_t::string;
+ j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
+ j.assert_invariant();
+ }
+};
+
+template<>
+struct external_constructor<value_t::number_float>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
+ {
+ j.m_type = value_t::number_float;
+ j.m_value = val;
+ j.assert_invariant();
+ }
+};
+
+template<>
+struct external_constructor<value_t::number_unsigned>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
+ {
+ j.m_type = value_t::number_unsigned;
+ j.m_value = val;
+ j.assert_invariant();
+ }
+};
+
+template<>
+struct external_constructor<value_t::number_integer>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
+ {
+ j.m_type = value_t::number_integer;
+ j.m_value = val;
+ j.assert_invariant();
+ }
+};
+
+template<>
+struct external_constructor<value_t::array>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
+ {
+ j.m_type = value_t::array;
+ j.m_value = arr;
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
+ {
+ j.m_type = value_t::array;
+ j.m_value = std::move(arr);
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType, typename CompatibleArrayType,
+ enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
+ int> = 0>
+ static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
+ {
+ using std::begin;
+ using std::end;
+ j.m_type = value_t::array;
+ j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, const std::vector<bool>& arr)
+ {
+ j.m_type = value_t::array;
+ j.m_value = value_t::array;
+ j.m_value.array->reserve(arr.size());
+ for (const bool x : arr)
+ {
+ j.m_value.array->push_back(x);
+ }
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType, typename T,
+ enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+ static void construct(BasicJsonType& j, const std::valarray<T>& arr)
+ {
+ j.m_type = value_t::array;
+ j.m_value = value_t::array;
+ j.m_value.array->resize(arr.size());
+ std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
+ j.assert_invariant();
+ }
+};
+
+template<>
+struct external_constructor<value_t::object>
+{
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
+ {
+ j.m_type = value_t::object;
+ j.m_value = obj;
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType>
+ static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
+ {
+ j.m_type = value_t::object;
+ j.m_value = std::move(obj);
+ j.assert_invariant();
+ }
+
+ template<typename BasicJsonType, typename CompatibleObjectType,
+ enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
+ static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
+ {
+ using std::begin;
+ using std::end;
+
+ j.m_type = value_t::object;
+ j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
+ j.assert_invariant();
+ }
+};
+
+/////////////
+// to_json //
+/////////////
+
+template<typename BasicJsonType, typename T,
+ enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
+void to_json(BasicJsonType& j, T b) noexcept
+{
+ external_constructor<value_t::boolean>::construct(j, b);
+}
+
+template<typename BasicJsonType, typename CompatibleString,
+ enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
+void to_json(BasicJsonType& j, const CompatibleString& s)
+{
+ external_constructor<value_t::string>::construct(j, s);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
+{
+ external_constructor<value_t::string>::construct(j, std::move(s));
+}
+
+template<typename BasicJsonType, typename FloatType,
+ enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
+void to_json(BasicJsonType& j, FloatType val) noexcept
+{
+ external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
+}
+
+template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
+ enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
+void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
+{
+ external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
+}
+
+template<typename BasicJsonType, typename CompatibleNumberIntegerType,
+ enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
+void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
+{
+ external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
+}
+
+template<typename BasicJsonType, typename EnumType,
+ enable_if_t<std::is_enum<EnumType>::value, int> = 0>
+void to_json(BasicJsonType& j, EnumType e) noexcept
+{
+ using underlying_type = typename std::underlying_type<EnumType>::type;
+ external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, const std::vector<bool>& e)
+{
+ external_constructor<value_t::array>::construct(j, e);
+}
+
+template <typename BasicJsonType, typename CompatibleArrayType,
+ enable_if_t<is_compatible_array_type<BasicJsonType,
+ CompatibleArrayType>::value and
+ not is_compatible_object_type<
+ BasicJsonType, CompatibleArrayType>::value and
+ not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
+ not is_basic_json<CompatibleArrayType>::value,
+ int> = 0>
+void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
+{
+ external_constructor<value_t::array>::construct(j, arr);
+}
+
+template<typename BasicJsonType, typename T,
+ enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
+void to_json(BasicJsonType& j, const std::valarray<T>& arr)
+{
+ external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
+{
+ external_constructor<value_t::array>::construct(j, std::move(arr));
+}
+
+template<typename BasicJsonType, typename CompatibleObjectType,
+ enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
+void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
+{
+ external_constructor<value_t::object>::construct(j, obj);
+}
+
+template<typename BasicJsonType>
+void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
+{
+ external_constructor<value_t::object>::construct(j, std::move(obj));
+}
+
+template <
+ typename BasicJsonType, typename T, std::size_t N,
+ enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
+ const T(&)[N]>::value,
+ int> = 0 >
+void to_json(BasicJsonType& j, const T(&arr)[N])
+{
+ external_constructor<value_t::array>::construct(j, arr);
+}
+
+template<typename BasicJsonType, typename... Args>
+void to_json(BasicJsonType& j, const std::pair<Args...>& p)
+{
+ j = { p.first, p.second };
+}
+
+// for https://github.com/nlohmann/json/pull/1134
+template < typename BasicJsonType, typename T,
+ enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
+void to_json(BasicJsonType& j, const T& b)
+{
+ j = { {b.key(), b.value()} };
+}
+
+template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
+void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
+{
+ j = { std::get<Idx>(t)... };
+}
+
+template<typename BasicJsonType, typename... Args>
+void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
+{
+ to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
+}
+
+struct to_json_fn
+{
+ template<typename BasicJsonType, typename T>
+ auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
+ -> decltype(to_json(j, std::forward<T>(val)), void())
+ {
+ return to_json(j, std::forward<T>(val));
+ }
+};
+} // namespace detail
+
+/// namespace to hold default `to_json` function
+namespace
+{
+constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
+} // namespace
+} // namespace nlohmann
+
+
+namespace nlohmann
+{
+
+template<typename, typename>
+struct adl_serializer
+{
+ /*!
+ @brief convert a JSON value to any value type
+
+ This function is usually called by the `get()` function of the
+ @ref basic_json class (either explicit or via conversion operators).
+
+ @param[in] j JSON value to read from
+ @param[in,out] val value to write to
+ */
+ template<typename BasicJsonType, typename ValueType>
+ static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
+ noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
+ -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
+ {
+ ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
+ }
+
+ /*!
+ @brief convert any value type to a JSON value
+
+ This function is usually called by the constructors of the @ref basic_json
+ class.
+
+ @param[in,out] j JSON value to write to
+ @param[in] val value to read from
+ */
+ template <typename BasicJsonType, typename ValueType>
+ static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
+ noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
+ -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
+ {
+ ::nlohmann::to_json(j, std::forward<ValueType>(val));
+ }
+};
+
+} // namespace nlohmann
+
+// #include <nlohmann/detail/conversions/from_json.hpp>
+
+// #include <nlohmann/detail/conversions/to_json.hpp>
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/input/binary_reader.hpp>
+
+
+#include <algorithm> // generate_n
+#include <array> // array
+#include <cassert> // assert
+#include <cmath> // ldexp
+#include <cstddef> // size_t
+#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
+#include <cstdio> // snprintf
+#include <cstring> // memcpy
+#include <iterator> // back_inserter
+#include <limits> // numeric_limits
+#include <string> // char_traits, string
+#include <utility> // make_pair, move
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+
+#include <array> // array
+#include <cassert> // assert
+#include <cstddef> // size_t
+#include <cstdio> //FILE *
+#include <cstring> // strlen
+#include <istream> // istream
+#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
+#include <memory> // shared_ptr, make_shared, addressof
+#include <numeric> // accumulate
+#include <string> // string, char_traits
+#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
+#include <utility> // pair, declval
+
+// #include <nlohmann/detail/iterators/iterator_traits.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+/// the supported input formats
+enum class input_format_t { json, cbor, msgpack, ubjson, bson };
+
+////////////////////
+// input adapters //
+////////////////////
+
+/*!
+@brief abstract input adapter interface
+
+Produces a stream of std::char_traits<char>::int_type characters from a
+std::istream, a buffer, or some other input type. Accepts the return of
+exactly one non-EOF character for future input. The int_type characters
+returned consist of all valid char values as positive values (typically
+unsigned char), plus an EOF value outside that range, specified by the value
+of the function std::char_traits<char>::eof(). This value is typically -1, but
+could be any arbitrary value which is not a valid char value.
+*/
+struct input_adapter_protocol
+{
+ /// get a character [0,255] or std::char_traits<char>::eof().
+ virtual std::char_traits<char>::int_type get_character() = 0;
+ virtual ~input_adapter_protocol() = default;
+};
+
+/// a type to simplify interfaces
+using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
+
+/*!
+Input adapter for stdio file access. This adapter read only 1 byte and do not use any
+ buffer. This adapter is a very low level adapter.
+*/
+class file_input_adapter : public input_adapter_protocol
+{
+ public:
+ explicit file_input_adapter(std::FILE* f) noexcept
+ : m_file(f)
+ {}
+
+ // make class move-only
+ file_input_adapter(const file_input_adapter&) = delete;
+ file_input_adapter(file_input_adapter&&) = default;
+ file_input_adapter& operator=(const file_input_adapter&) = delete;
+ file_input_adapter& operator=(file_input_adapter&&) = default;
+ ~file_input_adapter() override = default;
+
+ std::char_traits<char>::int_type get_character() noexcept override
+ {
+ return std::fgetc(m_file);
+ }
+
+ private:
+ /// the file pointer to read from
+ std::FILE* m_file;
+};
+
+
+/*!
+Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
+beginning of input. Does not support changing the underlying std::streambuf
+in mid-input. Maintains underlying std::istream and std::streambuf to support
+subsequent use of standard std::istream operations to process any input
+characters following those used in parsing the JSON input. Clears the
+std::istream flags; any input errors (e.g., EOF) will be detected by the first
+subsequent call for input from the std::istream.
+*/
+class input_stream_adapter : public input_adapter_protocol
+{
+ public:
+ ~input_stream_adapter() override
+ {
+ // clear stream flags; we use underlying streambuf I/O, do not
+ // maintain ifstream flags, except eof
+ is.clear(is.rdstate() & std::ios::eofbit);
+ }
+
+ explicit input_stream_adapter(std::istream& i)
+ : is(i), sb(*i.rdbuf())
+ {}
+
+ // delete because of pointer members
+ input_stream_adapter(const input_stream_adapter&) = delete;
+ input_stream_adapter& operator=(input_stream_adapter&) = delete;
+ input_stream_adapter(input_stream_adapter&&) = delete;
+ input_stream_adapter& operator=(input_stream_adapter&&) = delete;
+
+ // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
+ // ensure that std::char_traits<char>::eof() and the character 0xFF do not
+ // end up as the same value, eg. 0xFFFFFFFF.
+ std::char_traits<char>::int_type get_character() override
+ {
+ auto res = sb.sbumpc();
+ // set eof manually, as we don't use the istream interface.
+ if (res == EOF)
+ {
+ is.clear(is.rdstate() | std::ios::eofbit);
+ }
+ return res;
+ }
+
+ private:
+ /// the associated input stream
+ std::istream& is;
+ std::streambuf& sb;
+};
+
+/// input adapter for buffer input
+class input_buffer_adapter : public input_adapter_protocol
+{
+ public:
+ input_buffer_adapter(const char* b, const std::size_t l) noexcept
+ : cursor(b), limit(b + l)
+ {}
+
+ // delete because of pointer members
+ input_buffer_adapter(const input_buffer_adapter&) = delete;
+ input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
+ input_buffer_adapter(input_buffer_adapter&&) = delete;
+ input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
+ ~input_buffer_adapter() override = default;
+
+ std::char_traits<char>::int_type get_character() noexcept override
+ {
+ if (JSON_LIKELY(cursor < limit))
+ {
+ return std::char_traits<char>::to_int_type(*(cursor++));
+ }
+
+ return std::char_traits<char>::eof();
+ }
+
+ private:
+ /// pointer to the current character
+ const char* cursor;
+ /// pointer past the last character
+ const char* const limit;
+};
+
+template<typename WideStringType, size_t T>
+struct wide_string_input_helper
+{
+ // UTF-32
+ static void fill_buffer(const WideStringType& str,
+ size_t& current_wchar,
+ std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
+ size_t& utf8_bytes_index,
+ size_t& utf8_bytes_filled)
+ {
+ utf8_bytes_index = 0;
+
+ if (current_wchar == str.size())
+ {
+ utf8_bytes[0] = std::char_traits<char>::eof();
+ utf8_bytes_filled = 1;
+ }
+ else
+ {
+ // get the current character
+ const auto wc = static_cast<unsigned int>(str[current_wchar++]);
+
+ // UTF-32 to UTF-8 encoding
+ if (wc < 0x80)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+ utf8_bytes_filled = 1;
+ }
+ else if (wc <= 0x7FF)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
+ utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
+ utf8_bytes_filled = 2;
+ }
+ else if (wc <= 0xFFFF)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
+ utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
+ utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
+ utf8_bytes_filled = 3;
+ }
+ else if (wc <= 0x10FFFF)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
+ utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
+ utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
+ utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
+ utf8_bytes_filled = 4;
+ }
+ else
+ {
+ // unknown character
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+ utf8_bytes_filled = 1;
+ }
+ }
+ }
+};
+
+template<typename WideStringType>
+struct wide_string_input_helper<WideStringType, 2>
+{
+ // UTF-16
+ static void fill_buffer(const WideStringType& str,
+ size_t& current_wchar,
+ std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
+ size_t& utf8_bytes_index,
+ size_t& utf8_bytes_filled)
+ {
+ utf8_bytes_index = 0;
+
+ if (current_wchar == str.size())
+ {
+ utf8_bytes[0] = std::char_traits<char>::eof();
+ utf8_bytes_filled = 1;
+ }
+ else
+ {
+ // get the current character
+ const auto wc = static_cast<unsigned int>(str[current_wchar++]);
+
+ // UTF-16 to UTF-8 encoding
+ if (wc < 0x80)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+ utf8_bytes_filled = 1;
+ }
+ else if (wc <= 0x7FF)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
+ utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
+ utf8_bytes_filled = 2;
+ }
+ else if (0xD800 > wc or wc >= 0xE000)
+ {
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
+ utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
+ utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
+ utf8_bytes_filled = 3;
+ }
+ else
+ {
+ if (current_wchar < str.size())
+ {
+ const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
+ const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
+ utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
+ utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
+ utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
+ utf8_bytes_filled = 4;
+ }
+ else
+ {
+ // unknown character
+ ++current_wchar;
+ utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
+ utf8_bytes_filled = 1;
+ }
+ }
+ }
+ }
+};
+
+template<typename WideStringType>
+class wide_string_input_adapter : public input_adapter_protocol
+{
+ public:
+ explicit wide_string_input_adapter(const WideStringType& w) noexcept
+ : str(w)
+ {}
+
+ std::char_traits<char>::int_type get_character() noexcept override
+ {
+ // check if buffer needs to be filled
+ if (utf8_bytes_index == utf8_bytes_filled)
+ {
+ fill_buffer<sizeof(typename WideStringType::value_type)>();
+
+ assert(utf8_bytes_filled > 0);
+ assert(utf8_bytes_index == 0);
+ }
+
+ // use buffer
+ assert(utf8_bytes_filled > 0);
+ assert(utf8_bytes_index < utf8_bytes_filled);
+ return utf8_bytes[utf8_bytes_index++];
+ }
+
+ private:
+ template<size_t T>
+ void fill_buffer()
+ {
+ wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
+ }
+
+ /// the wstring to process
+ const WideStringType& str;
+
+ /// index of the current wchar in str
+ std::size_t current_wchar = 0;
+
+ /// a buffer for UTF-8 bytes
+ std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
+
+ /// index to the utf8_codes array for the next valid byte
+ std::size_t utf8_bytes_index = 0;
+ /// number of valid bytes in the utf8_codes array
+ std::size_t utf8_bytes_filled = 0;
+};
+
+class input_adapter
+{
+ public:
+ // native support
+ input_adapter(std::FILE* file)
+ : ia(std::make_shared<file_input_adapter>(file)) {}
+ /// input adapter for input stream
+ input_adapter(std::istream& i)
+ : ia(std::make_shared<input_stream_adapter>(i)) {}
+
+ /// input adapter for input stream
+ input_adapter(std::istream&& i)
+ : ia(std::make_shared<input_stream_adapter>(i)) {}
+
+ input_adapter(const std::wstring& ws)
+ : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
+
+ input_adapter(const std::u16string& ws)
+ : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
+
+ input_adapter(const std::u32string& ws)
+ : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
+
+ /// input adapter for buffer
+ template<typename CharT,
+ typename std::enable_if<
+ std::is_pointer<CharT>::value and
+ std::is_integral<typename std::remove_pointer<CharT>::type>::value and
+ sizeof(typename std::remove_pointer<CharT>::type) == 1,
+ int>::type = 0>
+ input_adapter(CharT b, std::size_t l)
+ : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
+
+ // derived support
+
+ /// input adapter for string literal
+ template<typename CharT,
+ typename std::enable_if<
+ std::is_pointer<CharT>::value and
+ std::is_integral<typename std::remove_pointer<CharT>::type>::value and
+ sizeof(typename std::remove_pointer<CharT>::type) == 1,
+ int>::type = 0>
+ input_adapter(CharT b)
+ : input_adapter(reinterpret_cast<const char*>(b),
+ std::strlen(reinterpret_cast<const char*>(b))) {}
+
+ /// input adapter for iterator range with contiguous storage
+ template<class IteratorType,
+ typename std::enable_if<
+ std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
+ int>::type = 0>
+ input_adapter(IteratorType first, IteratorType last)
+ {
+#ifndef NDEBUG
+ // assertion to check that the iterator range is indeed contiguous,
+ // see http://stackoverflow.com/a/35008842/266378 for more discussion
+ const auto is_contiguous = std::accumulate(
+ first, last, std::pair<bool, int>(true, 0),
+ [&first](std::pair<bool, int> res, decltype(*first) val)
+ {
+ res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
+ return res;
+ }).first;
+ assert(is_contiguous);
+#endif
+
+ // assertion to check that each element is 1 byte long
+ static_assert(
+ sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
+ "each element in the iterator range must have the size of 1 byte");
+
+ const auto len = static_cast<size_t>(std::distance(first, last));
+ if (JSON_LIKELY(len > 0))
+ {
+ // there is at least one element: use the address of first
+ ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
+ }
+ else
+ {
+ // the address of first cannot be used: use nullptr
+ ia = std::make_shared<input_buffer_adapter>(nullptr, len);
+ }
+ }
+
+ /// input adapter for array
+ template<class T, std::size_t N>
+ input_adapter(T (&array)[N])
+ : input_adapter(std::begin(array), std::end(array)) {}
+
+ /// input adapter for contiguous container
+ template<class ContiguousContainer, typename
+ std::enable_if<not std::is_pointer<ContiguousContainer>::value and
+ std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
+ int>::type = 0>
+ input_adapter(const ContiguousContainer& c)
+ : input_adapter(std::begin(c), std::end(c)) {}
+
+ operator input_adapter_t()
+ {
+ return ia;
+ }
+
+ private:
+ /// the actual adapter
+ input_adapter_t ia = nullptr;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/input/json_sax.hpp>
+
+
+#include <cassert> // assert
+#include <cstddef>
+#include <string> // string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+
+/*!
+@brief SAX interface
+
+This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
+Each function is called in different situations while the input is parsed. The
+boolean return value informs the parser whether to continue processing the
+input.
+*/
+template<typename BasicJsonType>
+struct json_sax
+{
+ /// type for (signed) integers
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ /// type for unsigned integers
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ /// type for floating-point numbers
+ using number_float_t = typename BasicJsonType::number_float_t;
+ /// type for strings
+ using string_t = typename BasicJsonType::string_t;
+
+ /*!
+ @brief a null value was read
+ @return whether parsing should proceed
+ */
+ virtual bool null() = 0;
+
+ /*!
+ @brief a boolean value was read
+ @param[in] val boolean value
+ @return whether parsing should proceed
+ */
+ virtual bool boolean(bool val) = 0;
+
+ /*!
+ @brief an integer number was read
+ @param[in] val integer value
+ @return whether parsing should proceed
+ */
+ virtual bool number_integer(number_integer_t val) = 0;
+
+ /*!
+ @brief an unsigned integer number was read
+ @param[in] val unsigned integer value
+ @return whether parsing should proceed
+ */
+ virtual bool number_unsigned(number_unsigned_t val) = 0;
+
+ /*!
+ @brief an floating-point number was read
+ @param[in] val floating-point value
+ @param[in] s raw token value
+ @return whether parsing should proceed
+ */
+ virtual bool number_float(number_float_t val, const string_t& s) = 0;
+
+ /*!
+ @brief a string was read
+ @param[in] val string value
+ @return whether parsing should proceed
+ @note It is safe to move the passed string.
+ */
+ virtual bool string(string_t& val) = 0;
+
+ /*!
+ @brief the beginning of an object was read
+ @param[in] elements number of object elements or -1 if unknown
+ @return whether parsing should proceed
+ @note binary formats may report the number of elements
+ */
+ virtual bool start_object(std::size_t elements) = 0;
+
+ /*!
+ @brief an object key was read
+ @param[in] val object key
+ @return whether parsing should proceed
+ @note It is safe to move the passed string.
+ */
+ virtual bool key(string_t& val) = 0;
+
+ /*!
+ @brief the end of an object was read
+ @return whether parsing should proceed
+ */
+ virtual bool end_object() = 0;
+
+ /*!
+ @brief the beginning of an array was read
+ @param[in] elements number of array elements or -1 if unknown
+ @return whether parsing should proceed
+ @note binary formats may report the number of elements
+ */
+ virtual bool start_array(std::size_t elements) = 0;
+
+ /*!
+ @brief the end of an array was read
+ @return whether parsing should proceed
+ */
+ virtual bool end_array() = 0;
+
+ /*!
+ @brief a parse error occurred
+ @param[in] position the position in the input where the error occurs
+ @param[in] last_token the last read token
+ @param[in] ex an exception object describing the error
+ @return whether parsing should proceed (must return false)
+ */
+ virtual bool parse_error(std::size_t position,
+ const std::string& last_token,
+ const detail::exception& ex) = 0;
+
+ virtual ~json_sax() = default;
+};
+
+
+namespace detail
+{
+/*!
+@brief SAX implementation to create a JSON value from SAX events
+
+This class implements the @ref json_sax interface and processes the SAX events
+to create a JSON value which makes it basically a DOM parser. The structure or
+hierarchy of the JSON value is managed by the stack `ref_stack` which contains
+a pointer to the respective array or object for each recursion depth.
+
+After successful parsing, the value that is passed by reference to the
+constructor contains the parsed value.
+
+@tparam BasicJsonType the JSON type
+*/
+template<typename BasicJsonType>
+class json_sax_dom_parser
+{
+ public:
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+
+ /*!
+ @param[in, out] r reference to a JSON value that is manipulated while
+ parsing
+ @param[in] allow_exceptions_ whether parse errors yield exceptions
+ */
+ explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
+ : root(r), allow_exceptions(allow_exceptions_)
+ {}
+
+ // make class move-only
+ json_sax_dom_parser(const json_sax_dom_parser&) = delete;
+ json_sax_dom_parser(json_sax_dom_parser&&) = default;
+ json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
+ json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
+ ~json_sax_dom_parser() = default;
+
+ bool null()
+ {
+ handle_value(nullptr);
+ return true;
+ }
+
+ bool boolean(bool val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool number_integer(number_integer_t val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool number_unsigned(number_unsigned_t val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool number_float(number_float_t val, const string_t& /*unused*/)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool string(string_t& val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool start_object(std::size_t len)
+ {
+ ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
+
+ if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
+ {
+ JSON_THROW(out_of_range::create(408,
+ "excessive object size: " + std::to_string(len)));
+ }
+
+ return true;
+ }
+
+ bool key(string_t& val)
+ {
+ // add null at given key and store the reference for later
+ object_element = &(ref_stack.back()->m_value.object->operator[](val));
+ return true;
+ }
+
+ bool end_object()
+ {
+ ref_stack.pop_back();
+ return true;
+ }
+
+ bool start_array(std::size_t len)
+ {
+ ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
+
+ if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
+ {
+ JSON_THROW(out_of_range::create(408,
+ "excessive array size: " + std::to_string(len)));
+ }
+
+ return true;
+ }
+
+ bool end_array()
+ {
+ ref_stack.pop_back();
+ return true;
+ }
+
+ bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
+ const detail::exception& ex)
+ {
+ errored = true;
+ if (allow_exceptions)
+ {
+ // determine the proper exception type from the id
+ switch ((ex.id / 100) % 100)
+ {
+ case 1:
+ JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
+ case 4:
+ JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
+ // LCOV_EXCL_START
+ case 2:
+ JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
+ case 3:
+ JSON_THROW(*static_cast<const detail::type_error*>(&ex));
+ case 5:
+ JSON_THROW(*static_cast<const detail::other_error*>(&ex));
+ default:
+ assert(false);
+ // LCOV_EXCL_STOP
+ }
+ }
+ return false;
+ }
+
+ constexpr bool is_errored() const
+ {
+ return errored;
+ }
+
+ private:
+ /*!
+ @invariant If the ref stack is empty, then the passed value will be the new
+ root.
+ @invariant If the ref stack contains a value, then it is an array or an
+ object to which we can add elements
+ */
+ template<typename Value>
+ BasicJsonType* handle_value(Value&& v)
+ {
+ if (ref_stack.empty())
+ {
+ root = BasicJsonType(std::forward<Value>(v));
+ return &root;
+ }
+
+ assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
+
+ if (ref_stack.back()->is_array())
+ {
+ ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
+ return &(ref_stack.back()->m_value.array->back());
+ }
+
+ assert(ref_stack.back()->is_object());
+ assert(object_element);
+ *object_element = BasicJsonType(std::forward<Value>(v));
+ return object_element;
+ }
+
+ /// the parsed JSON value
+ BasicJsonType& root;
+ /// stack to model hierarchy of values
+ std::vector<BasicJsonType*> ref_stack {};
+ /// helper to hold the reference for the next object element
+ BasicJsonType* object_element = nullptr;
+ /// whether a syntax error occurred
+ bool errored = false;
+ /// whether to throw exceptions in case of errors
+ const bool allow_exceptions = true;
+};
+
+template<typename BasicJsonType>
+class json_sax_dom_callback_parser
+{
+ public:
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+ using parser_callback_t = typename BasicJsonType::parser_callback_t;
+ using parse_event_t = typename BasicJsonType::parse_event_t;
+
+ json_sax_dom_callback_parser(BasicJsonType& r,
+ const parser_callback_t cb,
+ const bool allow_exceptions_ = true)
+ : root(r), callback(cb), allow_exceptions(allow_exceptions_)
+ {
+ keep_stack.push_back(true);
+ }
+
+ // make class move-only
+ json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
+ json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
+ json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
+ json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
+ ~json_sax_dom_callback_parser() = default;
+
+ bool null()
+ {
+ handle_value(nullptr);
+ return true;
+ }
+
+ bool boolean(bool val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool number_integer(number_integer_t val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool number_unsigned(number_unsigned_t val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool number_float(number_float_t val, const string_t& /*unused*/)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool string(string_t& val)
+ {
+ handle_value(val);
+ return true;
+ }
+
+ bool start_object(std::size_t len)
+ {
+ // check callback for object start
+ const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
+ keep_stack.push_back(keep);
+
+ auto val = handle_value(BasicJsonType::value_t::object, true);
+ ref_stack.push_back(val.second);
+
+ // check object limit
+ if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
+ {
+ JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
+ }
+
+ return true;
+ }
+
+ bool key(string_t& val)
+ {
+ BasicJsonType k = BasicJsonType(val);
+
+ // check callback for key
+ const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
+ key_keep_stack.push_back(keep);
+
+ // add discarded value at given key and store the reference for later
+ if (keep and ref_stack.back())
+ {
+ object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
+ }
+
+ return true;
+ }
+
+ bool end_object()
+ {
+ if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
+ {
+ // discard object
+ *ref_stack.back() = discarded;
+ }
+
+ assert(not ref_stack.empty());
+ assert(not keep_stack.empty());
+ ref_stack.pop_back();
+ keep_stack.pop_back();
+
+ if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
+ {
+ // remove discarded value
+ for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
+ {
+ if (it->is_discarded())
+ {
+ ref_stack.back()->erase(it);
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ bool start_array(std::size_t len)
+ {
+ const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
+ keep_stack.push_back(keep);
+
+ auto val = handle_value(BasicJsonType::value_t::array, true);
+ ref_stack.push_back(val.second);
+
+ // check array limit
+ if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
+ {
+ JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
+ }
+
+ return true;
+ }
+
+ bool end_array()
+ {
+ bool keep = true;
+
+ if (ref_stack.back())
+ {
+ keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
+ if (not keep)
+ {
+ // discard array
+ *ref_stack.back() = discarded;
+ }
+ }
+
+ assert(not ref_stack.empty());
+ assert(not keep_stack.empty());
+ ref_stack.pop_back();
+ keep_stack.pop_back();
+
+ // remove discarded value
+ if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
+ {
+ ref_stack.back()->m_value.array->pop_back();
+ }
+
+ return true;
+ }
+
+ bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
+ const detail::exception& ex)
+ {
+ errored = true;
+ if (allow_exceptions)
+ {
+ // determine the proper exception type from the id
+ switch ((ex.id / 100) % 100)
+ {
+ case 1:
+ JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
+ case 4:
+ JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
+ // LCOV_EXCL_START
+ case 2:
+ JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
+ case 3:
+ JSON_THROW(*static_cast<const detail::type_error*>(&ex));
+ case 5:
+ JSON_THROW(*static_cast<const detail::other_error*>(&ex));
+ default:
+ assert(false);
+ // LCOV_EXCL_STOP
+ }
+ }
+ return false;
+ }
+
+ constexpr bool is_errored() const
+ {
+ return errored;
+ }
+
+ private:
+ /*!
+ @param[in] v value to add to the JSON value we build during parsing
+ @param[in] skip_callback whether we should skip calling the callback
+ function; this is required after start_array() and
+ start_object() SAX events, because otherwise we would call the
+ callback function with an empty array or object, respectively.
+
+ @invariant If the ref stack is empty, then the passed value will be the new
+ root.
+ @invariant If the ref stack contains a value, then it is an array or an
+ object to which we can add elements
+
+ @return pair of boolean (whether value should be kept) and pointer (to the
+ passed value in the ref_stack hierarchy; nullptr if not kept)
+ */
+ template<typename Value>
+ std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
+ {
+ assert(not keep_stack.empty());
+
+ // do not handle this value if we know it would be added to a discarded
+ // container
+ if (not keep_stack.back())
+ {
+ return {false, nullptr};
+ }
+
+ // create value
+ auto value = BasicJsonType(std::forward<Value>(v));
+
+ // check callback
+ const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
+
+ // do not handle this value if we just learned it shall be discarded
+ if (not keep)
+ {
+ return {false, nullptr};
+ }
+
+ if (ref_stack.empty())
+ {
+ root = std::move(value);
+ return {true, &root};
+ }
+
+ // skip this value if we already decided to skip the parent
+ // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
+ if (not ref_stack.back())
+ {
+ return {false, nullptr};
+ }
+
+ // we now only expect arrays and objects
+ assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
+
+ // array
+ if (ref_stack.back()->is_array())
+ {
+ ref_stack.back()->m_value.array->push_back(std::move(value));
+ return {true, &(ref_stack.back()->m_value.array->back())};
+ }
+
+ // object
+ assert(ref_stack.back()->is_object());
+ // check if we should store an element for the current key
+ assert(not key_keep_stack.empty());
+ const bool store_element = key_keep_stack.back();
+ key_keep_stack.pop_back();
+
+ if (not store_element)
+ {
+ return {false, nullptr};
+ }
+
+ assert(object_element);
+ *object_element = std::move(value);
+ return {true, object_element};
+ }
+
+ /// the parsed JSON value
+ BasicJsonType& root;
+ /// stack to model hierarchy of values
+ std::vector<BasicJsonType*> ref_stack {};
+ /// stack to manage which values to keep
+ std::vector<bool> keep_stack {};
+ /// stack to manage which object keys to keep
+ std::vector<bool> key_keep_stack {};
+ /// helper to hold the reference for the next object element
+ BasicJsonType* object_element = nullptr;
+ /// whether a syntax error occurred
+ bool errored = false;
+ /// callback function
+ const parser_callback_t callback = nullptr;
+ /// whether to throw exceptions in case of errors
+ const bool allow_exceptions = true;
+ /// a discarded value for the callback
+ BasicJsonType discarded = BasicJsonType::value_t::discarded;
+};
+
+template<typename BasicJsonType>
+class json_sax_acceptor
+{
+ public:
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+
+ bool null()
+ {
+ return true;
+ }
+
+ bool boolean(bool /*unused*/)
+ {
+ return true;
+ }
+
+ bool number_integer(number_integer_t /*unused*/)
+ {
+ return true;
+ }
+
+ bool number_unsigned(number_unsigned_t /*unused*/)
+ {
+ return true;
+ }
+
+ bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
+ {
+ return true;
+ }
+
+ bool string(string_t& /*unused*/)
+ {
+ return true;
+ }
+
+ bool start_object(std::size_t /*unused*/ = std::size_t(-1))
+ {
+ return true;
+ }
+
+ bool key(string_t& /*unused*/)
+ {
+ return true;
+ }
+
+ bool end_object()
+ {
+ return true;
+ }
+
+ bool start_array(std::size_t /*unused*/ = std::size_t(-1))
+ {
+ return true;
+ }
+
+ bool end_array()
+ {
+ return true;
+ }
+
+ bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
+ {
+ return false;
+ }
+};
+} // namespace detail
+
+} // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/is_sax.hpp>
+
+
+#include <cstdint> // size_t
+#include <utility> // declval
+#include <string> // string
+
+// #include <nlohmann/detail/meta/detected.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template <typename T>
+using null_function_t = decltype(std::declval<T&>().null());
+
+template <typename T>
+using boolean_function_t =
+ decltype(std::declval<T&>().boolean(std::declval<bool>()));
+
+template <typename T, typename Integer>
+using number_integer_function_t =
+ decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
+
+template <typename T, typename Unsigned>
+using number_unsigned_function_t =
+ decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
+
+template <typename T, typename Float, typename String>
+using number_float_function_t = decltype(std::declval<T&>().number_float(
+ std::declval<Float>(), std::declval<const String&>()));
+
+template <typename T, typename String>
+using string_function_t =
+ decltype(std::declval<T&>().string(std::declval<String&>()));
+
+template <typename T>
+using start_object_function_t =
+ decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
+
+template <typename T, typename String>
+using key_function_t =
+ decltype(std::declval<T&>().key(std::declval<String&>()));
+
+template <typename T>
+using end_object_function_t = decltype(std::declval<T&>().end_object());
+
+template <typename T>
+using start_array_function_t =
+ decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
+
+template <typename T>
+using end_array_function_t = decltype(std::declval<T&>().end_array());
+
+template <typename T, typename Exception>
+using parse_error_function_t = decltype(std::declval<T&>().parse_error(
+ std::declval<std::size_t>(), std::declval<const std::string&>(),
+ std::declval<const Exception&>()));
+
+template <typename SAX, typename BasicJsonType>
+struct is_sax
+{
+ private:
+ static_assert(is_basic_json<BasicJsonType>::value,
+ "BasicJsonType must be of type basic_json<...>");
+
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+ using exception_t = typename BasicJsonType::exception;
+
+ public:
+ static constexpr bool value =
+ is_detected_exact<bool, null_function_t, SAX>::value &&
+ is_detected_exact<bool, boolean_function_t, SAX>::value &&
+ is_detected_exact<bool, number_integer_function_t, SAX,
+ number_integer_t>::value &&
+ is_detected_exact<bool, number_unsigned_function_t, SAX,
+ number_unsigned_t>::value &&
+ is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
+ string_t>::value &&
+ is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
+ is_detected_exact<bool, start_object_function_t, SAX>::value &&
+ is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
+ is_detected_exact<bool, end_object_function_t, SAX>::value &&
+ is_detected_exact<bool, start_array_function_t, SAX>::value &&
+ is_detected_exact<bool, end_array_function_t, SAX>::value &&
+ is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
+};
+
+template <typename SAX, typename BasicJsonType>
+struct is_sax_static_asserts
+{
+ private:
+ static_assert(is_basic_json<BasicJsonType>::value,
+ "BasicJsonType must be of type basic_json<...>");
+
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+ using exception_t = typename BasicJsonType::exception;
+
+ public:
+ static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
+ "Missing/invalid function: bool null()");
+ static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
+ "Missing/invalid function: bool boolean(bool)");
+ static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
+ "Missing/invalid function: bool boolean(bool)");
+ static_assert(
+ is_detected_exact<bool, number_integer_function_t, SAX,
+ number_integer_t>::value,
+ "Missing/invalid function: bool number_integer(number_integer_t)");
+ static_assert(
+ is_detected_exact<bool, number_unsigned_function_t, SAX,
+ number_unsigned_t>::value,
+ "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
+ static_assert(is_detected_exact<bool, number_float_function_t, SAX,
+ number_float_t, string_t>::value,
+ "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
+ static_assert(
+ is_detected_exact<bool, string_function_t, SAX, string_t>::value,
+ "Missing/invalid function: bool string(string_t&)");
+ static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
+ "Missing/invalid function: bool start_object(std::size_t)");
+ static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
+ "Missing/invalid function: bool key(string_t&)");
+ static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
+ "Missing/invalid function: bool end_object()");
+ static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
+ "Missing/invalid function: bool start_array(std::size_t)");
+ static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
+ "Missing/invalid function: bool end_array()");
+ static_assert(
+ is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
+ "Missing/invalid function: bool parse_error(std::size_t, const "
+ "std::string&, const exception&)");
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////
+// binary reader //
+///////////////////
+
+/*!
+@brief deserialization of CBOR, MessagePack, and UBJSON values
+*/
+template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
+class binary_reader
+{
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+ using json_sax_t = SAX;
+
+ public:
+ /*!
+ @brief create a binary reader
+
+ @param[in] adapter input adapter to read from
+ */
+ explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
+ {
+ (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
+ assert(ia);
+ }
+
+ // make class move-only
+ binary_reader(const binary_reader&) = delete;
+ binary_reader(binary_reader&&) = default;
+ binary_reader& operator=(const binary_reader&) = delete;
+ binary_reader& operator=(binary_reader&&) = default;
+ ~binary_reader() = default;
+
+ /*!
+ @param[in] format the binary format to parse
+ @param[in] sax_ a SAX event processor
+ @param[in] strict whether to expect the input to be consumed completed
+
+ @return
+ */
+ bool sax_parse(const input_format_t format,
+ json_sax_t* sax_,
+ const bool strict = true)
+ {
+ sax = sax_;
+ bool result = false;
+
+ switch (format)
+ {
+ case input_format_t::bson:
+ result = parse_bson_internal();
+ break;
+
+ case input_format_t::cbor:
+ result = parse_cbor_internal();
+ break;
+
+ case input_format_t::msgpack:
+ result = parse_msgpack_internal();
+ break;
+
+ case input_format_t::ubjson:
+ result = parse_ubjson_internal();
+ break;
+
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+
+ // strict mode: next byte must be EOF
+ if (result and strict)
+ {
+ if (format == input_format_t::ubjson)
+ {
+ get_ignore_noop();
+ }
+ else
+ {
+ get();
+ }
+
+ if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
+ {
+ return sax->parse_error(chars_read, get_token_string(),
+ parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
+ }
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief determine system byte order
+
+ @return true if and only if system's byte order is little endian
+
+ @note from http://stackoverflow.com/a/1001328/266378
+ */
+ static constexpr bool little_endianess(int num = 1) noexcept
+ {
+ return *reinterpret_cast<char*>(&num) == 1;
+ }
+
+ private:
+ //////////
+ // BSON //
+ //////////
+
+ /*!
+ @brief Reads in a BSON-object and passes it to the SAX-parser.
+ @return whether a valid BSON-value was passed to the SAX parser
+ */
+ bool parse_bson_internal()
+ {
+ std::int32_t document_size;
+ get_number<std::int32_t, true>(input_format_t::bson, document_size);
+
+ if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
+ {
+ return false;
+ }
+
+ if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
+ {
+ return false;
+ }
+
+ return sax->end_object();
+ }
+
+ /*!
+ @brief Parses a C-style string from the BSON input.
+ @param[in, out] result A reference to the string variable where the read
+ string is to be stored.
+ @return `true` if the \x00-byte indicating the end of the string was
+ encountered before the EOF; false` indicates an unexpected EOF.
+ */
+ bool get_bson_cstr(string_t& result)
+ {
+ auto out = std::back_inserter(result);
+ while (true)
+ {
+ get();
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
+ {
+ return false;
+ }
+ if (current == 0x00)
+ {
+ return true;
+ }
+ *out++ = static_cast<char>(current);
+ }
+
+ return true;
+ }
+
+ /*!
+ @brief Parses a zero-terminated string of length @a len from the BSON
+ input.
+ @param[in] len The length (including the zero-byte at the end) of the
+ string to be read.
+ @param[in, out] result A reference to the string variable where the read
+ string is to be stored.
+ @tparam NumberType The type of the length @a len
+ @pre len >= 1
+ @return `true` if the string was successfully parsed
+ */
+ template<typename NumberType>
+ bool get_bson_string(const NumberType len, string_t& result)
+ {
+ if (JSON_UNLIKELY(len < 1))
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
+ }
+
+ return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
+ }
+
+ /*!
+ @brief Read a BSON document element of the given @a element_type.
+ @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
+ @param[in] element_type_parse_position The position in the input stream,
+ where the `element_type` was read.
+ @warning Not all BSON element types are supported yet. An unsupported
+ @a element_type will give rise to a parse_error.114:
+ Unsupported BSON record type 0x...
+ @return whether a valid BSON-object/array was passed to the SAX parser
+ */
+ bool parse_bson_element_internal(const int element_type,
+ const std::size_t element_type_parse_position)
+ {
+ switch (element_type)
+ {
+ case 0x01: // double
+ {
+ double number;
+ return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ case 0x02: // string
+ {
+ std::int32_t len;
+ string_t value;
+ return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
+ }
+
+ case 0x03: // object
+ {
+ return parse_bson_internal();
+ }
+
+ case 0x04: // array
+ {
+ return parse_bson_array();
+ }
+
+ case 0x08: // boolean
+ {
+ return sax->boolean(get() != 0);
+ }
+
+ case 0x0A: // null
+ {
+ return sax->null();
+ }
+
+ case 0x10: // int32
+ {
+ std::int32_t value;
+ return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
+ }
+
+ case 0x12: // int64
+ {
+ std::int64_t value;
+ return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
+ }
+
+ default: // anything else not supported (yet)
+ {
+ std::array<char, 3> cr{{}};
+ (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
+ return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
+ }
+ }
+ }
+
+ /*!
+ @brief Read a BSON element list (as specified in the BSON-spec)
+
+ The same binary layout is used for objects and arrays, hence it must be
+ indicated with the argument @a is_array which one is expected
+ (true --> array, false --> object).
+
+ @param[in] is_array Determines if the element list being read is to be
+ treated as an object (@a is_array == false), or as an
+ array (@a is_array == true).
+ @return whether a valid BSON-object/array was passed to the SAX parser
+ */
+ bool parse_bson_element_list(const bool is_array)
+ {
+ string_t key;
+ while (int element_type = get())
+ {
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
+ {
+ return false;
+ }
+
+ const std::size_t element_type_parse_position = chars_read;
+ if (JSON_UNLIKELY(not get_bson_cstr(key)))
+ {
+ return false;
+ }
+
+ if (not is_array and not sax->key(key))
+ {
+ return false;
+ }
+
+ if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
+ {
+ return false;
+ }
+
+ // get_bson_cstr only appends
+ key.clear();
+ }
+
+ return true;
+ }
+
+ /*!
+ @brief Reads an array from the BSON input and passes it to the SAX-parser.
+ @return whether a valid BSON-array was passed to the SAX parser
+ */
+ bool parse_bson_array()
+ {
+ std::int32_t document_size;
+ get_number<std::int32_t, true>(input_format_t::bson, document_size);
+
+ if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
+ {
+ return false;
+ }
+
+ if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
+ {
+ return false;
+ }
+
+ return sax->end_array();
+ }
+
+ //////////
+ // CBOR //
+ //////////
+
+ /*!
+ @param[in] get_char whether a new character should be retrieved from the
+ input (true, default) or whether the last read
+ character should be considered instead
+
+ @return whether a valid CBOR value was passed to the SAX parser
+ */
+ bool parse_cbor_internal(const bool get_char = true)
+ {
+ switch (get_char ? get() : current)
+ {
+ // EOF
+ case std::char_traits<char>::eof():
+ return unexpect_eof(input_format_t::cbor, "value");
+
+ // Integer 0x00..0x17 (0..23)
+ case 0x00:
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ case 0x0C:
+ case 0x0D:
+ case 0x0E:
+ case 0x0F:
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ return sax->number_unsigned(static_cast<number_unsigned_t>(current));
+
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
+ {
+ std::uint8_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
+ }
+
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
+ {
+ std::uint16_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
+ }
+
+ case 0x1A: // Unsigned integer (four-byte uint32_t follows)
+ {
+ std::uint32_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
+ }
+
+ case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
+ {
+ std::uint64_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
+ }
+
+ // Negative integer -1-0x00..-1-0x17 (-1..-24)
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29:
+ case 0x2A:
+ case 0x2B:
+ case 0x2C:
+ case 0x2D:
+ case 0x2E:
+ case 0x2F:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
+
+ case 0x38: // Negative integer (one-byte uint8_t follows)
+ {
+ std::uint8_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
+ }
+
+ case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
+ {
+ std::uint16_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
+ }
+
+ case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
+ {
+ std::uint32_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
+ }
+
+ case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
+ {
+ std::uint64_t number;
+ return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
+ - static_cast<number_integer_t>(number));
+ }
+
+ // UTF-8 string (0x00..0x17 bytes follow)
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ case 0x66:
+ case 0x67:
+ case 0x68:
+ case 0x69:
+ case 0x6A:
+ case 0x6B:
+ case 0x6C:
+ case 0x6D:
+ case 0x6E:
+ case 0x6F:
+ case 0x70:
+ case 0x71:
+ case 0x72:
+ case 0x73:
+ case 0x74:
+ case 0x75:
+ case 0x76:
+ case 0x77:
+ case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+ case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+ case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
+ case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
+ case 0x7F: // UTF-8 string (indefinite length)
+ {
+ string_t s;
+ return get_cbor_string(s) and sax->string(s);
+ }
+
+ // array (0x00..0x17 data items follow)
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ case 0x83:
+ case 0x84:
+ case 0x85:
+ case 0x86:
+ case 0x87:
+ case 0x88:
+ case 0x89:
+ case 0x8A:
+ case 0x8B:
+ case 0x8C:
+ case 0x8D:
+ case 0x8E:
+ case 0x8F:
+ case 0x90:
+ case 0x91:
+ case 0x92:
+ case 0x93:
+ case 0x94:
+ case 0x95:
+ case 0x96:
+ case 0x97:
+ return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
+
+ case 0x98: // array (one-byte uint8_t for n follows)
+ {
+ std::uint8_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
+ }
+
+ case 0x99: // array (two-byte uint16_t for n follow)
+ {
+ std::uint16_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
+ }
+
+ case 0x9A: // array (four-byte uint32_t for n follow)
+ {
+ std::uint32_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
+ }
+
+ case 0x9B: // array (eight-byte uint64_t for n follow)
+ {
+ std::uint64_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
+ }
+
+ case 0x9F: // array (indefinite length)
+ return get_cbor_array(std::size_t(-1));
+
+ // map (0x00..0x17 pairs of data items follow)
+ case 0xA0:
+ case 0xA1:
+ case 0xA2:
+ case 0xA3:
+ case 0xA4:
+ case 0xA5:
+ case 0xA6:
+ case 0xA7:
+ case 0xA8:
+ case 0xA9:
+ case 0xAA:
+ case 0xAB:
+ case 0xAC:
+ case 0xAD:
+ case 0xAE:
+ case 0xAF:
+ case 0xB0:
+ case 0xB1:
+ case 0xB2:
+ case 0xB3:
+ case 0xB4:
+ case 0xB5:
+ case 0xB6:
+ case 0xB7:
+ return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
+
+ case 0xB8: // map (one-byte uint8_t for n follows)
+ {
+ std::uint8_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
+ }
+
+ case 0xB9: // map (two-byte uint16_t for n follow)
+ {
+ std::uint16_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
+ }
+
+ case 0xBA: // map (four-byte uint32_t for n follow)
+ {
+ std::uint32_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
+ }
+
+ case 0xBB: // map (eight-byte uint64_t for n follow)
+ {
+ std::uint64_t len;
+ return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
+ }
+
+ case 0xBF: // map (indefinite length)
+ return get_cbor_object(std::size_t(-1));
+
+ case 0xF4: // false
+ return sax->boolean(false);
+
+ case 0xF5: // true
+ return sax->boolean(true);
+
+ case 0xF6: // null
+ return sax->null();
+
+ case 0xF9: // Half-Precision Float (two-byte IEEE 754)
+ {
+ const int byte1_raw = get();
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
+ {
+ return false;
+ }
+ const int byte2_raw = get();
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
+ {
+ return false;
+ }
+
+ const auto byte1 = static_cast<unsigned char>(byte1_raw);
+ const auto byte2 = static_cast<unsigned char>(byte2_raw);
+
+ // code from RFC 7049, Appendix D, Figure 3:
+ // As half-precision floating-point numbers were only added
+ // to IEEE 754 in 2008, today's programming platforms often
+ // still only have limited support for them. It is very
+ // easy to include at least decoding support for them even
+ // without such support. An example of a small decoder for
+ // half-precision floating-point numbers in the C language
+ // is shown in Fig. 3.
+ const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
+ const double val = [&half]
+ {
+ const int exp = (half >> 10u) & 0x1Fu;
+ const unsigned int mant = half & 0x3FFu;
+ assert(0 <= exp and exp <= 32);
+ assert(0 <= mant and mant <= 1024);
+ switch (exp)
+ {
+ case 0:
+ return std::ldexp(mant, -24);
+ case 31:
+ return (mant == 0)
+ ? std::numeric_limits<double>::infinity()
+ : std::numeric_limits<double>::quiet_NaN();
+ default:
+ return std::ldexp(mant + 1024, exp - 25);
+ }
+ }();
+ return sax->number_float((half & 0x8000u) != 0
+ ? static_cast<number_float_t>(-val)
+ : static_cast<number_float_t>(val), "");
+ }
+
+ case 0xFA: // Single-Precision Float (four-byte IEEE 754)
+ {
+ float number;
+ return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
+ {
+ double number;
+ return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ default: // anything else (0xFF is handled inside the other types)
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
+ }
+ }
+ }
+
+ /*!
+ @brief reads a CBOR string
+
+ This function first reads starting bytes to determine the expected
+ string length and then copies this number of bytes into a string.
+ Additionally, CBOR's strings with indefinite lengths are supported.
+
+ @param[out] result created string
+
+ @return whether string creation completed
+ */
+ bool get_cbor_string(string_t& result)
+ {
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
+ {
+ return false;
+ }
+
+ switch (current)
+ {
+ // UTF-8 string (0x00..0x17 bytes follow)
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ case 0x66:
+ case 0x67:
+ case 0x68:
+ case 0x69:
+ case 0x6A:
+ case 0x6B:
+ case 0x6C:
+ case 0x6D:
+ case 0x6E:
+ case 0x6F:
+ case 0x70:
+ case 0x71:
+ case 0x72:
+ case 0x73:
+ case 0x74:
+ case 0x75:
+ case 0x76:
+ case 0x77:
+ {
+ return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
+ }
+
+ case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
+ {
+ std::uint8_t len;
+ return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
+ }
+
+ case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
+ {
+ std::uint16_t len;
+ return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
+ }
+
+ case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
+ {
+ std::uint32_t len;
+ return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
+ }
+
+ case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
+ {
+ std::uint64_t len;
+ return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
+ }
+
+ case 0x7F: // UTF-8 string (indefinite length)
+ {
+ while (get() != 0xFF)
+ {
+ string_t chunk;
+ if (not get_cbor_string(chunk))
+ {
+ return false;
+ }
+ result.append(chunk);
+ }
+ return true;
+ }
+
+ default:
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
+ }
+ }
+ }
+
+ /*!
+ @param[in] len the length of the array or std::size_t(-1) for an
+ array of indefinite size
+ @return whether array creation completed
+ */
+ bool get_cbor_array(const std::size_t len)
+ {
+ if (JSON_UNLIKELY(not sax->start_array(len)))
+ {
+ return false;
+ }
+
+ if (len != std::size_t(-1))
+ {
+ for (std::size_t i = 0; i < len; ++i)
+ {
+ if (JSON_UNLIKELY(not parse_cbor_internal()))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ while (get() != 0xFF)
+ {
+ if (JSON_UNLIKELY(not parse_cbor_internal(false)))
+ {
+ return false;
+ }
+ }
+ }
+
+ return sax->end_array();
+ }
+
+ /*!
+ @param[in] len the length of the object or std::size_t(-1) for an
+ object of indefinite size
+ @return whether object creation completed
+ */
+ bool get_cbor_object(const std::size_t len)
+ {
+ if (JSON_UNLIKELY(not sax->start_object(len)))
+ {
+ return false;
+ }
+
+ string_t key;
+ if (len != std::size_t(-1))
+ {
+ for (std::size_t i = 0; i < len; ++i)
+ {
+ get();
+ if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
+ {
+ return false;
+ }
+
+ if (JSON_UNLIKELY(not parse_cbor_internal()))
+ {
+ return false;
+ }
+ key.clear();
+ }
+ }
+ else
+ {
+ while (get() != 0xFF)
+ {
+ if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
+ {
+ return false;
+ }
+
+ if (JSON_UNLIKELY(not parse_cbor_internal()))
+ {
+ return false;
+ }
+ key.clear();
+ }
+ }
+
+ return sax->end_object();
+ }
+
+ /////////////
+ // MsgPack //
+ /////////////
+
+ /*!
+ @return whether a valid MessagePack value was passed to the SAX parser
+ */
+ bool parse_msgpack_internal()
+ {
+ switch (get())
+ {
+ // EOF
+ case std::char_traits<char>::eof():
+ return unexpect_eof(input_format_t::msgpack, "value");
+
+ // positive fixint
+ case 0x00:
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ case 0x0C:
+ case 0x0D:
+ case 0x0E:
+ case 0x0F:
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x1A:
+ case 0x1B:
+ case 0x1C:
+ case 0x1D:
+ case 0x1E:
+ case 0x1F:
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29:
+ case 0x2A:
+ case 0x2B:
+ case 0x2C:
+ case 0x2D:
+ case 0x2E:
+ case 0x2F:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ case 0x3A:
+ case 0x3B:
+ case 0x3C:
+ case 0x3D:
+ case 0x3E:
+ case 0x3F:
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4A:
+ case 0x4B:
+ case 0x4C:
+ case 0x4D:
+ case 0x4E:
+ case 0x4F:
+ case 0x50:
+ case 0x51:
+ case 0x52:
+ case 0x53:
+ case 0x54:
+ case 0x55:
+ case 0x56:
+ case 0x57:
+ case 0x58:
+ case 0x59:
+ case 0x5A:
+ case 0x5B:
+ case 0x5C:
+ case 0x5D:
+ case 0x5E:
+ case 0x5F:
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ case 0x66:
+ case 0x67:
+ case 0x68:
+ case 0x69:
+ case 0x6A:
+ case 0x6B:
+ case 0x6C:
+ case 0x6D:
+ case 0x6E:
+ case 0x6F:
+ case 0x70:
+ case 0x71:
+ case 0x72:
+ case 0x73:
+ case 0x74:
+ case 0x75:
+ case 0x76:
+ case 0x77:
+ case 0x78:
+ case 0x79:
+ case 0x7A:
+ case 0x7B:
+ case 0x7C:
+ case 0x7D:
+ case 0x7E:
+ case 0x7F:
+ return sax->number_unsigned(static_cast<number_unsigned_t>(current));
+
+ // fixmap
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ case 0x83:
+ case 0x84:
+ case 0x85:
+ case 0x86:
+ case 0x87:
+ case 0x88:
+ case 0x89:
+ case 0x8A:
+ case 0x8B:
+ case 0x8C:
+ case 0x8D:
+ case 0x8E:
+ case 0x8F:
+ return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
+
+ // fixarray
+ case 0x90:
+ case 0x91:
+ case 0x92:
+ case 0x93:
+ case 0x94:
+ case 0x95:
+ case 0x96:
+ case 0x97:
+ case 0x98:
+ case 0x99:
+ case 0x9A:
+ case 0x9B:
+ case 0x9C:
+ case 0x9D:
+ case 0x9E:
+ case 0x9F:
+ return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
+
+ // fixstr
+ case 0xA0:
+ case 0xA1:
+ case 0xA2:
+ case 0xA3:
+ case 0xA4:
+ case 0xA5:
+ case 0xA6:
+ case 0xA7:
+ case 0xA8:
+ case 0xA9:
+ case 0xAA:
+ case 0xAB:
+ case 0xAC:
+ case 0xAD:
+ case 0xAE:
+ case 0xAF:
+ case 0xB0:
+ case 0xB1:
+ case 0xB2:
+ case 0xB3:
+ case 0xB4:
+ case 0xB5:
+ case 0xB6:
+ case 0xB7:
+ case 0xB8:
+ case 0xB9:
+ case 0xBA:
+ case 0xBB:
+ case 0xBC:
+ case 0xBD:
+ case 0xBE:
+ case 0xBF:
+ {
+ string_t s;
+ return get_msgpack_string(s) and sax->string(s);
+ }
+
+ case 0xC0: // nil
+ return sax->null();
+
+ case 0xC2: // false
+ return sax->boolean(false);
+
+ case 0xC3: // true
+ return sax->boolean(true);
+
+ case 0xCA: // float 32
+ {
+ float number;
+ return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ case 0xCB: // float 64
+ {
+ double number;
+ return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ case 0xCC: // uint 8
+ {
+ std::uint8_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
+ }
+
+ case 0xCD: // uint 16
+ {
+ std::uint16_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
+ }
+
+ case 0xCE: // uint 32
+ {
+ std::uint32_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
+ }
+
+ case 0xCF: // uint 64
+ {
+ std::uint64_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
+ }
+
+ case 0xD0: // int 8
+ {
+ std::int8_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
+ }
+
+ case 0xD1: // int 16
+ {
+ std::int16_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
+ }
+
+ case 0xD2: // int 32
+ {
+ std::int32_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
+ }
+
+ case 0xD3: // int 64
+ {
+ std::int64_t number;
+ return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
+ }
+
+ case 0xD9: // str 8
+ case 0xDA: // str 16
+ case 0xDB: // str 32
+ {
+ string_t s;
+ return get_msgpack_string(s) and sax->string(s);
+ }
+
+ case 0xDC: // array 16
+ {
+ std::uint16_t len;
+ return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
+ }
+
+ case 0xDD: // array 32
+ {
+ std::uint32_t len;
+ return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
+ }
+
+ case 0xDE: // map 16
+ {
+ std::uint16_t len;
+ return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
+ }
+
+ case 0xDF: // map 32
+ {
+ std::uint32_t len;
+ return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
+ }
+
+ // negative fixint
+ case 0xE0:
+ case 0xE1:
+ case 0xE2:
+ case 0xE3:
+ case 0xE4:
+ case 0xE5:
+ case 0xE6:
+ case 0xE7:
+ case 0xE8:
+ case 0xE9:
+ case 0xEA:
+ case 0xEB:
+ case 0xEC:
+ case 0xED:
+ case 0xEE:
+ case 0xEF:
+ case 0xF0:
+ case 0xF1:
+ case 0xF2:
+ case 0xF3:
+ case 0xF4:
+ case 0xF5:
+ case 0xF6:
+ case 0xF7:
+ case 0xF8:
+ case 0xF9:
+ case 0xFA:
+ case 0xFB:
+ case 0xFC:
+ case 0xFD:
+ case 0xFE:
+ case 0xFF:
+ return sax->number_integer(static_cast<std::int8_t>(current));
+
+ default: // anything else
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
+ }
+ }
+ }
+
+ /*!
+ @brief reads a MessagePack string
+
+ This function first reads starting bytes to determine the expected
+ string length and then copies this number of bytes into a string.
+
+ @param[out] result created string
+
+ @return whether string creation completed
+ */
+ bool get_msgpack_string(string_t& result)
+ {
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
+ {
+ return false;
+ }
+
+ switch (current)
+ {
+ // fixstr
+ case 0xA0:
+ case 0xA1:
+ case 0xA2:
+ case 0xA3:
+ case 0xA4:
+ case 0xA5:
+ case 0xA6:
+ case 0xA7:
+ case 0xA8:
+ case 0xA9:
+ case 0xAA:
+ case 0xAB:
+ case 0xAC:
+ case 0xAD:
+ case 0xAE:
+ case 0xAF:
+ case 0xB0:
+ case 0xB1:
+ case 0xB2:
+ case 0xB3:
+ case 0xB4:
+ case 0xB5:
+ case 0xB6:
+ case 0xB7:
+ case 0xB8:
+ case 0xB9:
+ case 0xBA:
+ case 0xBB:
+ case 0xBC:
+ case 0xBD:
+ case 0xBE:
+ case 0xBF:
+ {
+ return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
+ }
+
+ case 0xD9: // str 8
+ {
+ std::uint8_t len;
+ return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
+ }
+
+ case 0xDA: // str 16
+ {
+ std::uint16_t len;
+ return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
+ }
+
+ case 0xDB: // str 32
+ {
+ std::uint32_t len;
+ return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
+ }
+
+ default:
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
+ }
+ }
+ }
+
+ /*!
+ @param[in] len the length of the array
+ @return whether array creation completed
+ */
+ bool get_msgpack_array(const std::size_t len)
+ {
+ if (JSON_UNLIKELY(not sax->start_array(len)))
+ {
+ return false;
+ }
+
+ for (std::size_t i = 0; i < len; ++i)
+ {
+ if (JSON_UNLIKELY(not parse_msgpack_internal()))
+ {
+ return false;
+ }
+ }
+
+ return sax->end_array();
+ }
+
+ /*!
+ @param[in] len the length of the object
+ @return whether object creation completed
+ */
+ bool get_msgpack_object(const std::size_t len)
+ {
+ if (JSON_UNLIKELY(not sax->start_object(len)))
+ {
+ return false;
+ }
+
+ string_t key;
+ for (std::size_t i = 0; i < len; ++i)
+ {
+ get();
+ if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
+ {
+ return false;
+ }
+
+ if (JSON_UNLIKELY(not parse_msgpack_internal()))
+ {
+ return false;
+ }
+ key.clear();
+ }
+
+ return sax->end_object();
+ }
+
+ ////////////
+ // UBJSON //
+ ////////////
+
+ /*!
+ @param[in] get_char whether a new character should be retrieved from the
+ input (true, default) or whether the last read
+ character should be considered instead
+
+ @return whether a valid UBJSON value was passed to the SAX parser
+ */
+ bool parse_ubjson_internal(const bool get_char = true)
+ {
+ return get_ubjson_value(get_char ? get_ignore_noop() : current);
+ }
+
+ /*!
+ @brief reads a UBJSON string
+
+ This function is either called after reading the 'S' byte explicitly
+ indicating a string, or in case of an object key where the 'S' byte can be
+ left out.
+
+ @param[out] result created string
+ @param[in] get_char whether a new character should be retrieved from the
+ input (true, default) or whether the last read
+ character should be considered instead
+
+ @return whether string creation completed
+ */
+ bool get_ubjson_string(string_t& result, const bool get_char = true)
+ {
+ if (get_char)
+ {
+ get(); // TODO(niels): may we ignore N here?
+ }
+
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
+ {
+ return false;
+ }
+
+ switch (current)
+ {
+ case 'U':
+ {
+ std::uint8_t len;
+ return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
+ }
+
+ case 'i':
+ {
+ std::int8_t len;
+ return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
+ }
+
+ case 'I':
+ {
+ std::int16_t len;
+ return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
+ }
+
+ case 'l':
+ {
+ std::int32_t len;
+ return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
+ }
+
+ case 'L':
+ {
+ std::int64_t len;
+ return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
+ }
+
+ default:
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
+ }
+ }
+
+ /*!
+ @param[out] result determined size
+ @return whether size determination completed
+ */
+ bool get_ubjson_size_value(std::size_t& result)
+ {
+ switch (get_ignore_noop())
+ {
+ case 'U':
+ {
+ std::uint8_t number;
+ if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
+ {
+ return false;
+ }
+ result = static_cast<std::size_t>(number);
+ return true;
+ }
+
+ case 'i':
+ {
+ std::int8_t number;
+ if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
+ {
+ return false;
+ }
+ result = static_cast<std::size_t>(number);
+ return true;
+ }
+
+ case 'I':
+ {
+ std::int16_t number;
+ if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
+ {
+ return false;
+ }
+ result = static_cast<std::size_t>(number);
+ return true;
+ }
+
+ case 'l':
+ {
+ std::int32_t number;
+ if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
+ {
+ return false;
+ }
+ result = static_cast<std::size_t>(number);
+ return true;
+ }
+
+ case 'L':
+ {
+ std::int64_t number;
+ if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
+ {
+ return false;
+ }
+ result = static_cast<std::size_t>(number);
+ return true;
+ }
+
+ default:
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
+ }
+ }
+ }
+
+ /*!
+ @brief determine the type and size for a container
+
+ In the optimized UBJSON format, a type and a size can be provided to allow
+ for a more compact representation.
+
+ @param[out] result pair of the size and the type
+
+ @return whether pair creation completed
+ */
+ bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
+ {
+ result.first = string_t::npos; // size
+ result.second = 0; // type
+
+ get_ignore_noop();
+
+ if (current == '$')
+ {
+ result.second = get(); // must not ignore 'N', because 'N' maybe the type
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
+ {
+ return false;
+ }
+
+ get_ignore_noop();
+ if (JSON_UNLIKELY(current != '#'))
+ {
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
+ {
+ return false;
+ }
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
+ }
+
+ return get_ubjson_size_value(result.first);
+ }
+
+ if (current == '#')
+ {
+ return get_ubjson_size_value(result.first);
+ }
+
+ return true;
+ }
+
+ /*!
+ @param prefix the previously read or set type prefix
+ @return whether value creation completed
+ */
+ bool get_ubjson_value(const int prefix)
+ {
+ switch (prefix)
+ {
+ case std::char_traits<char>::eof(): // EOF
+ return unexpect_eof(input_format_t::ubjson, "value");
+
+ case 'T': // true
+ return sax->boolean(true);
+ case 'F': // false
+ return sax->boolean(false);
+
+ case 'Z': // null
+ return sax->null();
+
+ case 'U':
+ {
+ std::uint8_t number;
+ return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
+ }
+
+ case 'i':
+ {
+ std::int8_t number;
+ return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
+ }
+
+ case 'I':
+ {
+ std::int16_t number;
+ return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
+ }
+
+ case 'l':
+ {
+ std::int32_t number;
+ return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
+ }
+
+ case 'L':
+ {
+ std::int64_t number;
+ return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
+ }
+
+ case 'd':
+ {
+ float number;
+ return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ case 'D':
+ {
+ double number;
+ return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
+ }
+
+ case 'C': // char
+ {
+ get();
+ if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
+ {
+ return false;
+ }
+ if (JSON_UNLIKELY(current > 127))
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
+ }
+ string_t s(1, static_cast<char>(current));
+ return sax->string(s);
+ }
+
+ case 'S': // string
+ {
+ string_t s;
+ return get_ubjson_string(s) and sax->string(s);
+ }
+
+ case '[': // array
+ return get_ubjson_array();
+
+ case '{': // object
+ return get_ubjson_object();
+
+ default: // anything else
+ {
+ auto last_token = get_token_string();
+ return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
+ }
+ }
+ }
+
+ /*!
+ @return whether array creation completed
+ */
+ bool get_ubjson_array()
+ {
+ std::pair<std::size_t, int> size_and_type;
+ if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
+ {
+ return false;
+ }
+
+ if (size_and_type.first != string_t::npos)
+ {
+ if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
+ {
+ return false;
+ }
+
+ if (size_and_type.second != 0)
+ {
+ if (size_and_type.second != 'N')
+ {
+ for (std::size_t i = 0; i < size_and_type.first; ++i)
+ {
+ if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (std::size_t i = 0; i < size_and_type.first; ++i)
+ {
+ if (JSON_UNLIKELY(not parse_ubjson_internal()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
+ {
+ return false;
+ }
+
+ while (current != ']')
+ {
+ if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
+ {
+ return false;
+ }
+ get_ignore_noop();
+ }
+ }
+
+ return sax->end_array();
+ }
+
+ /*!
+ @return whether object creation completed
+ */
+ bool get_ubjson_object()
+ {
+ std::pair<std::size_t, int> size_and_type;
+ if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
+ {
+ return false;
+ }
+
+ string_t key;
+ if (size_and_type.first != string_t::npos)
+ {
+ if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
+ {
+ return false;
+ }
+
+ if (size_and_type.second != 0)
+ {
+ for (std::size_t i = 0; i < size_and_type.first; ++i)
+ {
+ if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
+ {
+ return false;
+ }
+ if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
+ {
+ return false;
+ }
+ key.clear();
+ }
+ }
+ else
+ {
+ for (std::size_t i = 0; i < size_and_type.first; ++i)
+ {
+ if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
+ {
+ return false;
+ }
+ if (JSON_UNLIKELY(not parse_ubjson_internal()))
+ {
+ return false;
+ }
+ key.clear();
+ }
+ }
+ }
+ else
+ {
+ if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
+ {
+ return false;
+ }
+
+ while (current != '}')
+ {
+ if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
+ {
+ return false;
+ }
+ if (JSON_UNLIKELY(not parse_ubjson_internal()))
+ {
+ return false;
+ }
+ get_ignore_noop();
+ key.clear();
+ }
+ }
+
+ return sax->end_object();
+ }
+
+ ///////////////////////
+ // Utility functions //
+ ///////////////////////
+
+ /*!
+ @brief get next character from the input
+
+ This function provides the interface to the used input adapter. It does
+ not throw in case the input reached EOF, but returns a -'ve valued
+ `std::char_traits<char>::eof()` in that case.
+
+ @return character read from the input
+ */
+ int get()
+ {
+ ++chars_read;
+ return current = ia->get_character();
+ }
+
+ /*!
+ @return character read from the input after ignoring all 'N' entries
+ */
+ int get_ignore_noop()
+ {
+ do
+ {
+ get();
+ }
+ while (current == 'N');
+
+ return current;
+ }
+
+ /*
+ @brief read a number from the input
+
+ @tparam NumberType the type of the number
+ @param[in] format the current format (for diagnostics)
+ @param[out] result number of type @a NumberType
+
+ @return whether conversion completed
+
+ @note This function needs to respect the system's endianness, because
+ bytes in CBOR, MessagePack, and UBJSON are stored in network order
+ (big endian) and therefore need reordering on little endian systems.
+ */
+ template<typename NumberType, bool InputIsLittleEndian = false>
+ bool get_number(const input_format_t format, NumberType& result)
+ {
+ // step 1: read input into array with system's byte order
+ std::array<std::uint8_t, sizeof(NumberType)> vec;
+ for (std::size_t i = 0; i < sizeof(NumberType); ++i)
+ {
+ get();
+ if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
+ {
+ return false;
+ }
+
+ // reverse byte order prior to conversion if necessary
+ if (is_little_endian != InputIsLittleEndian)
+ {
+ vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
+ }
+ else
+ {
+ vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
+ }
+ }
+
+ // step 2: convert array into number of type T and return
+ std::memcpy(&result, vec.data(), sizeof(NumberType));
+ return true;
+ }
+
+ /*!
+ @brief create a string by reading characters from the input
+
+ @tparam NumberType the type of the number
+ @param[in] format the current format (for diagnostics)
+ @param[in] len number of characters to read
+ @param[out] result string created by reading @a len bytes
+
+ @return whether string creation completed
+
+ @note We can not reserve @a len bytes for the result, because @a len
+ may be too large. Usually, @ref unexpect_eof() detects the end of
+ the input before we run out of string memory.
+ */
+ template<typename NumberType>
+ bool get_string(const input_format_t format,
+ const NumberType len,
+ string_t& result)
+ {
+ bool success = true;
+ std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
+ {
+ get();
+ if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
+ {
+ success = false;
+ }
+ return static_cast<char>(current);
+ });
+ return success;
+ }
+
+ /*!
+ @param[in] format the current format (for diagnostics)
+ @param[in] context further context information (for diagnostics)
+ @return whether the last read character is not EOF
+ */
+ bool unexpect_eof(const input_format_t format, const char* context) const
+ {
+ if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
+ {
+ return sax->parse_error(chars_read, "<end of file>",
+ parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
+ }
+ return true;
+ }
+
+ /*!
+ @return a string representation of the last read byte
+ */
+ std::string get_token_string() const
+ {
+ std::array<char, 3> cr{{}};
+ (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
+ return std::string{cr.data()};
+ }
+
+ /*!
+ @param[in] format the current format
+ @param[in] detail a detailed error message
+ @param[in] context further contect information
+ @return a message string to use in the parse_error exceptions
+ */
+ std::string exception_message(const input_format_t format,
+ const std::string& detail,
+ const std::string& context) const
+ {
+ std::string error_msg = "syntax error while parsing ";
+
+ switch (format)
+ {
+ case input_format_t::cbor:
+ error_msg += "CBOR";
+ break;
+
+ case input_format_t::msgpack:
+ error_msg += "MessagePack";
+ break;
+
+ case input_format_t::ubjson:
+ error_msg += "UBJSON";
+ break;
+
+ case input_format_t::bson:
+ error_msg += "BSON";
+ break;
+
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+
+ return error_msg + " " + context + ": " + detail;
+ }
+
+ private:
+ /// input adapter
+ input_adapter_t ia = nullptr;
+
+ /// the current character
+ int current = std::char_traits<char>::eof();
+
+ /// the number of characters read
+ std::size_t chars_read = 0;
+
+ /// whether we can assume little endianness
+ const bool is_little_endian = little_endianess();
+
+ /// the SAX parser
+ json_sax_t* sax = nullptr;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+// #include <nlohmann/detail/input/lexer.hpp>
+
+
+#include <array> // array
+#include <clocale> // localeconv
+#include <cstddef> // size_t
+#include <cstdio> // snprintf
+#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
+#include <initializer_list> // initializer_list
+#include <string> // char_traits, string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+// #include <nlohmann/detail/input/position_t.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////
+// lexer //
+///////////
+
+/*!
+@brief lexical analysis
+
+This class organizes the lexical analysis during JSON deserialization.
+*/
+template<typename BasicJsonType>
+class lexer
+{
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+
+ public:
+ /// token types for the parser
+ enum class token_type
+ {
+ uninitialized, ///< indicating the scanner is uninitialized
+ literal_true, ///< the `true` literal
+ literal_false, ///< the `false` literal
+ literal_null, ///< the `null` literal
+ value_string, ///< a string -- use get_string() for actual value
+ value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
+ value_integer, ///< a signed integer -- use get_number_integer() for actual value
+ value_float, ///< an floating point number -- use get_number_float() for actual value
+ begin_array, ///< the character for array begin `[`
+ begin_object, ///< the character for object begin `{`
+ end_array, ///< the character for array end `]`
+ end_object, ///< the character for object end `}`
+ name_separator, ///< the name separator `:`
+ value_separator, ///< the value separator `,`
+ parse_error, ///< indicating a parse error
+ end_of_input, ///< indicating the end of the input buffer
+ literal_or_value ///< a literal or the begin of a value (only for diagnostics)
+ };
+
+ /// return name of values of type token_type (only used for errors)
+ static const char* token_type_name(const token_type t) noexcept
+ {
+ switch (t)
+ {
+ case token_type::uninitialized:
+ return "<uninitialized>";
+ case token_type::literal_true:
+ return "true literal";
+ case token_type::literal_false:
+ return "false literal";
+ case token_type::literal_null:
+ return "null literal";
+ case token_type::value_string:
+ return "string literal";
+ case lexer::token_type::value_unsigned:
+ case lexer::token_type::value_integer:
+ case lexer::token_type::value_float:
+ return "number literal";
+ case token_type::begin_array:
+ return "'['";
+ case token_type::begin_object:
+ return "'{'";
+ case token_type::end_array:
+ return "']'";
+ case token_type::end_object:
+ return "'}'";
+ case token_type::name_separator:
+ return "':'";
+ case token_type::value_separator:
+ return "','";
+ case token_type::parse_error:
+ return "<parse error>";
+ case token_type::end_of_input:
+ return "end of input";
+ case token_type::literal_or_value:
+ return "'[', '{', or a literal";
+ // LCOV_EXCL_START
+ default: // catch non-enum values
+ return "unknown token";
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ explicit lexer(detail::input_adapter_t&& adapter)
+ : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
+
+ // delete because of pointer members
+ lexer(const lexer&) = delete;
+ lexer(lexer&&) = delete;
+ lexer& operator=(lexer&) = delete;
+ lexer& operator=(lexer&&) = delete;
+ ~lexer() = default;
+
+ private:
+ /////////////////////
+ // locales
+ /////////////////////
+
+ /// return the locale-dependent decimal point
+ static char get_decimal_point() noexcept
+ {
+ const auto loc = localeconv();
+ assert(loc != nullptr);
+ return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
+ }
+
+ /////////////////////
+ // scan functions
+ /////////////////////
+
+ /*!
+ @brief get codepoint from 4 hex characters following `\u`
+
+ For input "\u c1 c2 c3 c4" the codepoint is:
+ (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
+ = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
+
+ Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
+ must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
+ conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
+ between the ASCII value of the character and the desired integer value.
+
+ @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
+ non-hex character)
+ */
+ int get_codepoint()
+ {
+ // this function only makes sense after reading `\u`
+ assert(current == 'u');
+ int codepoint = 0;
+
+ const auto factors = { 12u, 8u, 4u, 0u };
+ for (const auto factor : factors)
+ {
+ get();
+
+ if (current >= '0' and current <= '9')
+ {
+ codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
+ }
+ else if (current >= 'A' and current <= 'F')
+ {
+ codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
+ }
+ else if (current >= 'a' and current <= 'f')
+ {
+ codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
+ return codepoint;
+ }
+
+ /*!
+ @brief check if the next byte(s) are inside a given range
+
+ Adds the current byte and, for each passed range, reads a new byte and
+ checks if it is inside the range. If a violation was detected, set up an
+ error message and return false. Otherwise, return true.
+
+ @param[in] ranges list of integers; interpreted as list of pairs of
+ inclusive lower and upper bound, respectively
+
+ @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
+ 1, 2, or 3 pairs. This precondition is enforced by an assertion.
+
+ @return true if and only if no range violation was detected
+ */
+ bool next_byte_in_range(std::initializer_list<int> ranges)
+ {
+ assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
+ add(current);
+
+ for (auto range = ranges.begin(); range != ranges.end(); ++range)
+ {
+ get();
+ if (JSON_LIKELY(*range <= current and current <= *(++range)))
+ {
+ add(current);
+ }
+ else
+ {
+ error_message = "invalid string: ill-formed UTF-8 byte";
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /*!
+ @brief scan a string literal
+
+ This function scans a string according to Sect. 7 of RFC 7159. While
+ scanning, bytes are escaped and copied into buffer token_buffer. Then the
+ function returns successfully, token_buffer is *not* null-terminated (as it
+ may contain \0 bytes), and token_buffer.size() is the number of bytes in the
+ string.
+
+ @return token_type::value_string if string could be successfully scanned,
+ token_type::parse_error otherwise
+
+ @note In case of errors, variable error_message contains a textual
+ description.
+ */
+ token_type scan_string()
+ {
+ // reset token_buffer (ignore opening quote)
+ reset();
+
+ // we entered the function by reading an open quote
+ assert(current == '\"');
+
+ while (true)
+ {
+ // get next character
+ switch (get())
+ {
+ // end of file while parsing string
+ case std::char_traits<char>::eof():
+ {
+ error_message = "invalid string: missing closing quote";
+ return token_type::parse_error;
+ }
+
+ // closing quote
+ case '\"':
+ {
+ return token_type::value_string;
+ }
+
+ // escapes
+ case '\\':
+ {
+ switch (get())
+ {
+ // quotation mark
+ case '\"':
+ add('\"');
+ break;
+ // reverse solidus
+ case '\\':
+ add('\\');
+ break;
+ // solidus
+ case '/':
+ add('/');
+ break;
+ // backspace
+ case 'b':
+ add('\b');
+ break;
+ // form feed
+ case 'f':
+ add('\f');
+ break;
+ // line feed
+ case 'n':
+ add('\n');
+ break;
+ // carriage return
+ case 'r':
+ add('\r');
+ break;
+ // tab
+ case 't':
+ add('\t');
+ break;
+
+ // unicode escapes
+ case 'u':
+ {
+ const int codepoint1 = get_codepoint();
+ int codepoint = codepoint1; // start with codepoint1
+
+ if (JSON_UNLIKELY(codepoint1 == -1))
+ {
+ error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+ return token_type::parse_error;
+ }
+
+ // check if code point is a high surrogate
+ if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
+ {
+ // expect next \uxxxx entry
+ if (JSON_LIKELY(get() == '\\' and get() == 'u'))
+ {
+ const int codepoint2 = get_codepoint();
+
+ if (JSON_UNLIKELY(codepoint2 == -1))
+ {
+ error_message = "invalid string: '\\u' must be followed by 4 hex digits";
+ return token_type::parse_error;
+ }
+
+ // check if codepoint2 is a low surrogate
+ if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
+ {
+ // overwrite codepoint
+ codepoint = static_cast<int>(
+ // high surrogate occupies the most significant 22 bits
+ (static_cast<unsigned int>(codepoint1) << 10u)
+ // low surrogate occupies the least significant 15 bits
+ + static_cast<unsigned int>(codepoint2)
+ // there is still the 0xD800, 0xDC00 and 0x10000 noise
+ // in the result so we have to subtract with:
+ // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
+ - 0x35FDC00u);
+ }
+ else
+ {
+ error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+ return token_type::parse_error;
+ }
+ }
+ else
+ {
+ error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
+ return token_type::parse_error;
+ }
+ }
+ else
+ {
+ if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
+ {
+ error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
+ return token_type::parse_error;
+ }
+ }
+
+ // result of the above calculation yields a proper codepoint
+ assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
+
+ // translate codepoint into bytes
+ if (codepoint < 0x80)
+ {
+ // 1-byte characters: 0xxxxxxx (ASCII)
+ add(codepoint);
+ }
+ else if (codepoint <= 0x7FF)
+ {
+ // 2-byte characters: 110xxxxx 10xxxxxx
+ add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
+ add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
+ }
+ else if (codepoint <= 0xFFFF)
+ {
+ // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
+ add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
+ add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
+ add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
+ }
+ else
+ {
+ // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
+ add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
+ add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
+ add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
+ }
+
+ break;
+ }
+
+ // other characters after escape
+ default:
+ error_message = "invalid string: forbidden character after backslash";
+ return token_type::parse_error;
+ }
+
+ break;
+ }
+
+ // invalid control characters
+ case 0x00:
+ {
+ error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
+ return token_type::parse_error;
+ }
+
+ case 0x01:
+ {
+ error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
+ return token_type::parse_error;
+ }
+
+ case 0x02:
+ {
+ error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
+ return token_type::parse_error;
+ }
+
+ case 0x03:
+ {
+ error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
+ return token_type::parse_error;
+ }
+
+ case 0x04:
+ {
+ error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
+ return token_type::parse_error;
+ }
+
+ case 0x05:
+ {
+ error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
+ return token_type::parse_error;
+ }
+
+ case 0x06:
+ {
+ error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
+ return token_type::parse_error;
+ }
+
+ case 0x07:
+ {
+ error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
+ return token_type::parse_error;
+ }
+
+ case 0x08:
+ {
+ error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
+ return token_type::parse_error;
+ }
+
+ case 0x09:
+ {
+ error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
+ return token_type::parse_error;
+ }
+
+ case 0x0A:
+ {
+ error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
+ return token_type::parse_error;
+ }
+
+ case 0x0B:
+ {
+ error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
+ return token_type::parse_error;
+ }
+
+ case 0x0C:
+ {
+ error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
+ return token_type::parse_error;
+ }
+
+ case 0x0D:
+ {
+ error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
+ return token_type::parse_error;
+ }
+
+ case 0x0E:
+ {
+ error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
+ return token_type::parse_error;
+ }
+
+ case 0x0F:
+ {
+ error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
+ return token_type::parse_error;
+ }
+
+ case 0x10:
+ {
+ error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
+ return token_type::parse_error;
+ }
+
+ case 0x11:
+ {
+ error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
+ return token_type::parse_error;
+ }
+
+ case 0x12:
+ {
+ error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
+ return token_type::parse_error;
+ }
+
+ case 0x13:
+ {
+ error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
+ return token_type::parse_error;
+ }
+
+ case 0x14:
+ {
+ error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
+ return token_type::parse_error;
+ }
+
+ case 0x15:
+ {
+ error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
+ return token_type::parse_error;
+ }
+
+ case 0x16:
+ {
+ error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
+ return token_type::parse_error;
+ }
+
+ case 0x17:
+ {
+ error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
+ return token_type::parse_error;
+ }
+
+ case 0x18:
+ {
+ error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
+ return token_type::parse_error;
+ }
+
+ case 0x19:
+ {
+ error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
+ return token_type::parse_error;
+ }
+
+ case 0x1A:
+ {
+ error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
+ return token_type::parse_error;
+ }
+
+ case 0x1B:
+ {
+ error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
+ return token_type::parse_error;
+ }
+
+ case 0x1C:
+ {
+ error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
+ return token_type::parse_error;
+ }
+
+ case 0x1D:
+ {
+ error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
+ return token_type::parse_error;
+ }
+
+ case 0x1E:
+ {
+ error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
+ return token_type::parse_error;
+ }
+
+ case 0x1F:
+ {
+ error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
+ return token_type::parse_error;
+ }
+
+ // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
+ case 0x20:
+ case 0x21:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ case 0x27:
+ case 0x28:
+ case 0x29:
+ case 0x2A:
+ case 0x2B:
+ case 0x2C:
+ case 0x2D:
+ case 0x2E:
+ case 0x2F:
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x39:
+ case 0x3A:
+ case 0x3B:
+ case 0x3C:
+ case 0x3D:
+ case 0x3E:
+ case 0x3F:
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4A:
+ case 0x4B:
+ case 0x4C:
+ case 0x4D:
+ case 0x4E:
+ case 0x4F:
+ case 0x50:
+ case 0x51:
+ case 0x52:
+ case 0x53:
+ case 0x54:
+ case 0x55:
+ case 0x56:
+ case 0x57:
+ case 0x58:
+ case 0x59:
+ case 0x5A:
+ case 0x5B:
+ case 0x5D:
+ case 0x5E:
+ case 0x5F:
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ case 0x66:
+ case 0x67:
+ case 0x68:
+ case 0x69:
+ case 0x6A:
+ case 0x6B:
+ case 0x6C:
+ case 0x6D:
+ case 0x6E:
+ case 0x6F:
+ case 0x70:
+ case 0x71:
+ case 0x72:
+ case 0x73:
+ case 0x74:
+ case 0x75:
+ case 0x76:
+ case 0x77:
+ case 0x78:
+ case 0x79:
+ case 0x7A:
+ case 0x7B:
+ case 0x7C:
+ case 0x7D:
+ case 0x7E:
+ case 0x7F:
+ {
+ add(current);
+ break;
+ }
+
+ // U+0080..U+07FF: bytes C2..DF 80..BF
+ case 0xC2:
+ case 0xC3:
+ case 0xC4:
+ case 0xC5:
+ case 0xC6:
+ case 0xC7:
+ case 0xC8:
+ case 0xC9:
+ case 0xCA:
+ case 0xCB:
+ case 0xCC:
+ case 0xCD:
+ case 0xCE:
+ case 0xCF:
+ case 0xD0:
+ case 0xD1:
+ case 0xD2:
+ case 0xD3:
+ case 0xD4:
+ case 0xD5:
+ case 0xD6:
+ case 0xD7:
+ case 0xD8:
+ case 0xD9:
+ case 0xDA:
+ case 0xDB:
+ case 0xDC:
+ case 0xDD:
+ case 0xDE:
+ case 0xDF:
+ {
+ if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
+ case 0xE0:
+ {
+ if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
+ // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
+ case 0xE1:
+ case 0xE2:
+ case 0xE3:
+ case 0xE4:
+ case 0xE5:
+ case 0xE6:
+ case 0xE7:
+ case 0xE8:
+ case 0xE9:
+ case 0xEA:
+ case 0xEB:
+ case 0xEC:
+ case 0xEE:
+ case 0xEF:
+ {
+ if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // U+D000..U+D7FF: bytes ED 80..9F 80..BF
+ case 0xED:
+ {
+ if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
+ case 0xF0:
+ {
+ if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+ case 0xF1:
+ case 0xF2:
+ case 0xF3:
+ {
+ if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+ case 0xF4:
+ {
+ if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
+ {
+ return token_type::parse_error;
+ }
+ break;
+ }
+
+ // remaining bytes (80..C1 and F5..FF) are ill-formed
+ default:
+ {
+ error_message = "invalid string: ill-formed UTF-8 byte";
+ return token_type::parse_error;
+ }
+ }
+ }
+ }
+
+ static void strtof(float& f, const char* str, char** endptr) noexcept
+ {
+ f = std::strtof(str, endptr);
+ }
+
+ static void strtof(double& f, const char* str, char** endptr) noexcept
+ {
+ f = std::strtod(str, endptr);
+ }
+
+ static void strtof(long double& f, const char* str, char** endptr) noexcept
+ {
+ f = std::strtold(str, endptr);
+ }
+
+ /*!
+ @brief scan a number literal
+
+ This function scans a string according to Sect. 6 of RFC 7159.
+
+ The function is realized with a deterministic finite state machine derived
+ from the grammar described in RFC 7159. Starting in state "init", the
+ input is read and used to determined the next state. Only state "done"
+ accepts the number. State "error" is a trap state to model errors. In the
+ table below, "anything" means any character but the ones listed before.
+
+ state | 0 | 1-9 | e E | + | - | . | anything
+ ---------|----------|----------|----------|---------|---------|----------|-----------
+ init | zero | any1 | [error] | [error] | minus | [error] | [error]
+ minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
+ zero | done | done | exponent | done | done | decimal1 | done
+ any1 | any1 | any1 | exponent | done | done | decimal1 | done
+ decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
+ decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
+ exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
+ sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
+ any2 | any2 | any2 | done | done | done | done | done
+
+ The state machine is realized with one label per state (prefixed with
+ "scan_number_") and `goto` statements between them. The state machine
+ contains cycles, but any cycle can be left when EOF is read. Therefore,
+ the function is guaranteed to terminate.
+
+ During scanning, the read bytes are stored in token_buffer. This string is
+ then converted to a signed integer, an unsigned integer, or a
+ floating-point number.
+
+ @return token_type::value_unsigned, token_type::value_integer, or
+ token_type::value_float if number could be successfully scanned,
+ token_type::parse_error otherwise
+
+ @note The scanner is independent of the current locale. Internally, the
+ locale's decimal point is used instead of `.` to work with the
+ locale-dependent converters.
+ */
+ token_type scan_number() // lgtm [cpp/use-of-goto]
+ {
+ // reset token_buffer to store the number's bytes
+ reset();
+
+ // the type of the parsed number; initially set to unsigned; will be
+ // changed if minus sign, decimal point or exponent is read
+ token_type number_type = token_type::value_unsigned;
+
+ // state (init): we just found out we need to scan a number
+ switch (current)
+ {
+ case '-':
+ {
+ add(current);
+ goto scan_number_minus;
+ }
+
+ case '0':
+ {
+ add(current);
+ goto scan_number_zero;
+ }
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_any1;
+ }
+
+ // all other characters are rejected outside scan_number()
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+
+scan_number_minus:
+ // state: we just parsed a leading minus sign
+ number_type = token_type::value_integer;
+ switch (get())
+ {
+ case '0':
+ {
+ add(current);
+ goto scan_number_zero;
+ }
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_any1;
+ }
+
+ default:
+ {
+ error_message = "invalid number; expected digit after '-'";
+ return token_type::parse_error;
+ }
+ }
+
+scan_number_zero:
+ // state: we just parse a zero (maybe with a leading minus sign)
+ switch (get())
+ {
+ case '.':
+ {
+ add(decimal_point_char);
+ goto scan_number_decimal1;
+ }
+
+ case 'e':
+ case 'E':
+ {
+ add(current);
+ goto scan_number_exponent;
+ }
+
+ default:
+ goto scan_number_done;
+ }
+
+scan_number_any1:
+ // state: we just parsed a number 0-9 (maybe with a leading minus sign)
+ switch (get())
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_any1;
+ }
+
+ case '.':
+ {
+ add(decimal_point_char);
+ goto scan_number_decimal1;
+ }
+
+ case 'e':
+ case 'E':
+ {
+ add(current);
+ goto scan_number_exponent;
+ }
+
+ default:
+ goto scan_number_done;
+ }
+
+scan_number_decimal1:
+ // state: we just parsed a decimal point
+ number_type = token_type::value_float;
+ switch (get())
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_decimal2;
+ }
+
+ default:
+ {
+ error_message = "invalid number; expected digit after '.'";
+ return token_type::parse_error;
+ }
+ }
+
+scan_number_decimal2:
+ // we just parsed at least one number after a decimal point
+ switch (get())
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_decimal2;
+ }
+
+ case 'e':
+ case 'E':
+ {
+ add(current);
+ goto scan_number_exponent;
+ }
+
+ default:
+ goto scan_number_done;
+ }
+
+scan_number_exponent:
+ // we just parsed an exponent
+ number_type = token_type::value_float;
+ switch (get())
+ {
+ case '+':
+ case '-':
+ {
+ add(current);
+ goto scan_number_sign;
+ }
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_any2;
+ }
+
+ default:
+ {
+ error_message =
+ "invalid number; expected '+', '-', or digit after exponent";
+ return token_type::parse_error;
+ }
+ }
+
+scan_number_sign:
+ // we just parsed an exponent sign
+ switch (get())
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_any2;
+ }
+
+ default:
+ {
+ error_message = "invalid number; expected digit after exponent sign";
+ return token_type::parse_error;
+ }
+ }
+
+scan_number_any2:
+ // we just parsed a number after the exponent or exponent sign
+ switch (get())
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ add(current);
+ goto scan_number_any2;
+ }
+
+ default:
+ goto scan_number_done;
+ }
+
+scan_number_done:
+ // unget the character after the number (we only read it to know that
+ // we are done scanning a number)
+ unget();
+
+ char* endptr = nullptr;
+ errno = 0;
+
+ // try to parse integers first and fall back to floats
+ if (number_type == token_type::value_unsigned)
+ {
+ const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
+
+ // we checked the number format before
+ assert(endptr == token_buffer.data() + token_buffer.size());
+
+ if (errno == 0)
+ {
+ value_unsigned = static_cast<number_unsigned_t>(x);
+ if (value_unsigned == x)
+ {
+ return token_type::value_unsigned;
+ }
+ }
+ }
+ else if (number_type == token_type::value_integer)
+ {
+ const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
+
+ // we checked the number format before
+ assert(endptr == token_buffer.data() + token_buffer.size());
+
+ if (errno == 0)
+ {
+ value_integer = static_cast<number_integer_t>(x);
+ if (value_integer == x)
+ {
+ return token_type::value_integer;
+ }
+ }
+ }
+
+ // this code is reached if we parse a floating-point number or if an
+ // integer conversion above failed
+ strtof(value_float, token_buffer.data(), &endptr);
+
+ // we checked the number format before
+ assert(endptr == token_buffer.data() + token_buffer.size());
+
+ return token_type::value_float;
+ }
+
+ /*!
+ @param[in] literal_text the literal text to expect
+ @param[in] length the length of the passed literal text
+ @param[in] return_type the token type to return on success
+ */
+ token_type scan_literal(const char* literal_text, const std::size_t length,
+ token_type return_type)
+ {
+ assert(current == literal_text[0]);
+ for (std::size_t i = 1; i < length; ++i)
+ {
+ if (JSON_UNLIKELY(get() != literal_text[i]))
+ {
+ error_message = "invalid literal";
+ return token_type::parse_error;
+ }
+ }
+ return return_type;
+ }
+
+ /////////////////////
+ // input management
+ /////////////////////
+
+ /// reset token_buffer; current character is beginning of token
+ void reset() noexcept
+ {
+ token_buffer.clear();
+ token_string.clear();
+ token_string.push_back(std::char_traits<char>::to_char_type(current));
+ }
+
+ /*
+ @brief get next character from the input
+
+ This function provides the interface to the used input adapter. It does
+ not throw in case the input reached EOF, but returns a
+ `std::char_traits<char>::eof()` in that case. Stores the scanned characters
+ for use in error messages.
+
+ @return character read from the input
+ */
+ std::char_traits<char>::int_type get()
+ {
+ ++position.chars_read_total;
+ ++position.chars_read_current_line;
+
+ if (next_unget)
+ {
+ // just reset the next_unget variable and work with current
+ next_unget = false;
+ }
+ else
+ {
+ current = ia->get_character();
+ }
+
+ if (JSON_LIKELY(current != std::char_traits<char>::eof()))
+ {
+ token_string.push_back(std::char_traits<char>::to_char_type(current));
+ }
+
+ if (current == '\n')
+ {
+ ++position.lines_read;
+ position.chars_read_current_line = 0;
+ }
+
+ return current;
+ }
+
+ /*!
+ @brief unget current character (read it again on next get)
+
+ We implement unget by setting variable next_unget to true. The input is not
+ changed - we just simulate ungetting by modifying chars_read_total,
+ chars_read_current_line, and token_string. The next call to get() will
+ behave as if the unget character is read again.
+ */
+ void unget()
+ {
+ next_unget = true;
+
+ --position.chars_read_total;
+
+ // in case we "unget" a newline, we have to also decrement the lines_read
+ if (position.chars_read_current_line == 0)
+ {
+ if (position.lines_read > 0)
+ {
+ --position.lines_read;
+ }
+ }
+ else
+ {
+ --position.chars_read_current_line;
+ }
+
+ if (JSON_LIKELY(current != std::char_traits<char>::eof()))
+ {
+ assert(not token_string.empty());
+ token_string.pop_back();
+ }
+ }
+
+ /// add a character to token_buffer
+ void add(int c)
+ {
+ token_buffer.push_back(std::char_traits<char>::to_char_type(c));
+ }
+
+ public:
+ /////////////////////
+ // value getters
+ /////////////////////
+
+ /// return integer value
+ constexpr number_integer_t get_number_integer() const noexcept
+ {
+ return value_integer;
+ }
+
+ /// return unsigned integer value
+ constexpr number_unsigned_t get_number_unsigned() const noexcept
+ {
+ return value_unsigned;
+ }
+
+ /// return floating-point value
+ constexpr number_float_t get_number_float() const noexcept
+ {
+ return value_float;
+ }
+
+ /// return current string value (implicitly resets the token; useful only once)
+ string_t& get_string()
+ {
+ return token_buffer;
+ }
+
+ /////////////////////
+ // diagnostics
+ /////////////////////
+
+ /// return position of last read token
+ constexpr position_t get_position() const noexcept
+ {
+ return position;
+ }
+
+ /// return the last read token (for errors only). Will never contain EOF
+ /// (an arbitrary value that is not a valid char value, often -1), because
+ /// 255 may legitimately occur. May contain NUL, which should be escaped.
+ std::string get_token_string() const
+ {
+ // escape control characters
+ std::string result;
+ for (const auto c : token_string)
+ {
+ if ('\x00' <= c and c <= '\x1F')
+ {
+ // escape control characters
+ std::array<char, 9> cs{{}};
+ (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
+ result += cs.data();
+ }
+ else
+ {
+ // add character as is
+ result.push_back(c);
+ }
+ }
+
+ return result;
+ }
+
+ /// return syntax error message
+ constexpr const char* get_error_message() const noexcept
+ {
+ return error_message;
+ }
+
+ /////////////////////
+ // actual scanner
+ /////////////////////
+
+ /*!
+ @brief skip the UTF-8 byte order mark
+ @return true iff there is no BOM or the correct BOM has been skipped
+ */
+ bool skip_bom()
+ {
+ if (get() == 0xEF)
+ {
+ // check if we completely parse the BOM
+ return get() == 0xBB and get() == 0xBF;
+ }
+
+ // the first character is not the beginning of the BOM; unget it to
+ // process is later
+ unget();
+ return true;
+ }
+
+ token_type scan()
+ {
+ // initially, skip the BOM
+ if (position.chars_read_total == 0 and not skip_bom())
+ {
+ error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
+ return token_type::parse_error;
+ }
+
+ // read next character and ignore whitespace
+ do
+ {
+ get();
+ }
+ while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
+
+ switch (current)
+ {
+ // structural characters
+ case '[':
+ return token_type::begin_array;
+ case ']':
+ return token_type::end_array;
+ case '{':
+ return token_type::begin_object;
+ case '}':
+ return token_type::end_object;
+ case ':':
+ return token_type::name_separator;
+ case ',':
+ return token_type::value_separator;
+
+ // literals
+ case 't':
+ return scan_literal("true", 4, token_type::literal_true);
+ case 'f':
+ return scan_literal("false", 5, token_type::literal_false);
+ case 'n':
+ return scan_literal("null", 4, token_type::literal_null);
+
+ // string
+ case '\"':
+ return scan_string();
+
+ // number
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return scan_number();
+
+ // end of input (the null byte is needed when parsing from
+ // string literals)
+ case '\0':
+ case std::char_traits<char>::eof():
+ return token_type::end_of_input;
+
+ // error
+ default:
+ error_message = "invalid literal";
+ return token_type::parse_error;
+ }
+ }
+
+ private:
+ /// input adapter
+ detail::input_adapter_t ia = nullptr;
+
+ /// the current character
+ std::char_traits<char>::int_type current = std::char_traits<char>::eof();
+
+ /// whether the next get() call should just return current
+ bool next_unget = false;
+
+ /// the start position of the current token
+ position_t position {};
+
+ /// raw input token string (for error messages)
+ std::vector<char> token_string {};
+
+ /// buffer for variable-length tokens (numbers, strings)
+ string_t token_buffer {};
+
+ /// a description of occurred lexer errors
+ const char* error_message = "";
+
+ // number values
+ number_integer_t value_integer = 0;
+ number_unsigned_t value_unsigned = 0;
+ number_float_t value_float = 0;
+
+ /// the decimal point
+ const char decimal_point_char = '.';
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/input/parser.hpp>
+
+
+#include <cassert> // assert
+#include <cmath> // isfinite
+#include <cstdint> // uint8_t
+#include <functional> // function
+#include <string> // string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/input/input_adapters.hpp>
+
+// #include <nlohmann/detail/input/json_sax.hpp>
+
+// #include <nlohmann/detail/input/lexer.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/is_sax.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+////////////
+// parser //
+////////////
+
+/*!
+@brief syntax analysis
+
+This class implements a recursive decent parser.
+*/
+template<typename BasicJsonType>
+class parser
+{
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using string_t = typename BasicJsonType::string_t;
+ using lexer_t = lexer<BasicJsonType>;
+ using token_type = typename lexer_t::token_type;
+
+ public:
+ enum class parse_event_t : uint8_t
+ {
+ /// the parser read `{` and started to process a JSON object
+ object_start,
+ /// the parser read `}` and finished processing a JSON object
+ object_end,
+ /// the parser read `[` and started to process a JSON array
+ array_start,
+ /// the parser read `]` and finished processing a JSON array
+ array_end,
+ /// the parser read a key of a value in an object
+ key,
+ /// the parser finished reading a JSON value
+ value
+ };
+
+ using parser_callback_t =
+ std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
+
+ /// a parser reading from an input adapter
+ explicit parser(detail::input_adapter_t&& adapter,
+ const parser_callback_t cb = nullptr,
+ const bool allow_exceptions_ = true)
+ : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
+ {
+ // read first token
+ get_token();
+ }
+
+ /*!
+ @brief public parser interface
+
+ @param[in] strict whether to expect the last token to be EOF
+ @param[in,out] result parsed JSON value
+
+ @throw parse_error.101 in case of an unexpected token
+ @throw parse_error.102 if to_unicode fails or surrogate error
+ @throw parse_error.103 if to_unicode fails
+ */
+ void parse(const bool strict, BasicJsonType& result)
+ {
+ if (callback)
+ {
+ json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
+ sax_parse_internal(&sdp);
+ result.assert_invariant();
+
+ // in strict mode, input must be completely read
+ if (strict and (get_token() != token_type::end_of_input))
+ {
+ sdp.parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::end_of_input, "value")));
+ }
+
+ // in case of an error, return discarded value
+ if (sdp.is_errored())
+ {
+ result = value_t::discarded;
+ return;
+ }
+
+ // set top-level value to null if it was discarded by the callback
+ // function
+ if (result.is_discarded())
+ {
+ result = nullptr;
+ }
+ }
+ else
+ {
+ json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
+ sax_parse_internal(&sdp);
+ result.assert_invariant();
+
+ // in strict mode, input must be completely read
+ if (strict and (get_token() != token_type::end_of_input))
+ {
+ sdp.parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::end_of_input, "value")));
+ }
+
+ // in case of an error, return discarded value
+ if (sdp.is_errored())
+ {
+ result = value_t::discarded;
+ return;
+ }
+ }
+ }
+
+ /*!
+ @brief public accept interface
+
+ @param[in] strict whether to expect the last token to be EOF
+ @return whether the input is a proper JSON text
+ */
+ bool accept(const bool strict = true)
+ {
+ json_sax_acceptor<BasicJsonType> sax_acceptor;
+ return sax_parse(&sax_acceptor, strict);
+ }
+
+ template <typename SAX>
+ bool sax_parse(SAX* sax, const bool strict = true)
+ {
+ (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
+ const bool result = sax_parse_internal(sax);
+
+ // strict mode: next byte must be EOF
+ if (result and strict and (get_token() != token_type::end_of_input))
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::end_of_input, "value")));
+ }
+
+ return result;
+ }
+
+ private:
+ template <typename SAX>
+ bool sax_parse_internal(SAX* sax)
+ {
+ // stack to remember the hierarchy of structured values we are parsing
+ // true = array; false = object
+ std::vector<bool> states;
+ // value to avoid a goto (see comment where set to true)
+ bool skip_to_state_evaluation = false;
+
+ while (true)
+ {
+ if (not skip_to_state_evaluation)
+ {
+ // invariant: get_token() was called before each iteration
+ switch (last_token)
+ {
+ case token_type::begin_object:
+ {
+ if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
+ {
+ return false;
+ }
+
+ // closing } -> we are done
+ if (get_token() == token_type::end_object)
+ {
+ if (JSON_UNLIKELY(not sax->end_object()))
+ {
+ return false;
+ }
+ break;
+ }
+
+ // parse key
+ if (JSON_UNLIKELY(last_token != token_type::value_string))
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::value_string, "object key")));
+ }
+ if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
+ {
+ return false;
+ }
+
+ // parse separator (:)
+ if (JSON_UNLIKELY(get_token() != token_type::name_separator))
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::name_separator, "object separator")));
+ }
+
+ // remember we are now inside an object
+ states.push_back(false);
+
+ // parse values
+ get_token();
+ continue;
+ }
+
+ case token_type::begin_array:
+ {
+ if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
+ {
+ return false;
+ }
+
+ // closing ] -> we are done
+ if (get_token() == token_type::end_array)
+ {
+ if (JSON_UNLIKELY(not sax->end_array()))
+ {
+ return false;
+ }
+ break;
+ }
+
+ // remember we are now inside an array
+ states.push_back(true);
+
+ // parse values (no need to call get_token)
+ continue;
+ }
+
+ case token_type::value_float:
+ {
+ const auto res = m_lexer.get_number_float();
+
+ if (JSON_UNLIKELY(not std::isfinite(res)))
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
+ }
+
+ if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
+ {
+ return false;
+ }
+
+ break;
+ }
+
+ case token_type::literal_false:
+ {
+ if (JSON_UNLIKELY(not sax->boolean(false)))
+ {
+ return false;
+ }
+ break;
+ }
+
+ case token_type::literal_null:
+ {
+ if (JSON_UNLIKELY(not sax->null()))
+ {
+ return false;
+ }
+ break;
+ }
+
+ case token_type::literal_true:
+ {
+ if (JSON_UNLIKELY(not sax->boolean(true)))
+ {
+ return false;
+ }
+ break;
+ }
+
+ case token_type::value_integer:
+ {
+ if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
+ {
+ return false;
+ }
+ break;
+ }
+
+ case token_type::value_string:
+ {
+ if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
+ {
+ return false;
+ }
+ break;
+ }
+
+ case token_type::value_unsigned:
+ {
+ if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
+ {
+ return false;
+ }
+ break;
+ }
+
+ case token_type::parse_error:
+ {
+ // using "uninitialized" to avoid "expected" message
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::uninitialized, "value")));
+ }
+
+ default: // the last token was unexpected
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::literal_or_value, "value")));
+ }
+ }
+ }
+ else
+ {
+ skip_to_state_evaluation = false;
+ }
+
+ // we reached this line after we successfully parsed a value
+ if (states.empty())
+ {
+ // empty stack: we reached the end of the hierarchy: done
+ return true;
+ }
+
+ if (states.back()) // array
+ {
+ // comma -> next value
+ if (get_token() == token_type::value_separator)
+ {
+ // parse a new value
+ get_token();
+ continue;
+ }
+
+ // closing ]
+ if (JSON_LIKELY(last_token == token_type::end_array))
+ {
+ if (JSON_UNLIKELY(not sax->end_array()))
+ {
+ return false;
+ }
+
+ // We are done with this array. Before we can parse a
+ // new value, we need to evaluate the new state first.
+ // By setting skip_to_state_evaluation to false, we
+ // are effectively jumping to the beginning of this if.
+ assert(not states.empty());
+ states.pop_back();
+ skip_to_state_evaluation = true;
+ continue;
+ }
+
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::end_array, "array")));
+ }
+ else // object
+ {
+ // comma -> next value
+ if (get_token() == token_type::value_separator)
+ {
+ // parse key
+ if (JSON_UNLIKELY(get_token() != token_type::value_string))
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::value_string, "object key")));
+ }
+
+ if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
+ {
+ return false;
+ }
+
+ // parse separator (:)
+ if (JSON_UNLIKELY(get_token() != token_type::name_separator))
+ {
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::name_separator, "object separator")));
+ }
+
+ // parse values
+ get_token();
+ continue;
+ }
+
+ // closing }
+ if (JSON_LIKELY(last_token == token_type::end_object))
+ {
+ if (JSON_UNLIKELY(not sax->end_object()))
+ {
+ return false;
+ }
+
+ // We are done with this object. Before we can parse a
+ // new value, we need to evaluate the new state first.
+ // By setting skip_to_state_evaluation to false, we
+ // are effectively jumping to the beginning of this if.
+ assert(not states.empty());
+ states.pop_back();
+ skip_to_state_evaluation = true;
+ continue;
+ }
+
+ return sax->parse_error(m_lexer.get_position(),
+ m_lexer.get_token_string(),
+ parse_error::create(101, m_lexer.get_position(),
+ exception_message(token_type::end_object, "object")));
+ }
+ }
+ }
+
+ /// get next token from lexer
+ token_type get_token()
+ {
+ return last_token = m_lexer.scan();
+ }
+
+ std::string exception_message(const token_type expected, const std::string& context)
+ {
+ std::string error_msg = "syntax error ";
+
+ if (not context.empty())
+ {
+ error_msg += "while parsing " + context + " ";
+ }
+
+ error_msg += "- ";
+
+ if (last_token == token_type::parse_error)
+ {
+ error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
+ m_lexer.get_token_string() + "'";
+ }
+ else
+ {
+ error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
+ }
+
+ if (expected != token_type::uninitialized)
+ {
+ error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
+ }
+
+ return error_msg;
+ }
+
+ private:
+ /// callback function
+ const parser_callback_t callback = nullptr;
+ /// the type of the last read token
+ token_type last_token = token_type::uninitialized;
+ /// the lexer
+ lexer_t m_lexer;
+ /// whether to throw exceptions in case of errors
+ const bool allow_exceptions = true;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/internal_iterator.hpp>
+
+
+// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
+
+
+#include <cstddef> // ptrdiff_t
+#include <limits> // numeric_limits
+
+namespace nlohmann
+{
+namespace detail
+{
+/*
+@brief an iterator for primitive JSON types
+
+This class models an iterator for primitive JSON types (boolean, number,
+string). It's only purpose is to allow the iterator/const_iterator classes
+to "iterate" over primitive values. Internally, the iterator is modeled by
+a `difference_type` variable. Value begin_value (`0`) models the begin,
+end_value (`1`) models past the end.
+*/
+class primitive_iterator_t
+{
+ private:
+ using difference_type = std::ptrdiff_t;
+ static constexpr difference_type begin_value = 0;
+ static constexpr difference_type end_value = begin_value + 1;
+
+ /// iterator as signed integer type
+ difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
+
+ public:
+ constexpr difference_type get_value() const noexcept
+ {
+ return m_it;
+ }
+
+ /// set iterator to a defined beginning
+ void set_begin() noexcept
+ {
+ m_it = begin_value;
+ }
+
+ /// set iterator to a defined past the end
+ void set_end() noexcept
+ {
+ m_it = end_value;
+ }
+
+ /// return whether the iterator can be dereferenced
+ constexpr bool is_begin() const noexcept
+ {
+ return m_it == begin_value;
+ }
+
+ /// return whether the iterator is at end
+ constexpr bool is_end() const noexcept
+ {
+ return m_it == end_value;
+ }
+
+ friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+ {
+ return lhs.m_it == rhs.m_it;
+ }
+
+ friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+ {
+ return lhs.m_it < rhs.m_it;
+ }
+
+ primitive_iterator_t operator+(difference_type n) noexcept
+ {
+ auto result = *this;
+ result += n;
+ return result;
+ }
+
+ friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
+ {
+ return lhs.m_it - rhs.m_it;
+ }
+
+ primitive_iterator_t& operator++() noexcept
+ {
+ ++m_it;
+ return *this;
+ }
+
+ primitive_iterator_t const operator++(int) noexcept
+ {
+ auto result = *this;
+ ++m_it;
+ return result;
+ }
+
+ primitive_iterator_t& operator--() noexcept
+ {
+ --m_it;
+ return *this;
+ }
+
+ primitive_iterator_t const operator--(int) noexcept
+ {
+ auto result = *this;
+ --m_it;
+ return result;
+ }
+
+ primitive_iterator_t& operator+=(difference_type n) noexcept
+ {
+ m_it += n;
+ return *this;
+ }
+
+ primitive_iterator_t& operator-=(difference_type n) noexcept
+ {
+ m_it -= n;
+ return *this;
+ }
+};
+} // namespace detail
+} // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+/*!
+@brief an iterator value
+
+@note This structure could easily be a union, but MSVC currently does not allow
+unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
+*/
+template<typename BasicJsonType> struct internal_iterator
+{
+ /// iterator for JSON objects
+ typename BasicJsonType::object_t::iterator object_iterator {};
+ /// iterator for JSON arrays
+ typename BasicJsonType::array_t::iterator array_iterator {};
+ /// generic iterator for all other types
+ primitive_iterator_t primitive_iterator {};
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/iter_impl.hpp>
+
+
+#include <ciso646> // not
+#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
+#include <type_traits> // conditional, is_const, remove_const
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/iterators/internal_iterator.hpp>
+
+// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+// forward declare, to be able to friend it later on
+template<typename IteratorType> class iteration_proxy;
+template<typename IteratorType> class iteration_proxy_value;
+
+/*!
+@brief a template for a bidirectional iterator for the @ref basic_json class
+This class implements a both iterators (iterator and const_iterator) for the
+@ref basic_json class.
+@note An iterator is called *initialized* when a pointer to a JSON value has
+ been set (e.g., by a constructor or a copy assignment). If the iterator is
+ default-constructed, it is *uninitialized* and most methods are undefined.
+ **The library uses assertions to detect calls on uninitialized iterators.**
+@requirement The class satisfies the following concept requirements:
+-
+[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
+ The iterator that can be moved can be moved in both directions (i.e.
+ incremented and decremented).
+@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
+ iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
+*/
+template<typename BasicJsonType>
+class iter_impl
+{
+ /// allow basic_json to access private members
+ friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
+ friend BasicJsonType;
+ friend iteration_proxy<iter_impl>;
+ friend iteration_proxy_value<iter_impl>;
+
+ using object_t = typename BasicJsonType::object_t;
+ using array_t = typename BasicJsonType::array_t;
+ // make sure BasicJsonType is basic_json or const basic_json
+ static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
+ "iter_impl only accepts (const) basic_json");
+
+ public:
+
+ /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
+ /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
+ /// A user-defined iterator should provide publicly accessible typedefs named
+ /// iterator_category, value_type, difference_type, pointer, and reference.
+ /// Note that value_type is required to be non-const, even for constant iterators.
+ using iterator_category = std::bidirectional_iterator_tag;
+
+ /// the type of the values when the iterator is dereferenced
+ using value_type = typename BasicJsonType::value_type;
+ /// a type to represent differences between iterators
+ using difference_type = typename BasicJsonType::difference_type;
+ /// defines a pointer to the type iterated over (value_type)
+ using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
+ typename BasicJsonType::const_pointer,
+ typename BasicJsonType::pointer>::type;
+ /// defines a reference to the type iterated over (value_type)
+ using reference =
+ typename std::conditional<std::is_const<BasicJsonType>::value,
+ typename BasicJsonType::const_reference,
+ typename BasicJsonType::reference>::type;
+
+ /// default constructor
+ iter_impl() = default;
+
+ /*!
+ @brief constructor for a given JSON instance
+ @param[in] object pointer to a JSON object for this iterator
+ @pre object != nullptr
+ @post The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ explicit iter_impl(pointer object) noexcept : m_object(object)
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ m_it.object_iterator = typename object_t::iterator();
+ break;
+ }
+
+ case value_t::array:
+ {
+ m_it.array_iterator = typename array_t::iterator();
+ break;
+ }
+
+ default:
+ {
+ m_it.primitive_iterator = primitive_iterator_t();
+ break;
+ }
+ }
+ }
+
+ /*!
+ @note The conventional copy constructor and copy assignment are implicitly
+ defined. Combined with the following converting constructor and
+ assignment, they support: (1) copy from iterator to iterator, (2)
+ copy from const iterator to const iterator, and (3) conversion from
+ iterator to const iterator. However conversion from const iterator
+ to iterator is not defined.
+ */
+
+ /*!
+ @brief converting constructor
+ @param[in] other non-const iterator to copy from
+ @note It is not checked whether @a other is initialized.
+ */
+ iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
+ : m_object(other.m_object), m_it(other.m_it) {}
+
+ /*!
+ @brief converting assignment
+ @param[in,out] other non-const iterator to copy from
+ @return const/non-const iterator
+ @note It is not checked whether @a other is initialized.
+ */
+ iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
+ {
+ m_object = other.m_object;
+ m_it = other.m_it;
+ return *this;
+ }
+
+ private:
+ /*!
+ @brief set the iterator to the first value
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ void set_begin() noexcept
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ m_it.object_iterator = m_object->m_value.object->begin();
+ break;
+ }
+
+ case value_t::array:
+ {
+ m_it.array_iterator = m_object->m_value.array->begin();
+ break;
+ }
+
+ case value_t::null:
+ {
+ // set to end so begin()==end() is true: null is empty
+ m_it.primitive_iterator.set_end();
+ break;
+ }
+
+ default:
+ {
+ m_it.primitive_iterator.set_begin();
+ break;
+ }
+ }
+ }
+
+ /*!
+ @brief set the iterator past the last value
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ void set_end() noexcept
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ m_it.object_iterator = m_object->m_value.object->end();
+ break;
+ }
+
+ case value_t::array:
+ {
+ m_it.array_iterator = m_object->m_value.array->end();
+ break;
+ }
+
+ default:
+ {
+ m_it.primitive_iterator.set_end();
+ break;
+ }
+ }
+ }
+
+ public:
+ /*!
+ @brief return a reference to the value pointed to by the iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ reference operator*() const
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ assert(m_it.object_iterator != m_object->m_value.object->end());
+ return m_it.object_iterator->second;
+ }
+
+ case value_t::array:
+ {
+ assert(m_it.array_iterator != m_object->m_value.array->end());
+ return *m_it.array_iterator;
+ }
+
+ case value_t::null:
+ JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+ default:
+ {
+ if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
+ {
+ return *m_object;
+ }
+
+ JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+ }
+ }
+ }
+
+ /*!
+ @brief dereference the iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ pointer operator->() const
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ assert(m_it.object_iterator != m_object->m_value.object->end());
+ return &(m_it.object_iterator->second);
+ }
+
+ case value_t::array:
+ {
+ assert(m_it.array_iterator != m_object->m_value.array->end());
+ return &*m_it.array_iterator;
+ }
+
+ default:
+ {
+ if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
+ {
+ return m_object;
+ }
+
+ JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+ }
+ }
+ }
+
+ /*!
+ @brief post-increment (it++)
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl const operator++(int)
+ {
+ auto result = *this;
+ ++(*this);
+ return result;
+ }
+
+ /*!
+ @brief pre-increment (++it)
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl& operator++()
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ std::advance(m_it.object_iterator, 1);
+ break;
+ }
+
+ case value_t::array:
+ {
+ std::advance(m_it.array_iterator, 1);
+ break;
+ }
+
+ default:
+ {
+ ++m_it.primitive_iterator;
+ break;
+ }
+ }
+
+ return *this;
+ }
+
+ /*!
+ @brief post-decrement (it--)
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl const operator--(int)
+ {
+ auto result = *this;
+ --(*this);
+ return result;
+ }
+
+ /*!
+ @brief pre-decrement (--it)
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl& operator--()
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ {
+ std::advance(m_it.object_iterator, -1);
+ break;
+ }
+
+ case value_t::array:
+ {
+ std::advance(m_it.array_iterator, -1);
+ break;
+ }
+
+ default:
+ {
+ --m_it.primitive_iterator;
+ break;
+ }
+ }
+
+ return *this;
+ }
+
+ /*!
+ @brief comparison: equal
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ bool operator==(const iter_impl& other) const
+ {
+ // if objects are not the same, the comparison is undefined
+ if (JSON_UNLIKELY(m_object != other.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+ }
+
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ return (m_it.object_iterator == other.m_it.object_iterator);
+
+ case value_t::array:
+ return (m_it.array_iterator == other.m_it.array_iterator);
+
+ default:
+ return (m_it.primitive_iterator == other.m_it.primitive_iterator);
+ }
+ }
+
+ /*!
+ @brief comparison: not equal
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ bool operator!=(const iter_impl& other) const
+ {
+ return not operator==(other);
+ }
+
+ /*!
+ @brief comparison: smaller
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ bool operator<(const iter_impl& other) const
+ {
+ // if objects are not the same, the comparison is undefined
+ if (JSON_UNLIKELY(m_object != other.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
+ }
+
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
+
+ case value_t::array:
+ return (m_it.array_iterator < other.m_it.array_iterator);
+
+ default:
+ return (m_it.primitive_iterator < other.m_it.primitive_iterator);
+ }
+ }
+
+ /*!
+ @brief comparison: less than or equal
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ bool operator<=(const iter_impl& other) const
+ {
+ return not other.operator < (*this);
+ }
+
+ /*!
+ @brief comparison: greater than
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ bool operator>(const iter_impl& other) const
+ {
+ return not operator<=(other);
+ }
+
+ /*!
+ @brief comparison: greater than or equal
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ bool operator>=(const iter_impl& other) const
+ {
+ return not operator<(other);
+ }
+
+ /*!
+ @brief add to iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl& operator+=(difference_type i)
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+ case value_t::array:
+ {
+ std::advance(m_it.array_iterator, i);
+ break;
+ }
+
+ default:
+ {
+ m_it.primitive_iterator += i;
+ break;
+ }
+ }
+
+ return *this;
+ }
+
+ /*!
+ @brief subtract from iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl& operator-=(difference_type i)
+ {
+ return operator+=(-i);
+ }
+
+ /*!
+ @brief add to iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl operator+(difference_type i) const
+ {
+ auto result = *this;
+ result += i;
+ return result;
+ }
+
+ /*!
+ @brief addition of distance and iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ friend iter_impl operator+(difference_type i, const iter_impl& it)
+ {
+ auto result = it;
+ result += i;
+ return result;
+ }
+
+ /*!
+ @brief subtract from iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ iter_impl operator-(difference_type i) const
+ {
+ auto result = *this;
+ result -= i;
+ return result;
+ }
+
+ /*!
+ @brief return difference
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ difference_type operator-(const iter_impl& other) const
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
+
+ case value_t::array:
+ return m_it.array_iterator - other.m_it.array_iterator;
+
+ default:
+ return m_it.primitive_iterator - other.m_it.primitive_iterator;
+ }
+ }
+
+ /*!
+ @brief access to successor
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ reference operator[](difference_type n) const
+ {
+ assert(m_object != nullptr);
+
+ switch (m_object->m_type)
+ {
+ case value_t::object:
+ JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
+
+ case value_t::array:
+ return *std::next(m_it.array_iterator, n);
+
+ case value_t::null:
+ JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+
+ default:
+ {
+ if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
+ {
+ return *m_object;
+ }
+
+ JSON_THROW(invalid_iterator::create(214, "cannot get value"));
+ }
+ }
+ }
+
+ /*!
+ @brief return the key of an object iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ const typename object_t::key_type& key() const
+ {
+ assert(m_object != nullptr);
+
+ if (JSON_LIKELY(m_object->is_object()))
+ {
+ return m_it.object_iterator->first;
+ }
+
+ JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
+ }
+
+ /*!
+ @brief return the value of an iterator
+ @pre The iterator is initialized; i.e. `m_object != nullptr`.
+ */
+ reference value() const
+ {
+ return operator*();
+ }
+
+ private:
+ /// associated JSON instance
+ pointer m_object = nullptr;
+ /// the actual iterator of the associated instance
+ internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
+
+// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
+
+
+#include <cstddef> // ptrdiff_t
+#include <iterator> // reverse_iterator
+#include <utility> // declval
+
+namespace nlohmann
+{
+namespace detail
+{
+//////////////////////
+// reverse_iterator //
+//////////////////////
+
+/*!
+@brief a template for a reverse iterator class
+
+@tparam Base the base iterator type to reverse. Valid types are @ref
+iterator (to create @ref reverse_iterator) and @ref const_iterator (to
+create @ref const_reverse_iterator).
+
+@requirement The class satisfies the following concept requirements:
+-
+[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
+ The iterator that can be moved can be moved in both directions (i.e.
+ incremented and decremented).
+- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
+ It is possible to write to the pointed-to element (only if @a Base is
+ @ref iterator).
+
+@since version 1.0.0
+*/
+template<typename Base>
+class json_reverse_iterator : public std::reverse_iterator<Base>
+{
+ public:
+ using difference_type = std::ptrdiff_t;
+ /// shortcut to the reverse iterator adapter
+ using base_iterator = std::reverse_iterator<Base>;
+ /// the reference type for the pointed-to element
+ using reference = typename Base::reference;
+
+ /// create reverse iterator from iterator
+ explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
+ : base_iterator(it) {}
+
+ /// create reverse iterator from base class
+ explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
+
+ /// post-increment (it++)
+ json_reverse_iterator const operator++(int)
+ {
+ return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
+ }
+
+ /// pre-increment (++it)
+ json_reverse_iterator& operator++()
+ {
+ return static_cast<json_reverse_iterator&>(base_iterator::operator++());
+ }
+
+ /// post-decrement (it--)
+ json_reverse_iterator const operator--(int)
+ {
+ return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
+ }
+
+ /// pre-decrement (--it)
+ json_reverse_iterator& operator--()
+ {
+ return static_cast<json_reverse_iterator&>(base_iterator::operator--());
+ }
+
+ /// add to iterator
+ json_reverse_iterator& operator+=(difference_type i)
+ {
+ return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
+ }
+
+ /// add to iterator
+ json_reverse_iterator operator+(difference_type i) const
+ {
+ return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
+ }
+
+ /// subtract from iterator
+ json_reverse_iterator operator-(difference_type i) const
+ {
+ return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
+ }
+
+ /// return difference
+ difference_type operator-(const json_reverse_iterator& other) const
+ {
+ return base_iterator(*this) - base_iterator(other);
+ }
+
+ /// access to successor
+ reference operator[](difference_type n) const
+ {
+ return *(this->operator+(n));
+ }
+
+ /// return the key of an object iterator
+ auto key() const -> decltype(std::declval<Base>().key())
+ {
+ auto it = --this->base();
+ return it.key();
+ }
+
+ /// return the value of an iterator
+ reference value() const
+ {
+ auto it = --this->base();
+ return it.operator * ();
+ }
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
+
+// #include <nlohmann/detail/json_pointer.hpp>
+
+
+#include <algorithm> // all_of
+#include <cassert> // assert
+#include <numeric> // accumulate
+#include <string> // string
+#include <utility> // move
+#include <vector> // vector
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+template<typename BasicJsonType>
+class json_pointer
+{
+ // allow basic_json to access private members
+ NLOHMANN_BASIC_JSON_TPL_DECLARATION
+ friend class basic_json;
+
+ public:
+ /*!
+ @brief create JSON pointer
+
+ Create a JSON pointer according to the syntax described in
+ [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
+
+ @param[in] s string representing the JSON pointer; if omitted, the empty
+ string is assumed which references the whole JSON value
+
+ @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
+ not begin with a slash (`/`); see example below
+
+ @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
+ not followed by `0` (representing `~`) or `1` (representing `/`); see
+ example below
+
+ @liveexample{The example shows the construction several valid JSON pointers
+ as well as the exceptional behavior.,json_pointer}
+
+ @since version 2.0.0
+ */
+ explicit json_pointer(const std::string& s = "")
+ : reference_tokens(split(s))
+ {}
+
+ /*!
+ @brief return a string representation of the JSON pointer
+
+ @invariant For each JSON pointer `ptr`, it holds:
+ @code {.cpp}
+ ptr == json_pointer(ptr.to_string());
+ @endcode
+
+ @return a string representation of the JSON pointer
+
+ @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
+
+ @since version 2.0.0
+ */
+ std::string to_string() const
+ {
+ return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
+ std::string{},
+ [](const std::string & a, const std::string & b)
+ {
+ return a + "/" + escape(b);
+ });
+ }
+
+ /// @copydoc to_string()
+ operator std::string() const
+ {
+ return to_string();
+ }
+
+ /*!
+ @brief append another JSON pointer at the end of this JSON pointer
+
+ @param[in] ptr JSON pointer to append
+ @return JSON pointer with @a ptr appended
+
+ @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
+
+ @complexity Linear in the length of @a ptr.
+
+ @sa @ref operator/=(std::string) to append a reference token
+ @sa @ref operator/=(std::size_t) to append an array index
+ @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
+
+ @since version 3.6.0
+ */
+ json_pointer& operator/=(const json_pointer& ptr)
+ {
+ reference_tokens.insert(reference_tokens.end(),
+ ptr.reference_tokens.begin(),
+ ptr.reference_tokens.end());
+ return *this;
+ }
+
+ /*!
+ @brief append an unescaped reference token at the end of this JSON pointer
+
+ @param[in] token reference token to append
+ @return JSON pointer with @a token appended without escaping @a token
+
+ @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
+
+ @complexity Amortized constant.
+
+ @sa @ref operator/=(const json_pointer&) to append a JSON pointer
+ @sa @ref operator/=(std::size_t) to append an array index
+ @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
+
+ @since version 3.6.0
+ */
+ json_pointer& operator/=(std::string token)
+ {
+ push_back(std::move(token));
+ return *this;
+ }
+
+ /*!
+ @brief append an array index at the end of this JSON pointer
+
+ @param[in] array_index array index ot append
+ @return JSON pointer with @a array_index appended
+
+ @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
+
+ @complexity Amortized constant.
+
+ @sa @ref operator/=(const json_pointer&) to append a JSON pointer
+ @sa @ref operator/=(std::string) to append a reference token
+ @sa @ref operator/(const json_pointer&, std::string) for a binary operator
+
+ @since version 3.6.0
+ */
+ json_pointer& operator/=(std::size_t array_index)
+ {
+ return *this /= std::to_string(array_index);
+ }
+
+ /*!
+ @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
+
+ @param[in] lhs JSON pointer
+ @param[in] rhs JSON pointer
+ @return a new JSON pointer with @a rhs appended to @a lhs
+
+ @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
+
+ @complexity Linear in the length of @a lhs and @a rhs.
+
+ @sa @ref operator/=(const json_pointer&) to append a JSON pointer
+
+ @since version 3.6.0
+ */
+ friend json_pointer operator/(const json_pointer& lhs,
+ const json_pointer& rhs)
+ {
+ return json_pointer(lhs) /= rhs;
+ }
+
+ /*!
+ @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
+
+ @param[in] ptr JSON pointer
+ @param[in] token reference token
+ @return a new JSON pointer with unescaped @a token appended to @a ptr
+
+ @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
+
+ @complexity Linear in the length of @a ptr.
+
+ @sa @ref operator/=(std::string) to append a reference token
+
+ @since version 3.6.0
+ */
+ friend json_pointer operator/(const json_pointer& ptr, std::string token)
+ {
+ return json_pointer(ptr) /= std::move(token);
+ }
+
+ /*!
+ @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
+
+ @param[in] ptr JSON pointer
+ @param[in] array_index array index
+ @return a new JSON pointer with @a array_index appended to @a ptr
+
+ @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
+
+ @complexity Linear in the length of @a ptr.
+
+ @sa @ref operator/=(std::size_t) to append an array index
+
+ @since version 3.6.0
+ */
+ friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
+ {
+ return json_pointer(ptr) /= array_index;
+ }
+
+ /*!
+ @brief returns the parent of this JSON pointer
+
+ @return parent of this JSON pointer; in case this JSON pointer is the root,
+ the root itself is returned
+
+ @complexity Linear in the length of the JSON pointer.
+
+ @liveexample{The example shows the result of `parent_pointer` for different
+ JSON Pointers.,json_pointer__parent_pointer}
+
+ @since version 3.6.0
+ */
+ json_pointer parent_pointer() const
+ {
+ if (empty())
+ {
+ return *this;
+ }
+
+ json_pointer res = *this;
+ res.pop_back();
+ return res;
+ }
+
+ /*!
+ @brief remove last reference token
+
+ @pre not `empty()`
+
+ @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
+
+ @complexity Constant.
+
+ @throw out_of_range.405 if JSON pointer has no parent
+
+ @since version 3.6.0
+ */
+ void pop_back()
+ {
+ if (JSON_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+ }
+
+ reference_tokens.pop_back();
+ }
+
+ /*!
+ @brief return last reference token
+
+ @pre not `empty()`
+ @return last reference token
+
+ @liveexample{The example shows the usage of `back`.,json_pointer__back}
+
+ @complexity Constant.
+
+ @throw out_of_range.405 if JSON pointer has no parent
+
+ @since version 3.6.0
+ */
+ const std::string& back()
+ {
+ if (JSON_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+ }
+
+ return reference_tokens.back();
+ }
+
+ /*!
+ @brief append an unescaped token at the end of the reference pointer
+
+ @param[in] token token to add
+
+ @complexity Amortized constant.
+
+ @liveexample{The example shows the result of `push_back` for different
+ JSON Pointers.,json_pointer__push_back}
+
+ @since version 3.6.0
+ */
+ void push_back(const std::string& token)
+ {
+ reference_tokens.push_back(token);
+ }
+
+ /// @copydoc push_back(const std::string&)
+ void push_back(std::string&& token)
+ {
+ reference_tokens.push_back(std::move(token));
+ }
+
+ /*!
+ @brief return whether pointer points to the root document
+
+ @return true iff the JSON pointer points to the root document
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @liveexample{The example shows the result of `empty` for different JSON
+ Pointers.,json_pointer__empty}
+
+ @since version 3.6.0
+ */
+ bool empty() const noexcept
+ {
+ return reference_tokens.empty();
+ }
+
+ private:
+ /*!
+ @param[in] s reference token to be converted into an array index
+
+ @return integer representation of @a s
+
+ @throw out_of_range.404 if string @a s could not be converted to an integer
+ */
+ static int array_index(const std::string& s)
+ {
+ std::size_t processed_chars = 0;
+ const int res = std::stoi(s, &processed_chars);
+
+ // check if the string was completely read
+ if (JSON_UNLIKELY(processed_chars != s.size()))
+ {
+ JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
+ }
+
+ return res;
+ }
+
+ json_pointer top() const
+ {
+ if (JSON_UNLIKELY(empty()))
+ {
+ JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
+ }
+
+ json_pointer result = *this;
+ result.reference_tokens = {reference_tokens[0]};
+ return result;
+ }
+
+ /*!
+ @brief create and return a reference to the pointed to value
+
+ @complexity Linear in the number of reference tokens.
+
+ @throw parse_error.109 if array index is not a number
+ @throw type_error.313 if value cannot be unflattened
+ */
+ BasicJsonType& get_and_create(BasicJsonType& j) const
+ {
+ using size_type = typename BasicJsonType::size_type;
+ auto result = &j;
+
+ // in case no reference tokens exist, return a reference to the JSON value
+ // j which will be overwritten by a primitive value
+ for (const auto& reference_token : reference_tokens)
+ {
+ switch (result->m_type)
+ {
+ case detail::value_t::null:
+ {
+ if (reference_token == "0")
+ {
+ // start a new array if reference token is 0
+ result = &result->operator[](0);
+ }
+ else
+ {
+ // start a new object otherwise
+ result = &result->operator[](reference_token);
+ }
+ break;
+ }
+
+ case detail::value_t::object:
+ {
+ // create an entry in the object
+ result = &result->operator[](reference_token);
+ break;
+ }
+
+ case detail::value_t::array:
+ {
+ // create an entry in the array
+ JSON_TRY
+ {
+ result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
+ }
+ JSON_CATCH(std::invalid_argument&)
+ {
+ JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+ }
+ break;
+ }
+
+ /*
+ The following code is only reached if there exists a reference
+ token _and_ the current value is primitive. In this case, we have
+ an error situation, because primitive values may only occur as
+ single value; that is, with an empty list of reference tokens.
+ */
+ default:
+ JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
+ }
+ }
+
+ return *result;
+ }
+
+ /*!
+ @brief return a reference to the pointed to value
+
+ @note This version does not throw if a value is not present, but tries to
+ create nested values instead. For instance, calling this function
+ with pointer `"/this/that"` on a null value is equivalent to calling
+ `operator[]("this").operator[]("that")` on that value, effectively
+ changing the null value to an object.
+
+ @param[in] ptr a JSON value
+
+ @return reference to the JSON value pointed to by the JSON pointer
+
+ @complexity Linear in the length of the JSON pointer.
+
+ @throw parse_error.106 if an array index begins with '0'
+ @throw parse_error.109 if an array index was not a number
+ @throw out_of_range.404 if the JSON pointer can not be resolved
+ */
+ BasicJsonType& get_unchecked(BasicJsonType* ptr) const
+ {
+ using size_type = typename BasicJsonType::size_type;
+ for (const auto& reference_token : reference_tokens)
+ {
+ // convert null values to arrays or objects before continuing
+ if (ptr->m_type == detail::value_t::null)
+ {
+ // check if reference token is a number
+ const bool nums =
+ std::all_of(reference_token.begin(), reference_token.end(),
+ [](const char x)
+ {
+ return x >= '0' and x <= '9';
+ });
+
+ // change value to array for numbers or "-" or to object otherwise
+ *ptr = (nums or reference_token == "-")
+ ? detail::value_t::array
+ : detail::value_t::object;
+ }
+
+ switch (ptr->m_type)
+ {
+ case detail::value_t::object:
+ {
+ // use unchecked object access
+ ptr = &ptr->operator[](reference_token);
+ break;
+ }
+
+ case detail::value_t::array:
+ {
+ // error condition (cf. RFC 6901, Sect. 4)
+ if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+ {
+ JSON_THROW(detail::parse_error::create(106, 0,
+ "array index '" + reference_token +
+ "' must not begin with '0'"));
+ }
+
+ if (reference_token == "-")
+ {
+ // explicitly treat "-" as index beyond the end
+ ptr = &ptr->operator[](ptr->m_value.array->size());
+ }
+ else
+ {
+ // convert array index to number; unchecked access
+ JSON_TRY
+ {
+ ptr = &ptr->operator[](
+ static_cast<size_type>(array_index(reference_token)));
+ }
+ JSON_CATCH(std::invalid_argument&)
+ {
+ JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+ }
+ }
+ break;
+ }
+
+ default:
+ JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+ }
+ }
+
+ return *ptr;
+ }
+
+ /*!
+ @throw parse_error.106 if an array index begins with '0'
+ @throw parse_error.109 if an array index was not a number
+ @throw out_of_range.402 if the array index '-' is used
+ @throw out_of_range.404 if the JSON pointer can not be resolved
+ */
+ BasicJsonType& get_checked(BasicJsonType* ptr) const
+ {
+ using size_type = typename BasicJsonType::size_type;
+ for (const auto& reference_token : reference_tokens)
+ {
+ switch (ptr->m_type)
+ {
+ case detail::value_t::object:
+ {
+ // note: at performs range check
+ ptr = &ptr->at(reference_token);
+ break;
+ }
+
+ case detail::value_t::array:
+ {
+ if (JSON_UNLIKELY(reference_token == "-"))
+ {
+ // "-" always fails the range check
+ JSON_THROW(detail::out_of_range::create(402,
+ "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+ ") is out of range"));
+ }
+
+ // error condition (cf. RFC 6901, Sect. 4)
+ if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+ {
+ JSON_THROW(detail::parse_error::create(106, 0,
+ "array index '" + reference_token +
+ "' must not begin with '0'"));
+ }
+
+ // note: at performs range check
+ JSON_TRY
+ {
+ ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
+ }
+ JSON_CATCH(std::invalid_argument&)
+ {
+ JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+ }
+ break;
+ }
+
+ default:
+ JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+ }
+ }
+
+ return *ptr;
+ }
+
+ /*!
+ @brief return a const reference to the pointed to value
+
+ @param[in] ptr a JSON value
+
+ @return const reference to the JSON value pointed to by the JSON
+ pointer
+
+ @throw parse_error.106 if an array index begins with '0'
+ @throw parse_error.109 if an array index was not a number
+ @throw out_of_range.402 if the array index '-' is used
+ @throw out_of_range.404 if the JSON pointer can not be resolved
+ */
+ const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
+ {
+ using size_type = typename BasicJsonType::size_type;
+ for (const auto& reference_token : reference_tokens)
+ {
+ switch (ptr->m_type)
+ {
+ case detail::value_t::object:
+ {
+ // use unchecked object access
+ ptr = &ptr->operator[](reference_token);
+ break;
+ }
+
+ case detail::value_t::array:
+ {
+ if (JSON_UNLIKELY(reference_token == "-"))
+ {
+ // "-" cannot be used for const access
+ JSON_THROW(detail::out_of_range::create(402,
+ "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+ ") is out of range"));
+ }
+
+ // error condition (cf. RFC 6901, Sect. 4)
+ if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+ {
+ JSON_THROW(detail::parse_error::create(106, 0,
+ "array index '" + reference_token +
+ "' must not begin with '0'"));
+ }
+
+ // use unchecked array access
+ JSON_TRY
+ {
+ ptr = &ptr->operator[](
+ static_cast<size_type>(array_index(reference_token)));
+ }
+ JSON_CATCH(std::invalid_argument&)
+ {
+ JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+ }
+ break;
+ }
+
+ default:
+ JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+ }
+ }
+
+ return *ptr;
+ }
+
+ /*!
+ @throw parse_error.106 if an array index begins with '0'
+ @throw parse_error.109 if an array index was not a number
+ @throw out_of_range.402 if the array index '-' is used
+ @throw out_of_range.404 if the JSON pointer can not be resolved
+ */
+ const BasicJsonType& get_checked(const BasicJsonType* ptr) const
+ {
+ using size_type = typename BasicJsonType::size_type;
+ for (const auto& reference_token : reference_tokens)
+ {
+ switch (ptr->m_type)
+ {
+ case detail::value_t::object:
+ {
+ // note: at performs range check
+ ptr = &ptr->at(reference_token);
+ break;
+ }
+
+ case detail::value_t::array:
+ {
+ if (JSON_UNLIKELY(reference_token == "-"))
+ {
+ // "-" always fails the range check
+ JSON_THROW(detail::out_of_range::create(402,
+ "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
+ ") is out of range"));
+ }
+
+ // error condition (cf. RFC 6901, Sect. 4)
+ if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
+ {
+ JSON_THROW(detail::parse_error::create(106, 0,
+ "array index '" + reference_token +
+ "' must not begin with '0'"));
+ }
+
+ // note: at performs range check
+ JSON_TRY
+ {
+ ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
+ }
+ JSON_CATCH(std::invalid_argument&)
+ {
+ JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
+ }
+ break;
+ }
+
+ default:
+ JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
+ }
+ }
+
+ return *ptr;
+ }
+
+ /*!
+ @brief split the string input to reference tokens
+
+ @note This function is only called by the json_pointer constructor.
+ All exceptions below are documented there.
+
+ @throw parse_error.107 if the pointer is not empty or begins with '/'
+ @throw parse_error.108 if character '~' is not followed by '0' or '1'
+ */
+ static std::vector<std::string> split(const std::string& reference_string)
+ {
+ std::vector<std::string> result;
+
+ // special case: empty reference string -> no reference tokens
+ if (reference_string.empty())
+ {
+ return result;
+ }
+
+ // check if nonempty reference string begins with slash
+ if (JSON_UNLIKELY(reference_string[0] != '/'))
+ {
+ JSON_THROW(detail::parse_error::create(107, 1,
+ "JSON pointer must be empty or begin with '/' - was: '" +
+ reference_string + "'"));
+ }
+
+ // extract the reference tokens:
+ // - slash: position of the last read slash (or end of string)
+ // - start: position after the previous slash
+ for (
+ // search for the first slash after the first character
+ std::size_t slash = reference_string.find_first_of('/', 1),
+ // set the beginning of the first reference token
+ start = 1;
+ // we can stop if start == 0 (if slash == std::string::npos)
+ start != 0;
+ // set the beginning of the next reference token
+ // (will eventually be 0 if slash == std::string::npos)
+ start = (slash == std::string::npos) ? 0 : slash + 1,
+ // find next slash
+ slash = reference_string.find_first_of('/', start))
+ {
+ // use the text between the beginning of the reference token
+ // (start) and the last slash (slash).
+ auto reference_token = reference_string.substr(start, slash - start);
+
+ // check reference tokens are properly escaped
+ for (std::size_t pos = reference_token.find_first_of('~');
+ pos != std::string::npos;
+ pos = reference_token.find_first_of('~', pos + 1))
+ {
+ assert(reference_token[pos] == '~');
+
+ // ~ must be followed by 0 or 1
+ if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
+ (reference_token[pos + 1] != '0' and
+ reference_token[pos + 1] != '1')))
+ {
+ JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
+ }
+ }
+
+ // finally, store the reference token
+ unescape(reference_token);
+ result.push_back(reference_token);
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief replace all occurrences of a substring by another string
+
+ @param[in,out] s the string to manipulate; changed so that all
+ occurrences of @a f are replaced with @a t
+ @param[in] f the substring to replace with @a t
+ @param[in] t the string to replace @a f
+
+ @pre The search string @a f must not be empty. **This precondition is
+ enforced with an assertion.**
+
+ @since version 2.0.0
+ */
+ static void replace_substring(std::string& s, const std::string& f,
+ const std::string& t)
+ {
+ assert(not f.empty());
+ for (auto pos = s.find(f); // find first occurrence of f
+ pos != std::string::npos; // make sure f was found
+ s.replace(pos, f.size(), t), // replace with t, and
+ pos = s.find(f, pos + t.size())) // find next occurrence of f
+ {}
+ }
+
+ /// escape "~" to "~0" and "/" to "~1"
+ static std::string escape(std::string s)
+ {
+ replace_substring(s, "~", "~0");
+ replace_substring(s, "/", "~1");
+ return s;
+ }
+
+ /// unescape "~1" to tilde and "~0" to slash (order is important!)
+ static void unescape(std::string& s)
+ {
+ replace_substring(s, "~1", "/");
+ replace_substring(s, "~0", "~");
+ }
+
+ /*!
+ @param[in] reference_string the reference string to the current value
+ @param[in] value the value to consider
+ @param[in,out] result the result object to insert values to
+
+ @note Empty objects or arrays are flattened to `null`.
+ */
+ static void flatten(const std::string& reference_string,
+ const BasicJsonType& value,
+ BasicJsonType& result)
+ {
+ switch (value.m_type)
+ {
+ case detail::value_t::array:
+ {
+ if (value.m_value.array->empty())
+ {
+ // flatten empty array as null
+ result[reference_string] = nullptr;
+ }
+ else
+ {
+ // iterate array and use index as reference string
+ for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
+ {
+ flatten(reference_string + "/" + std::to_string(i),
+ value.m_value.array->operator[](i), result);
+ }
+ }
+ break;
+ }
+
+ case detail::value_t::object:
+ {
+ if (value.m_value.object->empty())
+ {
+ // flatten empty object as null
+ result[reference_string] = nullptr;
+ }
+ else
+ {
+ // iterate object and use keys as reference string
+ for (const auto& element : *value.m_value.object)
+ {
+ flatten(reference_string + "/" + escape(element.first), element.second, result);
+ }
+ }
+ break;
+ }
+
+ default:
+ {
+ // add primitive value with its reference string
+ result[reference_string] = value;
+ break;
+ }
+ }
+ }
+
+ /*!
+ @param[in] value flattened JSON
+
+ @return unflattened JSON
+
+ @throw parse_error.109 if array index is not a number
+ @throw type_error.314 if value is not an object
+ @throw type_error.315 if object values are not primitive
+ @throw type_error.313 if value cannot be unflattened
+ */
+ static BasicJsonType
+ unflatten(const BasicJsonType& value)
+ {
+ if (JSON_UNLIKELY(not value.is_object()))
+ {
+ JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
+ }
+
+ BasicJsonType result;
+
+ // iterate the JSON object values
+ for (const auto& element : *value.m_value.object)
+ {
+ if (JSON_UNLIKELY(not element.second.is_primitive()))
+ {
+ JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
+ }
+
+ // assign value to reference pointed to by JSON pointer; Note that if
+ // the JSON pointer is "" (i.e., points to the whole value), function
+ // get_and_create returns a reference to result itself. An assignment
+ // will then create a primitive value.
+ json_pointer(element.first).get_and_create(result) = element.second;
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief compares two JSON pointers for equality
+
+ @param[in] lhs JSON pointer to compare
+ @param[in] rhs JSON pointer to compare
+ @return whether @a lhs is equal to @a rhs
+
+ @complexity Linear in the length of the JSON pointer
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+ */
+ friend bool operator==(json_pointer const& lhs,
+ json_pointer const& rhs) noexcept
+ {
+ return lhs.reference_tokens == rhs.reference_tokens;
+ }
+
+ /*!
+ @brief compares two JSON pointers for inequality
+
+ @param[in] lhs JSON pointer to compare
+ @param[in] rhs JSON pointer to compare
+ @return whether @a lhs is not equal @a rhs
+
+ @complexity Linear in the length of the JSON pointer
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+ */
+ friend bool operator!=(json_pointer const& lhs,
+ json_pointer const& rhs) noexcept
+ {
+ return not (lhs == rhs);
+ }
+
+ /// the reference tokens
+ std::vector<std::string> reference_tokens;
+};
+} // namespace nlohmann
+
+// #include <nlohmann/detail/json_ref.hpp>
+
+
+#include <initializer_list>
+#include <utility>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+template<typename BasicJsonType>
+class json_ref
+{
+ public:
+ using value_type = BasicJsonType;
+
+ json_ref(value_type&& value)
+ : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
+ {}
+
+ json_ref(const value_type& value)
+ : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
+ {}
+
+ json_ref(std::initializer_list<json_ref> init)
+ : owned_value(init), value_ref(&owned_value), is_rvalue(true)
+ {}
+
+ template <
+ class... Args,
+ enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
+ json_ref(Args && ... args)
+ : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
+ is_rvalue(true) {}
+
+ // class should be movable only
+ json_ref(json_ref&&) = default;
+ json_ref(const json_ref&) = delete;
+ json_ref& operator=(const json_ref&) = delete;
+ json_ref& operator=(json_ref&&) = delete;
+ ~json_ref() = default;
+
+ value_type moved_or_copied() const
+ {
+ if (is_rvalue)
+ {
+ return std::move(*value_ref);
+ }
+ return *value_ref;
+ }
+
+ value_type const& operator*() const
+ {
+ return *static_cast<value_type const*>(value_ref);
+ }
+
+ value_type const* operator->() const
+ {
+ return static_cast<value_type const*>(value_ref);
+ }
+
+ private:
+ mutable value_type owned_value = nullptr;
+ value_type* value_ref = nullptr;
+ const bool is_rvalue;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/meta/type_traits.hpp>
+
+// #include <nlohmann/detail/output/binary_writer.hpp>
+
+
+#include <algorithm> // reverse
+#include <array> // array
+#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
+#include <cstring> // memcpy
+#include <limits> // numeric_limits
+#include <string> // string
+
+// #include <nlohmann/detail/input/binary_reader.hpp>
+
+// #include <nlohmann/detail/output/output_adapters.hpp>
+
+
+#include <algorithm> // copy
+#include <cstddef> // size_t
+#include <ios> // streamsize
+#include <iterator> // back_inserter
+#include <memory> // shared_ptr, make_shared
+#include <ostream> // basic_ostream
+#include <string> // basic_string
+#include <vector> // vector
+
+namespace nlohmann
+{
+namespace detail
+{
+/// abstract output adapter interface
+template<typename CharType> struct output_adapter_protocol
+{
+ virtual void write_character(CharType c) = 0;
+ virtual void write_characters(const CharType* s, std::size_t length) = 0;
+ virtual ~output_adapter_protocol() = default;
+};
+
+/// a type to simplify interfaces
+template<typename CharType>
+using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
+
+/// output adapter for byte vectors
+template<typename CharType>
+class output_vector_adapter : public output_adapter_protocol<CharType>
+{
+ public:
+ explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
+ : v(vec)
+ {}
+
+ void write_character(CharType c) override
+ {
+ v.push_back(c);
+ }
+
+ void write_characters(const CharType* s, std::size_t length) override
+ {
+ std::copy(s, s + length, std::back_inserter(v));
+ }
+
+ private:
+ std::vector<CharType>& v;
+};
+
+/// output adapter for output streams
+template<typename CharType>
+class output_stream_adapter : public output_adapter_protocol<CharType>
+{
+ public:
+ explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
+ : stream(s)
+ {}
+
+ void write_character(CharType c) override
+ {
+ stream.put(c);
+ }
+
+ void write_characters(const CharType* s, std::size_t length) override
+ {
+ stream.write(s, static_cast<std::streamsize>(length));
+ }
+
+ private:
+ std::basic_ostream<CharType>& stream;
+};
+
+/// output adapter for basic_string
+template<typename CharType, typename StringType = std::basic_string<CharType>>
+class output_string_adapter : public output_adapter_protocol<CharType>
+{
+ public:
+ explicit output_string_adapter(StringType& s) noexcept
+ : str(s)
+ {}
+
+ void write_character(CharType c) override
+ {
+ str.push_back(c);
+ }
+
+ void write_characters(const CharType* s, std::size_t length) override
+ {
+ str.append(s, length);
+ }
+
+ private:
+ StringType& str;
+};
+
+template<typename CharType, typename StringType = std::basic_string<CharType>>
+class output_adapter
+{
+ public:
+ output_adapter(std::vector<CharType>& vec)
+ : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
+
+ output_adapter(std::basic_ostream<CharType>& s)
+ : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
+
+ output_adapter(StringType& s)
+ : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
+
+ operator output_adapter_t<CharType>()
+ {
+ return oa;
+ }
+
+ private:
+ output_adapter_t<CharType> oa = nullptr;
+};
+} // namespace detail
+} // namespace nlohmann
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////
+// binary writer //
+///////////////////
+
+/*!
+@brief serialization to CBOR and MessagePack values
+*/
+template<typename BasicJsonType, typename CharType>
+class binary_writer
+{
+ using string_t = typename BasicJsonType::string_t;
+
+ public:
+ /*!
+ @brief create a binary writer
+
+ @param[in] adapter output adapter to write to
+ */
+ explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
+ {
+ assert(oa);
+ }
+
+ /*!
+ @param[in] j JSON value to serialize
+ @pre j.type() == value_t::object
+ */
+ void write_bson(const BasicJsonType& j)
+ {
+ switch (j.type())
+ {
+ case value_t::object:
+ {
+ write_bson_object(*j.m_value.object);
+ break;
+ }
+
+ default:
+ {
+ JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
+ }
+ }
+ }
+
+ /*!
+ @param[in] j JSON value to serialize
+ */
+ void write_cbor(const BasicJsonType& j)
+ {
+ switch (j.type())
+ {
+ case value_t::null:
+ {
+ oa->write_character(to_char_type(0xF6));
+ break;
+ }
+
+ case value_t::boolean:
+ {
+ oa->write_character(j.m_value.boolean
+ ? to_char_type(0xF5)
+ : to_char_type(0xF4));
+ break;
+ }
+
+ case value_t::number_integer:
+ {
+ if (j.m_value.number_integer >= 0)
+ {
+ // CBOR does not differentiate between positive signed
+ // integers and unsigned integers. Therefore, we used the
+ // code from the value_t::number_unsigned case here.
+ if (j.m_value.number_integer <= 0x17)
+ {
+ write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ oa->write_character(to_char_type(0x18));
+ write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ oa->write_character(to_char_type(0x19));
+ write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ oa->write_character(to_char_type(0x1A));
+ write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
+ }
+ else
+ {
+ oa->write_character(to_char_type(0x1B));
+ write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
+ }
+ }
+ else
+ {
+ // The conversions below encode the sign in the first
+ // byte, and the value is converted to a positive number.
+ const auto positive_number = -1 - j.m_value.number_integer;
+ if (j.m_value.number_integer >= -24)
+ {
+ write_number(static_cast<std::uint8_t>(0x20 + positive_number));
+ }
+ else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ oa->write_character(to_char_type(0x38));
+ write_number(static_cast<std::uint8_t>(positive_number));
+ }
+ else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ oa->write_character(to_char_type(0x39));
+ write_number(static_cast<std::uint16_t>(positive_number));
+ }
+ else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ oa->write_character(to_char_type(0x3A));
+ write_number(static_cast<std::uint32_t>(positive_number));
+ }
+ else
+ {
+ oa->write_character(to_char_type(0x3B));
+ write_number(static_cast<std::uint64_t>(positive_number));
+ }
+ }
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ if (j.m_value.number_unsigned <= 0x17)
+ {
+ write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ oa->write_character(to_char_type(0x18));
+ write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ oa->write_character(to_char_type(0x19));
+ write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ oa->write_character(to_char_type(0x1A));
+ write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
+ }
+ else
+ {
+ oa->write_character(to_char_type(0x1B));
+ write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
+ }
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
+ write_number(j.m_value.number_float);
+ break;
+ }
+
+ case value_t::string:
+ {
+ // step 1: write control byte and the string length
+ const auto N = j.m_value.string->size();
+ if (N <= 0x17)
+ {
+ write_number(static_cast<std::uint8_t>(0x60 + N));
+ }
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ oa->write_character(to_char_type(0x78));
+ write_number(static_cast<std::uint8_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ oa->write_character(to_char_type(0x79));
+ write_number(static_cast<std::uint16_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ oa->write_character(to_char_type(0x7A));
+ write_number(static_cast<std::uint32_t>(N));
+ }
+ // LCOV_EXCL_START
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+ {
+ oa->write_character(to_char_type(0x7B));
+ write_number(static_cast<std::uint64_t>(N));
+ }
+ // LCOV_EXCL_STOP
+
+ // step 2: write the string
+ oa->write_characters(
+ reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+ j.m_value.string->size());
+ break;
+ }
+
+ case value_t::array:
+ {
+ // step 1: write control byte and the array size
+ const auto N = j.m_value.array->size();
+ if (N <= 0x17)
+ {
+ write_number(static_cast<std::uint8_t>(0x80 + N));
+ }
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ oa->write_character(to_char_type(0x98));
+ write_number(static_cast<std::uint8_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ oa->write_character(to_char_type(0x99));
+ write_number(static_cast<std::uint16_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ oa->write_character(to_char_type(0x9A));
+ write_number(static_cast<std::uint32_t>(N));
+ }
+ // LCOV_EXCL_START
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+ {
+ oa->write_character(to_char_type(0x9B));
+ write_number(static_cast<std::uint64_t>(N));
+ }
+ // LCOV_EXCL_STOP
+
+ // step 2: write each element
+ for (const auto& el : *j.m_value.array)
+ {
+ write_cbor(el);
+ }
+ break;
+ }
+
+ case value_t::object:
+ {
+ // step 1: write control byte and the object size
+ const auto N = j.m_value.object->size();
+ if (N <= 0x17)
+ {
+ write_number(static_cast<std::uint8_t>(0xA0 + N));
+ }
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ oa->write_character(to_char_type(0xB8));
+ write_number(static_cast<std::uint8_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ oa->write_character(to_char_type(0xB9));
+ write_number(static_cast<std::uint16_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ oa->write_character(to_char_type(0xBA));
+ write_number(static_cast<std::uint32_t>(N));
+ }
+ // LCOV_EXCL_START
+ else if (N <= (std::numeric_limits<std::uint64_t>::max)())
+ {
+ oa->write_character(to_char_type(0xBB));
+ write_number(static_cast<std::uint64_t>(N));
+ }
+ // LCOV_EXCL_STOP
+
+ // step 2: write each element
+ for (const auto& el : *j.m_value.object)
+ {
+ write_cbor(el.first);
+ write_cbor(el.second);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /*!
+ @param[in] j JSON value to serialize
+ */
+ void write_msgpack(const BasicJsonType& j)
+ {
+ switch (j.type())
+ {
+ case value_t::null: // nil
+ {
+ oa->write_character(to_char_type(0xC0));
+ break;
+ }
+
+ case value_t::boolean: // true and false
+ {
+ oa->write_character(j.m_value.boolean
+ ? to_char_type(0xC3)
+ : to_char_type(0xC2));
+ break;
+ }
+
+ case value_t::number_integer:
+ {
+ if (j.m_value.number_integer >= 0)
+ {
+ // MessagePack does not differentiate between positive
+ // signed integers and unsigned integers. Therefore, we used
+ // the code from the value_t::number_unsigned case here.
+ if (j.m_value.number_unsigned < 128)
+ {
+ // positive fixnum
+ write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ // uint 8
+ oa->write_character(to_char_type(0xCC));
+ write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ // uint 16
+ oa->write_character(to_char_type(0xCD));
+ write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ // uint 32
+ oa->write_character(to_char_type(0xCE));
+ write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
+ {
+ // uint 64
+ oa->write_character(to_char_type(0xCF));
+ write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
+ }
+ }
+ else
+ {
+ if (j.m_value.number_integer >= -32)
+ {
+ // negative fixnum
+ write_number(static_cast<std::int8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
+ j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
+ {
+ // int 8
+ oa->write_character(to_char_type(0xD0));
+ write_number(static_cast<std::int8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
+ j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
+ {
+ // int 16
+ oa->write_character(to_char_type(0xD1));
+ write_number(static_cast<std::int16_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
+ j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
+ {
+ // int 32
+ oa->write_character(to_char_type(0xD2));
+ write_number(static_cast<std::int32_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
+ j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
+ {
+ // int 64
+ oa->write_character(to_char_type(0xD3));
+ write_number(static_cast<std::int64_t>(j.m_value.number_integer));
+ }
+ }
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ if (j.m_value.number_unsigned < 128)
+ {
+ // positive fixnum
+ write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ // uint 8
+ oa->write_character(to_char_type(0xCC));
+ write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ // uint 16
+ oa->write_character(to_char_type(0xCD));
+ write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ // uint 32
+ oa->write_character(to_char_type(0xCE));
+ write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
+ }
+ else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
+ {
+ // uint 64
+ oa->write_character(to_char_type(0xCF));
+ write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
+ }
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
+ write_number(j.m_value.number_float);
+ break;
+ }
+
+ case value_t::string:
+ {
+ // step 1: write control byte and the string length
+ const auto N = j.m_value.string->size();
+ if (N <= 31)
+ {
+ // fixstr
+ write_number(static_cast<std::uint8_t>(0xA0 | N));
+ }
+ else if (N <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ // str 8
+ oa->write_character(to_char_type(0xD9));
+ write_number(static_cast<std::uint8_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ // str 16
+ oa->write_character(to_char_type(0xDA));
+ write_number(static_cast<std::uint16_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ // str 32
+ oa->write_character(to_char_type(0xDB));
+ write_number(static_cast<std::uint32_t>(N));
+ }
+
+ // step 2: write the string
+ oa->write_characters(
+ reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+ j.m_value.string->size());
+ break;
+ }
+
+ case value_t::array:
+ {
+ // step 1: write control byte and the array size
+ const auto N = j.m_value.array->size();
+ if (N <= 15)
+ {
+ // fixarray
+ write_number(static_cast<std::uint8_t>(0x90 | N));
+ }
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ // array 16
+ oa->write_character(to_char_type(0xDC));
+ write_number(static_cast<std::uint16_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ // array 32
+ oa->write_character(to_char_type(0xDD));
+ write_number(static_cast<std::uint32_t>(N));
+ }
+
+ // step 2: write each element
+ for (const auto& el : *j.m_value.array)
+ {
+ write_msgpack(el);
+ }
+ break;
+ }
+
+ case value_t::object:
+ {
+ // step 1: write control byte and the object size
+ const auto N = j.m_value.object->size();
+ if (N <= 15)
+ {
+ // fixmap
+ write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
+ }
+ else if (N <= (std::numeric_limits<std::uint16_t>::max)())
+ {
+ // map 16
+ oa->write_character(to_char_type(0xDE));
+ write_number(static_cast<std::uint16_t>(N));
+ }
+ else if (N <= (std::numeric_limits<std::uint32_t>::max)())
+ {
+ // map 32
+ oa->write_character(to_char_type(0xDF));
+ write_number(static_cast<std::uint32_t>(N));
+ }
+
+ // step 2: write each element
+ for (const auto& el : *j.m_value.object)
+ {
+ write_msgpack(el.first);
+ write_msgpack(el.second);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /*!
+ @param[in] j JSON value to serialize
+ @param[in] use_count whether to use '#' prefixes (optimized format)
+ @param[in] use_type whether to use '$' prefixes (optimized format)
+ @param[in] add_prefix whether prefixes need to be used for this value
+ */
+ void write_ubjson(const BasicJsonType& j, const bool use_count,
+ const bool use_type, const bool add_prefix = true)
+ {
+ switch (j.type())
+ {
+ case value_t::null:
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('Z'));
+ }
+ break;
+ }
+
+ case value_t::boolean:
+ {
+ if (add_prefix)
+ {
+ oa->write_character(j.m_value.boolean
+ ? to_char_type('T')
+ : to_char_type('F'));
+ }
+ break;
+ }
+
+ case value_t::number_integer:
+ {
+ write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
+ break;
+ }
+
+ case value_t::string:
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('S'));
+ }
+ write_number_with_ubjson_prefix(j.m_value.string->size(), true);
+ oa->write_characters(
+ reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
+ j.m_value.string->size());
+ break;
+ }
+
+ case value_t::array:
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('['));
+ }
+
+ bool prefix_required = true;
+ if (use_type and not j.m_value.array->empty())
+ {
+ assert(use_count);
+ const CharType first_prefix = ubjson_prefix(j.front());
+ const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
+ [this, first_prefix](const BasicJsonType & v)
+ {
+ return ubjson_prefix(v) == first_prefix;
+ });
+
+ if (same_prefix)
+ {
+ prefix_required = false;
+ oa->write_character(to_char_type('$'));
+ oa->write_character(first_prefix);
+ }
+ }
+
+ if (use_count)
+ {
+ oa->write_character(to_char_type('#'));
+ write_number_with_ubjson_prefix(j.m_value.array->size(), true);
+ }
+
+ for (const auto& el : *j.m_value.array)
+ {
+ write_ubjson(el, use_count, use_type, prefix_required);
+ }
+
+ if (not use_count)
+ {
+ oa->write_character(to_char_type(']'));
+ }
+
+ break;
+ }
+
+ case value_t::object:
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('{'));
+ }
+
+ bool prefix_required = true;
+ if (use_type and not j.m_value.object->empty())
+ {
+ assert(use_count);
+ const CharType first_prefix = ubjson_prefix(j.front());
+ const bool same_prefix = std::all_of(j.begin(), j.end(),
+ [this, first_prefix](const BasicJsonType & v)
+ {
+ return ubjson_prefix(v) == first_prefix;
+ });
+
+ if (same_prefix)
+ {
+ prefix_required = false;
+ oa->write_character(to_char_type('$'));
+ oa->write_character(first_prefix);
+ }
+ }
+
+ if (use_count)
+ {
+ oa->write_character(to_char_type('#'));
+ write_number_with_ubjson_prefix(j.m_value.object->size(), true);
+ }
+
+ for (const auto& el : *j.m_value.object)
+ {
+ write_number_with_ubjson_prefix(el.first.size(), true);
+ oa->write_characters(
+ reinterpret_cast<const CharType*>(el.first.c_str()),
+ el.first.size());
+ write_ubjson(el.second, use_count, use_type, prefix_required);
+ }
+
+ if (not use_count)
+ {
+ oa->write_character(to_char_type('}'));
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ private:
+ //////////
+ // BSON //
+ //////////
+
+ /*!
+ @return The size of a BSON document entry header, including the id marker
+ and the entry name size (and its null-terminator).
+ */
+ static std::size_t calc_bson_entry_header_size(const string_t& name)
+ {
+ const auto it = name.find(static_cast<typename string_t::value_type>(0));
+ if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
+ {
+ JSON_THROW(out_of_range::create(409,
+ "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
+ }
+
+ return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
+ }
+
+ /*!
+ @brief Writes the given @a element_type and @a name to the output adapter
+ */
+ void write_bson_entry_header(const string_t& name,
+ const std::uint8_t element_type)
+ {
+ oa->write_character(to_char_type(element_type)); // boolean
+ oa->write_characters(
+ reinterpret_cast<const CharType*>(name.c_str()),
+ name.size() + 1u);
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and boolean value @a value
+ */
+ void write_bson_boolean(const string_t& name,
+ const bool value)
+ {
+ write_bson_entry_header(name, 0x08);
+ oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and double value @a value
+ */
+ void write_bson_double(const string_t& name,
+ const double value)
+ {
+ write_bson_entry_header(name, 0x01);
+ write_number<double, true>(value);
+ }
+
+ /*!
+ @return The size of the BSON-encoded string in @a value
+ */
+ static std::size_t calc_bson_string_size(const string_t& value)
+ {
+ return sizeof(std::int32_t) + value.size() + 1ul;
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and string value @a value
+ */
+ void write_bson_string(const string_t& name,
+ const string_t& value)
+ {
+ write_bson_entry_header(name, 0x02);
+
+ write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
+ oa->write_characters(
+ reinterpret_cast<const CharType*>(value.c_str()),
+ value.size() + 1);
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and null value
+ */
+ void write_bson_null(const string_t& name)
+ {
+ write_bson_entry_header(name, 0x0A);
+ }
+
+ /*!
+ @return The size of the BSON-encoded integer @a value
+ */
+ static std::size_t calc_bson_integer_size(const std::int64_t value)
+ {
+ return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
+ ? sizeof(std::int32_t)
+ : sizeof(std::int64_t);
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and integer @a value
+ */
+ void write_bson_integer(const string_t& name,
+ const std::int64_t value)
+ {
+ if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
+ {
+ write_bson_entry_header(name, 0x10); // int32
+ write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
+ }
+ else
+ {
+ write_bson_entry_header(name, 0x12); // int64
+ write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
+ }
+ }
+
+ /*!
+ @return The size of the BSON-encoded unsigned integer in @a j
+ */
+ static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
+ {
+ return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+ ? sizeof(std::int32_t)
+ : sizeof(std::int64_t);
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and unsigned @a value
+ */
+ void write_bson_unsigned(const string_t& name,
+ const std::uint64_t value)
+ {
+ if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+ {
+ write_bson_entry_header(name, 0x10 /* int32 */);
+ write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
+ }
+ else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
+ {
+ write_bson_entry_header(name, 0x12 /* int64 */);
+ write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
+ }
+ else
+ {
+ JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
+ }
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and object @a value
+ */
+ void write_bson_object_entry(const string_t& name,
+ const typename BasicJsonType::object_t& value)
+ {
+ write_bson_entry_header(name, 0x03); // object
+ write_bson_object(value);
+ }
+
+ /*!
+ @return The size of the BSON-encoded array @a value
+ */
+ static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
+ {
+ std::size_t embedded_document_size = 0ul;
+ std::size_t array_index = 0ul;
+
+ for (const auto& el : value)
+ {
+ embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
+ }
+
+ return sizeof(std::int32_t) + embedded_document_size + 1ul;
+ }
+
+ /*!
+ @brief Writes a BSON element with key @a name and array @a value
+ */
+ void write_bson_array(const string_t& name,
+ const typename BasicJsonType::array_t& value)
+ {
+ write_bson_entry_header(name, 0x04); // array
+ write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
+
+ std::size_t array_index = 0ul;
+
+ for (const auto& el : value)
+ {
+ write_bson_element(std::to_string(array_index++), el);
+ }
+
+ oa->write_character(to_char_type(0x00));
+ }
+
+ /*!
+ @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
+ @return The calculated size for the BSON document entry for @a j with the given @a name.
+ */
+ static std::size_t calc_bson_element_size(const string_t& name,
+ const BasicJsonType& j)
+ {
+ const auto header_size = calc_bson_entry_header_size(name);
+ switch (j.type())
+ {
+ case value_t::object:
+ return header_size + calc_bson_object_size(*j.m_value.object);
+
+ case value_t::array:
+ return header_size + calc_bson_array_size(*j.m_value.array);
+
+ case value_t::boolean:
+ return header_size + 1ul;
+
+ case value_t::number_float:
+ return header_size + 8ul;
+
+ case value_t::number_integer:
+ return header_size + calc_bson_integer_size(j.m_value.number_integer);
+
+ case value_t::number_unsigned:
+ return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
+
+ case value_t::string:
+ return header_size + calc_bson_string_size(*j.m_value.string);
+
+ case value_t::null:
+ return header_size + 0ul;
+
+ // LCOV_EXCL_START
+ default:
+ assert(false);
+ return 0ul;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ /*!
+ @brief Serializes the JSON value @a j to BSON and associates it with the
+ key @a name.
+ @param name The name to associate with the JSON entity @a j within the
+ current BSON document
+ @return The size of the BSON entry
+ */
+ void write_bson_element(const string_t& name,
+ const BasicJsonType& j)
+ {
+ switch (j.type())
+ {
+ case value_t::object:
+ return write_bson_object_entry(name, *j.m_value.object);
+
+ case value_t::array:
+ return write_bson_array(name, *j.m_value.array);
+
+ case value_t::boolean:
+ return write_bson_boolean(name, j.m_value.boolean);
+
+ case value_t::number_float:
+ return write_bson_double(name, j.m_value.number_float);
+
+ case value_t::number_integer:
+ return write_bson_integer(name, j.m_value.number_integer);
+
+ case value_t::number_unsigned:
+ return write_bson_unsigned(name, j.m_value.number_unsigned);
+
+ case value_t::string:
+ return write_bson_string(name, *j.m_value.string);
+
+ case value_t::null:
+ return write_bson_null(name);
+
+ // LCOV_EXCL_START
+ default:
+ assert(false);
+ return;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ /*!
+ @brief Calculates the size of the BSON serialization of the given
+ JSON-object @a j.
+ @param[in] j JSON value to serialize
+ @pre j.type() == value_t::object
+ */
+ static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
+ {
+ std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
+ [](size_t result, const typename BasicJsonType::object_t::value_type & el)
+ {
+ return result += calc_bson_element_size(el.first, el.second);
+ });
+
+ return sizeof(std::int32_t) + document_size + 1ul;
+ }
+
+ /*!
+ @param[in] j JSON value to serialize
+ @pre j.type() == value_t::object
+ */
+ void write_bson_object(const typename BasicJsonType::object_t& value)
+ {
+ write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
+
+ for (const auto& el : value)
+ {
+ write_bson_element(el.first, el.second);
+ }
+
+ oa->write_character(to_char_type(0x00));
+ }
+
+ //////////
+ // CBOR //
+ //////////
+
+ static constexpr CharType get_cbor_float_prefix(float /*unused*/)
+ {
+ return to_char_type(0xFA); // Single-Precision Float
+ }
+
+ static constexpr CharType get_cbor_float_prefix(double /*unused*/)
+ {
+ return to_char_type(0xFB); // Double-Precision Float
+ }
+
+ /////////////
+ // MsgPack //
+ /////////////
+
+ static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
+ {
+ return to_char_type(0xCA); // float 32
+ }
+
+ static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
+ {
+ return to_char_type(0xCB); // float 64
+ }
+
+ ////////////
+ // UBJSON //
+ ////////////
+
+ // UBJSON: write number (floating point)
+ template<typename NumberType, typename std::enable_if<
+ std::is_floating_point<NumberType>::value, int>::type = 0>
+ void write_number_with_ubjson_prefix(const NumberType n,
+ const bool add_prefix)
+ {
+ if (add_prefix)
+ {
+ oa->write_character(get_ubjson_float_prefix(n));
+ }
+ write_number(n);
+ }
+
+ // UBJSON: write number (unsigned integer)
+ template<typename NumberType, typename std::enable_if<
+ std::is_unsigned<NumberType>::value, int>::type = 0>
+ void write_number_with_ubjson_prefix(const NumberType n,
+ const bool add_prefix)
+ {
+ if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('i')); // int8
+ }
+ write_number(static_cast<std::uint8_t>(n));
+ }
+ else if (n <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('U')); // uint8
+ }
+ write_number(static_cast<std::uint8_t>(n));
+ }
+ else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('I')); // int16
+ }
+ write_number(static_cast<std::int16_t>(n));
+ }
+ else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('l')); // int32
+ }
+ write_number(static_cast<std::int32_t>(n));
+ }
+ else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('L')); // int64
+ }
+ write_number(static_cast<std::int64_t>(n));
+ }
+ else
+ {
+ JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
+ }
+ }
+
+ // UBJSON: write number (signed integer)
+ template<typename NumberType, typename std::enable_if<
+ std::is_signed<NumberType>::value and
+ not std::is_floating_point<NumberType>::value, int>::type = 0>
+ void write_number_with_ubjson_prefix(const NumberType n,
+ const bool add_prefix)
+ {
+ if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('i')); // int8
+ }
+ write_number(static_cast<std::int8_t>(n));
+ }
+ else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('U')); // uint8
+ }
+ write_number(static_cast<std::uint8_t>(n));
+ }
+ else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('I')); // int16
+ }
+ write_number(static_cast<std::int16_t>(n));
+ }
+ else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('l')); // int32
+ }
+ write_number(static_cast<std::int32_t>(n));
+ }
+ else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
+ {
+ if (add_prefix)
+ {
+ oa->write_character(to_char_type('L')); // int64
+ }
+ write_number(static_cast<std::int64_t>(n));
+ }
+ // LCOV_EXCL_START
+ else
+ {
+ JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
+ }
+ // LCOV_EXCL_STOP
+ }
+
+ /*!
+ @brief determine the type prefix of container values
+
+ @note This function does not need to be 100% accurate when it comes to
+ integer limits. In case a number exceeds the limits of int64_t,
+ this will be detected by a later call to function
+ write_number_with_ubjson_prefix. Therefore, we return 'L' for any
+ value that does not fit the previous limits.
+ */
+ CharType ubjson_prefix(const BasicJsonType& j) const noexcept
+ {
+ switch (j.type())
+ {
+ case value_t::null:
+ return 'Z';
+
+ case value_t::boolean:
+ return j.m_value.boolean ? 'T' : 'F';
+
+ case value_t::number_integer:
+ {
+ if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
+ {
+ return 'i';
+ }
+ if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ return 'U';
+ }
+ if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
+ {
+ return 'I';
+ }
+ if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
+ {
+ return 'l';
+ }
+ // no check and assume int64_t (see note above)
+ return 'L';
+ }
+
+ case value_t::number_unsigned:
+ {
+ if (j.m_value.number_unsigned <= (std::numeric_limits<std::int8_t>::max)())
+ {
+ return 'i';
+ }
+ if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
+ {
+ return 'U';
+ }
+ if (j.m_value.number_unsigned <= (std::numeric_limits<std::int16_t>::max)())
+ {
+ return 'I';
+ }
+ if (j.m_value.number_unsigned <= (std::numeric_limits<std::int32_t>::max)())
+ {
+ return 'l';
+ }
+ // no check and assume int64_t (see note above)
+ return 'L';
+ }
+
+ case value_t::number_float:
+ return get_ubjson_float_prefix(j.m_value.number_float);
+
+ case value_t::string:
+ return 'S';
+
+ case value_t::array:
+ return '[';
+
+ case value_t::object:
+ return '{';
+
+ default: // discarded values
+ return 'N';
+ }
+ }
+
+ static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
+ {
+ return 'd'; // float 32
+ }
+
+ static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
+ {
+ return 'D'; // float 64
+ }
+
+ ///////////////////////
+ // Utility functions //
+ ///////////////////////
+
+ /*
+ @brief write a number to output input
+ @param[in] n number of type @a NumberType
+ @tparam NumberType the type of the number
+ @tparam OutputIsLittleEndian Set to true if output data is
+ required to be little endian
+
+ @note This function needs to respect the system's endianness, because bytes
+ in CBOR, MessagePack, and UBJSON are stored in network order (big
+ endian) and therefore need reordering on little endian systems.
+ */
+ template<typename NumberType, bool OutputIsLittleEndian = false>
+ void write_number(const NumberType n)
+ {
+ // step 1: write number to array of length NumberType
+ std::array<CharType, sizeof(NumberType)> vec;
+ std::memcpy(vec.data(), &n, sizeof(NumberType));
+
+ // step 2: write array to output (with possible reordering)
+ if (is_little_endian != OutputIsLittleEndian)
+ {
+ // reverse byte order prior to conversion if necessary
+ std::reverse(vec.begin(), vec.end());
+ }
+
+ oa->write_characters(vec.data(), sizeof(NumberType));
+ }
+
+ public:
+ // The following to_char_type functions are implement the conversion
+ // between uint8_t and CharType. In case CharType is not unsigned,
+ // such a conversion is required to allow values greater than 128.
+ // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
+ template < typename C = CharType,
+ enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
+ static constexpr CharType to_char_type(std::uint8_t x) noexcept
+ {
+ return *reinterpret_cast<char*>(&x);
+ }
+
+ template < typename C = CharType,
+ enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
+ static CharType to_char_type(std::uint8_t x) noexcept
+ {
+ static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
+ static_assert(std::is_pod<CharType>::value, "CharType must be POD");
+ CharType result;
+ std::memcpy(&result, &x, sizeof(x));
+ return result;
+ }
+
+ template<typename C = CharType,
+ enable_if_t<std::is_unsigned<C>::value>* = nullptr>
+ static constexpr CharType to_char_type(std::uint8_t x) noexcept
+ {
+ return x;
+ }
+
+ template < typename InputCharType, typename C = CharType,
+ enable_if_t <
+ std::is_signed<C>::value and
+ std::is_signed<char>::value and
+ std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
+ > * = nullptr >
+ static constexpr CharType to_char_type(InputCharType x) noexcept
+ {
+ return x;
+ }
+
+ private:
+ /// whether we can assume little endianness
+ const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
+
+ /// the output
+ output_adapter_t<CharType> oa = nullptr;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/output/output_adapters.hpp>
+
+// #include <nlohmann/detail/output/serializer.hpp>
+
+
+#include <algorithm> // reverse, remove, fill, find, none_of
+#include <array> // array
+#include <cassert> // assert
+#include <ciso646> // and, or
+#include <clocale> // localeconv, lconv
+#include <cmath> // labs, isfinite, isnan, signbit
+#include <cstddef> // size_t, ptrdiff_t
+#include <cstdint> // uint8_t
+#include <cstdio> // snprintf
+#include <limits> // numeric_limits
+#include <string> // string
+#include <type_traits> // is_same
+#include <utility> // move
+
+// #include <nlohmann/detail/conversions/to_chars.hpp>
+
+
+#include <array> // array
+#include <cassert> // assert
+#include <ciso646> // or, and, not
+#include <cmath> // signbit, isfinite
+#include <cstdint> // intN_t, uintN_t
+#include <cstring> // memcpy, memmove
+#include <limits> // numeric_limits
+#include <type_traits> // conditional
+
+namespace nlohmann
+{
+namespace detail
+{
+
+/*!
+@brief implements the Grisu2 algorithm for binary to decimal floating-point
+conversion.
+
+This implementation is a slightly modified version of the reference
+implementation which may be obtained from
+http://florian.loitsch.com/publications (bench.tar.gz).
+
+The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
+
+For a detailed description of the algorithm see:
+
+[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
+ Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
+ Language Design and Implementation, PLDI 2010
+[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
+ Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
+ Design and Implementation, PLDI 1996
+*/
+namespace dtoa_impl
+{
+
+template <typename Target, typename Source>
+Target reinterpret_bits(const Source source)
+{
+ static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
+
+ Target target;
+ std::memcpy(&target, &source, sizeof(Source));
+ return target;
+}
+
+struct diyfp // f * 2^e
+{
+ static constexpr int kPrecision = 64; // = q
+
+ std::uint64_t f = 0;
+ int e = 0;
+
+ constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
+
+ /*!
+ @brief returns x - y
+ @pre x.e == y.e and x.f >= y.f
+ */
+ static diyfp sub(const diyfp& x, const diyfp& y) noexcept
+ {
+ assert(x.e == y.e);
+ assert(x.f >= y.f);
+
+ return {x.f - y.f, x.e};
+ }
+
+ /*!
+ @brief returns x * y
+ @note The result is rounded. (Only the upper q bits are returned.)
+ */
+ static diyfp mul(const diyfp& x, const diyfp& y) noexcept
+ {
+ static_assert(kPrecision == 64, "internal error");
+
+ // Computes:
+ // f = round((x.f * y.f) / 2^q)
+ // e = x.e + y.e + q
+
+ // Emulate the 64-bit * 64-bit multiplication:
+ //
+ // p = u * v
+ // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
+ // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
+ // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
+ // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
+ // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
+ // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
+ // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
+ //
+ // (Since Q might be larger than 2^32 - 1)
+ //
+ // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
+ //
+ // (Q_hi + H does not overflow a 64-bit int)
+ //
+ // = p_lo + 2^64 p_hi
+
+ const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
+ const std::uint64_t u_hi = x.f >> 32u;
+ const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
+ const std::uint64_t v_hi = y.f >> 32u;
+
+ const std::uint64_t p0 = u_lo * v_lo;
+ const std::uint64_t p1 = u_lo * v_hi;
+ const std::uint64_t p2 = u_hi * v_lo;
+ const std::uint64_t p3 = u_hi * v_hi;
+
+ const std::uint64_t p0_hi = p0 >> 32u;
+ const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
+ const std::uint64_t p1_hi = p1 >> 32u;
+ const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
+ const std::uint64_t p2_hi = p2 >> 32u;
+
+ std::uint64_t Q = p0_hi + p1_lo + p2_lo;
+
+ // The full product might now be computed as
+ //
+ // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
+ // p_lo = p0_lo + (Q << 32)
+ //
+ // But in this particular case here, the full p_lo is not required.
+ // Effectively we only need to add the highest bit in p_lo to p_hi (and
+ // Q_hi + 1 does not overflow).
+
+ Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
+
+ const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
+
+ return {h, x.e + y.e + 64};
+ }
+
+ /*!
+ @brief normalize x such that the significand is >= 2^(q-1)
+ @pre x.f != 0
+ */
+ static diyfp normalize(diyfp x) noexcept
+ {
+ assert(x.f != 0);
+
+ while ((x.f >> 63u) == 0)
+ {
+ x.f <<= 1u;
+ x.e--;
+ }
+
+ return x;
+ }
+
+ /*!
+ @brief normalize x such that the result has the exponent E
+ @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
+ */
+ static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
+ {
+ const int delta = x.e - target_exponent;
+
+ assert(delta >= 0);
+ assert(((x.f << delta) >> delta) == x.f);
+
+ return {x.f << delta, target_exponent};
+ }
+};
+
+struct boundaries
+{
+ diyfp w;
+ diyfp minus;
+ diyfp plus;
+};
+
+/*!
+Compute the (normalized) diyfp representing the input number 'value' and its
+boundaries.
+
+@pre value must be finite and positive
+*/
+template <typename FloatType>
+boundaries compute_boundaries(FloatType value)
+{
+ assert(std::isfinite(value));
+ assert(value > 0);
+
+ // Convert the IEEE representation into a diyfp.
+ //
+ // If v is denormal:
+ // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
+ // If v is normalized:
+ // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
+
+ static_assert(std::numeric_limits<FloatType>::is_iec559,
+ "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
+
+ constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
+ constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
+ constexpr int kMinExp = 1 - kBias;
+ constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
+
+ using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
+
+ const std::uint64_t bits = reinterpret_bits<bits_type>(value);
+ const std::uint64_t E = bits >> (kPrecision - 1);
+ const std::uint64_t F = bits & (kHiddenBit - 1);
+
+ const bool is_denormal = E == 0;
+ const diyfp v = is_denormal
+ ? diyfp(F, kMinExp)
+ : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
+
+ // Compute the boundaries m- and m+ of the floating-point value
+ // v = f * 2^e.
+ //
+ // Determine v- and v+, the floating-point predecessor and successor if v,
+ // respectively.
+ //
+ // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
+ // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
+ //
+ // v+ = v + 2^e
+ //
+ // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
+ // between m- and m+ round to v, regardless of how the input rounding
+ // algorithm breaks ties.
+ //
+ // ---+-------------+-------------+-------------+-------------+--- (A)
+ // v- m- v m+ v+
+ //
+ // -----------------+------+------+-------------+-------------+--- (B)
+ // v- m- v m+ v+
+
+ const bool lower_boundary_is_closer = F == 0 and E > 1;
+ const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
+ const diyfp m_minus = lower_boundary_is_closer
+ ? diyfp(4 * v.f - 1, v.e - 2) // (B)
+ : diyfp(2 * v.f - 1, v.e - 1); // (A)
+
+ // Determine the normalized w+ = m+.
+ const diyfp w_plus = diyfp::normalize(m_plus);
+
+ // Determine w- = m- such that e_(w-) = e_(w+).
+ const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
+
+ return {diyfp::normalize(v), w_minus, w_plus};
+}
+
+// Given normalized diyfp w, Grisu needs to find a (normalized) cached
+// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
+// within a certain range [alpha, gamma] (Definition 3.2 from [1])
+//
+// alpha <= e = e_c + e_w + q <= gamma
+//
+// or
+//
+// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
+// <= f_c * f_w * 2^gamma
+//
+// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
+//
+// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
+//
+// or
+//
+// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
+//
+// The choice of (alpha,gamma) determines the size of the table and the form of
+// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
+// in practice:
+//
+// The idea is to cut the number c * w = f * 2^e into two parts, which can be
+// processed independently: An integral part p1, and a fractional part p2:
+//
+// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
+// = (f div 2^-e) + (f mod 2^-e) * 2^e
+// = p1 + p2 * 2^e
+//
+// The conversion of p1 into decimal form requires a series of divisions and
+// modulos by (a power of) 10. These operations are faster for 32-bit than for
+// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
+// achieved by choosing
+//
+// -e >= 32 or e <= -32 := gamma
+//
+// In order to convert the fractional part
+//
+// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
+//
+// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
+// d[-i] are extracted in order:
+//
+// (10 * p2) div 2^-e = d[-1]
+// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
+//
+// The multiplication by 10 must not overflow. It is sufficient to choose
+//
+// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
+//
+// Since p2 = f mod 2^-e < 2^-e,
+//
+// -e <= 60 or e >= -60 := alpha
+
+constexpr int kAlpha = -60;
+constexpr int kGamma = -32;
+
+struct cached_power // c = f * 2^e ~= 10^k
+{
+ std::uint64_t f;
+ int e;
+ int k;
+};
+
+/*!
+For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
+power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
+satisfies (Definition 3.2 from [1])
+
+ alpha <= e_c + e + q <= gamma.
+*/
+inline cached_power get_cached_power_for_binary_exponent(int e)
+{
+ // Now
+ //
+ // alpha <= e_c + e + q <= gamma (1)
+ // ==> f_c * 2^alpha <= c * 2^e * 2^q
+ //
+ // and since the c's are normalized, 2^(q-1) <= f_c,
+ //
+ // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
+ // ==> 2^(alpha - e - 1) <= c
+ //
+ // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
+ //
+ // k = ceil( log_10( 2^(alpha - e - 1) ) )
+ // = ceil( (alpha - e - 1) * log_10(2) )
+ //
+ // From the paper:
+ // "In theory the result of the procedure could be wrong since c is rounded,
+ // and the computation itself is approximated [...]. In practice, however,
+ // this simple function is sufficient."
+ //
+ // For IEEE double precision floating-point numbers converted into
+ // normalized diyfp's w = f * 2^e, with q = 64,
+ //
+ // e >= -1022 (min IEEE exponent)
+ // -52 (p - 1)
+ // -52 (p - 1, possibly normalize denormal IEEE numbers)
+ // -11 (normalize the diyfp)
+ // = -1137
+ //
+ // and
+ //
+ // e <= +1023 (max IEEE exponent)
+ // -52 (p - 1)
+ // -11 (normalize the diyfp)
+ // = 960
+ //
+ // This binary exponent range [-1137,960] results in a decimal exponent
+ // range [-307,324]. One does not need to store a cached power for each
+ // k in this range. For each such k it suffices to find a cached power
+ // such that the exponent of the product lies in [alpha,gamma].
+ // This implies that the difference of the decimal exponents of adjacent
+ // table entries must be less than or equal to
+ //
+ // floor( (gamma - alpha) * log_10(2) ) = 8.
+ //
+ // (A smaller distance gamma-alpha would require a larger table.)
+
+ // NB:
+ // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
+
+ constexpr int kCachedPowersMinDecExp = -300;
+ constexpr int kCachedPowersDecStep = 8;
+
+ static constexpr std::array<cached_power, 79> kCachedPowers =
+ {
+ {
+ { 0xAB70FE17C79AC6CA, -1060, -300 },
+ { 0xFF77B1FCBEBCDC4F, -1034, -292 },
+ { 0xBE5691EF416BD60C, -1007, -284 },
+ { 0x8DD01FAD907FFC3C, -980, -276 },
+ { 0xD3515C2831559A83, -954, -268 },
+ { 0x9D71AC8FADA6C9B5, -927, -260 },
+ { 0xEA9C227723EE8BCB, -901, -252 },
+ { 0xAECC49914078536D, -874, -244 },
+ { 0x823C12795DB6CE57, -847, -236 },
+ { 0xC21094364DFB5637, -821, -228 },
+ { 0x9096EA6F3848984F, -794, -220 },
+ { 0xD77485CB25823AC7, -768, -212 },
+ { 0xA086CFCD97BF97F4, -741, -204 },
+ { 0xEF340A98172AACE5, -715, -196 },
+ { 0xB23867FB2A35B28E, -688, -188 },
+ { 0x84C8D4DFD2C63F3B, -661, -180 },
+ { 0xC5DD44271AD3CDBA, -635, -172 },
+ { 0x936B9FCEBB25C996, -608, -164 },
+ { 0xDBAC6C247D62A584, -582, -156 },
+ { 0xA3AB66580D5FDAF6, -555, -148 },
+ { 0xF3E2F893DEC3F126, -529, -140 },
+ { 0xB5B5ADA8AAFF80B8, -502, -132 },
+ { 0x87625F056C7C4A8B, -475, -124 },
+ { 0xC9BCFF6034C13053, -449, -116 },
+ { 0x964E858C91BA2655, -422, -108 },
+ { 0xDFF9772470297EBD, -396, -100 },
+ { 0xA6DFBD9FB8E5B88F, -369, -92 },
+ { 0xF8A95FCF88747D94, -343, -84 },
+ { 0xB94470938FA89BCF, -316, -76 },
+ { 0x8A08F0F8BF0F156B, -289, -68 },
+ { 0xCDB02555653131B6, -263, -60 },
+ { 0x993FE2C6D07B7FAC, -236, -52 },
+ { 0xE45C10C42A2B3B06, -210, -44 },
+ { 0xAA242499697392D3, -183, -36 },
+ { 0xFD87B5F28300CA0E, -157, -28 },
+ { 0xBCE5086492111AEB, -130, -20 },
+ { 0x8CBCCC096F5088CC, -103, -12 },
+ { 0xD1B71758E219652C, -77, -4 },
+ { 0x9C40000000000000, -50, 4 },
+ { 0xE8D4A51000000000, -24, 12 },
+ { 0xAD78EBC5AC620000, 3, 20 },
+ { 0x813F3978F8940984, 30, 28 },
+ { 0xC097CE7BC90715B3, 56, 36 },
+ { 0x8F7E32CE7BEA5C70, 83, 44 },
+ { 0xD5D238A4ABE98068, 109, 52 },
+ { 0x9F4F2726179A2245, 136, 60 },
+ { 0xED63A231D4C4FB27, 162, 68 },
+ { 0xB0DE65388CC8ADA8, 189, 76 },
+ { 0x83C7088E1AAB65DB, 216, 84 },
+ { 0xC45D1DF942711D9A, 242, 92 },
+ { 0x924D692CA61BE758, 269, 100 },
+ { 0xDA01EE641A708DEA, 295, 108 },
+ { 0xA26DA3999AEF774A, 322, 116 },
+ { 0xF209787BB47D6B85, 348, 124 },
+ { 0xB454E4A179DD1877, 375, 132 },
+ { 0x865B86925B9BC5C2, 402, 140 },
+ { 0xC83553C5C8965D3D, 428, 148 },
+ { 0x952AB45CFA97A0B3, 455, 156 },
+ { 0xDE469FBD99A05FE3, 481, 164 },
+ { 0xA59BC234DB398C25, 508, 172 },
+ { 0xF6C69A72A3989F5C, 534, 180 },
+ { 0xB7DCBF5354E9BECE, 561, 188 },
+ { 0x88FCF317F22241E2, 588, 196 },
+ { 0xCC20CE9BD35C78A5, 614, 204 },
+ { 0x98165AF37B2153DF, 641, 212 },
+ { 0xE2A0B5DC971F303A, 667, 220 },
+ { 0xA8D9D1535CE3B396, 694, 228 },
+ { 0xFB9B7CD9A4A7443C, 720, 236 },
+ { 0xBB764C4CA7A44410, 747, 244 },
+ { 0x8BAB8EEFB6409C1A, 774, 252 },
+ { 0xD01FEF10A657842C, 800, 260 },
+ { 0x9B10A4E5E9913129, 827, 268 },
+ { 0xE7109BFBA19C0C9D, 853, 276 },
+ { 0xAC2820D9623BF429, 880, 284 },
+ { 0x80444B5E7AA7CF85, 907, 292 },
+ { 0xBF21E44003ACDD2D, 933, 300 },
+ { 0x8E679C2F5E44FF8F, 960, 308 },
+ { 0xD433179D9C8CB841, 986, 316 },
+ { 0x9E19DB92B4E31BA9, 1013, 324 },
+ }
+ };
+
+ // This computation gives exactly the same results for k as
+ // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
+ // for |e| <= 1500, but doesn't require floating-point operations.
+ // NB: log_10(2) ~= 78913 / 2^18
+ assert(e >= -1500);
+ assert(e <= 1500);
+ const int f = kAlpha - e - 1;
+ const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
+
+ const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
+ assert(index >= 0);
+ assert(static_cast<std::size_t>(index) < kCachedPowers.size());
+
+ const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
+ assert(kAlpha <= cached.e + e + 64);
+ assert(kGamma >= cached.e + e + 64);
+
+ return cached;
+}
+
+/*!
+For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
+For n == 0, returns 1 and sets pow10 := 1.
+*/
+inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
+{
+ // LCOV_EXCL_START
+ if (n >= 1000000000)
+ {
+ pow10 = 1000000000;
+ return 10;
+ }
+ // LCOV_EXCL_STOP
+ else if (n >= 100000000)
+ {
+ pow10 = 100000000;
+ return 9;
+ }
+ else if (n >= 10000000)
+ {
+ pow10 = 10000000;
+ return 8;
+ }
+ else if (n >= 1000000)
+ {
+ pow10 = 1000000;
+ return 7;
+ }
+ else if (n >= 100000)
+ {
+ pow10 = 100000;
+ return 6;
+ }
+ else if (n >= 10000)
+ {
+ pow10 = 10000;
+ return 5;
+ }
+ else if (n >= 1000)
+ {
+ pow10 = 1000;
+ return 4;
+ }
+ else if (n >= 100)
+ {
+ pow10 = 100;
+ return 3;
+ }
+ else if (n >= 10)
+ {
+ pow10 = 10;
+ return 2;
+ }
+ else
+ {
+ pow10 = 1;
+ return 1;
+ }
+}
+
+inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
+ std::uint64_t rest, std::uint64_t ten_k)
+{
+ assert(len >= 1);
+ assert(dist <= delta);
+ assert(rest <= delta);
+ assert(ten_k > 0);
+
+ // <--------------------------- delta ---->
+ // <---- dist --------->
+ // --------------[------------------+-------------------]--------------
+ // M- w M+
+ //
+ // ten_k
+ // <------>
+ // <---- rest ---->
+ // --------------[------------------+----+--------------]--------------
+ // w V
+ // = buf * 10^k
+ //
+ // ten_k represents a unit-in-the-last-place in the decimal representation
+ // stored in buf.
+ // Decrement buf by ten_k while this takes buf closer to w.
+
+ // The tests are written in this order to avoid overflow in unsigned
+ // integer arithmetic.
+
+ while (rest < dist
+ and delta - rest >= ten_k
+ and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
+ {
+ assert(buf[len - 1] != '0');
+ buf[len - 1]--;
+ rest += ten_k;
+ }
+}
+
+/*!
+Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
+M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
+*/
+inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
+ diyfp M_minus, diyfp w, diyfp M_plus)
+{
+ static_assert(kAlpha >= -60, "internal error");
+ static_assert(kGamma <= -32, "internal error");
+
+ // Generates the digits (and the exponent) of a decimal floating-point
+ // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
+ // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
+ //
+ // <--------------------------- delta ---->
+ // <---- dist --------->
+ // --------------[------------------+-------------------]--------------
+ // M- w M+
+ //
+ // Grisu2 generates the digits of M+ from left to right and stops as soon as
+ // V is in [M-,M+].
+
+ assert(M_plus.e >= kAlpha);
+ assert(M_plus.e <= kGamma);
+
+ std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
+ std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
+
+ // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
+ //
+ // M+ = f * 2^e
+ // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
+ // = ((p1 ) * 2^-e + (p2 )) * 2^e
+ // = p1 + p2 * 2^e
+
+ const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
+
+ auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
+ std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
+
+ // 1)
+ //
+ // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
+
+ assert(p1 > 0);
+
+ std::uint32_t pow10;
+ const int k = find_largest_pow10(p1, pow10);
+
+ // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
+ //
+ // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
+ // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
+ //
+ // M+ = p1 + p2 * 2^e
+ // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
+ // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
+ // = d[k-1] * 10^(k-1) + ( rest) * 2^e
+ //
+ // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
+ //
+ // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
+ //
+ // but stop as soon as
+ //
+ // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
+
+ int n = k;
+ while (n > 0)
+ {
+ // Invariants:
+ // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
+ // pow10 = 10^(n-1) <= p1 < 10^n
+ //
+ const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
+ const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
+ //
+ // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
+ // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
+ //
+ assert(d <= 9);
+ buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
+ //
+ // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
+ //
+ p1 = r;
+ n--;
+ //
+ // M+ = buffer * 10^n + (p1 + p2 * 2^e)
+ // pow10 = 10^n
+ //
+
+ // Now check if enough digits have been generated.
+ // Compute
+ //
+ // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
+ //
+ // Note:
+ // Since rest and delta share the same exponent e, it suffices to
+ // compare the significands.
+ const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
+ if (rest <= delta)
+ {
+ // V = buffer * 10^n, with M- <= V <= M+.
+
+ decimal_exponent += n;
+
+ // We may now just stop. But instead look if the buffer could be
+ // decremented to bring V closer to w.
+ //
+ // pow10 = 10^n is now 1 ulp in the decimal representation V.
+ // The rounding procedure works with diyfp's with an implicit
+ // exponent of e.
+ //
+ // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
+ //
+ const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
+ grisu2_round(buffer, length, dist, delta, rest, ten_n);
+
+ return;
+ }
+
+ pow10 /= 10;
+ //
+ // pow10 = 10^(n-1) <= p1 < 10^n
+ // Invariants restored.
+ }
+
+ // 2)
+ //
+ // The digits of the integral part have been generated:
+ //
+ // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
+ // = buffer + p2 * 2^e
+ //
+ // Now generate the digits of the fractional part p2 * 2^e.
+ //
+ // Note:
+ // No decimal point is generated: the exponent is adjusted instead.
+ //
+ // p2 actually represents the fraction
+ //
+ // p2 * 2^e
+ // = p2 / 2^-e
+ // = d[-1] / 10^1 + d[-2] / 10^2 + ...
+ //
+ // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
+ //
+ // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
+ // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
+ //
+ // using
+ //
+ // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
+ // = ( d) * 2^-e + ( r)
+ //
+ // or
+ // 10^m * p2 * 2^e = d + r * 2^e
+ //
+ // i.e.
+ //
+ // M+ = buffer + p2 * 2^e
+ // = buffer + 10^-m * (d + r * 2^e)
+ // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
+ //
+ // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
+
+ assert(p2 > delta);
+
+ int m = 0;
+ for (;;)
+ {
+ // Invariant:
+ // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
+ // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
+ // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
+ // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
+ //
+ assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
+ p2 *= 10;
+ const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
+ const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
+ //
+ // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
+ // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
+ // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
+ //
+ assert(d <= 9);
+ buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
+ //
+ // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
+ //
+ p2 = r;
+ m++;
+ //
+ // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
+ // Invariant restored.
+
+ // Check if enough digits have been generated.
+ //
+ // 10^-m * p2 * 2^e <= delta * 2^e
+ // p2 * 2^e <= 10^m * delta * 2^e
+ // p2 <= 10^m * delta
+ delta *= 10;
+ dist *= 10;
+ if (p2 <= delta)
+ {
+ break;
+ }
+ }
+
+ // V = buffer * 10^-m, with M- <= V <= M+.
+
+ decimal_exponent -= m;
+
+ // 1 ulp in the decimal representation is now 10^-m.
+ // Since delta and dist are now scaled by 10^m, we need to do the
+ // same with ulp in order to keep the units in sync.
+ //
+ // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
+ //
+ const std::uint64_t ten_m = one.f;
+ grisu2_round(buffer, length, dist, delta, p2, ten_m);
+
+ // By construction this algorithm generates the shortest possible decimal
+ // number (Loitsch, Theorem 6.2) which rounds back to w.
+ // For an input number of precision p, at least
+ //
+ // N = 1 + ceil(p * log_10(2))
+ //
+ // decimal digits are sufficient to identify all binary floating-point
+ // numbers (Matula, "In-and-Out conversions").
+ // This implies that the algorithm does not produce more than N decimal
+ // digits.
+ //
+ // N = 17 for p = 53 (IEEE double precision)
+ // N = 9 for p = 24 (IEEE single precision)
+}
+
+/*!
+v = buf * 10^decimal_exponent
+len is the length of the buffer (number of decimal digits)
+The buffer must be large enough, i.e. >= max_digits10.
+*/
+inline void grisu2(char* buf, int& len, int& decimal_exponent,
+ diyfp m_minus, diyfp v, diyfp m_plus)
+{
+ assert(m_plus.e == m_minus.e);
+ assert(m_plus.e == v.e);
+
+ // --------(-----------------------+-----------------------)-------- (A)
+ // m- v m+
+ //
+ // --------------------(-----------+-----------------------)-------- (B)
+ // m- v m+
+ //
+ // First scale v (and m- and m+) such that the exponent is in the range
+ // [alpha, gamma].
+
+ const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
+
+ const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
+
+ // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
+ const diyfp w = diyfp::mul(v, c_minus_k);
+ const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
+ const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
+
+ // ----(---+---)---------------(---+---)---------------(---+---)----
+ // w- w w+
+ // = c*m- = c*v = c*m+
+ //
+ // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
+ // w+ are now off by a small amount.
+ // In fact:
+ //
+ // w - v * 10^k < 1 ulp
+ //
+ // To account for this inaccuracy, add resp. subtract 1 ulp.
+ //
+ // --------+---[---------------(---+---)---------------]---+--------
+ // w- M- w M+ w+
+ //
+ // Now any number in [M-, M+] (bounds included) will round to w when input,
+ // regardless of how the input rounding algorithm breaks ties.
+ //
+ // And digit_gen generates the shortest possible such number in [M-, M+].
+ // Note that this does not mean that Grisu2 always generates the shortest
+ // possible number in the interval (m-, m+).
+ const diyfp M_minus(w_minus.f + 1, w_minus.e);
+ const diyfp M_plus (w_plus.f - 1, w_plus.e );
+
+ decimal_exponent = -cached.k; // = -(-k) = k
+
+ grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
+}
+
+/*!
+v = buf * 10^decimal_exponent
+len is the length of the buffer (number of decimal digits)
+The buffer must be large enough, i.e. >= max_digits10.
+*/
+template <typename FloatType>
+void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
+{
+ static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
+ "internal error: not enough precision");
+
+ assert(std::isfinite(value));
+ assert(value > 0);
+
+ // If the neighbors (and boundaries) of 'value' are always computed for double-precision
+ // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
+ // decimal representations are not exactly "short".
+ //
+ // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
+ // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
+ // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
+ // does.
+ // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
+ // representation using the corresponding std::from_chars function recovers value exactly". That
+ // indicates that single precision floating-point numbers should be recovered using
+ // 'std::strtof'.
+ //
+ // NB: If the neighbors are computed for single-precision numbers, there is a single float
+ // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
+ // value is off by 1 ulp.
+#if 0
+ const boundaries w = compute_boundaries(static_cast<double>(value));
+#else
+ const boundaries w = compute_boundaries(value);
+#endif
+
+ grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
+}
+
+/*!
+@brief appends a decimal representation of e to buf
+@return a pointer to the element following the exponent.
+@pre -1000 < e < 1000
+*/
+inline char* append_exponent(char* buf, int e)
+{
+ assert(e > -1000);
+ assert(e < 1000);
+
+ if (e < 0)
+ {
+ e = -e;
+ *buf++ = '-';
+ }
+ else
+ {
+ *buf++ = '+';
+ }
+
+ auto k = static_cast<std::uint32_t>(e);
+ if (k < 10)
+ {
+ // Always print at least two digits in the exponent.
+ // This is for compatibility with printf("%g").
+ *buf++ = '0';
+ *buf++ = static_cast<char>('0' + k);
+ }
+ else if (k < 100)
+ {
+ *buf++ = static_cast<char>('0' + k / 10);
+ k %= 10;
+ *buf++ = static_cast<char>('0' + k);
+ }
+ else
+ {
+ *buf++ = static_cast<char>('0' + k / 100);
+ k %= 100;
+ *buf++ = static_cast<char>('0' + k / 10);
+ k %= 10;
+ *buf++ = static_cast<char>('0' + k);
+ }
+
+ return buf;
+}
+
+/*!
+@brief prettify v = buf * 10^decimal_exponent
+
+If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
+notation. Otherwise it will be printed in exponential notation.
+
+@pre min_exp < 0
+@pre max_exp > 0
+*/
+inline char* format_buffer(char* buf, int len, int decimal_exponent,
+ int min_exp, int max_exp)
+{
+ assert(min_exp < 0);
+ assert(max_exp > 0);
+
+ const int k = len;
+ const int n = len + decimal_exponent;
+
+ // v = buf * 10^(n-k)
+ // k is the length of the buffer (number of decimal digits)
+ // n is the position of the decimal point relative to the start of the buffer.
+
+ if (k <= n and n <= max_exp)
+ {
+ // digits[000]
+ // len <= max_exp + 2
+
+ std::memset(buf + k, '0', static_cast<size_t>(n - k));
+ // Make it look like a floating-point number (#362, #378)
+ buf[n + 0] = '.';
+ buf[n + 1] = '0';
+ return buf + (n + 2);
+ }
+
+ if (0 < n and n <= max_exp)
+ {
+ // dig.its
+ // len <= max_digits10 + 1
+
+ assert(k > n);
+
+ std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
+ buf[n] = '.';
+ return buf + (k + 1);
+ }
+
+ if (min_exp < n and n <= 0)
+ {
+ // 0.[000]digits
+ // len <= 2 + (-min_exp - 1) + max_digits10
+
+ std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
+ buf[0] = '0';
+ buf[1] = '.';
+ std::memset(buf + 2, '0', static_cast<size_t>(-n));
+ return buf + (2 + (-n) + k);
+ }
+
+ if (k == 1)
+ {
+ // dE+123
+ // len <= 1 + 5
+
+ buf += 1;
+ }
+ else
+ {
+ // d.igitsE+123
+ // len <= max_digits10 + 1 + 5
+
+ std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
+ buf[1] = '.';
+ buf += 1 + k;
+ }
+
+ *buf++ = 'e';
+ return append_exponent(buf, n - 1);
+}
+
+} // namespace dtoa_impl
+
+/*!
+@brief generates a decimal representation of the floating-point number value in [first, last).
+
+The format of the resulting decimal representation is similar to printf's %g
+format. Returns an iterator pointing past-the-end of the decimal representation.
+
+@note The input number must be finite, i.e. NaN's and Inf's are not supported.
+@note The buffer must be large enough.
+@note The result is NOT null-terminated.
+*/
+template <typename FloatType>
+char* to_chars(char* first, const char* last, FloatType value)
+{
+ static_cast<void>(last); // maybe unused - fix warning
+ assert(std::isfinite(value));
+
+ // Use signbit(value) instead of (value < 0) since signbit works for -0.
+ if (std::signbit(value))
+ {
+ value = -value;
+ *first++ = '-';
+ }
+
+ if (value == 0) // +-0
+ {
+ *first++ = '0';
+ // Make it look like a floating-point number (#362, #378)
+ *first++ = '.';
+ *first++ = '0';
+ return first;
+ }
+
+ assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
+
+ // Compute v = buffer * 10^decimal_exponent.
+ // The decimal digits are stored in the buffer, which needs to be interpreted
+ // as an unsigned decimal integer.
+ // len is the length of the buffer, i.e. the number of decimal digits.
+ int len = 0;
+ int decimal_exponent = 0;
+ dtoa_impl::grisu2(first, len, decimal_exponent, value);
+
+ assert(len <= std::numeric_limits<FloatType>::max_digits10);
+
+ // Format the buffer like printf("%.*g", prec, value)
+ constexpr int kMinExp = -4;
+ // Use digits10 here to increase compatibility with version 2.
+ constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
+
+ assert(last - first >= kMaxExp + 2);
+ assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
+ assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
+
+ return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
+}
+
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/exceptions.hpp>
+
+// #include <nlohmann/detail/macro_scope.hpp>
+
+// #include <nlohmann/detail/meta/cpp_future.hpp>
+
+// #include <nlohmann/detail/output/binary_writer.hpp>
+
+// #include <nlohmann/detail/output/output_adapters.hpp>
+
+// #include <nlohmann/detail/value_t.hpp>
+
+
+namespace nlohmann
+{
+namespace detail
+{
+///////////////////
+// serialization //
+///////////////////
+
+/// how to treat decoding errors
+enum class error_handler_t
+{
+ strict, ///< throw a type_error exception in case of invalid UTF-8
+ replace, ///< replace invalid UTF-8 sequences with U+FFFD
+ ignore ///< ignore invalid UTF-8 sequences
+};
+
+template<typename BasicJsonType>
+class serializer
+{
+ using string_t = typename BasicJsonType::string_t;
+ using number_float_t = typename BasicJsonType::number_float_t;
+ using number_integer_t = typename BasicJsonType::number_integer_t;
+ using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ static constexpr std::uint8_t UTF8_ACCEPT = 0;
+ static constexpr std::uint8_t UTF8_REJECT = 1;
+
+ public:
+ /*!
+ @param[in] s output stream to serialize to
+ @param[in] ichar indentation character to use
+ @param[in] error_handler_ how to react on decoding errors
+ */
+ serializer(output_adapter_t<char> s, const char ichar,
+ error_handler_t error_handler_ = error_handler_t::strict)
+ : o(std::move(s))
+ , loc(std::localeconv())
+ , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
+ , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
+ , indent_char(ichar)
+ , indent_string(512, indent_char)
+ , error_handler(error_handler_)
+ {}
+
+ // delete because of pointer members
+ serializer(const serializer&) = delete;
+ serializer& operator=(const serializer&) = delete;
+ serializer(serializer&&) = delete;
+ serializer& operator=(serializer&&) = delete;
+ ~serializer() = default;
+
+ /*!
+ @brief internal implementation of the serialization function
+
+ This function is called by the public member function dump and organizes
+ the serialization internally. The indentation level is propagated as
+ additional parameter. In case of arrays and objects, the function is
+ called recursively.
+
+ - strings and object keys are escaped using `escape_string()`
+ - integer numbers are converted implicitly via `operator<<`
+ - floating-point numbers are converted to a string using `"%g"` format
+
+ @param[in] val value to serialize
+ @param[in] pretty_print whether the output shall be pretty-printed
+ @param[in] indent_step the indent level
+ @param[in] current_indent the current indent level (only used internally)
+ */
+ void dump(const BasicJsonType& val, const bool pretty_print,
+ const bool ensure_ascii,
+ const unsigned int indent_step,
+ const unsigned int current_indent = 0)
+ {
+ switch (val.m_type)
+ {
+ case value_t::object:
+ {
+ if (val.m_value.object->empty())
+ {
+ o->write_characters("{}", 2);
+ return;
+ }
+
+ if (pretty_print)
+ {
+ o->write_characters("{\n", 2);
+
+ // variable to hold indentation for recursive calls
+ const auto new_indent = current_indent + indent_step;
+ if (JSON_UNLIKELY(indent_string.size() < new_indent))
+ {
+ indent_string.resize(indent_string.size() * 2, ' ');
+ }
+
+ // first n-1 elements
+ auto i = val.m_value.object->cbegin();
+ for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
+ {
+ o->write_characters(indent_string.c_str(), new_indent);
+ o->write_character('\"');
+ dump_escaped(i->first, ensure_ascii);
+ o->write_characters("\": ", 3);
+ dump(i->second, true, ensure_ascii, indent_step, new_indent);
+ o->write_characters(",\n", 2);
+ }
+
+ // last element
+ assert(i != val.m_value.object->cend());
+ assert(std::next(i) == val.m_value.object->cend());
+ o->write_characters(indent_string.c_str(), new_indent);
+ o->write_character('\"');
+ dump_escaped(i->first, ensure_ascii);
+ o->write_characters("\": ", 3);
+ dump(i->second, true, ensure_ascii, indent_step, new_indent);
+
+ o->write_character('\n');
+ o->write_characters(indent_string.c_str(), current_indent);
+ o->write_character('}');
+ }
+ else
+ {
+ o->write_character('{');
+
+ // first n-1 elements
+ auto i = val.m_value.object->cbegin();
+ for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
+ {
+ o->write_character('\"');
+ dump_escaped(i->first, ensure_ascii);
+ o->write_characters("\":", 2);
+ dump(i->second, false, ensure_ascii, indent_step, current_indent);
+ o->write_character(',');
+ }
+
+ // last element
+ assert(i != val.m_value.object->cend());
+ assert(std::next(i) == val.m_value.object->cend());
+ o->write_character('\"');
+ dump_escaped(i->first, ensure_ascii);
+ o->write_characters("\":", 2);
+ dump(i->second, false, ensure_ascii, indent_step, current_indent);
+
+ o->write_character('}');
+ }
+
+ return;
+ }
+
+ case value_t::array:
+ {
+ if (val.m_value.array->empty())
+ {
+ o->write_characters("[]", 2);
+ return;
+ }
+
+ if (pretty_print)
+ {
+ o->write_characters("[\n", 2);
+
+ // variable to hold indentation for recursive calls
+ const auto new_indent = current_indent + indent_step;
+ if (JSON_UNLIKELY(indent_string.size() < new_indent))
+ {
+ indent_string.resize(indent_string.size() * 2, ' ');
+ }
+
+ // first n-1 elements
+ for (auto i = val.m_value.array->cbegin();
+ i != val.m_value.array->cend() - 1; ++i)
+ {
+ o->write_characters(indent_string.c_str(), new_indent);
+ dump(*i, true, ensure_ascii, indent_step, new_indent);
+ o->write_characters(",\n", 2);
+ }
+
+ // last element
+ assert(not val.m_value.array->empty());
+ o->write_characters(indent_string.c_str(), new_indent);
+ dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
+
+ o->write_character('\n');
+ o->write_characters(indent_string.c_str(), current_indent);
+ o->write_character(']');
+ }
+ else
+ {
+ o->write_character('[');
+
+ // first n-1 elements
+ for (auto i = val.m_value.array->cbegin();
+ i != val.m_value.array->cend() - 1; ++i)
+ {
+ dump(*i, false, ensure_ascii, indent_step, current_indent);
+ o->write_character(',');
+ }
+
+ // last element
+ assert(not val.m_value.array->empty());
+ dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
+
+ o->write_character(']');
+ }
+
+ return;
+ }
+
+ case value_t::string:
+ {
+ o->write_character('\"');
+ dump_escaped(*val.m_value.string, ensure_ascii);
+ o->write_character('\"');
+ return;
+ }
+
+ case value_t::boolean:
+ {
+ if (val.m_value.boolean)
+ {
+ o->write_characters("true", 4);
+ }
+ else
+ {
+ o->write_characters("false", 5);
+ }
+ return;
+ }
+
+ case value_t::number_integer:
+ {
+ dump_integer(val.m_value.number_integer);
+ return;
+ }
+
+ case value_t::number_unsigned:
+ {
+ dump_integer(val.m_value.number_unsigned);
+ return;
+ }
+
+ case value_t::number_float:
+ {
+ dump_float(val.m_value.number_float);
+ return;
+ }
+
+ case value_t::discarded:
+ {
+ o->write_characters("<discarded>", 11);
+ return;
+ }
+
+ case value_t::null:
+ {
+ o->write_characters("null", 4);
+ return;
+ }
+
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+ }
+
+ private:
+ /*!
+ @brief dump escaped string
+
+ Escape a string by replacing certain special characters by a sequence of an
+ escape character (backslash) and another character and other control
+ characters by a sequence of "\u" followed by a four-digit hex
+ representation. The escaped string is written to output stream @a o.
+
+ @param[in] s the string to escape
+ @param[in] ensure_ascii whether to escape non-ASCII characters with
+ \uXXXX sequences
+
+ @complexity Linear in the length of string @a s.
+ */
+ void dump_escaped(const string_t& s, const bool ensure_ascii)
+ {
+ std::uint32_t codepoint;
+ std::uint8_t state = UTF8_ACCEPT;
+ std::size_t bytes = 0; // number of bytes written to string_buffer
+
+ // number of bytes written at the point of the last valid byte
+ std::size_t bytes_after_last_accept = 0;
+ std::size_t undumped_chars = 0;
+
+ for (std::size_t i = 0; i < s.size(); ++i)
+ {
+ const auto byte = static_cast<uint8_t>(s[i]);
+
+ switch (decode(state, codepoint, byte))
+ {
+ case UTF8_ACCEPT: // decode found a new code point
+ {
+ switch (codepoint)
+ {
+ case 0x08: // backspace
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = 'b';
+ break;
+ }
+
+ case 0x09: // horizontal tab
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = 't';
+ break;
+ }
+
+ case 0x0A: // newline
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = 'n';
+ break;
+ }
+
+ case 0x0C: // formfeed
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = 'f';
+ break;
+ }
+
+ case 0x0D: // carriage return
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = 'r';
+ break;
+ }
+
+ case 0x22: // quotation mark
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = '\"';
+ break;
+ }
+
+ case 0x5C: // reverse solidus
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = '\\';
+ break;
+ }
+
+ default:
+ {
+ // escape control characters (0x00..0x1F) or, if
+ // ensure_ascii parameter is used, non-ASCII characters
+ if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
+ {
+ if (codepoint <= 0xFFFF)
+ {
+ (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
+ static_cast<std::uint16_t>(codepoint));
+ bytes += 6;
+ }
+ else
+ {
+ (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
+ static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
+ static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
+ bytes += 12;
+ }
+ }
+ else
+ {
+ // copy byte to buffer (all previous bytes
+ // been copied have in default case above)
+ string_buffer[bytes++] = s[i];
+ }
+ break;
+ }
+ }
+
+ // write buffer and reset index; there must be 13 bytes
+ // left, as this is the maximal number of bytes to be
+ // written ("\uxxxx\uxxxx\0") for one code point
+ if (string_buffer.size() - bytes < 13)
+ {
+ o->write_characters(string_buffer.data(), bytes);
+ bytes = 0;
+ }
+
+ // remember the byte position of this accept
+ bytes_after_last_accept = bytes;
+ undumped_chars = 0;
+ break;
+ }
+
+ case UTF8_REJECT: // decode found invalid UTF-8 byte
+ {
+ switch (error_handler)
+ {
+ case error_handler_t::strict:
+ {
+ std::string sn(3, '\0');
+ (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
+ JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
+ }
+
+ case error_handler_t::ignore:
+ case error_handler_t::replace:
+ {
+ // in case we saw this character the first time, we
+ // would like to read it again, because the byte
+ // may be OK for itself, but just not OK for the
+ // previous sequence
+ if (undumped_chars > 0)
+ {
+ --i;
+ }
+
+ // reset length buffer to the last accepted index;
+ // thus removing/ignoring the invalid characters
+ bytes = bytes_after_last_accept;
+
+ if (error_handler == error_handler_t::replace)
+ {
+ // add a replacement character
+ if (ensure_ascii)
+ {
+ string_buffer[bytes++] = '\\';
+ string_buffer[bytes++] = 'u';
+ string_buffer[bytes++] = 'f';
+ string_buffer[bytes++] = 'f';
+ string_buffer[bytes++] = 'f';
+ string_buffer[bytes++] = 'd';
+ }
+ else
+ {
+ string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
+ string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
+ string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
+ }
+
+ // write buffer and reset index; there must be 13 bytes
+ // left, as this is the maximal number of bytes to be
+ // written ("\uxxxx\uxxxx\0") for one code point
+ if (string_buffer.size() - bytes < 13)
+ {
+ o->write_characters(string_buffer.data(), bytes);
+ bytes = 0;
+ }
+
+ bytes_after_last_accept = bytes;
+ }
+
+ undumped_chars = 0;
+
+ // continue processing the string
+ state = UTF8_ACCEPT;
+ break;
+ }
+
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+ break;
+ }
+
+ default: // decode found yet incomplete multi-byte code point
+ {
+ if (not ensure_ascii)
+ {
+ // code point will not be escaped - copy byte to buffer
+ string_buffer[bytes++] = s[i];
+ }
+ ++undumped_chars;
+ break;
+ }
+ }
+ }
+
+ // we finished processing the string
+ if (JSON_LIKELY(state == UTF8_ACCEPT))
+ {
+ // write buffer
+ if (bytes > 0)
+ {
+ o->write_characters(string_buffer.data(), bytes);
+ }
+ }
+ else
+ {
+ // we finish reading, but do not accept: string was incomplete
+ switch (error_handler)
+ {
+ case error_handler_t::strict:
+ {
+ std::string sn(3, '\0');
+ (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
+ JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
+ }
+
+ case error_handler_t::ignore:
+ {
+ // write all accepted bytes
+ o->write_characters(string_buffer.data(), bytes_after_last_accept);
+ break;
+ }
+
+ case error_handler_t::replace:
+ {
+ // write all accepted bytes
+ o->write_characters(string_buffer.data(), bytes_after_last_accept);
+ // add a replacement character
+ if (ensure_ascii)
+ {
+ o->write_characters("\\ufffd", 6);
+ }
+ else
+ {
+ o->write_characters("\xEF\xBF\xBD", 3);
+ }
+ break;
+ }
+
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+ }
+ }
+
+ /*!
+ @brief count digits
+
+ Count the number of decimal (base 10) digits for an input unsigned integer.
+
+ @param[in] x unsigned integer number to count its digits
+ @return number of decimal digits
+ */
+ inline unsigned int count_digits(number_unsigned_t x) noexcept
+ {
+ unsigned int n_digits = 1;
+ for (;;)
+ {
+ if (x < 10)
+ {
+ return n_digits;
+ }
+ if (x < 100)
+ {
+ return n_digits + 1;
+ }
+ if (x < 1000)
+ {
+ return n_digits + 2;
+ }
+ if (x < 10000)
+ {
+ return n_digits + 3;
+ }
+ x = x / 10000u;
+ n_digits += 4;
+ }
+ }
+
+ /*!
+ @brief dump an integer
+
+ Dump a given integer to output stream @a o. Works internally with
+ @a number_buffer.
+
+ @param[in] x integer number (signed or unsigned) to dump
+ @tparam NumberType either @a number_integer_t or @a number_unsigned_t
+ */
+ template<typename NumberType, detail::enable_if_t<
+ std::is_same<NumberType, number_unsigned_t>::value or
+ std::is_same<NumberType, number_integer_t>::value,
+ int> = 0>
+ void dump_integer(NumberType x)
+ {
+ static constexpr std::array<std::array<char, 2>, 100> digits_to_99
+ {
+ {
+ {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
+ {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
+ {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
+ {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
+ {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
+ {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
+ {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
+ {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
+ {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
+ {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
+ }
+ };
+
+ // special case for "0"
+ if (x == 0)
+ {
+ o->write_character('0');
+ return;
+ }
+
+ // use a pointer to fill the buffer
+ auto buffer_ptr = number_buffer.begin();
+
+ const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
+ number_unsigned_t abs_value;
+
+ unsigned int n_chars;
+
+ if (is_negative)
+ {
+ *buffer_ptr = '-';
+ abs_value = static_cast<number_unsigned_t>(std::abs(static_cast<std::intmax_t>(x)));
+
+ // account one more byte for the minus sign
+ n_chars = 1 + count_digits(abs_value);
+ }
+ else
+ {
+ abs_value = static_cast<number_unsigned_t>(x);
+ n_chars = count_digits(abs_value);
+ }
+
+ // spare 1 byte for '\0'
+ assert(n_chars < number_buffer.size() - 1);
+
+ // jump to the end to generate the string from backward
+ // so we later avoid reversing the result
+ buffer_ptr += n_chars;
+
+ // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
+ // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
+ while (abs_value >= 100)
+ {
+ const auto digits_index = static_cast<unsigned>((abs_value % 100));
+ abs_value /= 100;
+ *(--buffer_ptr) = digits_to_99[digits_index][1];
+ *(--buffer_ptr) = digits_to_99[digits_index][0];
+ }
+
+ if (abs_value >= 10)
+ {
+ const auto digits_index = static_cast<unsigned>(abs_value);
+ *(--buffer_ptr) = digits_to_99[digits_index][1];
+ *(--buffer_ptr) = digits_to_99[digits_index][0];
+ }
+ else
+ {
+ *(--buffer_ptr) = static_cast<char>('0' + abs_value);
+ }
+
+ o->write_characters(number_buffer.data(), n_chars);
+ }
+
+ /*!
+ @brief dump a floating-point number
+
+ Dump a given floating-point number to output stream @a o. Works internally
+ with @a number_buffer.
+
+ @param[in] x floating-point number to dump
+ */
+ void dump_float(number_float_t x)
+ {
+ // NaN / inf
+ if (not std::isfinite(x))
+ {
+ o->write_characters("null", 4);
+ return;
+ }
+
+ // If number_float_t is an IEEE-754 single or double precision number,
+ // use the Grisu2 algorithm to produce short numbers which are
+ // guaranteed to round-trip, using strtof and strtod, resp.
+ //
+ // NB: The test below works if <long double> == <double>.
+ static constexpr bool is_ieee_single_or_double
+ = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
+ (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
+
+ dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
+ }
+
+ void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
+ {
+ char* begin = number_buffer.data();
+ char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
+
+ o->write_characters(begin, static_cast<size_t>(end - begin));
+ }
+
+ void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
+ {
+ // get number of digits for a float -> text -> float round-trip
+ static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
+
+ // the actual conversion
+ std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
+
+ // negative value indicates an error
+ assert(len > 0);
+ // check if buffer was large enough
+ assert(static_cast<std::size_t>(len) < number_buffer.size());
+
+ // erase thousands separator
+ if (thousands_sep != '\0')
+ {
+ const auto end = std::remove(number_buffer.begin(),
+ number_buffer.begin() + len, thousands_sep);
+ std::fill(end, number_buffer.end(), '\0');
+ assert((end - number_buffer.begin()) <= len);
+ len = (end - number_buffer.begin());
+ }
+
+ // convert decimal point to '.'
+ if (decimal_point != '\0' and decimal_point != '.')
+ {
+ const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
+ if (dec_pos != number_buffer.end())
+ {
+ *dec_pos = '.';
+ }
+ }
+
+ o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
+
+ // determine if need to append ".0"
+ const bool value_is_int_like =
+ std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
+ [](char c)
+ {
+ return c == '.' or c == 'e';
+ });
+
+ if (value_is_int_like)
+ {
+ o->write_characters(".0", 2);
+ }
+ }
+
+ /*!
+ @brief check whether a string is UTF-8 encoded
+
+ The function checks each byte of a string whether it is UTF-8 encoded. The
+ result of the check is stored in the @a state parameter. The function must
+ be called initially with state 0 (accept). State 1 means the string must
+ be rejected, because the current byte is not allowed. If the string is
+ completely processed, but the state is non-zero, the string ended
+ prematurely; that is, the last byte indicated more bytes should have
+ followed.
+
+ @param[in,out] state the state of the decoding
+ @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
+ @param[in] byte next byte to decode
+ @return new state
+
+ @note The function has been edited: a std::array is used.
+
+ @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+ @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+ */
+ static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
+ {
+ static const std::array<std::uint8_t, 400> utf8d =
+ {
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
+ 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
+ 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
+ 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
+ 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
+ 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
+ 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
+ }
+ };
+
+ const std::uint8_t type = utf8d[byte];
+
+ codep = (state != UTF8_ACCEPT)
+ ? (byte & 0x3fu) | (codep << 6u)
+ : (0xFFu >> type) & (byte);
+
+ state = utf8d[256u + state * 16u + type];
+ return state;
+ }
+
+ private:
+ /// the output of the serializer
+ output_adapter_t<char> o = nullptr;
+
+ /// a (hopefully) large enough character buffer
+ std::array<char, 64> number_buffer{{}};
+
+ /// the locale
+ const std::lconv* loc = nullptr;
+ /// the locale's thousand separator character
+ const char thousands_sep = '\0';
+ /// the locale's decimal point character
+ const char decimal_point = '\0';
+
+ /// string buffer
+ std::array<char, 512> string_buffer{{}};
+
+ /// the indentation character
+ const char indent_char;
+ /// the indentation string
+ string_t indent_string;
+
+ /// error_handler how to react on decoding errors
+ const error_handler_t error_handler;
+};
+} // namespace detail
+} // namespace nlohmann
+
+// #include <nlohmann/detail/value_t.hpp>
+
+// #include <nlohmann/json_fwd.hpp>
+
+
+/*!
+@brief namespace for Niels Lohmann
+@see https://github.com/nlohmann
+@since version 1.0.0
+*/
+namespace nlohmann
+{
+
+/*!
+@brief a class to store JSON values
+
+@tparam ObjectType type for JSON objects (`std::map` by default; will be used
+in @ref object_t)
+@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
+in @ref array_t)
+@tparam StringType type for JSON strings and object keys (`std::string` by
+default; will be used in @ref string_t)
+@tparam BooleanType type for JSON booleans (`bool` by default; will be used
+in @ref boolean_t)
+@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
+default; will be used in @ref number_integer_t)
+@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
+`uint64_t` by default; will be used in @ref number_unsigned_t)
+@tparam NumberFloatType type for JSON floating-point numbers (`double` by
+default; will be used in @ref number_float_t)
+@tparam AllocatorType type of the allocator to use (`std::allocator` by
+default)
+@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
+and `from_json()` (@ref adl_serializer by default)
+
+@requirement The class satisfies the following concept requirements:
+- Basic
+ - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
+ JSON values can be default constructed. The result will be a JSON null
+ value.
+ - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
+ A JSON value can be constructed from an rvalue argument.
+ - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
+ A JSON value can be copy-constructed from an lvalue expression.
+ - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
+ A JSON value van be assigned from an rvalue argument.
+ - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
+ A JSON value can be copy-assigned from an lvalue expression.
+ - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
+ JSON values can be destructed.
+- Layout
+ - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
+ JSON values have
+ [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
+ All non-static data members are private and standard layout types, the
+ class has no virtual functions or (virtual) base classes.
+- Library-wide
+ - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
+ JSON values can be compared with `==`, see @ref
+ operator==(const_reference,const_reference).
+ - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
+ JSON values can be compared with `<`, see @ref
+ operator<(const_reference,const_reference).
+ - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
+ Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
+ other compatible types, using unqualified function call @ref swap().
+ - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
+ JSON values can be compared against `std::nullptr_t` objects which are used
+ to model the `null` value.
+- Container
+ - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
+ JSON values can be used like STL containers and provide iterator access.
+ - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
+ JSON values can be used like STL containers and provide reverse iterator
+ access.
+
+@invariant The member variables @a m_value and @a m_type have the following
+relationship:
+- If `m_type == value_t::object`, then `m_value.object != nullptr`.
+- If `m_type == value_t::array`, then `m_value.array != nullptr`.
+- If `m_type == value_t::string`, then `m_value.string != nullptr`.
+The invariants are checked by member function assert_invariant().
+
+@internal
+@note ObjectType trick from http://stackoverflow.com/a/9860911
+@endinternal
+
+@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
+Format](http://rfc7159.net/rfc7159)
+
+@since version 1.0.0
+
+@nosubgrouping
+*/
+NLOHMANN_BASIC_JSON_TPL_DECLARATION
+class basic_json
+{
+ private:
+ template<detail::value_t> friend struct detail::external_constructor;
+ friend ::nlohmann::json_pointer<basic_json>;
+ friend ::nlohmann::detail::parser<basic_json>;
+ friend ::nlohmann::detail::serializer<basic_json>;
+ template<typename BasicJsonType>
+ friend class ::nlohmann::detail::iter_impl;
+ template<typename BasicJsonType, typename CharType>
+ friend class ::nlohmann::detail::binary_writer;
+ template<typename BasicJsonType, typename SAX>
+ friend class ::nlohmann::detail::binary_reader;
+ template<typename BasicJsonType>
+ friend class ::nlohmann::detail::json_sax_dom_parser;
+ template<typename BasicJsonType>
+ friend class ::nlohmann::detail::json_sax_dom_callback_parser;
+
+ /// workaround type for MSVC
+ using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
+
+ // convenience aliases for types residing in namespace detail;
+ using lexer = ::nlohmann::detail::lexer<basic_json>;
+ using parser = ::nlohmann::detail::parser<basic_json>;
+
+ using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
+ template<typename BasicJsonType>
+ using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
+ template<typename BasicJsonType>
+ using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
+ template<typename Iterator>
+ using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
+ template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
+
+ template<typename CharType>
+ using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
+
+ using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
+ template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
+
+ using serializer = ::nlohmann::detail::serializer<basic_json>;
+
+ public:
+ using value_t = detail::value_t;
+ /// JSON Pointer, see @ref nlohmann::json_pointer
+ using json_pointer = ::nlohmann::json_pointer<basic_json>;
+ template<typename T, typename SFINAE>
+ using json_serializer = JSONSerializer<T, SFINAE>;
+ /// how to treat decoding errors
+ using error_handler_t = detail::error_handler_t;
+ /// helper type for initializer lists of basic_json values
+ using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
+
+ using input_format_t = detail::input_format_t;
+ /// SAX interface type, see @ref nlohmann::json_sax
+ using json_sax_t = json_sax<basic_json>;
+
+ ////////////////
+ // exceptions //
+ ////////////////
+
+ /// @name exceptions
+ /// Classes to implement user-defined exceptions.
+ /// @{
+
+ /// @copydoc detail::exception
+ using exception = detail::exception;
+ /// @copydoc detail::parse_error
+ using parse_error = detail::parse_error;
+ /// @copydoc detail::invalid_iterator
+ using invalid_iterator = detail::invalid_iterator;
+ /// @copydoc detail::type_error
+ using type_error = detail::type_error;
+ /// @copydoc detail::out_of_range
+ using out_of_range = detail::out_of_range;
+ /// @copydoc detail::other_error
+ using other_error = detail::other_error;
+
+ /// @}
+
+
+ /////////////////////
+ // container types //
+ /////////////////////
+
+ /// @name container types
+ /// The canonic container types to use @ref basic_json like any other STL
+ /// container.
+ /// @{
+
+ /// the type of elements in a basic_json container
+ using value_type = basic_json;
+
+ /// the type of an element reference
+ using reference = value_type&;
+ /// the type of an element const reference
+ using const_reference = const value_type&;
+
+ /// a type to represent differences between iterators
+ using difference_type = std::ptrdiff_t;
+ /// a type to represent container sizes
+ using size_type = std::size_t;
+
+ /// the allocator type
+ using allocator_type = AllocatorType<basic_json>;
+
+ /// the type of an element pointer
+ using pointer = typename std::allocator_traits<allocator_type>::pointer;
+ /// the type of an element const pointer
+ using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
+
+ /// an iterator for a basic_json container
+ using iterator = iter_impl<basic_json>;
+ /// a const iterator for a basic_json container
+ using const_iterator = iter_impl<const basic_json>;
+ /// a reverse iterator for a basic_json container
+ using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
+ /// a const reverse iterator for a basic_json container
+ using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
+
+ /// @}
+
+
+ /*!
+ @brief returns the allocator associated with the container
+ */
+ static allocator_type get_allocator()
+ {
+ return allocator_type();
+ }
+
+ /*!
+ @brief returns version information on the library
+
+ This function returns a JSON object with information about the library,
+ including the version number and information on the platform and compiler.
+
+ @return JSON object holding version information
+ key | description
+ ----------- | ---------------
+ `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
+ `copyright` | The copyright line for the library as string.
+ `name` | The name of the library as string.
+ `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
+ `url` | The URL of the project as string.
+ `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
+
+ @liveexample{The following code shows an example output of the `meta()`
+ function.,meta}
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @complexity Constant.
+
+ @since 2.1.0
+ */
+ JSON_NODISCARD
+ static basic_json meta()
+ {
+ basic_json result;
+
+ result["copyright"] = "(C) 2013-2017 Niels Lohmann";
+ result["name"] = "JSON for Modern C++";
+ result["url"] = "https://github.com/nlohmann/json";
+ result["version"]["string"] =
+ std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
+ std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
+ std::to_string(NLOHMANN_JSON_VERSION_PATCH);
+ result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
+ result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
+ result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
+
+#ifdef _WIN32
+ result["platform"] = "win32";
+#elif defined __linux__
+ result["platform"] = "linux";
+#elif defined __APPLE__
+ result["platform"] = "apple";
+#elif defined __unix__
+ result["platform"] = "unix";
+#else
+ result["platform"] = "unknown";
+#endif
+
+#if defined(__ICC) || defined(__INTEL_COMPILER)
+ result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
+#elif defined(__clang__)
+ result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
+#elif defined(__GNUC__) || defined(__GNUG__)
+ result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
+#elif defined(__HP_cc) || defined(__HP_aCC)
+ result["compiler"] = "hp"
+#elif defined(__IBMCPP__)
+ result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
+#elif defined(_MSC_VER)
+ result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
+#elif defined(__PGI)
+ result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
+#elif defined(__SUNPRO_CC)
+ result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
+#else
+ result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
+#endif
+
+#ifdef __cplusplus
+ result["compiler"]["c++"] = std::to_string(__cplusplus);
+#else
+ result["compiler"]["c++"] = "unknown";
+#endif
+ return result;
+ }
+
+
+ ///////////////////////////
+ // JSON value data types //
+ ///////////////////////////
+
+ /// @name JSON value data types
+ /// The data types to store a JSON value. These types are derived from
+ /// the template arguments passed to class @ref basic_json.
+ /// @{
+
+#if defined(JSON_HAS_CPP_14)
+ // Use transparent comparator if possible, combined with perfect forwarding
+ // on find() and count() calls prevents unnecessary string construction.
+ using object_comparator_t = std::less<>;
+#else
+ using object_comparator_t = std::less<StringType>;
+#endif
+
+ /*!
+ @brief a type for an object
+
+ [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
+ > An object is an unordered collection of zero or more name/value pairs,
+ > where a name is a string and a value is a string, number, boolean, null,
+ > object, or array.
+
+ To store objects in C++, a type is defined by the template parameters
+ described below.
+
+ @tparam ObjectType the container to store objects (e.g., `std::map` or
+ `std::unordered_map`)
+ @tparam StringType the type of the keys or names (e.g., `std::string`).
+ The comparison function `std::less<StringType>` is used to order elements
+ inside the container.
+ @tparam AllocatorType the allocator to use for objects (e.g.,
+ `std::allocator`)
+
+ #### Default type
+
+ With the default values for @a ObjectType (`std::map`), @a StringType
+ (`std::string`), and @a AllocatorType (`std::allocator`), the default
+ value for @a object_t is:
+
+ @code {.cpp}
+ std::map<
+ std::string, // key_type
+ basic_json, // value_type
+ std::less<std::string>, // key_compare
+ std::allocator<std::pair<const std::string, basic_json>> // allocator_type
+ >
+ @endcode
+
+ #### Behavior
+
+ The choice of @a object_t influences the behavior of the JSON class. With
+ the default type, objects have the following behavior:
+
+ - When all names are unique, objects will be interoperable in the sense
+ that all software implementations receiving that object will agree on
+ the name-value mappings.
+ - When the names within an object are not unique, it is unspecified which
+ one of the values for a given key will be chosen. For instance,
+ `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
+ `{"key": 2}`.
+ - Internally, name/value pairs are stored in lexicographical order of the
+ names. Objects will also be serialized (see @ref dump) in this order.
+ For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
+ and serialized as `{"a": 2, "b": 1}`.
+ - When comparing objects, the order of the name/value pairs is irrelevant.
+ This makes objects interoperable in the sense that they will not be
+ affected by these differences. For instance, `{"b": 1, "a": 2}` and
+ `{"a": 2, "b": 1}` will be treated as equal.
+
+ #### Limits
+
+ [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+ > An implementation may set limits on the maximum depth of nesting.
+
+ In this class, the object's limit of nesting is not explicitly constrained.
+ However, a maximum depth of nesting may be introduced by the compiler or
+ runtime environment. A theoretical limit can be queried by calling the
+ @ref max_size function of a JSON object.
+
+ #### Storage
+
+ Objects are stored as pointers in a @ref basic_json type. That is, for any
+ access to object values, a pointer of type `object_t*` must be
+ dereferenced.
+
+ @sa @ref array_t -- type for an array value
+
+ @since version 1.0.0
+
+ @note The order name/value pairs are added to the object is *not*
+ preserved by the library. Therefore, iterating an object may return
+ name/value pairs in a different order than they were originally stored. In
+ fact, keys will be traversed in alphabetical order as `std::map` with
+ `std::less` is used by default. Please note this behavior conforms to [RFC
+ 7159](http://rfc7159.net/rfc7159), because any order implements the
+ specified "unordered" nature of JSON objects.
+ */
+ using object_t = ObjectType<StringType,
+ basic_json,
+ object_comparator_t,
+ AllocatorType<std::pair<const StringType,
+ basic_json>>>;
+
+ /*!
+ @brief a type for an array
+
+ [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
+ > An array is an ordered sequence of zero or more values.
+
+ To store objects in C++, a type is defined by the template parameters
+ explained below.
+
+ @tparam ArrayType container type to store arrays (e.g., `std::vector` or
+ `std::list`)
+ @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
+
+ #### Default type
+
+ With the default values for @a ArrayType (`std::vector`) and @a
+ AllocatorType (`std::allocator`), the default value for @a array_t is:
+
+ @code {.cpp}
+ std::vector<
+ basic_json, // value_type
+ std::allocator<basic_json> // allocator_type
+ >
+ @endcode
+
+ #### Limits
+
+ [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+ > An implementation may set limits on the maximum depth of nesting.
+
+ In this class, the array's limit of nesting is not explicitly constrained.
+ However, a maximum depth of nesting may be introduced by the compiler or
+ runtime environment. A theoretical limit can be queried by calling the
+ @ref max_size function of a JSON array.
+
+ #### Storage
+
+ Arrays are stored as pointers in a @ref basic_json type. That is, for any
+ access to array values, a pointer of type `array_t*` must be dereferenced.
+
+ @sa @ref object_t -- type for an object value
+
+ @since version 1.0.0
+ */
+ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
+
+ /*!
+ @brief a type for a string
+
+ [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
+ > A string is a sequence of zero or more Unicode characters.
+
+ To store objects in C++, a type is defined by the template parameter
+ described below. Unicode values are split by the JSON class into
+ byte-sized characters during deserialization.
+
+ @tparam StringType the container to store strings (e.g., `std::string`).
+ Note this container is used for keys/names in objects, see @ref object_t.
+
+ #### Default type
+
+ With the default values for @a StringType (`std::string`), the default
+ value for @a string_t is:
+
+ @code {.cpp}
+ std::string
+ @endcode
+
+ #### Encoding
+
+ Strings are stored in UTF-8 encoding. Therefore, functions like
+ `std::string::size()` or `std::string::length()` return the number of
+ bytes in the string rather than the number of characters or glyphs.
+
+ #### String comparison
+
+ [RFC 7159](http://rfc7159.net/rfc7159) states:
+ > Software implementations are typically required to test names of object
+ > members for equality. Implementations that transform the textual
+ > representation into sequences of Unicode code units and then perform the
+ > comparison numerically, code unit by code unit, are interoperable in the
+ > sense that implementations will agree in all cases on equality or
+ > inequality of two strings. For example, implementations that compare
+ > strings with escaped characters unconverted may incorrectly find that
+ > `"a\\b"` and `"a\u005Cb"` are not equal.
+
+ This implementation is interoperable as it does compare strings code unit
+ by code unit.
+
+ #### Storage
+
+ String values are stored as pointers in a @ref basic_json type. That is,
+ for any access to string values, a pointer of type `string_t*` must be
+ dereferenced.
+
+ @since version 1.0.0
+ */
+ using string_t = StringType;
+
+ /*!
+ @brief a type for a boolean
+
+ [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
+ type which differentiates the two literals `true` and `false`.
+
+ To store objects in C++, a type is defined by the template parameter @a
+ BooleanType which chooses the type to use.
+
+ #### Default type
+
+ With the default values for @a BooleanType (`bool`), the default value for
+ @a boolean_t is:
+
+ @code {.cpp}
+ bool
+ @endcode
+
+ #### Storage
+
+ Boolean values are stored directly inside a @ref basic_json type.
+
+ @since version 1.0.0
+ */
+ using boolean_t = BooleanType;
+
+ /*!
+ @brief a type for a number (integer)
+
+ [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
+ > The representation of numbers is similar to that used in most
+ > programming languages. A number is represented in base 10 using decimal
+ > digits. It contains an integer component that may be prefixed with an
+ > optional minus sign, which may be followed by a fraction part and/or an
+ > exponent part. Leading zeros are not allowed. (...) Numeric values that
+ > cannot be represented in the grammar below (such as Infinity and NaN)
+ > are not permitted.
+
+ This description includes both integer and floating-point numbers.
+ However, C++ allows more precise storage if it is known whether the number
+ is a signed integer, an unsigned integer or a floating-point number.
+ Therefore, three different types, @ref number_integer_t, @ref
+ number_unsigned_t and @ref number_float_t are used.
+
+ To store integer numbers in C++, a type is defined by the template
+ parameter @a NumberIntegerType which chooses the type to use.
+
+ #### Default type
+
+ With the default values for @a NumberIntegerType (`int64_t`), the default
+ value for @a number_integer_t is:
+
+ @code {.cpp}
+ int64_t
+ @endcode
+
+ #### Default behavior
+
+ - The restrictions about leading zeros is not enforced in C++. Instead,
+ leading zeros in integer literals lead to an interpretation as octal
+ number. Internally, the value will be stored as decimal number. For
+ instance, the C++ integer literal `010` will be serialized to `8`.
+ During deserialization, leading zeros yield an error.
+ - Not-a-number (NaN) values will be serialized to `null`.
+
+ #### Limits
+
+ [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+ > An implementation may set limits on the range and precision of numbers.
+
+ When the default type is used, the maximal integer number that can be
+ stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
+ that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
+ that are out of range will yield over/underflow when used in a
+ constructor. During deserialization, too large or small integer numbers
+ will be automatically be stored as @ref number_unsigned_t or @ref
+ number_float_t.
+
+ [RFC 7159](http://rfc7159.net/rfc7159) further states:
+ > Note that when such software is used, numbers that are integers and are
+ > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
+ > that implementations will agree exactly on their numeric values.
+
+ As this range is a subrange of the exactly supported range [INT64_MIN,
+ INT64_MAX], this class's integer type is interoperable.
+
+ #### Storage
+
+ Integer number values are stored directly inside a @ref basic_json type.
+
+ @sa @ref number_float_t -- type for number values (floating-point)
+
+ @sa @ref number_unsigned_t -- type for number values (unsigned integer)
+
+ @since version 1.0.0
+ */
+ using number_integer_t = NumberIntegerType;
+
+ /*!
+ @brief a type for a number (unsigned)
+
+ [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
+ > The representation of numbers is similar to that used in most
+ > programming languages. A number is represented in base 10 using decimal
+ > digits. It contains an integer component that may be prefixed with an
+ > optional minus sign, which may be followed by a fraction part and/or an
+ > exponent part. Leading zeros are not allowed. (...) Numeric values that
+ > cannot be represented in the grammar below (such as Infinity and NaN)
+ > are not permitted.
+
+ This description includes both integer and floating-point numbers.
+ However, C++ allows more precise storage if it is known whether the number
+ is a signed integer, an unsigned integer or a floating-point number.
+ Therefore, three different types, @ref number_integer_t, @ref
+ number_unsigned_t and @ref number_float_t are used.
+
+ To store unsigned integer numbers in C++, a type is defined by the
+ template parameter @a NumberUnsignedType which chooses the type to use.
+
+ #### Default type
+
+ With the default values for @a NumberUnsignedType (`uint64_t`), the
+ default value for @a number_unsigned_t is:
+
+ @code {.cpp}
+ uint64_t
+ @endcode
+
+ #### Default behavior
+
+ - The restrictions about leading zeros is not enforced in C++. Instead,
+ leading zeros in integer literals lead to an interpretation as octal
+ number. Internally, the value will be stored as decimal number. For
+ instance, the C++ integer literal `010` will be serialized to `8`.
+ During deserialization, leading zeros yield an error.
+ - Not-a-number (NaN) values will be serialized to `null`.
+
+ #### Limits
+
+ [RFC 7159](http://rfc7159.net/rfc7159) specifies:
+ > An implementation may set limits on the range and precision of numbers.
+
+ When the default type is used, the maximal integer number that can be
+ stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
+ number that can be stored is `0`. Integer numbers that are out of range
+ will yield over/underflow when used in a constructor. During
+ deserialization, too large or small integer numbers will be automatically
+ be stored as @ref number_integer_t or @ref number_float_t.
+
+ [RFC 7159](http://rfc7159.net/rfc7159) further states:
+ > Note that when such software is used, numbers that are integers and are
+ > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
+ > that implementations will agree exactly on their numeric values.
+
+ As this range is a subrange (when considered in conjunction with the
+ number_integer_t type) of the exactly supported range [0, UINT64_MAX],
+ this class's integer type is interoperable.
+
+ #### Storage
+
+ Integer number values are stored directly inside a @ref basic_json type.
+
+ @sa @ref number_float_t -- type for number values (floating-point)
+ @sa @ref number_integer_t -- type for number values (integer)
+
+ @since version 2.0.0
+ */
+ using number_unsigned_t = NumberUnsignedType;
+
+ /*!
+ @brief a type for a number (floating-point)
+
+ [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
+ > The representation of numbers is similar to that used in most
+ > programming languages. A number is represented in base 10 using decimal
+ > digits. It contains an integer component that may be prefixed with an
+ > optional minus sign, which may be followed by a fraction part and/or an
+ > exponent part. Leading zeros are not allowed. (...) Numeric values that
+ > cannot be represented in the grammar below (such as Infinity and NaN)
+ > are not permitted.
+
+ This description includes both integer and floating-point numbers.
+ However, C++ allows more precise storage if it is known whether the number
+ is a signed integer, an unsigned integer or a floating-point number.
+ Therefore, three different types, @ref number_integer_t, @ref
+ number_unsigned_t and @ref number_float_t are used.
+
+ To store floating-point numbers in C++, a type is defined by the template
+ parameter @a NumberFloatType which chooses the type to use.
+
+ #### Default type
+
+ With the default values for @a NumberFloatType (`double`), the default
+ value for @a number_float_t is:
+
+ @code {.cpp}
+ double
+ @endcode
+
+ #### Default behavior
+
+ - The restrictions about leading zeros is not enforced in C++. Instead,
+ leading zeros in floating-point literals will be ignored. Internally,
+ the value will be stored as decimal number. For instance, the C++
+ floating-point literal `01.2` will be serialized to `1.2`. During
+ deserialization, leading zeros yield an error.
+ - Not-a-number (NaN) values will be serialized to `null`.
+
+ #### Limits
+
+ [RFC 7159](http://rfc7159.net/rfc7159) states:
+ > This specification allows implementations to set limits on the range and
+ > precision of numbers accepted. Since software that implements IEEE
+ > 754-2008 binary64 (double precision) numbers is generally available and
+ > widely used, good interoperability can be achieved by implementations
+ > that expect no more precision or range than these provide, in the sense
+ > that implementations will approximate JSON numbers within the expected
+ > precision.
+
+ This implementation does exactly follow this approach, as it uses double
+ precision floating-point numbers. Note values smaller than
+ `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
+ will be stored as NaN internally and be serialized to `null`.
+
+ #### Storage
+
+ Floating-point number values are stored directly inside a @ref basic_json
+ type.
+
+ @sa @ref number_integer_t -- type for number values (integer)
+
+ @sa @ref number_unsigned_t -- type for number values (unsigned integer)
+
+ @since version 1.0.0
+ */
+ using number_float_t = NumberFloatType;
+
+ /// @}
+
+ private:
+
+ /// helper for exception-safe object creation
+ template<typename T, typename... Args>
+ static T* create(Args&& ... args)
+ {
+ AllocatorType<T> alloc;
+ using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
+
+ auto deleter = [&](T * object)
+ {
+ AllocatorTraits::deallocate(alloc, object, 1);
+ };
+ std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
+ AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
+ assert(object != nullptr);
+ return object.release();
+ }
+
+ ////////////////////////
+ // JSON value storage //
+ ////////////////////////
+
+ /*!
+ @brief a JSON value
+
+ The actual storage for a JSON value of the @ref basic_json class. This
+ union combines the different storage types for the JSON value types
+ defined in @ref value_t.
+
+ JSON type | value_t type | used type
+ --------- | --------------- | ------------------------
+ object | object | pointer to @ref object_t
+ array | array | pointer to @ref array_t
+ string | string | pointer to @ref string_t
+ boolean | boolean | @ref boolean_t
+ number | number_integer | @ref number_integer_t
+ number | number_unsigned | @ref number_unsigned_t
+ number | number_float | @ref number_float_t
+ null | null | *no value is stored*
+
+ @note Variable-length types (objects, arrays, and strings) are stored as
+ pointers. The size of the union should not exceed 64 bits if the default
+ value types are used.
+
+ @since version 1.0.0
+ */
+ union json_value
+ {
+ /// object (stored with pointer to save storage)
+ object_t* object;
+ /// array (stored with pointer to save storage)
+ array_t* array;
+ /// string (stored with pointer to save storage)
+ string_t* string;
+ /// boolean
+ boolean_t boolean;
+ /// number (integer)
+ number_integer_t number_integer;
+ /// number (unsigned integer)
+ number_unsigned_t number_unsigned;
+ /// number (floating-point)
+ number_float_t number_float;
+
+ /// default constructor (for null values)
+ json_value() = default;
+ /// constructor for booleans
+ json_value(boolean_t v) noexcept : boolean(v) {}
+ /// constructor for numbers (integer)
+ json_value(number_integer_t v) noexcept : number_integer(v) {}
+ /// constructor for numbers (unsigned)
+ json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
+ /// constructor for numbers (floating-point)
+ json_value(number_float_t v) noexcept : number_float(v) {}
+ /// constructor for empty values of a given type
+ json_value(value_t t)
+ {
+ switch (t)
+ {
+ case value_t::object:
+ {
+ object = create<object_t>();
+ break;
+ }
+
+ case value_t::array:
+ {
+ array = create<array_t>();
+ break;
+ }
+
+ case value_t::string:
+ {
+ string = create<string_t>("");
+ break;
+ }
+
+ case value_t::boolean:
+ {
+ boolean = boolean_t(false);
+ break;
+ }
+
+ case value_t::number_integer:
+ {
+ number_integer = number_integer_t(0);
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ number_unsigned = number_unsigned_t(0);
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ number_float = number_float_t(0.0);
+ break;
+ }
+
+ case value_t::null:
+ {
+ object = nullptr; // silence warning, see #821
+ break;
+ }
+
+ default:
+ {
+ object = nullptr; // silence warning, see #821
+ if (JSON_UNLIKELY(t == value_t::null))
+ {
+ JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.6.1")); // LCOV_EXCL_LINE
+ }
+ break;
+ }
+ }
+ }
+
+ /// constructor for strings
+ json_value(const string_t& value)
+ {
+ string = create<string_t>(value);
+ }
+
+ /// constructor for rvalue strings
+ json_value(string_t&& value)
+ {
+ string = create<string_t>(std::move(value));
+ }
+
+ /// constructor for objects
+ json_value(const object_t& value)
+ {
+ object = create<object_t>(value);
+ }
+
+ /// constructor for rvalue objects
+ json_value(object_t&& value)
+ {
+ object = create<object_t>(std::move(value));
+ }
+
+ /// constructor for arrays
+ json_value(const array_t& value)
+ {
+ array = create<array_t>(value);
+ }
+
+ /// constructor for rvalue arrays
+ json_value(array_t&& value)
+ {
+ array = create<array_t>(std::move(value));
+ }
+
+ void destroy(value_t t) noexcept
+ {
+ switch (t)
+ {
+ case value_t::object:
+ {
+ AllocatorType<object_t> alloc;
+ std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
+ std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
+ break;
+ }
+
+ case value_t::array:
+ {
+ AllocatorType<array_t> alloc;
+ std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
+ std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
+ break;
+ }
+
+ case value_t::string:
+ {
+ AllocatorType<string_t> alloc;
+ std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
+ std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+ };
+
+ /*!
+ @brief checks the class invariants
+
+ This function asserts the class invariants. It needs to be called at the
+ end of every constructor to make sure that created objects respect the
+ invariant. Furthermore, it has to be called each time the type of a JSON
+ value is changed, because the invariant expresses a relationship between
+ @a m_type and @a m_value.
+ */
+ void assert_invariant() const noexcept
+ {
+ assert(m_type != value_t::object or m_value.object != nullptr);
+ assert(m_type != value_t::array or m_value.array != nullptr);
+ assert(m_type != value_t::string or m_value.string != nullptr);
+ }
+
+ public:
+ //////////////////////////
+ // JSON parser callback //
+ //////////////////////////
+
+ /*!
+ @brief parser event types
+
+ The parser callback distinguishes the following events:
+ - `object_start`: the parser read `{` and started to process a JSON object
+ - `key`: the parser read a key of a value in an object
+ - `object_end`: the parser read `}` and finished processing a JSON object
+ - `array_start`: the parser read `[` and started to process a JSON array
+ - `array_end`: the parser read `]` and finished processing a JSON array
+ - `value`: the parser finished reading a JSON value
+
+ @image html callback_events.png "Example when certain parse events are triggered"
+
+ @sa @ref parser_callback_t for more information and examples
+ */
+ using parse_event_t = typename parser::parse_event_t;
+
+ /*!
+ @brief per-element parser callback type
+
+ With a parser callback function, the result of parsing a JSON text can be
+ influenced. When passed to @ref parse, it is called on certain events
+ (passed as @ref parse_event_t via parameter @a event) with a set recursion
+ depth @a depth and context JSON value @a parsed. The return value of the
+ callback function is a boolean indicating whether the element that emitted
+ the callback shall be kept or not.
+
+ We distinguish six scenarios (determined by the event type) in which the
+ callback function can be called. The following table describes the values
+ of the parameters @a depth, @a event, and @a parsed.
+
+ parameter @a event | description | parameter @a depth | parameter @a parsed
+ ------------------ | ----------- | ------------------ | -------------------
+ parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
+ parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
+ parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
+ parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
+ parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
+ parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
+
+ @image html callback_events.png "Example when certain parse events are triggered"
+
+ Discarding a value (i.e., returning `false`) has different effects
+ depending on the context in which function was called:
+
+ - Discarded values in structured types are skipped. That is, the parser
+ will behave as if the discarded value was never read.
+ - In case a value outside a structured type is skipped, it is replaced
+ with `null`. This case happens if the top-level element is skipped.
+
+ @param[in] depth the depth of the recursion during parsing
+
+ @param[in] event an event of type parse_event_t indicating the context in
+ the callback function has been called
+
+ @param[in,out] parsed the current intermediate parse result; note that
+ writing to this value has no effect for parse_event_t::key events
+
+ @return Whether the JSON value which called the function during parsing
+ should be kept (`true`) or not (`false`). In the latter case, it is either
+ skipped completely or replaced by an empty discarded object.
+
+ @sa @ref parse for examples
+
+ @since version 1.0.0
+ */
+ using parser_callback_t = typename parser::parser_callback_t;
+
+ //////////////////
+ // constructors //
+ //////////////////
+
+ /// @name constructors and destructors
+ /// Constructors of class @ref basic_json, copy/move constructor, copy
+ /// assignment, static functions creating objects, and the destructor.
+ /// @{
+
+ /*!
+ @brief create an empty value with a given type
+
+ Create an empty JSON value with a given type. The value will be default
+ initialized with an empty value which depends on the type:
+
+ Value type | initial value
+ ----------- | -------------
+ null | `null`
+ boolean | `false`
+ string | `""`
+ number | `0`
+ object | `{}`
+ array | `[]`
+
+ @param[in] v the type of the value to create
+
+ @complexity Constant.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @liveexample{The following code shows the constructor for different @ref
+ value_t values,basic_json__value_t}
+
+ @sa @ref clear() -- restores the postcondition of this constructor
+
+ @since version 1.0.0
+ */
+ basic_json(const value_t v)
+ : m_type(v), m_value(v)
+ {
+ assert_invariant();
+ }
+
+ /*!
+ @brief create a null object
+
+ Create a `null` JSON value. It either takes a null pointer as parameter
+ (explicitly creating `null`) or no parameter (implicitly creating `null`).
+ The passed null pointer itself is not read -- it is only used to choose
+ the right constructor.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this constructor never throws
+ exceptions.
+
+ @liveexample{The following code shows the constructor with and without a
+ null pointer parameter.,basic_json__nullptr_t}
+
+ @since version 1.0.0
+ */
+ basic_json(std::nullptr_t = nullptr) noexcept
+ : basic_json(value_t::null)
+ {
+ assert_invariant();
+ }
+
+ /*!
+ @brief create a JSON value
+
+ This is a "catch all" constructor for all compatible JSON types; that is,
+ types for which a `to_json()` method exists. The constructor forwards the
+ parameter @a val to that method (to `json_serializer<U>::to_json` method
+ with `U = uncvref_t<CompatibleType>`, to be exact).
+
+ Template type @a CompatibleType includes, but is not limited to, the
+ following types:
+ - **arrays**: @ref array_t and all kinds of compatible containers such as
+ `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
+ `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
+ `std::multiset`, and `std::unordered_multiset` with a `value_type` from
+ which a @ref basic_json value can be constructed.
+ - **objects**: @ref object_t and all kinds of compatible associative
+ containers such as `std::map`, `std::unordered_map`, `std::multimap`,
+ and `std::unordered_multimap` with a `key_type` compatible to
+ @ref string_t and a `value_type` from which a @ref basic_json value can
+ be constructed.
+ - **strings**: @ref string_t, string literals, and all compatible string
+ containers can be used.
+ - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
+ @ref number_float_t, and all convertible number types such as `int`,
+ `size_t`, `int64_t`, `float` or `double` can be used.
+ - **boolean**: @ref boolean_t / `bool` can be used.
+
+ See the examples below.
+
+ @tparam CompatibleType a type such that:
+ - @a CompatibleType is not derived from `std::istream`,
+ - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
+ constructors),
+ - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
+ - @a CompatibleType is not a @ref basic_json nested type (e.g.,
+ @ref json_pointer, @ref iterator, etc ...)
+ - @ref @ref json_serializer<U> has a
+ `to_json(basic_json_t&, CompatibleType&&)` method
+
+ @tparam U = `uncvref_t<CompatibleType>`
+
+ @param[in] val the value to be forwarded to the respective constructor
+
+ @complexity Usually linear in the size of the passed @a val, also
+ depending on the implementation of the called `to_json()`
+ method.
+
+ @exceptionsafety Depends on the called constructor. For types directly
+ supported by the library (i.e., all types for which no `to_json()` function
+ was provided), strong guarantee holds: if an exception is thrown, there are
+ no changes to any JSON value.
+
+ @liveexample{The following code shows the constructor with several
+ compatible types.,basic_json__CompatibleType}
+
+ @since version 2.1.0
+ */
+ template <typename CompatibleType,
+ typename U = detail::uncvref_t<CompatibleType>,
+ detail::enable_if_t<
+ not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
+ basic_json(CompatibleType && val) noexcept(noexcept(
+ JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
+ std::forward<CompatibleType>(val))))
+ {
+ JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
+ assert_invariant();
+ }
+
+ /*!
+ @brief create a JSON value from an existing one
+
+ This is a constructor for existing @ref basic_json types.
+ It does not hijack copy/move constructors, since the parameter has different
+ template arguments than the current ones.
+
+ The constructor tries to convert the internal @ref m_value of the parameter.
+
+ @tparam BasicJsonType a type such that:
+ - @a BasicJsonType is a @ref basic_json type.
+ - @a BasicJsonType has different template arguments than @ref basic_json_t.
+
+ @param[in] val the @ref basic_json value to be converted.
+
+ @complexity Usually linear in the size of the passed @a val, also
+ depending on the implementation of the called `to_json()`
+ method.
+
+ @exceptionsafety Depends on the called constructor. For types directly
+ supported by the library (i.e., all types for which no `to_json()` function
+ was provided), strong guarantee holds: if an exception is thrown, there are
+ no changes to any JSON value.
+
+ @since version 3.2.0
+ */
+ template <typename BasicJsonType,
+ detail::enable_if_t<
+ detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
+ basic_json(const BasicJsonType& val)
+ {
+ using other_boolean_t = typename BasicJsonType::boolean_t;
+ using other_number_float_t = typename BasicJsonType::number_float_t;
+ using other_number_integer_t = typename BasicJsonType::number_integer_t;
+ using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
+ using other_string_t = typename BasicJsonType::string_t;
+ using other_object_t = typename BasicJsonType::object_t;
+ using other_array_t = typename BasicJsonType::array_t;
+
+ switch (val.type())
+ {
+ case value_t::boolean:
+ JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
+ break;
+ case value_t::number_float:
+ JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
+ break;
+ case value_t::number_integer:
+ JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
+ break;
+ case value_t::number_unsigned:
+ JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
+ break;
+ case value_t::string:
+ JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
+ break;
+ case value_t::object:
+ JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
+ break;
+ case value_t::array:
+ JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
+ break;
+ case value_t::null:
+ *this = nullptr;
+ break;
+ case value_t::discarded:
+ m_type = value_t::discarded;
+ break;
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+ assert_invariant();
+ }
+
+ /*!
+ @brief create a container (array or object) from an initializer list
+
+ Creates a JSON value of type array or object from the passed initializer
+ list @a init. In case @a type_deduction is `true` (default), the type of
+ the JSON value to be created is deducted from the initializer list @a init
+ according to the following rules:
+
+ 1. If the list is empty, an empty JSON object value `{}` is created.
+ 2. If the list consists of pairs whose first element is a string, a JSON
+ object value is created where the first elements of the pairs are
+ treated as keys and the second elements are as values.
+ 3. In all other cases, an array is created.
+
+ The rules aim to create the best fit between a C++ initializer list and
+ JSON values. The rationale is as follows:
+
+ 1. The empty initializer list is written as `{}` which is exactly an empty
+ JSON object.
+ 2. C++ has no way of describing mapped types other than to list a list of
+ pairs. As JSON requires that keys must be of type string, rule 2 is the
+ weakest constraint one can pose on initializer lists to interpret them
+ as an object.
+ 3. In all other cases, the initializer list could not be interpreted as
+ JSON object type, so interpreting it as JSON array type is safe.
+
+ With the rules described above, the following JSON values cannot be
+ expressed by an initializer list:
+
+ - the empty array (`[]`): use @ref array(initializer_list_t)
+ with an empty initializer list in this case
+ - arrays whose elements satisfy rule 2: use @ref
+ array(initializer_list_t) with the same initializer list
+ in this case
+
+ @note When used without parentheses around an empty initializer list, @ref
+ basic_json() is called instead of this function, yielding the JSON null
+ value.
+
+ @param[in] init initializer list with JSON values
+
+ @param[in] type_deduction internal parameter; when set to `true`, the type
+ of the JSON value is deducted from the initializer list @a init; when set
+ to `false`, the type provided via @a manual_type is forced. This mode is
+ used by the functions @ref array(initializer_list_t) and
+ @ref object(initializer_list_t).
+
+ @param[in] manual_type internal parameter; when @a type_deduction is set
+ to `false`, the created JSON value will use the provided type (only @ref
+ value_t::array and @ref value_t::object are valid); when @a type_deduction
+ is set to `true`, this parameter has no effect
+
+ @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
+ `value_t::object`, but @a init contains an element which is not a pair
+ whose first element is a string. In this case, the constructor could not
+ create an object. If @a type_deduction would have be `true`, an array
+ would have been created. See @ref object(initializer_list_t)
+ for an example.
+
+ @complexity Linear in the size of the initializer list @a init.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @liveexample{The example below shows how JSON values are created from
+ initializer lists.,basic_json__list_init_t}
+
+ @sa @ref array(initializer_list_t) -- create a JSON array
+ value from an initializer list
+ @sa @ref object(initializer_list_t) -- create a JSON object
+ value from an initializer list
+
+ @since version 1.0.0
+ */
+ basic_json(initializer_list_t init,
+ bool type_deduction = true,
+ value_t manual_type = value_t::array)
+ {
+ // check if each element is an array with two elements whose first
+ // element is a string
+ bool is_an_object = std::all_of(init.begin(), init.end(),
+ [](const detail::json_ref<basic_json>& element_ref)
+ {
+ return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
+ });
+
+ // adjust type if type deduction is not wanted
+ if (not type_deduction)
+ {
+ // if array is wanted, do not create an object though possible
+ if (manual_type == value_t::array)
+ {
+ is_an_object = false;
+ }
+
+ // if object is wanted but impossible, throw an exception
+ if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
+ {
+ JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
+ }
+ }
+
+ if (is_an_object)
+ {
+ // the initializer list is a list of pairs -> create object
+ m_type = value_t::object;
+ m_value = value_t::object;
+
+ std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
+ {
+ auto element = element_ref.moved_or_copied();
+ m_value.object->emplace(
+ std::move(*((*element.m_value.array)[0].m_value.string)),
+ std::move((*element.m_value.array)[1]));
+ });
+ }
+ else
+ {
+ // the initializer list describes an array -> create array
+ m_type = value_t::array;
+ m_value.array = create<array_t>(init.begin(), init.end());
+ }
+
+ assert_invariant();
+ }
+
+ /*!
+ @brief explicitly create an array from an initializer list
+
+ Creates a JSON array value from a given initializer list. That is, given a
+ list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
+ initializer list is empty, the empty array `[]` is created.
+
+ @note This function is only needed to express two edge cases that cannot
+ be realized with the initializer list constructor (@ref
+ basic_json(initializer_list_t, bool, value_t)). These cases
+ are:
+ 1. creating an array whose elements are all pairs whose first element is a
+ string -- in this case, the initializer list constructor would create an
+ object, taking the first elements as keys
+ 2. creating an empty array -- passing the empty initializer list to the
+ initializer list constructor yields an empty object
+
+ @param[in] init initializer list with JSON values to create an array from
+ (optional)
+
+ @return JSON array value
+
+ @complexity Linear in the size of @a init.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @liveexample{The following code shows an example for the `array`
+ function.,array}
+
+ @sa @ref basic_json(initializer_list_t, bool, value_t) --
+ create a JSON value from an initializer list
+ @sa @ref object(initializer_list_t) -- create a JSON object
+ value from an initializer list
+
+ @since version 1.0.0
+ */
+ JSON_NODISCARD
+ static basic_json array(initializer_list_t init = {})
+ {
+ return basic_json(init, false, value_t::array);
+ }
+
+ /*!
+ @brief explicitly create an object from an initializer list
+
+ Creates a JSON object value from a given initializer list. The initializer
+ lists elements must be pairs, and their first elements must be strings. If
+ the initializer list is empty, the empty object `{}` is created.
+
+ @note This function is only added for symmetry reasons. In contrast to the
+ related function @ref array(initializer_list_t), there are
+ no cases which can only be expressed by this function. That is, any
+ initializer list @a init can also be passed to the initializer list
+ constructor @ref basic_json(initializer_list_t, bool, value_t).
+
+ @param[in] init initializer list to create an object from (optional)
+
+ @return JSON object value
+
+ @throw type_error.301 if @a init is not a list of pairs whose first
+ elements are strings. In this case, no object can be created. When such a
+ value is passed to @ref basic_json(initializer_list_t, bool, value_t),
+ an array would have been created from the passed initializer list @a init.
+ See example below.
+
+ @complexity Linear in the size of @a init.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @liveexample{The following code shows an example for the `object`
+ function.,object}
+
+ @sa @ref basic_json(initializer_list_t, bool, value_t) --
+ create a JSON value from an initializer list
+ @sa @ref array(initializer_list_t) -- create a JSON array
+ value from an initializer list
+
+ @since version 1.0.0
+ */
+ JSON_NODISCARD
+ static basic_json object(initializer_list_t init = {})
+ {
+ return basic_json(init, false, value_t::object);
+ }
+
+ /*!
+ @brief construct an array with count copies of given value
+
+ Constructs a JSON array value by creating @a cnt copies of a passed value.
+ In case @a cnt is `0`, an empty array is created.
+
+ @param[in] cnt the number of JSON copies of @a val to create
+ @param[in] val the JSON value to copy
+
+ @post `std::distance(begin(),end()) == cnt` holds.
+
+ @complexity Linear in @a cnt.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @liveexample{The following code shows examples for the @ref
+ basic_json(size_type\, const basic_json&)
+ constructor.,basic_json__size_type_basic_json}
+
+ @since version 1.0.0
+ */
+ basic_json(size_type cnt, const basic_json& val)
+ : m_type(value_t::array)
+ {
+ m_value.array = create<array_t>(cnt, val);
+ assert_invariant();
+ }
+
+ /*!
+ @brief construct a JSON container given an iterator range
+
+ Constructs the JSON value with the contents of the range `[first, last)`.
+ The semantics depends on the different types a JSON value can have:
+ - In case of a null type, invalid_iterator.206 is thrown.
+ - In case of other primitive types (number, boolean, or string), @a first
+ must be `begin()` and @a last must be `end()`. In this case, the value is
+ copied. Otherwise, invalid_iterator.204 is thrown.
+ - In case of structured types (array, object), the constructor behaves as
+ similar versions for `std::vector` or `std::map`; that is, a JSON array
+ or object is constructed from the values in the range.
+
+ @tparam InputIT an input iterator type (@ref iterator or @ref
+ const_iterator)
+
+ @param[in] first begin of the range to copy from (included)
+ @param[in] last end of the range to copy from (excluded)
+
+ @pre Iterators @a first and @a last must be initialized. **This
+ precondition is enforced with an assertion (see warning).** If
+ assertions are switched off, a violation of this precondition yields
+ undefined behavior.
+
+ @pre Range `[first, last)` is valid. Usually, this precondition cannot be
+ checked efficiently. Only certain edge cases are detected; see the
+ description of the exceptions below. A violation of this precondition
+ yields undefined behavior.
+
+ @warning A precondition is enforced with a runtime assertion that will
+ result in calling `std::abort` if this precondition is not met.
+ Assertions can be disabled by defining `NDEBUG` at compile time.
+ See https://en.cppreference.com/w/cpp/error/assert for more
+ information.
+
+ @throw invalid_iterator.201 if iterators @a first and @a last are not
+ compatible (i.e., do not belong to the same JSON value). In this case,
+ the range `[first, last)` is undefined.
+ @throw invalid_iterator.204 if iterators @a first and @a last belong to a
+ primitive type (number, boolean, or string), but @a first does not point
+ to the first element any more. In this case, the range `[first, last)` is
+ undefined. See example code below.
+ @throw invalid_iterator.206 if iterators @a first and @a last belong to a
+ null value. In this case, the range `[first, last)` is undefined.
+
+ @complexity Linear in distance between @a first and @a last.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @liveexample{The example below shows several ways to create JSON values by
+ specifying a subrange with iterators.,basic_json__InputIt_InputIt}
+
+ @since version 1.0.0
+ */
+ template<class InputIT, typename std::enable_if<
+ std::is_same<InputIT, typename basic_json_t::iterator>::value or
+ std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
+ basic_json(InputIT first, InputIT last)
+ {
+ assert(first.m_object != nullptr);
+ assert(last.m_object != nullptr);
+
+ // make sure iterator fits the current value
+ if (JSON_UNLIKELY(first.m_object != last.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
+ }
+
+ // copy type from first iterator
+ m_type = first.m_object->m_type;
+
+ // check if iterator range is complete for primitive values
+ switch (m_type)
+ {
+ case value_t::boolean:
+ case value_t::number_float:
+ case value_t::number_integer:
+ case value_t::number_unsigned:
+ case value_t::string:
+ {
+ if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
+ or not last.m_it.primitive_iterator.is_end()))
+ {
+ JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ switch (m_type)
+ {
+ case value_t::number_integer:
+ {
+ m_value.number_integer = first.m_object->m_value.number_integer;
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ m_value.number_unsigned = first.m_object->m_value.number_unsigned;
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ m_value.number_float = first.m_object->m_value.number_float;
+ break;
+ }
+
+ case value_t::boolean:
+ {
+ m_value.boolean = first.m_object->m_value.boolean;
+ break;
+ }
+
+ case value_t::string:
+ {
+ m_value = *first.m_object->m_value.string;
+ break;
+ }
+
+ case value_t::object:
+ {
+ m_value.object = create<object_t>(first.m_it.object_iterator,
+ last.m_it.object_iterator);
+ break;
+ }
+
+ case value_t::array:
+ {
+ m_value.array = create<array_t>(first.m_it.array_iterator,
+ last.m_it.array_iterator);
+ break;
+ }
+
+ default:
+ JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
+ std::string(first.m_object->type_name())));
+ }
+
+ assert_invariant();
+ }
+
+
+ ///////////////////////////////////////
+ // other constructors and destructor //
+ ///////////////////////////////////////
+
+ /// @private
+ basic_json(const detail::json_ref<basic_json>& ref)
+ : basic_json(ref.moved_or_copied())
+ {}
+
+ /*!
+ @brief copy constructor
+
+ Creates a copy of a given JSON value.
+
+ @param[in] other the JSON value to copy
+
+ @post `*this == other`
+
+ @complexity Linear in the size of @a other.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes to any JSON value.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is linear.
+ - As postcondition, it holds: `other == basic_json(other)`.
+
+ @liveexample{The following code shows an example for the copy
+ constructor.,basic_json__basic_json}
+
+ @since version 1.0.0
+ */
+ basic_json(const basic_json& other)
+ : m_type(other.m_type)
+ {
+ // check of passed value is valid
+ other.assert_invariant();
+
+ switch (m_type)
+ {
+ case value_t::object:
+ {
+ m_value = *other.m_value.object;
+ break;
+ }
+
+ case value_t::array:
+ {
+ m_value = *other.m_value.array;
+ break;
+ }
+
+ case value_t::string:
+ {
+ m_value = *other.m_value.string;
+ break;
+ }
+
+ case value_t::boolean:
+ {
+ m_value = other.m_value.boolean;
+ break;
+ }
+
+ case value_t::number_integer:
+ {
+ m_value = other.m_value.number_integer;
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ m_value = other.m_value.number_unsigned;
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ m_value = other.m_value.number_float;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ assert_invariant();
+ }
+
+ /*!
+ @brief move constructor
+
+ Move constructor. Constructs a JSON value with the contents of the given
+ value @a other using move semantics. It "steals" the resources from @a
+ other and leaves it as JSON null value.
+
+ @param[in,out] other value to move to this object
+
+ @post `*this` has the same value as @a other before the call.
+ @post @a other is a JSON null value.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this constructor never throws
+ exceptions.
+
+ @requirement This function helps `basic_json` satisfying the
+ [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
+ requirements.
+
+ @liveexample{The code below shows the move constructor explicitly called
+ via std::move.,basic_json__moveconstructor}
+
+ @since version 1.0.0
+ */
+ basic_json(basic_json&& other) noexcept
+ : m_type(std::move(other.m_type)),
+ m_value(std::move(other.m_value))
+ {
+ // check that passed value is valid
+ other.assert_invariant();
+
+ // invalidate payload
+ other.m_type = value_t::null;
+ other.m_value = {};
+
+ assert_invariant();
+ }
+
+ /*!
+ @brief copy assignment
+
+ Copy assignment operator. Copies a JSON value via the "copy and swap"
+ strategy: It is expressed in terms of the copy constructor, destructor,
+ and the `swap()` member function.
+
+ @param[in] other value to copy from
+
+ @complexity Linear.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is linear.
+
+ @liveexample{The code below shows and example for the copy assignment. It
+ creates a copy of value `a` which is then swapped with `b`. Finally\, the
+ copy of `a` (which is the null value after the swap) is
+ destroyed.,basic_json__copyassignment}
+
+ @since version 1.0.0
+ */
+ basic_json& operator=(basic_json other) noexcept (
+ std::is_nothrow_move_constructible<value_t>::value and
+ std::is_nothrow_move_assignable<value_t>::value and
+ std::is_nothrow_move_constructible<json_value>::value and
+ std::is_nothrow_move_assignable<json_value>::value
+ )
+ {
+ // check that passed value is valid
+ other.assert_invariant();
+
+ using std::swap;
+ swap(m_type, other.m_type);
+ swap(m_value, other.m_value);
+
+ assert_invariant();
+ return *this;
+ }
+
+ /*!
+ @brief destructor
+
+ Destroys the JSON value and frees all allocated memory.
+
+ @complexity Linear.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is linear.
+ - All stored elements are destroyed and all memory is freed.
+
+ @since version 1.0.0
+ */
+ ~basic_json() noexcept
+ {
+ assert_invariant();
+ m_value.destroy(m_type);
+ }
+
+ /// @}
+
+ public:
+ ///////////////////////
+ // object inspection //
+ ///////////////////////
+
+ /// @name object inspection
+ /// Functions to inspect the type of a JSON value.
+ /// @{
+
+ /*!
+ @brief serialization
+
+ Serialization function for JSON values. The function tries to mimic
+ Python's `json.dumps()` function, and currently supports its @a indent
+ and @a ensure_ascii parameters.
+
+ @param[in] indent If indent is nonnegative, then array elements and object
+ members will be pretty-printed with that indent level. An indent level of
+ `0` will only insert newlines. `-1` (the default) selects the most compact
+ representation.
+ @param[in] indent_char The character to use for indentation if @a indent is
+ greater than `0`. The default is ` ` (space).
+ @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
+ in the output are escaped with `\uXXXX` sequences, and the result consists
+ of ASCII characters only.
+ @param[in] error_handler how to react on decoding errors; there are three
+ possible values: `strict` (throws and exception in case a decoding error
+ occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
+ and `ignore` (ignore invalid UTF-8 sequences during serialization).
+
+ @return string containing the serialization of the JSON value
+
+ @throw type_error.316 if a string stored inside the JSON value is not
+ UTF-8 encoded
+
+ @complexity Linear.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @liveexample{The following example shows the effect of different @a indent\,
+ @a indent_char\, and @a ensure_ascii parameters to the result of the
+ serialization.,dump}
+
+ @see https://docs.python.org/2/library/json.html#json.dump
+
+ @since version 1.0.0; indentation character @a indent_char, option
+ @a ensure_ascii and exceptions added in version 3.0.0; error
+ handlers added in version 3.4.0.
+ */
+ string_t dump(const int indent = -1,
+ const char indent_char = ' ',
+ const bool ensure_ascii = false,
+ const error_handler_t error_handler = error_handler_t::strict) const
+ {
+ string_t result;
+ serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
+
+ if (indent >= 0)
+ {
+ s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
+ }
+ else
+ {
+ s.dump(*this, false, ensure_ascii, 0);
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief return the type of the JSON value (explicit)
+
+ Return the type of the JSON value as a value from the @ref value_t
+ enumeration.
+
+ @return the type of the JSON value
+ Value type | return value
+ ------------------------- | -------------------------
+ null | value_t::null
+ boolean | value_t::boolean
+ string | value_t::string
+ number (integer) | value_t::number_integer
+ number (unsigned integer) | value_t::number_unsigned
+ number (floating-point) | value_t::number_float
+ object | value_t::object
+ array | value_t::array
+ discarded | value_t::discarded
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `type()` for all JSON
+ types.,type}
+
+ @sa @ref operator value_t() -- return the type of the JSON value (implicit)
+ @sa @ref type_name() -- return the type as string
+
+ @since version 1.0.0
+ */
+ constexpr value_t type() const noexcept
+ {
+ return m_type;
+ }
+
+ /*!
+ @brief return whether type is primitive
+
+ This function returns true if and only if the JSON type is primitive
+ (string, number, boolean, or null).
+
+ @return `true` if type is primitive (string, number, boolean, or null),
+ `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_primitive()` for all JSON
+ types.,is_primitive}
+
+ @sa @ref is_structured() -- returns whether JSON value is structured
+ @sa @ref is_null() -- returns whether JSON value is `null`
+ @sa @ref is_string() -- returns whether JSON value is a string
+ @sa @ref is_boolean() -- returns whether JSON value is a boolean
+ @sa @ref is_number() -- returns whether JSON value is a number
+
+ @since version 1.0.0
+ */
+ constexpr bool is_primitive() const noexcept
+ {
+ return is_null() or is_string() or is_boolean() or is_number();
+ }
+
+ /*!
+ @brief return whether type is structured
+
+ This function returns true if and only if the JSON type is structured
+ (array or object).
+
+ @return `true` if type is structured (array or object), `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_structured()` for all JSON
+ types.,is_structured}
+
+ @sa @ref is_primitive() -- returns whether value is primitive
+ @sa @ref is_array() -- returns whether value is an array
+ @sa @ref is_object() -- returns whether value is an object
+
+ @since version 1.0.0
+ */
+ constexpr bool is_structured() const noexcept
+ {
+ return is_array() or is_object();
+ }
+
+ /*!
+ @brief return whether value is null
+
+ This function returns true if and only if the JSON value is null.
+
+ @return `true` if type is null, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_null()` for all JSON
+ types.,is_null}
+
+ @since version 1.0.0
+ */
+ constexpr bool is_null() const noexcept
+ {
+ return m_type == value_t::null;
+ }
+
+ /*!
+ @brief return whether value is a boolean
+
+ This function returns true if and only if the JSON value is a boolean.
+
+ @return `true` if type is boolean, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_boolean()` for all JSON
+ types.,is_boolean}
+
+ @since version 1.0.0
+ */
+ constexpr bool is_boolean() const noexcept
+ {
+ return m_type == value_t::boolean;
+ }
+
+ /*!
+ @brief return whether value is a number
+
+ This function returns true if and only if the JSON value is a number. This
+ includes both integer (signed and unsigned) and floating-point values.
+
+ @return `true` if type is number (regardless whether integer, unsigned
+ integer or floating-type), `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_number()` for all JSON
+ types.,is_number}
+
+ @sa @ref is_number_integer() -- check if value is an integer or unsigned
+ integer number
+ @sa @ref is_number_unsigned() -- check if value is an unsigned integer
+ number
+ @sa @ref is_number_float() -- check if value is a floating-point number
+
+ @since version 1.0.0
+ */
+ constexpr bool is_number() const noexcept
+ {
+ return is_number_integer() or is_number_float();
+ }
+
+ /*!
+ @brief return whether value is an integer number
+
+ This function returns true if and only if the JSON value is a signed or
+ unsigned integer number. This excludes floating-point values.
+
+ @return `true` if type is an integer or unsigned integer number, `false`
+ otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_number_integer()` for all
+ JSON types.,is_number_integer}
+
+ @sa @ref is_number() -- check if value is a number
+ @sa @ref is_number_unsigned() -- check if value is an unsigned integer
+ number
+ @sa @ref is_number_float() -- check if value is a floating-point number
+
+ @since version 1.0.0
+ */
+ constexpr bool is_number_integer() const noexcept
+ {
+ return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
+ }
+
+ /*!
+ @brief return whether value is an unsigned integer number
+
+ This function returns true if and only if the JSON value is an unsigned
+ integer number. This excludes floating-point and signed integer values.
+
+ @return `true` if type is an unsigned integer number, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_number_unsigned()` for all
+ JSON types.,is_number_unsigned}
+
+ @sa @ref is_number() -- check if value is a number
+ @sa @ref is_number_integer() -- check if value is an integer or unsigned
+ integer number
+ @sa @ref is_number_float() -- check if value is a floating-point number
+
+ @since version 2.0.0
+ */
+ constexpr bool is_number_unsigned() const noexcept
+ {
+ return m_type == value_t::number_unsigned;
+ }
+
+ /*!
+ @brief return whether value is a floating-point number
+
+ This function returns true if and only if the JSON value is a
+ floating-point number. This excludes signed and unsigned integer values.
+
+ @return `true` if type is a floating-point number, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_number_float()` for all
+ JSON types.,is_number_float}
+
+ @sa @ref is_number() -- check if value is number
+ @sa @ref is_number_integer() -- check if value is an integer number
+ @sa @ref is_number_unsigned() -- check if value is an unsigned integer
+ number
+
+ @since version 1.0.0
+ */
+ constexpr bool is_number_float() const noexcept
+ {
+ return m_type == value_t::number_float;
+ }
+
+ /*!
+ @brief return whether value is an object
+
+ This function returns true if and only if the JSON value is an object.
+
+ @return `true` if type is object, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_object()` for all JSON
+ types.,is_object}
+
+ @since version 1.0.0
+ */
+ constexpr bool is_object() const noexcept
+ {
+ return m_type == value_t::object;
+ }
+
+ /*!
+ @brief return whether value is an array
+
+ This function returns true if and only if the JSON value is an array.
+
+ @return `true` if type is array, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_array()` for all JSON
+ types.,is_array}
+
+ @since version 1.0.0
+ */
+ constexpr bool is_array() const noexcept
+ {
+ return m_type == value_t::array;
+ }
+
+ /*!
+ @brief return whether value is a string
+
+ This function returns true if and only if the JSON value is a string.
+
+ @return `true` if type is string, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_string()` for all JSON
+ types.,is_string}
+
+ @since version 1.0.0
+ */
+ constexpr bool is_string() const noexcept
+ {
+ return m_type == value_t::string;
+ }
+
+ /*!
+ @brief return whether value is discarded
+
+ This function returns true if and only if the JSON value was discarded
+ during parsing with a callback function (see @ref parser_callback_t).
+
+ @note This function will always be `false` for JSON values after parsing.
+ That is, discarded values can only occur during parsing, but will be
+ removed when inside a structured value or replaced by null in other cases.
+
+ @return `true` if type is discarded, `false` otherwise.
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies `is_discarded()` for all JSON
+ types.,is_discarded}
+
+ @since version 1.0.0
+ */
+ constexpr bool is_discarded() const noexcept
+ {
+ return m_type == value_t::discarded;
+ }
+
+ /*!
+ @brief return the type of the JSON value (implicit)
+
+ Implicitly return the type of the JSON value as a value from the @ref
+ value_t enumeration.
+
+ @return the type of the JSON value
+
+ @complexity Constant.
+
+ @exceptionsafety No-throw guarantee: this member function never throws
+ exceptions.
+
+ @liveexample{The following code exemplifies the @ref value_t operator for
+ all JSON types.,operator__value_t}
+
+ @sa @ref type() -- return the type of the JSON value (explicit)
+ @sa @ref type_name() -- return the type as string
+
+ @since version 1.0.0
+ */
+ constexpr operator value_t() const noexcept
+ {
+ return m_type;
+ }
+
+ /// @}
+
+ private:
+ //////////////////
+ // value access //
+ //////////////////
+
+ /// get a boolean (explicit)
+ boolean_t get_impl(boolean_t* /*unused*/) const
+ {
+ if (JSON_LIKELY(is_boolean()))
+ {
+ return m_value.boolean;
+ }
+
+ JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
+ }
+
+ /// get a pointer to the value (object)
+ object_t* get_impl_ptr(object_t* /*unused*/) noexcept
+ {
+ return is_object() ? m_value.object : nullptr;
+ }
+
+ /// get a pointer to the value (object)
+ constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
+ {
+ return is_object() ? m_value.object : nullptr;
+ }
+
+ /// get a pointer to the value (array)
+ array_t* get_impl_ptr(array_t* /*unused*/) noexcept
+ {
+ return is_array() ? m_value.array : nullptr;
+ }
+
+ /// get a pointer to the value (array)
+ constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
+ {
+ return is_array() ? m_value.array : nullptr;
+ }
+
+ /// get a pointer to the value (string)
+ string_t* get_impl_ptr(string_t* /*unused*/) noexcept
+ {
+ return is_string() ? m_value.string : nullptr;
+ }
+
+ /// get a pointer to the value (string)
+ constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
+ {
+ return is_string() ? m_value.string : nullptr;
+ }
+
+ /// get a pointer to the value (boolean)
+ boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
+ {
+ return is_boolean() ? &m_value.boolean : nullptr;
+ }
+
+ /// get a pointer to the value (boolean)
+ constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
+ {
+ return is_boolean() ? &m_value.boolean : nullptr;
+ }
+
+ /// get a pointer to the value (integer number)
+ number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
+ {
+ return is_number_integer() ? &m_value.number_integer : nullptr;
+ }
+
+ /// get a pointer to the value (integer number)
+ constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
+ {
+ return is_number_integer() ? &m_value.number_integer : nullptr;
+ }
+
+ /// get a pointer to the value (unsigned number)
+ number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
+ {
+ return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+ }
+
+ /// get a pointer to the value (unsigned number)
+ constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
+ {
+ return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
+ }
+
+ /// get a pointer to the value (floating-point number)
+ number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
+ {
+ return is_number_float() ? &m_value.number_float : nullptr;
+ }
+
+ /// get a pointer to the value (floating-point number)
+ constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
+ {
+ return is_number_float() ? &m_value.number_float : nullptr;
+ }
+
+ /*!
+ @brief helper function to implement get_ref()
+
+ This function helps to implement get_ref() without code duplication for
+ const and non-const overloads
+
+ @tparam ThisType will be deduced as `basic_json` or `const basic_json`
+
+ @throw type_error.303 if ReferenceType does not match underlying value
+ type of the current JSON
+ */
+ template<typename ReferenceType, typename ThisType>
+ static ReferenceType get_ref_impl(ThisType& obj)
+ {
+ // delegate the call to get_ptr<>()
+ auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
+
+ if (JSON_LIKELY(ptr != nullptr))
+ {
+ return *ptr;
+ }
+
+ JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
+ }
+
+ public:
+ /// @name value access
+ /// Direct access to the stored value of a JSON value.
+ /// @{
+
+ /*!
+ @brief get special-case overload
+
+ This overloads avoids a lot of template boilerplate, it can be seen as the
+ identity method
+
+ @tparam BasicJsonType == @ref basic_json
+
+ @return a copy of *this
+
+ @complexity Constant.
+
+ @since version 2.1.0
+ */
+ template<typename BasicJsonType, detail::enable_if_t<
+ std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
+ int> = 0>
+ basic_json get() const
+ {
+ return *this;
+ }
+
+ /*!
+ @brief get special-case overload
+
+ This overloads converts the current @ref basic_json in a different
+ @ref basic_json type
+
+ @tparam BasicJsonType == @ref basic_json
+
+ @return a copy of *this, converted into @tparam BasicJsonType
+
+ @complexity Depending on the implementation of the called `from_json()`
+ method.
+
+ @since version 3.2.0
+ */
+ template<typename BasicJsonType, detail::enable_if_t<
+ not std::is_same<BasicJsonType, basic_json>::value and
+ detail::is_basic_json<BasicJsonType>::value, int> = 0>
+ BasicJsonType get() const
+ {
+ return *this;
+ }
+
+ /*!
+ @brief get a value (explicit)
+
+ Explicit type conversion between the JSON value and a compatible value
+ which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
+ and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
+ The value is converted by calling the @ref json_serializer<ValueType>
+ `from_json()` method.
+
+ The function is equivalent to executing
+ @code {.cpp}
+ ValueType ret;
+ JSONSerializer<ValueType>::from_json(*this, ret);
+ return ret;
+ @endcode
+
+ This overloads is chosen if:
+ - @a ValueType is not @ref basic_json,
+ - @ref json_serializer<ValueType> has a `from_json()` method of the form
+ `void from_json(const basic_json&, ValueType&)`, and
+ - @ref json_serializer<ValueType> does not have a `from_json()` method of
+ the form `ValueType from_json(const basic_json&)`
+
+ @tparam ValueTypeCV the provided value type
+ @tparam ValueType the returned value type
+
+ @return copy of the JSON value, converted to @a ValueType
+
+ @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+ @liveexample{The example below shows several conversions from JSON values
+ to other types. There a few things to note: (1) Floating-point numbers can
+ be converted to integers\, (2) A JSON array can be converted to a standard
+ `std::vector<short>`\, (3) A JSON object can be converted to C++
+ associative containers such as `std::unordered_map<std::string\,
+ json>`.,get__ValueType_const}
+
+ @since version 2.1.0
+ */
+ template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+ detail::enable_if_t <
+ not detail::is_basic_json<ValueType>::value and
+ detail::has_from_json<basic_json_t, ValueType>::value and
+ not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+ int> = 0>
+ ValueType get() const noexcept(noexcept(
+ JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
+ {
+ // we cannot static_assert on ValueTypeCV being non-const, because
+ // there is support for get<const basic_json_t>(), which is why we
+ // still need the uncvref
+ static_assert(not std::is_reference<ValueTypeCV>::value,
+ "get() cannot be used with reference types, you might want to use get_ref()");
+ static_assert(std::is_default_constructible<ValueType>::value,
+ "types must be DefaultConstructible when used with get()");
+
+ ValueType ret;
+ JSONSerializer<ValueType>::from_json(*this, ret);
+ return ret;
+ }
+
+ /*!
+ @brief get a value (explicit); special case
+
+ Explicit type conversion between the JSON value and a compatible value
+ which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
+ and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
+ The value is converted by calling the @ref json_serializer<ValueType>
+ `from_json()` method.
+
+ The function is equivalent to executing
+ @code {.cpp}
+ return JSONSerializer<ValueTypeCV>::from_json(*this);
+ @endcode
+
+ This overloads is chosen if:
+ - @a ValueType is not @ref basic_json and
+ - @ref json_serializer<ValueType> has a `from_json()` method of the form
+ `ValueType from_json(const basic_json&)`
+
+ @note If @ref json_serializer<ValueType> has both overloads of
+ `from_json()`, this one is chosen.
+
+ @tparam ValueTypeCV the provided value type
+ @tparam ValueType the returned value type
+
+ @return copy of the JSON value, converted to @a ValueType
+
+ @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+ @since version 2.1.0
+ */
+ template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
+ detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
+ detail::has_non_default_from_json<basic_json_t, ValueType>::value,
+ int> = 0>
+ ValueType get() const noexcept(noexcept(
+ JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
+ {
+ static_assert(not std::is_reference<ValueTypeCV>::value,
+ "get() cannot be used with reference types, you might want to use get_ref()");
+ return JSONSerializer<ValueTypeCV>::from_json(*this);
+ }
+
+ /*!
+ @brief get a value (explicit)
+
+ Explicit type conversion between the JSON value and a compatible value.
+ The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
+ `from_json()` method.
+
+ The function is equivalent to executing
+ @code {.cpp}
+ ValueType v;
+ JSONSerializer<ValueType>::from_json(*this, v);
+ @endcode
+
+ This overloads is chosen if:
+ - @a ValueType is not @ref basic_json,
+ - @ref json_serializer<ValueType> has a `from_json()` method of the form
+ `void from_json(const basic_json&, ValueType&)`, and
+
+ @tparam ValueType the input parameter type.
+
+ @return the input parameter, allowing chaining calls.
+
+ @throw what @ref json_serializer<ValueType> `from_json()` method throws
+
+ @liveexample{The example below shows several conversions from JSON values
+ to other types. There a few things to note: (1) Floating-point numbers can
+ be converted to integers\, (2) A JSON array can be converted to a standard
+ `std::vector<short>`\, (3) A JSON object can be converted to C++
+ associative containers such as `std::unordered_map<std::string\,
+ json>`.,get_to}
+
+ @since version 3.3.0
+ */
+ template<typename ValueType,
+ detail::enable_if_t <
+ not detail::is_basic_json<ValueType>::value and
+ detail::has_from_json<basic_json_t, ValueType>::value,
+ int> = 0>
+ ValueType & get_to(ValueType& v) const noexcept(noexcept(
+ JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
+ {
+ JSONSerializer<ValueType>::from_json(*this, v);
+ return v;
+ }
+
+
+ /*!
+ @brief get a pointer value (implicit)
+
+ Implicit pointer access to the internally stored JSON value. No copies are
+ made.
+
+ @warning Writing data to the pointee of the result yields an undefined
+ state.
+
+ @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
+ object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
+ @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
+ assertion.
+
+ @return pointer to the internally stored JSON value if the requested
+ pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how pointers to internal values of a
+ JSON value can be requested. Note that no type conversions are made and a
+ `nullptr` is returned if the value and the requested pointer type does not
+ match.,get_ptr}
+
+ @since version 1.0.0
+ */
+ template<typename PointerType, typename std::enable_if<
+ std::is_pointer<PointerType>::value, int>::type = 0>
+ auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
+ {
+ // delegate the call to get_impl_ptr<>()
+ return get_impl_ptr(static_cast<PointerType>(nullptr));
+ }
+
+ /*!
+ @brief get a pointer value (implicit)
+ @copydoc get_ptr()
+ */
+ template<typename PointerType, typename std::enable_if<
+ std::is_pointer<PointerType>::value and
+ std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
+ constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
+ {
+ // delegate the call to get_impl_ptr<>() const
+ return get_impl_ptr(static_cast<PointerType>(nullptr));
+ }
+
+ /*!
+ @brief get a pointer value (explicit)
+
+ Explicit pointer access to the internally stored JSON value. No copies are
+ made.
+
+ @warning The pointer becomes invalid if the underlying JSON object
+ changes.
+
+ @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
+ object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
+ @ref number_unsigned_t, or @ref number_float_t.
+
+ @return pointer to the internally stored JSON value if the requested
+ pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how pointers to internal values of a
+ JSON value can be requested. Note that no type conversions are made and a
+ `nullptr` is returned if the value and the requested pointer type does not
+ match.,get__PointerType}
+
+ @sa @ref get_ptr() for explicit pointer-member access
+
+ @since version 1.0.0
+ */
+ template<typename PointerType, typename std::enable_if<
+ std::is_pointer<PointerType>::value, int>::type = 0>
+ auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
+ {
+ // delegate the call to get_ptr
+ return get_ptr<PointerType>();
+ }
+
+ /*!
+ @brief get a pointer value (explicit)
+ @copydoc get()
+ */
+ template<typename PointerType, typename std::enable_if<
+ std::is_pointer<PointerType>::value, int>::type = 0>
+ constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
+ {
+ // delegate the call to get_ptr
+ return get_ptr<PointerType>();
+ }
+
+ /*!
+ @brief get a reference value (implicit)
+
+ Implicit reference access to the internally stored JSON value. No copies
+ are made.
+
+ @warning Writing data to the referee of the result yields an undefined
+ state.
+
+ @tparam ReferenceType reference type; must be a reference to @ref array_t,
+ @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
+ @ref number_float_t. Enforced by static assertion.
+
+ @return reference to the internally stored JSON value if the requested
+ reference type @a ReferenceType fits to the JSON value; throws
+ type_error.303 otherwise
+
+ @throw type_error.303 in case passed type @a ReferenceType is incompatible
+ with the stored JSON value; see example below
+
+ @complexity Constant.
+
+ @liveexample{The example shows several calls to `get_ref()`.,get_ref}
+
+ @since version 1.1.0
+ */
+ template<typename ReferenceType, typename std::enable_if<
+ std::is_reference<ReferenceType>::value, int>::type = 0>
+ ReferenceType get_ref()
+ {
+ // delegate call to get_ref_impl
+ return get_ref_impl<ReferenceType>(*this);
+ }
+
+ /*!
+ @brief get a reference value (implicit)
+ @copydoc get_ref()
+ */
+ template<typename ReferenceType, typename std::enable_if<
+ std::is_reference<ReferenceType>::value and
+ std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
+ ReferenceType get_ref() const
+ {
+ // delegate call to get_ref_impl
+ return get_ref_impl<ReferenceType>(*this);
+ }
+
+ /*!
+ @brief get a value (implicit)
+
+ Implicit type conversion between the JSON value and a compatible value.
+ The call is realized by calling @ref get() const.
+
+ @tparam ValueType non-pointer type compatible to the JSON value, for
+ instance `int` for JSON integer numbers, `bool` for JSON booleans, or
+ `std::vector` types for JSON arrays. The character type of @ref string_t
+ as well as an initializer list of this type is excluded to avoid
+ ambiguities as these types implicitly convert to `std::string`.
+
+ @return copy of the JSON value, converted to type @a ValueType
+
+ @throw type_error.302 in case passed type @a ValueType is incompatible
+ to the JSON value type (e.g., the JSON value is of type boolean, but a
+ string is requested); see example below
+
+ @complexity Linear in the size of the JSON value.
+
+ @liveexample{The example below shows several conversions from JSON values
+ to other types. There a few things to note: (1) Floating-point numbers can
+ be converted to integers\, (2) A JSON array can be converted to a standard
+ `std::vector<short>`\, (3) A JSON object can be converted to C++
+ associative containers such as `std::unordered_map<std::string\,
+ json>`.,operator__ValueType}
+
+ @since version 1.0.0
+ */
+ template < typename ValueType, typename std::enable_if <
+ not std::is_pointer<ValueType>::value and
+ not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
+ not std::is_same<ValueType, typename string_t::value_type>::value and
+ not detail::is_basic_json<ValueType>::value
+
+#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
+ and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
+#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
+ and not std::is_same<ValueType, typename std::string_view>::value
+#endif
+#endif
+ and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
+ , int >::type = 0 >
+ operator ValueType() const
+ {
+ // delegate the call to get<>() const
+ return get<ValueType>();
+ }
+
+ /// @}
+
+
+ ////////////////////
+ // element access //
+ ////////////////////
+
+ /// @name element access
+ /// Access to the JSON value.
+ /// @{
+
+ /*!
+ @brief access specified array element with bounds checking
+
+ Returns a reference to the element at specified location @a idx, with
+ bounds checking.
+
+ @param[in] idx index of the element to access
+
+ @return reference to the element at index @a idx
+
+ @throw type_error.304 if the JSON value is not an array; in this case,
+ calling `at` with an index makes no sense. See example below.
+ @throw out_of_range.401 if the index @a idx is out of range of the array;
+ that is, `idx >= size()`. See example below.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Constant.
+
+ @since version 1.0.0
+
+ @liveexample{The example below shows how array elements can be read and
+ written using `at()`. It also demonstrates the different exceptions that
+ can be thrown.,at__size_type}
+ */
+ reference at(size_type idx)
+ {
+ // at only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ JSON_TRY
+ {
+ return m_value.array->at(idx);
+ }
+ JSON_CATCH (std::out_of_range&)
+ {
+ // create better exception explanation
+ JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+ }
+ }
+ else
+ {
+ JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+ }
+ }
+
+ /*!
+ @brief access specified array element with bounds checking
+
+ Returns a const reference to the element at specified location @a idx,
+ with bounds checking.
+
+ @param[in] idx index of the element to access
+
+ @return const reference to the element at index @a idx
+
+ @throw type_error.304 if the JSON value is not an array; in this case,
+ calling `at` with an index makes no sense. See example below.
+ @throw out_of_range.401 if the index @a idx is out of range of the array;
+ that is, `idx >= size()`. See example below.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Constant.
+
+ @since version 1.0.0
+
+ @liveexample{The example below shows how array elements can be read using
+ `at()`. It also demonstrates the different exceptions that can be thrown.,
+ at__size_type_const}
+ */
+ const_reference at(size_type idx) const
+ {
+ // at only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ JSON_TRY
+ {
+ return m_value.array->at(idx);
+ }
+ JSON_CATCH (std::out_of_range&)
+ {
+ // create better exception explanation
+ JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+ }
+ }
+ else
+ {
+ JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+ }
+ }
+
+ /*!
+ @brief access specified object element with bounds checking
+
+ Returns a reference to the element at with specified key @a key, with
+ bounds checking.
+
+ @param[in] key key of the element to access
+
+ @return reference to the element at key @a key
+
+ @throw type_error.304 if the JSON value is not an object; in this case,
+ calling `at` with a key makes no sense. See example below.
+ @throw out_of_range.403 if the key @a key is is not stored in the object;
+ that is, `find(key) == end()`. See example below.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Logarithmic in the size of the container.
+
+ @sa @ref operator[](const typename object_t::key_type&) for unchecked
+ access by reference
+ @sa @ref value() for access by value with a default value
+
+ @since version 1.0.0
+
+ @liveexample{The example below shows how object elements can be read and
+ written using `at()`. It also demonstrates the different exceptions that
+ can be thrown.,at__object_t_key_type}
+ */
+ reference at(const typename object_t::key_type& key)
+ {
+ // at only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ JSON_TRY
+ {
+ return m_value.object->at(key);
+ }
+ JSON_CATCH (std::out_of_range&)
+ {
+ // create better exception explanation
+ JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
+ }
+ }
+ else
+ {
+ JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+ }
+ }
+
+ /*!
+ @brief access specified object element with bounds checking
+
+ Returns a const reference to the element at with specified key @a key,
+ with bounds checking.
+
+ @param[in] key key of the element to access
+
+ @return const reference to the element at key @a key
+
+ @throw type_error.304 if the JSON value is not an object; in this case,
+ calling `at` with a key makes no sense. See example below.
+ @throw out_of_range.403 if the key @a key is is not stored in the object;
+ that is, `find(key) == end()`. See example below.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Logarithmic in the size of the container.
+
+ @sa @ref operator[](const typename object_t::key_type&) for unchecked
+ access by reference
+ @sa @ref value() for access by value with a default value
+
+ @since version 1.0.0
+
+ @liveexample{The example below shows how object elements can be read using
+ `at()`. It also demonstrates the different exceptions that can be thrown.,
+ at__object_t_key_type_const}
+ */
+ const_reference at(const typename object_t::key_type& key) const
+ {
+ // at only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ JSON_TRY
+ {
+ return m_value.object->at(key);
+ }
+ JSON_CATCH (std::out_of_range&)
+ {
+ // create better exception explanation
+ JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
+ }
+ }
+ else
+ {
+ JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
+ }
+ }
+
+ /*!
+ @brief access specified array element
+
+ Returns a reference to the element at specified location @a idx.
+
+ @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
+ then the array is silently filled up with `null` values to make `idx` a
+ valid reference to the last stored element.
+
+ @param[in] idx index of the element to access
+
+ @return reference to the element at index @a idx
+
+ @throw type_error.305 if the JSON value is not an array or null; in that
+ cases, using the [] operator with an index makes no sense.
+
+ @complexity Constant if @a idx is in the range of the array. Otherwise
+ linear in `idx - size()`.
+
+ @liveexample{The example below shows how array elements can be read and
+ written using `[]` operator. Note the addition of `null`
+ values.,operatorarray__size_type}
+
+ @since version 1.0.0
+ */
+ reference operator[](size_type idx)
+ {
+ // implicitly convert null value to an empty array
+ if (is_null())
+ {
+ m_type = value_t::array;
+ m_value.array = create<array_t>();
+ assert_invariant();
+ }
+
+ // operator[] only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ // fill up array with null values if given idx is outside range
+ if (idx >= m_value.array->size())
+ {
+ m_value.array->insert(m_value.array->end(),
+ idx - m_value.array->size() + 1,
+ basic_json());
+ }
+
+ return m_value.array->operator[](idx);
+ }
+
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief access specified array element
+
+ Returns a const reference to the element at specified location @a idx.
+
+ @param[in] idx index of the element to access
+
+ @return const reference to the element at index @a idx
+
+ @throw type_error.305 if the JSON value is not an array; in that case,
+ using the [] operator with an index makes no sense.
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how array elements can be read using
+ the `[]` operator.,operatorarray__size_type_const}
+
+ @since version 1.0.0
+ */
+ const_reference operator[](size_type idx) const
+ {
+ // const operator[] only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ return m_value.array->operator[](idx);
+ }
+
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief access specified object element
+
+ Returns a reference to the element at with specified key @a key.
+
+ @note If @a key is not found in the object, then it is silently added to
+ the object and filled with a `null` value to make `key` a valid reference.
+ In case the value was `null` before, it is converted to an object.
+
+ @param[in] key key of the element to access
+
+ @return reference to the element at key @a key
+
+ @throw type_error.305 if the JSON value is not an object or null; in that
+ cases, using the [] operator with a key makes no sense.
+
+ @complexity Logarithmic in the size of the container.
+
+ @liveexample{The example below shows how object elements can be read and
+ written using the `[]` operator.,operatorarray__key_type}
+
+ @sa @ref at(const typename object_t::key_type&) for access by reference
+ with range checking
+ @sa @ref value() for access by value with a default value
+
+ @since version 1.0.0
+ */
+ reference operator[](const typename object_t::key_type& key)
+ {
+ // implicitly convert null value to an empty object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value.object = create<object_t>();
+ assert_invariant();
+ }
+
+ // operator[] only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ return m_value.object->operator[](key);
+ }
+
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief read-only access specified object element
+
+ Returns a const reference to the element at with specified key @a key. No
+ bounds checking is performed.
+
+ @warning If the element with key @a key does not exist, the behavior is
+ undefined.
+
+ @param[in] key key of the element to access
+
+ @return const reference to the element at key @a key
+
+ @pre The element with key @a key must exist. **This precondition is
+ enforced with an assertion.**
+
+ @throw type_error.305 if the JSON value is not an object; in that case,
+ using the [] operator with a key makes no sense.
+
+ @complexity Logarithmic in the size of the container.
+
+ @liveexample{The example below shows how object elements can be read using
+ the `[]` operator.,operatorarray__key_type_const}
+
+ @sa @ref at(const typename object_t::key_type&) for access by reference
+ with range checking
+ @sa @ref value() for access by value with a default value
+
+ @since version 1.0.0
+ */
+ const_reference operator[](const typename object_t::key_type& key) const
+ {
+ // const operator[] only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ assert(m_value.object->find(key) != m_value.object->end());
+ return m_value.object->find(key)->second;
+ }
+
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief access specified object element
+
+ Returns a reference to the element at with specified key @a key.
+
+ @note If @a key is not found in the object, then it is silently added to
+ the object and filled with a `null` value to make `key` a valid reference.
+ In case the value was `null` before, it is converted to an object.
+
+ @param[in] key key of the element to access
+
+ @return reference to the element at key @a key
+
+ @throw type_error.305 if the JSON value is not an object or null; in that
+ cases, using the [] operator with a key makes no sense.
+
+ @complexity Logarithmic in the size of the container.
+
+ @liveexample{The example below shows how object elements can be read and
+ written using the `[]` operator.,operatorarray__key_type}
+
+ @sa @ref at(const typename object_t::key_type&) for access by reference
+ with range checking
+ @sa @ref value() for access by value with a default value
+
+ @since version 1.1.0
+ */
+ template<typename T>
+ reference operator[](T* key)
+ {
+ // implicitly convert null to object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value = value_t::object;
+ assert_invariant();
+ }
+
+ // at only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ return m_value.object->operator[](key);
+ }
+
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief read-only access specified object element
+
+ Returns a const reference to the element at with specified key @a key. No
+ bounds checking is performed.
+
+ @warning If the element with key @a key does not exist, the behavior is
+ undefined.
+
+ @param[in] key key of the element to access
+
+ @return const reference to the element at key @a key
+
+ @pre The element with key @a key must exist. **This precondition is
+ enforced with an assertion.**
+
+ @throw type_error.305 if the JSON value is not an object; in that case,
+ using the [] operator with a key makes no sense.
+
+ @complexity Logarithmic in the size of the container.
+
+ @liveexample{The example below shows how object elements can be read using
+ the `[]` operator.,operatorarray__key_type_const}
+
+ @sa @ref at(const typename object_t::key_type&) for access by reference
+ with range checking
+ @sa @ref value() for access by value with a default value
+
+ @since version 1.1.0
+ */
+ template<typename T>
+ const_reference operator[](T* key) const
+ {
+ // at only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ assert(m_value.object->find(key) != m_value.object->end());
+ return m_value.object->find(key)->second;
+ }
+
+ JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief access specified object element with default value
+
+ Returns either a copy of an object's element at the specified key @a key
+ or a given default value if no element with key @a key exists.
+
+ The function is basically equivalent to executing
+ @code {.cpp}
+ try {
+ return at(key);
+ } catch(out_of_range) {
+ return default_value;
+ }
+ @endcode
+
+ @note Unlike @ref at(const typename object_t::key_type&), this function
+ does not throw if the given key @a key was not found.
+
+ @note Unlike @ref operator[](const typename object_t::key_type& key), this
+ function does not implicitly add an element to the position defined by @a
+ key. This function is furthermore also applicable to const objects.
+
+ @param[in] key key of the element to access
+ @param[in] default_value the value to return if @a key is not found
+
+ @tparam ValueType type compatible to JSON values, for instance `int` for
+ JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
+ JSON arrays. Note the type of the expected value at @a key and the default
+ value @a default_value must be compatible.
+
+ @return copy of the element at key @a key or @a default_value if @a key
+ is not found
+
+ @throw type_error.306 if the JSON value is not an object; in that case,
+ using `value()` with a key makes no sense.
+
+ @complexity Logarithmic in the size of the container.
+
+ @liveexample{The example below shows how object elements can be queried
+ with a default value.,basic_json__value}
+
+ @sa @ref at(const typename object_t::key_type&) for access by reference
+ with range checking
+ @sa @ref operator[](const typename object_t::key_type&) for unchecked
+ access by reference
+
+ @since version 1.0.0
+ */
+ template<class ValueType, typename std::enable_if<
+ std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
+ ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
+ {
+ // at only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ // if key is found, return value and given default value otherwise
+ const auto it = find(key);
+ if (it != end())
+ {
+ return *it;
+ }
+
+ return default_value;
+ }
+
+ JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief overload for a default value of type const char*
+ @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
+ */
+ string_t value(const typename object_t::key_type& key, const char* default_value) const
+ {
+ return value(key, string_t(default_value));
+ }
+
+ /*!
+ @brief access specified object element via JSON Pointer with default value
+
+ Returns either a copy of an object's element at the specified key @a key
+ or a given default value if no element with key @a key exists.
+
+ The function is basically equivalent to executing
+ @code {.cpp}
+ try {
+ return at(ptr);
+ } catch(out_of_range) {
+ return default_value;
+ }
+ @endcode
+
+ @note Unlike @ref at(const json_pointer&), this function does not throw
+ if the given key @a key was not found.
+
+ @param[in] ptr a JSON pointer to the element to access
+ @param[in] default_value the value to return if @a ptr found no value
+
+ @tparam ValueType type compatible to JSON values, for instance `int` for
+ JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
+ JSON arrays. Note the type of the expected value at @a key and the default
+ value @a default_value must be compatible.
+
+ @return copy of the element at key @a key or @a default_value if @a key
+ is not found
+
+ @throw type_error.306 if the JSON value is not an object; in that case,
+ using `value()` with a key makes no sense.
+
+ @complexity Logarithmic in the size of the container.
+
+ @liveexample{The example below shows how object elements can be queried
+ with a default value.,basic_json__value_ptr}
+
+ @sa @ref operator[](const json_pointer&) for unchecked access by reference
+
+ @since version 2.0.2
+ */
+ template<class ValueType, typename std::enable_if<
+ std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
+ ValueType value(const json_pointer& ptr, const ValueType& default_value) const
+ {
+ // at only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ // if pointer resolves a value, return it or use default value
+ JSON_TRY
+ {
+ return ptr.get_checked(this);
+ }
+ JSON_INTERNAL_CATCH (out_of_range&)
+ {
+ return default_value;
+ }
+ }
+
+ JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief overload for a default value of type const char*
+ @copydoc basic_json::value(const json_pointer&, ValueType) const
+ */
+ string_t value(const json_pointer& ptr, const char* default_value) const
+ {
+ return value(ptr, string_t(default_value));
+ }
+
+ /*!
+ @brief access the first element
+
+ Returns a reference to the first element in the container. For a JSON
+ container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
+
+ @return In case of a structured type (array or object), a reference to the
+ first element is returned. In case of number, string, or boolean values, a
+ reference to the value is returned.
+
+ @complexity Constant.
+
+ @pre The JSON value must not be `null` (would throw `std::out_of_range`)
+ or an empty array or object (undefined behavior, **guarded by
+ assertions**).
+ @post The JSON value remains unchanged.
+
+ @throw invalid_iterator.214 when called on `null` value
+
+ @liveexample{The following code shows an example for `front()`.,front}
+
+ @sa @ref back() -- access the last element
+
+ @since version 1.0.0
+ */
+ reference front()
+ {
+ return *begin();
+ }
+
+ /*!
+ @copydoc basic_json::front()
+ */
+ const_reference front() const
+ {
+ return *cbegin();
+ }
+
+ /*!
+ @brief access the last element
+
+ Returns a reference to the last element in the container. For a JSON
+ container `c`, the expression `c.back()` is equivalent to
+ @code {.cpp}
+ auto tmp = c.end();
+ --tmp;
+ return *tmp;
+ @endcode
+
+ @return In case of a structured type (array or object), a reference to the
+ last element is returned. In case of number, string, or boolean values, a
+ reference to the value is returned.
+
+ @complexity Constant.
+
+ @pre The JSON value must not be `null` (would throw `std::out_of_range`)
+ or an empty array or object (undefined behavior, **guarded by
+ assertions**).
+ @post The JSON value remains unchanged.
+
+ @throw invalid_iterator.214 when called on a `null` value. See example
+ below.
+
+ @liveexample{The following code shows an example for `back()`.,back}
+
+ @sa @ref front() -- access the first element
+
+ @since version 1.0.0
+ */
+ reference back()
+ {
+ auto tmp = end();
+ --tmp;
+ return *tmp;
+ }
+
+ /*!
+ @copydoc basic_json::back()
+ */
+ const_reference back() const
+ {
+ auto tmp = cend();
+ --tmp;
+ return *tmp;
+ }
+
+ /*!
+ @brief remove element given an iterator
+
+ Removes the element specified by iterator @a pos. The iterator @a pos must
+ be valid and dereferenceable. Thus the `end()` iterator (which is valid,
+ but is not dereferenceable) cannot be used as a value for @a pos.
+
+ If called on a primitive type other than `null`, the resulting JSON value
+ will be `null`.
+
+ @param[in] pos iterator to the element to remove
+ @return Iterator following the last removed element. If the iterator @a
+ pos refers to the last element, the `end()` iterator is returned.
+
+ @tparam IteratorType an @ref iterator or @ref const_iterator
+
+ @post Invalidates iterators and references at or after the point of the
+ erase, including the `end()` iterator.
+
+ @throw type_error.307 if called on a `null` value; example: `"cannot use
+ erase() with null"`
+ @throw invalid_iterator.202 if called on an iterator which does not belong
+ to the current JSON value; example: `"iterator does not fit current
+ value"`
+ @throw invalid_iterator.205 if called on a primitive type with invalid
+ iterator (i.e., any iterator which is not `begin()`); example: `"iterator
+ out of range"`
+
+ @complexity The complexity depends on the type:
+ - objects: amortized constant
+ - arrays: linear in distance between @a pos and the end of the container
+ - strings: linear in the length of the string
+ - other types: constant
+
+ @liveexample{The example shows the result of `erase()` for different JSON
+ types.,erase__IteratorType}
+
+ @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
+ the given range
+ @sa @ref erase(const typename object_t::key_type&) -- removes the element
+ from an object at the given key
+ @sa @ref erase(const size_type) -- removes the element from an array at
+ the given index
+
+ @since version 1.0.0
+ */
+ template<class IteratorType, typename std::enable_if<
+ std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+ std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+ = 0>
+ IteratorType erase(IteratorType pos)
+ {
+ // make sure iterator fits the current value
+ if (JSON_UNLIKELY(this != pos.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+ }
+
+ IteratorType result = end();
+
+ switch (m_type)
+ {
+ case value_t::boolean:
+ case value_t::number_float:
+ case value_t::number_integer:
+ case value_t::number_unsigned:
+ case value_t::string:
+ {
+ if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
+ {
+ JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
+ }
+
+ if (is_string())
+ {
+ AllocatorType<string_t> alloc;
+ std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+ std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+ m_value.string = nullptr;
+ }
+
+ m_type = value_t::null;
+ assert_invariant();
+ break;
+ }
+
+ case value_t::object:
+ {
+ result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
+ break;
+ }
+
+ case value_t::array:
+ {
+ result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
+ break;
+ }
+
+ default:
+ JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief remove elements given an iterator range
+
+ Removes the element specified by the range `[first; last)`. The iterator
+ @a first does not need to be dereferenceable if `first == last`: erasing
+ an empty range is a no-op.
+
+ If called on a primitive type other than `null`, the resulting JSON value
+ will be `null`.
+
+ @param[in] first iterator to the beginning of the range to remove
+ @param[in] last iterator past the end of the range to remove
+ @return Iterator following the last removed element. If the iterator @a
+ second refers to the last element, the `end()` iterator is returned.
+
+ @tparam IteratorType an @ref iterator or @ref const_iterator
+
+ @post Invalidates iterators and references at or after the point of the
+ erase, including the `end()` iterator.
+
+ @throw type_error.307 if called on a `null` value; example: `"cannot use
+ erase() with null"`
+ @throw invalid_iterator.203 if called on iterators which does not belong
+ to the current JSON value; example: `"iterators do not fit current value"`
+ @throw invalid_iterator.204 if called on a primitive type with invalid
+ iterators (i.e., if `first != begin()` and `last != end()`); example:
+ `"iterators out of range"`
+
+ @complexity The complexity depends on the type:
+ - objects: `log(size()) + std::distance(first, last)`
+ - arrays: linear in the distance between @a first and @a last, plus linear
+ in the distance between @a last and end of the container
+ - strings: linear in the length of the string
+ - other types: constant
+
+ @liveexample{The example shows the result of `erase()` for different JSON
+ types.,erase__IteratorType_IteratorType}
+
+ @sa @ref erase(IteratorType) -- removes the element at a given position
+ @sa @ref erase(const typename object_t::key_type&) -- removes the element
+ from an object at the given key
+ @sa @ref erase(const size_type) -- removes the element from an array at
+ the given index
+
+ @since version 1.0.0
+ */
+ template<class IteratorType, typename std::enable_if<
+ std::is_same<IteratorType, typename basic_json_t::iterator>::value or
+ std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
+ = 0>
+ IteratorType erase(IteratorType first, IteratorType last)
+ {
+ // make sure iterator fits the current value
+ if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
+ }
+
+ IteratorType result = end();
+
+ switch (m_type)
+ {
+ case value_t::boolean:
+ case value_t::number_float:
+ case value_t::number_integer:
+ case value_t::number_unsigned:
+ case value_t::string:
+ {
+ if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
+ or not last.m_it.primitive_iterator.is_end()))
+ {
+ JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
+ }
+
+ if (is_string())
+ {
+ AllocatorType<string_t> alloc;
+ std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
+ std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
+ m_value.string = nullptr;
+ }
+
+ m_type = value_t::null;
+ assert_invariant();
+ break;
+ }
+
+ case value_t::object:
+ {
+ result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
+ last.m_it.object_iterator);
+ break;
+ }
+
+ case value_t::array:
+ {
+ result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
+ last.m_it.array_iterator);
+ break;
+ }
+
+ default:
+ JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief remove element from a JSON object given a key
+
+ Removes elements from a JSON object with the key value @a key.
+
+ @param[in] key value of the elements to remove
+
+ @return Number of elements removed. If @a ObjectType is the default
+ `std::map` type, the return value will always be `0` (@a key was not
+ found) or `1` (@a key was found).
+
+ @post References and iterators to the erased elements are invalidated.
+ Other references and iterators are not affected.
+
+ @throw type_error.307 when called on a type other than JSON object;
+ example: `"cannot use erase() with null"`
+
+ @complexity `log(size()) + count(key)`
+
+ @liveexample{The example shows the effect of `erase()`.,erase__key_type}
+
+ @sa @ref erase(IteratorType) -- removes the element at a given position
+ @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
+ the given range
+ @sa @ref erase(const size_type) -- removes the element from an array at
+ the given index
+
+ @since version 1.0.0
+ */
+ size_type erase(const typename object_t::key_type& key)
+ {
+ // this erase only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ return m_value.object->erase(key);
+ }
+
+ JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief remove element from a JSON array given an index
+
+ Removes element from a JSON array at the index @a idx.
+
+ @param[in] idx index of the element to remove
+
+ @throw type_error.307 when called on a type other than JSON object;
+ example: `"cannot use erase() with null"`
+ @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
+ is out of range"`
+
+ @complexity Linear in distance between @a idx and the end of the container.
+
+ @liveexample{The example shows the effect of `erase()`.,erase__size_type}
+
+ @sa @ref erase(IteratorType) -- removes the element at a given position
+ @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
+ the given range
+ @sa @ref erase(const typename object_t::key_type&) -- removes the element
+ from an object at the given key
+
+ @since version 1.0.0
+ */
+ void erase(const size_type idx)
+ {
+ // this erase only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ if (JSON_UNLIKELY(idx >= size()))
+ {
+ JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+ }
+
+ m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
+ }
+ else
+ {
+ JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
+ }
+ }
+
+ /// @}
+
+
+ ////////////
+ // lookup //
+ ////////////
+
+ /// @name lookup
+ /// @{
+
+ /*!
+ @brief find an element in a JSON object
+
+ Finds an element in a JSON object with key equivalent to @a key. If the
+ element is not found or the JSON value is not an object, end() is
+ returned.
+
+ @note This method always returns @ref end() when executed on a JSON type
+ that is not an object.
+
+ @param[in] key key value of the element to search for.
+
+ @return Iterator to an element with key equivalent to @a key. If no such
+ element is found or the JSON value is not an object, past-the-end (see
+ @ref end()) iterator is returned.
+
+ @complexity Logarithmic in the size of the JSON object.
+
+ @liveexample{The example shows how `find()` is used.,find__key_type}
+
+ @sa @ref contains(KeyT&&) const -- checks whether a key exists
+
+ @since version 1.0.0
+ */
+ template<typename KeyT>
+ iterator find(KeyT&& key)
+ {
+ auto result = end();
+
+ if (is_object())
+ {
+ result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief find an element in a JSON object
+ @copydoc find(KeyT&&)
+ */
+ template<typename KeyT>
+ const_iterator find(KeyT&& key) const
+ {
+ auto result = cend();
+
+ if (is_object())
+ {
+ result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief returns the number of occurrences of a key in a JSON object
+
+ Returns the number of elements with key @a key. If ObjectType is the
+ default `std::map` type, the return value will always be `0` (@a key was
+ not found) or `1` (@a key was found).
+
+ @note This method always returns `0` when executed on a JSON type that is
+ not an object.
+
+ @param[in] key key value of the element to count
+
+ @return Number of elements with key @a key. If the JSON value is not an
+ object, the return value will be `0`.
+
+ @complexity Logarithmic in the size of the JSON object.
+
+ @liveexample{The example shows how `count()` is used.,count}
+
+ @since version 1.0.0
+ */
+ template<typename KeyT>
+ size_type count(KeyT&& key) const
+ {
+ // return 0 for all nonobject types
+ return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
+ }
+
+ /*!
+ @brief check the existence of an element in a JSON object
+
+ Check whether an element exists in a JSON object with key equivalent to
+ @a key. If the element is not found or the JSON value is not an object,
+ false is returned.
+
+ @note This method always returns false when executed on a JSON type
+ that is not an object.
+
+ @param[in] key key value to check its existence.
+
+ @return true if an element with specified @a key exists. If no such
+ element with such key is found or the JSON value is not an object,
+ false is returned.
+
+ @complexity Logarithmic in the size of the JSON object.
+
+ @liveexample{The following code shows an example for `contains()`.,contains}
+
+ @sa @ref find(KeyT&&) -- returns an iterator to an object element
+
+ @since version 3.6.0
+ */
+ template<typename KeyT>
+ bool contains(KeyT&& key) const
+ {
+ return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
+ }
+
+ /// @}
+
+
+ ///////////////
+ // iterators //
+ ///////////////
+
+ /// @name iterators
+ /// @{
+
+ /*!
+ @brief returns an iterator to the first element
+
+ Returns an iterator to the first element.
+
+ @image html range-begin-end.svg "Illustration from cppreference.com"
+
+ @return iterator to the first element
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+
+ @liveexample{The following code shows an example for `begin()`.,begin}
+
+ @sa @ref cbegin() -- returns a const iterator to the beginning
+ @sa @ref end() -- returns an iterator to the end
+ @sa @ref cend() -- returns a const iterator to the end
+
+ @since version 1.0.0
+ */
+ iterator begin() noexcept
+ {
+ iterator result(this);
+ result.set_begin();
+ return result;
+ }
+
+ /*!
+ @copydoc basic_json::cbegin()
+ */
+ const_iterator begin() const noexcept
+ {
+ return cbegin();
+ }
+
+ /*!
+ @brief returns a const iterator to the first element
+
+ Returns a const iterator to the first element.
+
+ @image html range-begin-end.svg "Illustration from cppreference.com"
+
+ @return const iterator to the first element
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
+
+ @liveexample{The following code shows an example for `cbegin()`.,cbegin}
+
+ @sa @ref begin() -- returns an iterator to the beginning
+ @sa @ref end() -- returns an iterator to the end
+ @sa @ref cend() -- returns a const iterator to the end
+
+ @since version 1.0.0
+ */
+ const_iterator cbegin() const noexcept
+ {
+ const_iterator result(this);
+ result.set_begin();
+ return result;
+ }
+
+ /*!
+ @brief returns an iterator to one past the last element
+
+ Returns an iterator to one past the last element.
+
+ @image html range-begin-end.svg "Illustration from cppreference.com"
+
+ @return iterator one past the last element
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+
+ @liveexample{The following code shows an example for `end()`.,end}
+
+ @sa @ref cend() -- returns a const iterator to the end
+ @sa @ref begin() -- returns an iterator to the beginning
+ @sa @ref cbegin() -- returns a const iterator to the beginning
+
+ @since version 1.0.0
+ */
+ iterator end() noexcept
+ {
+ iterator result(this);
+ result.set_end();
+ return result;
+ }
+
+ /*!
+ @copydoc basic_json::cend()
+ */
+ const_iterator end() const noexcept
+ {
+ return cend();
+ }
+
+ /*!
+ @brief returns a const iterator to one past the last element
+
+ Returns a const iterator to one past the last element.
+
+ @image html range-begin-end.svg "Illustration from cppreference.com"
+
+ @return const iterator one past the last element
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
+
+ @liveexample{The following code shows an example for `cend()`.,cend}
+
+ @sa @ref end() -- returns an iterator to the end
+ @sa @ref begin() -- returns an iterator to the beginning
+ @sa @ref cbegin() -- returns a const iterator to the beginning
+
+ @since version 1.0.0
+ */
+ const_iterator cend() const noexcept
+ {
+ const_iterator result(this);
+ result.set_end();
+ return result;
+ }
+
+ /*!
+ @brief returns an iterator to the reverse-beginning
+
+ Returns an iterator to the reverse-beginning; that is, the last element.
+
+ @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `reverse_iterator(end())`.
+
+ @liveexample{The following code shows an example for `rbegin()`.,rbegin}
+
+ @sa @ref crbegin() -- returns a const reverse iterator to the beginning
+ @sa @ref rend() -- returns a reverse iterator to the end
+ @sa @ref crend() -- returns a const reverse iterator to the end
+
+ @since version 1.0.0
+ */
+ reverse_iterator rbegin() noexcept
+ {
+ return reverse_iterator(end());
+ }
+
+ /*!
+ @copydoc basic_json::crbegin()
+ */
+ const_reverse_iterator rbegin() const noexcept
+ {
+ return crbegin();
+ }
+
+ /*!
+ @brief returns an iterator to the reverse-end
+
+ Returns an iterator to the reverse-end; that is, one before the first
+ element.
+
+ @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `reverse_iterator(begin())`.
+
+ @liveexample{The following code shows an example for `rend()`.,rend}
+
+ @sa @ref crend() -- returns a const reverse iterator to the end
+ @sa @ref rbegin() -- returns a reverse iterator to the beginning
+ @sa @ref crbegin() -- returns a const reverse iterator to the beginning
+
+ @since version 1.0.0
+ */
+ reverse_iterator rend() noexcept
+ {
+ return reverse_iterator(begin());
+ }
+
+ /*!
+ @copydoc basic_json::crend()
+ */
+ const_reverse_iterator rend() const noexcept
+ {
+ return crend();
+ }
+
+ /*!
+ @brief returns a const reverse iterator to the last element
+
+ Returns a const iterator to the reverse-beginning; that is, the last
+ element.
+
+ @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
+
+ @liveexample{The following code shows an example for `crbegin()`.,crbegin}
+
+ @sa @ref rbegin() -- returns a reverse iterator to the beginning
+ @sa @ref rend() -- returns a reverse iterator to the end
+ @sa @ref crend() -- returns a const reverse iterator to the end
+
+ @since version 1.0.0
+ */
+ const_reverse_iterator crbegin() const noexcept
+ {
+ return const_reverse_iterator(cend());
+ }
+
+ /*!
+ @brief returns a const reverse iterator to one before the first
+
+ Returns a const reverse iterator to the reverse-end; that is, one before
+ the first element.
+
+ @image html range-rbegin-rend.svg "Illustration from cppreference.com"
+
+ @complexity Constant.
+
+ @requirement This function helps `basic_json` satisfying the
+ [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
+
+ @liveexample{The following code shows an example for `crend()`.,crend}
+
+ @sa @ref rend() -- returns a reverse iterator to the end
+ @sa @ref rbegin() -- returns a reverse iterator to the beginning
+ @sa @ref crbegin() -- returns a const reverse iterator to the beginning
+
+ @since version 1.0.0
+ */
+ const_reverse_iterator crend() const noexcept
+ {
+ return const_reverse_iterator(cbegin());
+ }
+
+ public:
+ /*!
+ @brief wrapper to access iterator member functions in range-based for
+
+ This function allows to access @ref iterator::key() and @ref
+ iterator::value() during range-based for loops. In these loops, a
+ reference to the JSON values is returned, so there is no access to the
+ underlying iterator.
+
+ For loop without iterator_wrapper:
+
+ @code{cpp}
+ for (auto it = j_object.begin(); it != j_object.end(); ++it)
+ {
+ std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
+ }
+ @endcode
+
+ Range-based for loop without iterator proxy:
+
+ @code{cpp}
+ for (auto it : j_object)
+ {
+ // "it" is of type json::reference and has no key() member
+ std::cout << "value: " << it << '\n';
+ }
+ @endcode
+
+ Range-based for loop with iterator proxy:
+
+ @code{cpp}
+ for (auto it : json::iterator_wrapper(j_object))
+ {
+ std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
+ }
+ @endcode
+
+ @note When iterating over an array, `key()` will return the index of the
+ element as string (see example).
+
+ @param[in] ref reference to a JSON value
+ @return iteration proxy object wrapping @a ref with an interface to use in
+ range-based for loops
+
+ @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Constant.
+
+ @note The name of this function is not yet final and may change in the
+ future.
+
+ @deprecated This stream operator is deprecated and will be removed in
+ future 4.0.0 of the library. Please use @ref items() instead;
+ that is, replace `json::iterator_wrapper(j)` with `j.items()`.
+ */
+ JSON_DEPRECATED
+ static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
+ {
+ return ref.items();
+ }
+
+ /*!
+ @copydoc iterator_wrapper(reference)
+ */
+ JSON_DEPRECATED
+ static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
+ {
+ return ref.items();
+ }
+
+ /*!
+ @brief helper to access iterator member functions in range-based for
+
+ This function allows to access @ref iterator::key() and @ref
+ iterator::value() during range-based for loops. In these loops, a
+ reference to the JSON values is returned, so there is no access to the
+ underlying iterator.
+
+ For loop without `items()` function:
+
+ @code{cpp}
+ for (auto it = j_object.begin(); it != j_object.end(); ++it)
+ {
+ std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
+ }
+ @endcode
+
+ Range-based for loop without `items()` function:
+
+ @code{cpp}
+ for (auto it : j_object)
+ {
+ // "it" is of type json::reference and has no key() member
+ std::cout << "value: " << it << '\n';
+ }
+ @endcode
+
+ Range-based for loop with `items()` function:
+
+ @code{cpp}
+ for (auto& el : j_object.items())
+ {
+ std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
+ }
+ @endcode
+
+ The `items()` function also allows to use
+ [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
+ (C++17):
+
+ @code{cpp}
+ for (auto& [key, val] : j_object.items())
+ {
+ std::cout << "key: " << key << ", value:" << val << '\n';
+ }
+ @endcode
+
+ @note When iterating over an array, `key()` will return the index of the
+ element as string (see example). For primitive types (e.g., numbers),
+ `key()` returns an empty string.
+
+ @return iteration proxy object wrapping @a ref with an interface to use in
+ range-based for loops
+
+ @liveexample{The following code shows how the function is used.,items}
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Constant.
+
+ @since version 3.1.0, structured bindings support since 3.5.0.
+ */
+ iteration_proxy<iterator> items() noexcept
+ {
+ return iteration_proxy<iterator>(*this);
+ }
+
+ /*!
+ @copydoc items()
+ */
+ iteration_proxy<const_iterator> items() const noexcept
+ {
+ return iteration_proxy<const_iterator>(*this);
+ }
+
+ /// @}
+
+
+ //////////////
+ // capacity //
+ //////////////
+
+ /// @name capacity
+ /// @{
+
+ /*!
+ @brief checks whether the container is empty.
+
+ Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
+
+ @return The return value depends on the different types and is
+ defined as follows:
+ Value type | return value
+ ----------- | -------------
+ null | `true`
+ boolean | `false`
+ string | `false`
+ number | `false`
+ object | result of function `object_t::empty()`
+ array | result of function `array_t::empty()`
+
+ @liveexample{The following code uses `empty()` to check if a JSON
+ object contains any elements.,empty}
+
+ @complexity Constant, as long as @ref array_t and @ref object_t satisfy
+ the Container concept; that is, their `empty()` functions have constant
+ complexity.
+
+ @iterators No changes.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @note This function does not return whether a string stored as JSON value
+ is empty - it returns whether the JSON container itself is empty which is
+ false in the case of a string.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `begin() == end()`.
+
+ @sa @ref size() -- returns the number of elements
+
+ @since version 1.0.0
+ */
+ bool empty() const noexcept
+ {
+ switch (m_type)
+ {
+ case value_t::null:
+ {
+ // null values are empty
+ return true;
+ }
+
+ case value_t::array:
+ {
+ // delegate call to array_t::empty()
+ return m_value.array->empty();
+ }
+
+ case value_t::object:
+ {
+ // delegate call to object_t::empty()
+ return m_value.object->empty();
+ }
+
+ default:
+ {
+ // all other types are nonempty
+ return false;
+ }
+ }
+ }
+
+ /*!
+ @brief returns the number of elements
+
+ Returns the number of elements in a JSON value.
+
+ @return The return value depends on the different types and is
+ defined as follows:
+ Value type | return value
+ ----------- | -------------
+ null | `0`
+ boolean | `1`
+ string | `1`
+ number | `1`
+ object | result of function object_t::size()
+ array | result of function array_t::size()
+
+ @liveexample{The following code calls `size()` on the different value
+ types.,size}
+
+ @complexity Constant, as long as @ref array_t and @ref object_t satisfy
+ the Container concept; that is, their size() functions have constant
+ complexity.
+
+ @iterators No changes.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @note This function does not return the length of a string stored as JSON
+ value - it returns the number of elements in the JSON value which is 1 in
+ the case of a string.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of `std::distance(begin(), end())`.
+
+ @sa @ref empty() -- checks whether the container is empty
+ @sa @ref max_size() -- returns the maximal number of elements
+
+ @since version 1.0.0
+ */
+ size_type size() const noexcept
+ {
+ switch (m_type)
+ {
+ case value_t::null:
+ {
+ // null values are empty
+ return 0;
+ }
+
+ case value_t::array:
+ {
+ // delegate call to array_t::size()
+ return m_value.array->size();
+ }
+
+ case value_t::object:
+ {
+ // delegate call to object_t::size()
+ return m_value.object->size();
+ }
+
+ default:
+ {
+ // all other types have size 1
+ return 1;
+ }
+ }
+ }
+
+ /*!
+ @brief returns the maximum possible number of elements
+
+ Returns the maximum number of elements a JSON value is able to hold due to
+ system or library implementation limitations, i.e. `std::distance(begin(),
+ end())` for the JSON value.
+
+ @return The return value depends on the different types and is
+ defined as follows:
+ Value type | return value
+ ----------- | -------------
+ null | `0` (same as `size()`)
+ boolean | `1` (same as `size()`)
+ string | `1` (same as `size()`)
+ number | `1` (same as `size()`)
+ object | result of function `object_t::max_size()`
+ array | result of function `array_t::max_size()`
+
+ @liveexample{The following code calls `max_size()` on the different value
+ types. Note the output is implementation specific.,max_size}
+
+ @complexity Constant, as long as @ref array_t and @ref object_t satisfy
+ the Container concept; that is, their `max_size()` functions have constant
+ complexity.
+
+ @iterators No changes.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @requirement This function helps `basic_json` satisfying the
+ [Container](https://en.cppreference.com/w/cpp/named_req/Container)
+ requirements:
+ - The complexity is constant.
+ - Has the semantics of returning `b.size()` where `b` is the largest
+ possible JSON value.
+
+ @sa @ref size() -- returns the number of elements
+
+ @since version 1.0.0
+ */
+ size_type max_size() const noexcept
+ {
+ switch (m_type)
+ {
+ case value_t::array:
+ {
+ // delegate call to array_t::max_size()
+ return m_value.array->max_size();
+ }
+
+ case value_t::object:
+ {
+ // delegate call to object_t::max_size()
+ return m_value.object->max_size();
+ }
+
+ default:
+ {
+ // all other types have max_size() == size()
+ return size();
+ }
+ }
+ }
+
+ /// @}
+
+
+ ///////////////
+ // modifiers //
+ ///////////////
+
+ /// @name modifiers
+ /// @{
+
+ /*!
+ @brief clears the contents
+
+ Clears the content of a JSON value and resets it to the default value as
+ if @ref basic_json(value_t) would have been called with the current value
+ type from @ref type():
+
+ Value type | initial value
+ ----------- | -------------
+ null | `null`
+ boolean | `false`
+ string | `""`
+ number | `0`
+ object | `{}`
+ array | `[]`
+
+ @post Has the same effect as calling
+ @code {.cpp}
+ *this = basic_json(type());
+ @endcode
+
+ @liveexample{The example below shows the effect of `clear()` to different
+ JSON types.,clear}
+
+ @complexity Linear in the size of the JSON value.
+
+ @iterators All iterators, pointers and references related to this container
+ are invalidated.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @sa @ref basic_json(value_t) -- constructor that creates an object with the
+ same value than calling `clear()`
+
+ @since version 1.0.0
+ */
+ void clear() noexcept
+ {
+ switch (m_type)
+ {
+ case value_t::number_integer:
+ {
+ m_value.number_integer = 0;
+ break;
+ }
+
+ case value_t::number_unsigned:
+ {
+ m_value.number_unsigned = 0;
+ break;
+ }
+
+ case value_t::number_float:
+ {
+ m_value.number_float = 0.0;
+ break;
+ }
+
+ case value_t::boolean:
+ {
+ m_value.boolean = false;
+ break;
+ }
+
+ case value_t::string:
+ {
+ m_value.string->clear();
+ break;
+ }
+
+ case value_t::array:
+ {
+ m_value.array->clear();
+ break;
+ }
+
+ case value_t::object:
+ {
+ m_value.object->clear();
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /*!
+ @brief add an object to an array
+
+ Appends the given element @a val to the end of the JSON value. If the
+ function is called on a JSON null value, an empty array is created before
+ appending @a val.
+
+ @param[in] val the value to add to the JSON array
+
+ @throw type_error.308 when called on a type other than JSON array or
+ null; example: `"cannot use push_back() with number"`
+
+ @complexity Amortized constant.
+
+ @liveexample{The example shows how `push_back()` and `+=` can be used to
+ add elements to a JSON array. Note how the `null` value was silently
+ converted to a JSON array.,push_back}
+
+ @since version 1.0.0
+ */
+ void push_back(basic_json&& val)
+ {
+ // push_back only works for null objects or arrays
+ if (JSON_UNLIKELY(not(is_null() or is_array())))
+ {
+ JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
+ }
+
+ // transform null object into an array
+ if (is_null())
+ {
+ m_type = value_t::array;
+ m_value = value_t::array;
+ assert_invariant();
+ }
+
+ // add element to array (move semantics)
+ m_value.array->push_back(std::move(val));
+ // invalidate object: mark it null so we do not call the destructor
+ // cppcheck-suppress accessMoved
+ val.m_type = value_t::null;
+ }
+
+ /*!
+ @brief add an object to an array
+ @copydoc push_back(basic_json&&)
+ */
+ reference operator+=(basic_json&& val)
+ {
+ push_back(std::move(val));
+ return *this;
+ }
+
+ /*!
+ @brief add an object to an array
+ @copydoc push_back(basic_json&&)
+ */
+ void push_back(const basic_json& val)
+ {
+ // push_back only works for null objects or arrays
+ if (JSON_UNLIKELY(not(is_null() or is_array())))
+ {
+ JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
+ }
+
+ // transform null object into an array
+ if (is_null())
+ {
+ m_type = value_t::array;
+ m_value = value_t::array;
+ assert_invariant();
+ }
+
+ // add element to array
+ m_value.array->push_back(val);
+ }
+
+ /*!
+ @brief add an object to an array
+ @copydoc push_back(basic_json&&)
+ */
+ reference operator+=(const basic_json& val)
+ {
+ push_back(val);
+ return *this;
+ }
+
+ /*!
+ @brief add an object to an object
+
+ Inserts the given element @a val to the JSON object. If the function is
+ called on a JSON null value, an empty object is created before inserting
+ @a val.
+
+ @param[in] val the value to add to the JSON object
+
+ @throw type_error.308 when called on a type other than JSON object or
+ null; example: `"cannot use push_back() with number"`
+
+ @complexity Logarithmic in the size of the container, O(log(`size()`)).
+
+ @liveexample{The example shows how `push_back()` and `+=` can be used to
+ add elements to a JSON object. Note how the `null` value was silently
+ converted to a JSON object.,push_back__object_t__value}
+
+ @since version 1.0.0
+ */
+ void push_back(const typename object_t::value_type& val)
+ {
+ // push_back only works for null objects or objects
+ if (JSON_UNLIKELY(not(is_null() or is_object())))
+ {
+ JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
+ }
+
+ // transform null object into an object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value = value_t::object;
+ assert_invariant();
+ }
+
+ // add element to array
+ m_value.object->insert(val);
+ }
+
+ /*!
+ @brief add an object to an object
+ @copydoc push_back(const typename object_t::value_type&)
+ */
+ reference operator+=(const typename object_t::value_type& val)
+ {
+ push_back(val);
+ return *this;
+ }
+
+ /*!
+ @brief add an object to an object
+
+ This function allows to use `push_back` with an initializer list. In case
+
+ 1. the current value is an object,
+ 2. the initializer list @a init contains only two elements, and
+ 3. the first element of @a init is a string,
+
+ @a init is converted into an object element and added using
+ @ref push_back(const typename object_t::value_type&). Otherwise, @a init
+ is converted to a JSON value and added using @ref push_back(basic_json&&).
+
+ @param[in] init an initializer list
+
+ @complexity Linear in the size of the initializer list @a init.
+
+ @note This function is required to resolve an ambiguous overload error,
+ because pairs like `{"key", "value"}` can be both interpreted as
+ `object_t::value_type` or `std::initializer_list<basic_json>`, see
+ https://github.com/nlohmann/json/issues/235 for more information.
+
+ @liveexample{The example shows how initializer lists are treated as
+ objects when possible.,push_back__initializer_list}
+ */
+ void push_back(initializer_list_t init)
+ {
+ if (is_object() and init.size() == 2 and (*init.begin())->is_string())
+ {
+ basic_json&& key = init.begin()->moved_or_copied();
+ push_back(typename object_t::value_type(
+ std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
+ }
+ else
+ {
+ push_back(basic_json(init));
+ }
+ }
+
+ /*!
+ @brief add an object to an object
+ @copydoc push_back(initializer_list_t)
+ */
+ reference operator+=(initializer_list_t init)
+ {
+ push_back(init);
+ return *this;
+ }
+
+ /*!
+ @brief add an object to an array
+
+ Creates a JSON value from the passed parameters @a args to the end of the
+ JSON value. If the function is called on a JSON null value, an empty array
+ is created before appending the value created from @a args.
+
+ @param[in] args arguments to forward to a constructor of @ref basic_json
+ @tparam Args compatible types to create a @ref basic_json object
+
+ @throw type_error.311 when called on a type other than JSON array or
+ null; example: `"cannot use emplace_back() with number"`
+
+ @complexity Amortized constant.
+
+ @liveexample{The example shows how `push_back()` can be used to add
+ elements to a JSON array. Note how the `null` value was silently converted
+ to a JSON array.,emplace_back}
+
+ @since version 2.0.8
+ */
+ template<class... Args>
+ void emplace_back(Args&& ... args)
+ {
+ // emplace_back only works for null objects or arrays
+ if (JSON_UNLIKELY(not(is_null() or is_array())))
+ {
+ JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
+ }
+
+ // transform null object into an array
+ if (is_null())
+ {
+ m_type = value_t::array;
+ m_value = value_t::array;
+ assert_invariant();
+ }
+
+ // add element to array (perfect forwarding)
+ m_value.array->emplace_back(std::forward<Args>(args)...);
+ }
+
+ /*!
+ @brief add an object to an object if key does not exist
+
+ Inserts a new element into a JSON object constructed in-place with the
+ given @a args if there is no element with the key in the container. If the
+ function is called on a JSON null value, an empty object is created before
+ appending the value created from @a args.
+
+ @param[in] args arguments to forward to a constructor of @ref basic_json
+ @tparam Args compatible types to create a @ref basic_json object
+
+ @return a pair consisting of an iterator to the inserted element, or the
+ already-existing element if no insertion happened, and a bool
+ denoting whether the insertion took place.
+
+ @throw type_error.311 when called on a type other than JSON object or
+ null; example: `"cannot use emplace() with number"`
+
+ @complexity Logarithmic in the size of the container, O(log(`size()`)).
+
+ @liveexample{The example shows how `emplace()` can be used to add elements
+ to a JSON object. Note how the `null` value was silently converted to a
+ JSON object. Further note how no value is added if there was already one
+ value stored with the same key.,emplace}
+
+ @since version 2.0.8
+ */
+ template<class... Args>
+ std::pair<iterator, bool> emplace(Args&& ... args)
+ {
+ // emplace only works for null objects or arrays
+ if (JSON_UNLIKELY(not(is_null() or is_object())))
+ {
+ JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
+ }
+
+ // transform null object into an object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value = value_t::object;
+ assert_invariant();
+ }
+
+ // add element to array (perfect forwarding)
+ auto res = m_value.object->emplace(std::forward<Args>(args)...);
+ // create result iterator and set iterator to the result of emplace
+ auto it = begin();
+ it.m_it.object_iterator = res.first;
+
+ // return pair of iterator and boolean
+ return {it, res.second};
+ }
+
+ /// Helper for insertion of an iterator
+ /// @note: This uses std::distance to support GCC 4.8,
+ /// see https://github.com/nlohmann/json/pull/1257
+ template<typename... Args>
+ iterator insert_iterator(const_iterator pos, Args&& ... args)
+ {
+ iterator result(this);
+ assert(m_value.array != nullptr);
+
+ auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
+ m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
+ result.m_it.array_iterator = m_value.array->begin() + insert_pos;
+
+ // This could have been written as:
+ // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
+ // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
+
+ return result;
+ }
+
+ /*!
+ @brief inserts element
+
+ Inserts element @a val before iterator @a pos.
+
+ @param[in] pos iterator before which the content will be inserted; may be
+ the end() iterator
+ @param[in] val element to insert
+ @return iterator pointing to the inserted @a val.
+
+ @throw type_error.309 if called on JSON values other than arrays;
+ example: `"cannot use insert() with string"`
+ @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+ example: `"iterator does not fit current value"`
+
+ @complexity Constant plus linear in the distance between @a pos and end of
+ the container.
+
+ @liveexample{The example shows how `insert()` is used.,insert}
+
+ @since version 1.0.0
+ */
+ iterator insert(const_iterator pos, const basic_json& val)
+ {
+ // insert only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ // check if iterator pos fits to this JSON value
+ if (JSON_UNLIKELY(pos.m_object != this))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+ }
+
+ // insert to array and return iterator
+ return insert_iterator(pos, val);
+ }
+
+ JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief inserts element
+ @copydoc insert(const_iterator, const basic_json&)
+ */
+ iterator insert(const_iterator pos, basic_json&& val)
+ {
+ return insert(pos, val);
+ }
+
+ /*!
+ @brief inserts elements
+
+ Inserts @a cnt copies of @a val before iterator @a pos.
+
+ @param[in] pos iterator before which the content will be inserted; may be
+ the end() iterator
+ @param[in] cnt number of copies of @a val to insert
+ @param[in] val element to insert
+ @return iterator pointing to the first element inserted, or @a pos if
+ `cnt==0`
+
+ @throw type_error.309 if called on JSON values other than arrays; example:
+ `"cannot use insert() with string"`
+ @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+ example: `"iterator does not fit current value"`
+
+ @complexity Linear in @a cnt plus linear in the distance between @a pos
+ and end of the container.
+
+ @liveexample{The example shows how `insert()` is used.,insert__count}
+
+ @since version 1.0.0
+ */
+ iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
+ {
+ // insert only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ // check if iterator pos fits to this JSON value
+ if (JSON_UNLIKELY(pos.m_object != this))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+ }
+
+ // insert to array and return iterator
+ return insert_iterator(pos, cnt, val);
+ }
+
+ JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+ }
+
+ /*!
+ @brief inserts elements
+
+ Inserts elements from range `[first, last)` before iterator @a pos.
+
+ @param[in] pos iterator before which the content will be inserted; may be
+ the end() iterator
+ @param[in] first begin of the range of elements to insert
+ @param[in] last end of the range of elements to insert
+
+ @throw type_error.309 if called on JSON values other than arrays; example:
+ `"cannot use insert() with string"`
+ @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+ example: `"iterator does not fit current value"`
+ @throw invalid_iterator.210 if @a first and @a last do not belong to the
+ same JSON value; example: `"iterators do not fit"`
+ @throw invalid_iterator.211 if @a first or @a last are iterators into
+ container for which insert is called; example: `"passed iterators may not
+ belong to container"`
+
+ @return iterator pointing to the first element inserted, or @a pos if
+ `first==last`
+
+ @complexity Linear in `std::distance(first, last)` plus linear in the
+ distance between @a pos and end of the container.
+
+ @liveexample{The example shows how `insert()` is used.,insert__range}
+
+ @since version 1.0.0
+ */
+ iterator insert(const_iterator pos, const_iterator first, const_iterator last)
+ {
+ // insert only works for arrays
+ if (JSON_UNLIKELY(not is_array()))
+ {
+ JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+ }
+
+ // check if iterator pos fits to this JSON value
+ if (JSON_UNLIKELY(pos.m_object != this))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+ }
+
+ // check if range iterators belong to the same JSON object
+ if (JSON_UNLIKELY(first.m_object != last.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+ }
+
+ if (JSON_UNLIKELY(first.m_object == this))
+ {
+ JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
+ }
+
+ // insert to array and return iterator
+ return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
+ }
+
+ /*!
+ @brief inserts elements
+
+ Inserts elements from initializer list @a ilist before iterator @a pos.
+
+ @param[in] pos iterator before which the content will be inserted; may be
+ the end() iterator
+ @param[in] ilist initializer list to insert the values from
+
+ @throw type_error.309 if called on JSON values other than arrays; example:
+ `"cannot use insert() with string"`
+ @throw invalid_iterator.202 if @a pos is not an iterator of *this;
+ example: `"iterator does not fit current value"`
+
+ @return iterator pointing to the first element inserted, or @a pos if
+ `ilist` is empty
+
+ @complexity Linear in `ilist.size()` plus linear in the distance between
+ @a pos and end of the container.
+
+ @liveexample{The example shows how `insert()` is used.,insert__ilist}
+
+ @since version 1.0.0
+ */
+ iterator insert(const_iterator pos, initializer_list_t ilist)
+ {
+ // insert only works for arrays
+ if (JSON_UNLIKELY(not is_array()))
+ {
+ JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+ }
+
+ // check if iterator pos fits to this JSON value
+ if (JSON_UNLIKELY(pos.m_object != this))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
+ }
+
+ // insert to array and return iterator
+ return insert_iterator(pos, ilist.begin(), ilist.end());
+ }
+
+ /*!
+ @brief inserts elements
+
+ Inserts elements from range `[first, last)`.
+
+ @param[in] first begin of the range of elements to insert
+ @param[in] last end of the range of elements to insert
+
+ @throw type_error.309 if called on JSON values other than objects; example:
+ `"cannot use insert() with string"`
+ @throw invalid_iterator.202 if iterator @a first or @a last does does not
+ point to an object; example: `"iterators first and last must point to
+ objects"`
+ @throw invalid_iterator.210 if @a first and @a last do not belong to the
+ same JSON value; example: `"iterators do not fit"`
+
+ @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
+ of elements to insert.
+
+ @liveexample{The example shows how `insert()` is used.,insert__range_object}
+
+ @since version 3.0.0
+ */
+ void insert(const_iterator first, const_iterator last)
+ {
+ // insert only works for objects
+ if (JSON_UNLIKELY(not is_object()))
+ {
+ JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
+ }
+
+ // check if range iterators belong to the same JSON object
+ if (JSON_UNLIKELY(first.m_object != last.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+ }
+
+ // passed iterators must belong to objects
+ if (JSON_UNLIKELY(not first.m_object->is_object()))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+ }
+
+ m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
+ }
+
+ /*!
+ @brief updates a JSON object from another object, overwriting existing keys
+
+ Inserts all values from JSON object @a j and overwrites existing keys.
+
+ @param[in] j JSON object to read values from
+
+ @throw type_error.312 if called on JSON values other than objects; example:
+ `"cannot use update() with string"`
+
+ @complexity O(N*log(size() + N)), where N is the number of elements to
+ insert.
+
+ @liveexample{The example shows how `update()` is used.,update}
+
+ @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
+
+ @since version 3.0.0
+ */
+ void update(const_reference j)
+ {
+ // implicitly convert null value to an empty object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value.object = create<object_t>();
+ assert_invariant();
+ }
+
+ if (JSON_UNLIKELY(not is_object()))
+ {
+ JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
+ }
+ if (JSON_UNLIKELY(not j.is_object()))
+ {
+ JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
+ }
+
+ for (auto it = j.cbegin(); it != j.cend(); ++it)
+ {
+ m_value.object->operator[](it.key()) = it.value();
+ }
+ }
+
+ /*!
+ @brief updates a JSON object from another object, overwriting existing keys
+
+ Inserts all values from from range `[first, last)` and overwrites existing
+ keys.
+
+ @param[in] first begin of the range of elements to insert
+ @param[in] last end of the range of elements to insert
+
+ @throw type_error.312 if called on JSON values other than objects; example:
+ `"cannot use update() with string"`
+ @throw invalid_iterator.202 if iterator @a first or @a last does does not
+ point to an object; example: `"iterators first and last must point to
+ objects"`
+ @throw invalid_iterator.210 if @a first and @a last do not belong to the
+ same JSON value; example: `"iterators do not fit"`
+
+ @complexity O(N*log(size() + N)), where N is the number of elements to
+ insert.
+
+ @liveexample{The example shows how `update()` is used__range.,update}
+
+ @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
+
+ @since version 3.0.0
+ */
+ void update(const_iterator first, const_iterator last)
+ {
+ // implicitly convert null value to an empty object
+ if (is_null())
+ {
+ m_type = value_t::object;
+ m_value.object = create<object_t>();
+ assert_invariant();
+ }
+
+ if (JSON_UNLIKELY(not is_object()))
+ {
+ JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
+ }
+
+ // check if range iterators belong to the same JSON object
+ if (JSON_UNLIKELY(first.m_object != last.m_object))
+ {
+ JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
+ }
+
+ // passed iterators must belong to objects
+ if (JSON_UNLIKELY(not first.m_object->is_object()
+ or not last.m_object->is_object()))
+ {
+ JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
+ }
+
+ for (auto it = first; it != last; ++it)
+ {
+ m_value.object->operator[](it.key()) = it.value();
+ }
+ }
+
+ /*!
+ @brief exchanges the values
+
+ Exchanges the contents of the JSON value with those of @a other. Does not
+ invoke any move, copy, or swap operations on individual elements. All
+ iterators and references remain valid. The past-the-end iterator is
+ invalidated.
+
+ @param[in,out] other JSON value to exchange the contents with
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how JSON values can be swapped with
+ `swap()`.,swap__reference}
+
+ @since version 1.0.0
+ */
+ void swap(reference other) noexcept (
+ std::is_nothrow_move_constructible<value_t>::value and
+ std::is_nothrow_move_assignable<value_t>::value and
+ std::is_nothrow_move_constructible<json_value>::value and
+ std::is_nothrow_move_assignable<json_value>::value
+ )
+ {
+ std::swap(m_type, other.m_type);
+ std::swap(m_value, other.m_value);
+ assert_invariant();
+ }
+
+ /*!
+ @brief exchanges the values
+
+ Exchanges the contents of a JSON array with those of @a other. Does not
+ invoke any move, copy, or swap operations on individual elements. All
+ iterators and references remain valid. The past-the-end iterator is
+ invalidated.
+
+ @param[in,out] other array to exchange the contents with
+
+ @throw type_error.310 when JSON value is not an array; example: `"cannot
+ use swap() with string"`
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how arrays can be swapped with
+ `swap()`.,swap__array_t}
+
+ @since version 1.0.0
+ */
+ void swap(array_t& other)
+ {
+ // swap only works for arrays
+ if (JSON_LIKELY(is_array()))
+ {
+ std::swap(*(m_value.array), other);
+ }
+ else
+ {
+ JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+ }
+ }
+
+ /*!
+ @brief exchanges the values
+
+ Exchanges the contents of a JSON object with those of @a other. Does not
+ invoke any move, copy, or swap operations on individual elements. All
+ iterators and references remain valid. The past-the-end iterator is
+ invalidated.
+
+ @param[in,out] other object to exchange the contents with
+
+ @throw type_error.310 when JSON value is not an object; example:
+ `"cannot use swap() with string"`
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how objects can be swapped with
+ `swap()`.,swap__object_t}
+
+ @since version 1.0.0
+ */
+ void swap(object_t& other)
+ {
+ // swap only works for objects
+ if (JSON_LIKELY(is_object()))
+ {
+ std::swap(*(m_value.object), other);
+ }
+ else
+ {
+ JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+ }
+ }
+
+ /*!
+ @brief exchanges the values
+
+ Exchanges the contents of a JSON string with those of @a other. Does not
+ invoke any move, copy, or swap operations on individual elements. All
+ iterators and references remain valid. The past-the-end iterator is
+ invalidated.
+
+ @param[in,out] other string to exchange the contents with
+
+ @throw type_error.310 when JSON value is not a string; example: `"cannot
+ use swap() with boolean"`
+
+ @complexity Constant.
+
+ @liveexample{The example below shows how strings can be swapped with
+ `swap()`.,swap__string_t}
+
+ @since version 1.0.0
+ */
+ void swap(string_t& other)
+ {
+ // swap only works for strings
+ if (JSON_LIKELY(is_string()))
+ {
+ std::swap(*(m_value.string), other);
+ }
+ else
+ {
+ JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
+ }
+ }
+
+ /// @}
+
+ public:
+ //////////////////////////////////////////
+ // lexicographical comparison operators //
+ //////////////////////////////////////////
+
+ /// @name lexicographical comparison operators
+ /// @{
+
+ /*!
+ @brief comparison: equal
+
+ Compares two JSON values for equality according to the following rules:
+ - Two JSON values are equal if (1) they are from the same type and (2)
+ their stored values are the same according to their respective
+ `operator==`.
+ - Integer and floating-point numbers are automatically converted before
+ comparison. Note than two NaN values are always treated as unequal.
+ - Two JSON null values are equal.
+
+ @note Floating-point inside JSON values numbers are compared with
+ `json::number_float_t::operator==` which is `double::operator==` by
+ default. To compare floating-point while respecting an epsilon, an alternative
+ [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
+ could be used, for instance
+ @code {.cpp}
+ template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
+ inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
+ {
+ return std::abs(a - b) <= epsilon;
+ }
+ @endcode
+
+ @note NaN values never compare equal to themselves or to other NaN values.
+
+ @param[in] lhs first JSON value to consider
+ @param[in] rhs second JSON value to consider
+ @return whether the values @a lhs and @a rhs are equal
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @complexity Linear.
+
+ @liveexample{The example demonstrates comparing several JSON
+ types.,operator__equal}
+
+ @since version 1.0.0
+ */
+ friend bool operator==(const_reference lhs, const_reference rhs) noexcept
+ {
+ const auto lhs_type = lhs.type();
+ const auto rhs_type = rhs.type();
+
+ if (lhs_type == rhs_type)
+ {
+ switch (lhs_type)
+ {
+ case value_t::array:
+ return *lhs.m_value.array == *rhs.m_value.array;
+
+ case value_t::object:
+ return *lhs.m_value.object == *rhs.m_value.object;
+
+ case value_t::null:
+ return true;
+
+ case value_t::string:
+ return *lhs.m_value.string == *rhs.m_value.string;
+
+ case value_t::boolean:
+ return lhs.m_value.boolean == rhs.m_value.boolean;
+
+ case value_t::number_integer:
+ return lhs.m_value.number_integer == rhs.m_value.number_integer;
+
+ case value_t::number_unsigned:
+ return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
+
+ case value_t::number_float:
+ return lhs.m_value.number_float == rhs.m_value.number_float;
+
+ default:
+ return false;
+ }
+ }
+ else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
+ {
+ return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
+ }
+ else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
+ {
+ return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
+ }
+ else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
+ {
+ return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
+ }
+ else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
+ {
+ return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
+ }
+ else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
+ {
+ return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
+ }
+ else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
+ {
+ return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+ }
+
+ return false;
+ }
+
+ /*!
+ @brief comparison: equal
+ @copydoc operator==(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
+ {
+ return lhs == basic_json(rhs);
+ }
+
+ /*!
+ @brief comparison: equal
+ @copydoc operator==(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
+ {
+ return basic_json(lhs) == rhs;
+ }
+
+ /*!
+ @brief comparison: not equal
+
+ Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
+
+ @param[in] lhs first JSON value to consider
+ @param[in] rhs second JSON value to consider
+ @return whether the values @a lhs and @a rhs are not equal
+
+ @complexity Linear.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @liveexample{The example demonstrates comparing several JSON
+ types.,operator__notequal}
+
+ @since version 1.0.0
+ */
+ friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
+ {
+ return not (lhs == rhs);
+ }
+
+ /*!
+ @brief comparison: not equal
+ @copydoc operator!=(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
+ {
+ return lhs != basic_json(rhs);
+ }
+
+ /*!
+ @brief comparison: not equal
+ @copydoc operator!=(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
+ {
+ return basic_json(lhs) != rhs;
+ }
+
+ /*!
+ @brief comparison: less than
+
+ Compares whether one JSON value @a lhs is less than another JSON value @a
+ rhs according to the following rules:
+ - If @a lhs and @a rhs have the same type, the values are compared using
+ the default `<` operator.
+ - Integer and floating-point numbers are automatically converted before
+ comparison
+ - In case @a lhs and @a rhs have different types, the values are ignored
+ and the order of the types is considered, see
+ @ref operator<(const value_t, const value_t).
+
+ @param[in] lhs first JSON value to consider
+ @param[in] rhs second JSON value to consider
+ @return whether @a lhs is less than @a rhs
+
+ @complexity Linear.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @liveexample{The example demonstrates comparing several JSON
+ types.,operator__less}
+
+ @since version 1.0.0
+ */
+ friend bool operator<(const_reference lhs, const_reference rhs) noexcept
+ {
+ const auto lhs_type = lhs.type();
+ const auto rhs_type = rhs.type();
+
+ if (lhs_type == rhs_type)
+ {
+ switch (lhs_type)
+ {
+ case value_t::array:
+ // note parentheses are necessary, see
+ // https://github.com/nlohmann/json/issues/1530
+ return (*lhs.m_value.array) < (*rhs.m_value.array);
+
+ case value_t::object:
+ return *lhs.m_value.object < *rhs.m_value.object;
+
+ case value_t::null:
+ return false;
+
+ case value_t::string:
+ return *lhs.m_value.string < *rhs.m_value.string;
+
+ case value_t::boolean:
+ return lhs.m_value.boolean < rhs.m_value.boolean;
+
+ case value_t::number_integer:
+ return lhs.m_value.number_integer < rhs.m_value.number_integer;
+
+ case value_t::number_unsigned:
+ return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
+
+ case value_t::number_float:
+ return lhs.m_value.number_float < rhs.m_value.number_float;
+
+ default:
+ return false;
+ }
+ }
+ else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
+ {
+ return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
+ }
+ else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
+ {
+ return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
+ }
+ else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
+ {
+ return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
+ }
+ else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
+ {
+ return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
+ }
+ else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
+ {
+ return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
+ }
+ else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
+ {
+ return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
+ }
+
+ // We only reach this line if we cannot compare values. In that case,
+ // we compare types. Note we have to call the operator explicitly,
+ // because MSVC has problems otherwise.
+ return operator<(lhs_type, rhs_type);
+ }
+
+ /*!
+ @brief comparison: less than
+ @copydoc operator<(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
+ {
+ return lhs < basic_json(rhs);
+ }
+
+ /*!
+ @brief comparison: less than
+ @copydoc operator<(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
+ {
+ return basic_json(lhs) < rhs;
+ }
+
+ /*!
+ @brief comparison: less than or equal
+
+ Compares whether one JSON value @a lhs is less than or equal to another
+ JSON value by calculating `not (rhs < lhs)`.
+
+ @param[in] lhs first JSON value to consider
+ @param[in] rhs second JSON value to consider
+ @return whether @a lhs is less than or equal to @a rhs
+
+ @complexity Linear.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @liveexample{The example demonstrates comparing several JSON
+ types.,operator__greater}
+
+ @since version 1.0.0
+ */
+ friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
+ {
+ return not (rhs < lhs);
+ }
+
+ /*!
+ @brief comparison: less than or equal
+ @copydoc operator<=(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
+ {
+ return lhs <= basic_json(rhs);
+ }
+
+ /*!
+ @brief comparison: less than or equal
+ @copydoc operator<=(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
+ {
+ return basic_json(lhs) <= rhs;
+ }
+
+ /*!
+ @brief comparison: greater than
+
+ Compares whether one JSON value @a lhs is greater than another
+ JSON value by calculating `not (lhs <= rhs)`.
+
+ @param[in] lhs first JSON value to consider
+ @param[in] rhs second JSON value to consider
+ @return whether @a lhs is greater than to @a rhs
+
+ @complexity Linear.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @liveexample{The example demonstrates comparing several JSON
+ types.,operator__lessequal}
+
+ @since version 1.0.0
+ */
+ friend bool operator>(const_reference lhs, const_reference rhs) noexcept
+ {
+ return not (lhs <= rhs);
+ }
+
+ /*!
+ @brief comparison: greater than
+ @copydoc operator>(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
+ {
+ return lhs > basic_json(rhs);
+ }
+
+ /*!
+ @brief comparison: greater than
+ @copydoc operator>(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
+ {
+ return basic_json(lhs) > rhs;
+ }
+
+ /*!
+ @brief comparison: greater than or equal
+
+ Compares whether one JSON value @a lhs is greater than or equal to another
+ JSON value by calculating `not (lhs < rhs)`.
+
+ @param[in] lhs first JSON value to consider
+ @param[in] rhs second JSON value to consider
+ @return whether @a lhs is greater than or equal to @a rhs
+
+ @complexity Linear.
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @liveexample{The example demonstrates comparing several JSON
+ types.,operator__greaterequal}
+
+ @since version 1.0.0
+ */
+ friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
+ {
+ return not (lhs < rhs);
+ }
+
+ /*!
+ @brief comparison: greater than or equal
+ @copydoc operator>=(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
+ {
+ return lhs >= basic_json(rhs);
+ }
+
+ /*!
+ @brief comparison: greater than or equal
+ @copydoc operator>=(const_reference, const_reference)
+ */
+ template<typename ScalarType, typename std::enable_if<
+ std::is_scalar<ScalarType>::value, int>::type = 0>
+ friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
+ {
+ return basic_json(lhs) >= rhs;
+ }
+
+ /// @}
+
+ ///////////////////
+ // serialization //
+ ///////////////////
+
+ /// @name serialization
+ /// @{
+
+ /*!
+ @brief serialize to stream
+
+ Serialize the given JSON value @a j to the output stream @a o. The JSON
+ value will be serialized using the @ref dump member function.
+
+ - The indentation of the output can be controlled with the member variable
+ `width` of the output stream @a o. For instance, using the manipulator
+ `std::setw(4)` on @a o sets the indentation level to `4` and the
+ serialization result is the same as calling `dump(4)`.
+
+ - The indentation character can be controlled with the member variable
+ `fill` of the output stream @a o. For instance, the manipulator
+ `std::setfill('\\t')` sets indentation to use a tab character rather than
+ the default space character.
+
+ @param[in,out] o stream to serialize to
+ @param[in] j JSON value to serialize
+
+ @return the stream @a o
+
+ @throw type_error.316 if a string stored inside the JSON value is not
+ UTF-8 encoded
+
+ @complexity Linear.
+
+ @liveexample{The example below shows the serialization with different
+ parameters to `width` to adjust the indentation level.,operator_serialize}
+
+ @since version 1.0.0; indentation character added in version 3.0.0
+ */
+ friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
+ {
+ // read width member and use it as indentation parameter if nonzero
+ const bool pretty_print = o.width() > 0;
+ const auto indentation = pretty_print ? o.width() : 0;
+
+ // reset width to 0 for subsequent calls to this stream
+ o.width(0);
+
+ // do the actual serialization
+ serializer s(detail::output_adapter<char>(o), o.fill());
+ s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
+ return o;
+ }
+
+ /*!
+ @brief serialize to stream
+ @deprecated This stream operator is deprecated and will be removed in
+ future 4.0.0 of the library. Please use
+ @ref operator<<(std::ostream&, const basic_json&)
+ instead; that is, replace calls like `j >> o;` with `o << j;`.
+ @since version 1.0.0; deprecated since version 3.0.0
+ */
+ JSON_DEPRECATED
+ friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
+ {
+ return o << j;
+ }
+
+ /// @}
+
+
+ /////////////////////
+ // deserialization //
+ /////////////////////
+
+ /// @name deserialization
+ /// @{
+
+ /*!
+ @brief deserialize from a compatible input
+
+ This function reads from a compatible input. Examples are:
+ - an array of 1-byte values
+ - strings with character/literal type with size of 1 byte
+ - input streams
+ - container with contiguous storage of 1-byte values. Compatible container
+ types include `std::vector`, `std::string`, `std::array`,
+ `std::valarray`, and `std::initializer_list`. Furthermore, C-style
+ arrays can be used with `std::begin()`/`std::end()`. User-defined
+ containers can be used as long as they implement random-access iterators
+ and a contiguous storage.
+
+ @pre Each element of the container has a size of 1 byte. Violating this
+ precondition yields undefined behavior. **This precondition is enforced
+ with a static assertion.**
+
+ @pre The container storage is contiguous. Violating this precondition
+ yields undefined behavior. **This precondition is enforced with an
+ assertion.**
+
+ @warning There is no way to enforce all preconditions at compile-time. If
+ the function is called with a noncompliant container and with
+ assertions switched off, the behavior is undefined and will most
+ likely yield segmentation violation.
+
+ @param[in] i input to read from
+ @param[in] cb a parser callback function of type @ref parser_callback_t
+ which is used to control the deserialization by filtering unwanted values
+ (optional)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value; in case of a parse error and
+ @a allow_exceptions set to `false`, the return value will be
+ value_t::discarded.
+
+ @throw parse_error.101 if a parse error occurs; example: `""unexpected end
+ of input; expected string literal""`
+ @throw parse_error.102 if to_unicode fails or surrogate error
+ @throw parse_error.103 if to_unicode fails
+
+ @complexity Linear in the length of the input. The parser is a predictive
+ LL(1) parser. The complexity can be higher if the parser callback function
+ @a cb has a super-linear complexity.
+
+ @note A UTF-8 byte order mark is silently ignored.
+
+ @liveexample{The example below demonstrates the `parse()` function reading
+ from an array.,parse__array__parser_callback_t}
+
+ @liveexample{The example below demonstrates the `parse()` function with
+ and without callback function.,parse__string__parser_callback_t}
+
+ @liveexample{The example below demonstrates the `parse()` function with
+ and without callback function.,parse__istream__parser_callback_t}
+
+ @liveexample{The example below demonstrates the `parse()` function reading
+ from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
+
+ @since version 2.0.3 (contiguous containers)
+ */
+ JSON_NODISCARD
+ static basic_json parse(detail::input_adapter&& i,
+ const parser_callback_t cb = nullptr,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ parser(i, cb, allow_exceptions).parse(true, result);
+ return result;
+ }
+
+ static bool accept(detail::input_adapter&& i)
+ {
+ return parser(i).accept(true);
+ }
+
+ /*!
+ @brief generate SAX events
+
+ The SAX event lister must follow the interface of @ref json_sax.
+
+ This function reads from a compatible input. Examples are:
+ - an array of 1-byte values
+ - strings with character/literal type with size of 1 byte
+ - input streams
+ - container with contiguous storage of 1-byte values. Compatible container
+ types include `std::vector`, `std::string`, `std::array`,
+ `std::valarray`, and `std::initializer_list`. Furthermore, C-style
+ arrays can be used with `std::begin()`/`std::end()`. User-defined
+ containers can be used as long as they implement random-access iterators
+ and a contiguous storage.
+
+ @pre Each element of the container has a size of 1 byte. Violating this
+ precondition yields undefined behavior. **This precondition is enforced
+ with a static assertion.**
+
+ @pre The container storage is contiguous. Violating this precondition
+ yields undefined behavior. **This precondition is enforced with an
+ assertion.**
+
+ @warning There is no way to enforce all preconditions at compile-time. If
+ the function is called with a noncompliant container and with
+ assertions switched off, the behavior is undefined and will most
+ likely yield segmentation violation.
+
+ @param[in] i input to read from
+ @param[in,out] sax SAX event listener
+ @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
+ @param[in] strict whether the input has to be consumed completely
+
+ @return return value of the last processed SAX event
+
+ @throw parse_error.101 if a parse error occurs; example: `""unexpected end
+ of input; expected string literal""`
+ @throw parse_error.102 if to_unicode fails or surrogate error
+ @throw parse_error.103 if to_unicode fails
+
+ @complexity Linear in the length of the input. The parser is a predictive
+ LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
+ a super-linear complexity.
+
+ @note A UTF-8 byte order mark is silently ignored.
+
+ @liveexample{The example below demonstrates the `sax_parse()` function
+ reading from string and processing the events with a user-defined SAX
+ event consumer.,sax_parse}
+
+ @since version 3.2.0
+ */
+ template <typename SAX>
+ static bool sax_parse(detail::input_adapter&& i, SAX* sax,
+ input_format_t format = input_format_t::json,
+ const bool strict = true)
+ {
+ assert(sax);
+ return format == input_format_t::json
+ ? parser(std::move(i)).sax_parse(sax, strict)
+ : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
+ }
+
+ /*!
+ @brief deserialize from an iterator range with contiguous storage
+
+ This function reads from an iterator range of a container with contiguous
+ storage of 1-byte values. Compatible container types include
+ `std::vector`, `std::string`, `std::array`, `std::valarray`, and
+ `std::initializer_list`. Furthermore, C-style arrays can be used with
+ `std::begin()`/`std::end()`. User-defined containers can be used as long
+ as they implement random-access iterators and a contiguous storage.
+
+ @pre The iterator range is contiguous. Violating this precondition yields
+ undefined behavior. **This precondition is enforced with an assertion.**
+ @pre Each element in the range has a size of 1 byte. Violating this
+ precondition yields undefined behavior. **This precondition is enforced
+ with a static assertion.**
+
+ @warning There is no way to enforce all preconditions at compile-time. If
+ the function is called with noncompliant iterators and with
+ assertions switched off, the behavior is undefined and will most
+ likely yield segmentation violation.
+
+ @tparam IteratorType iterator of container with contiguous storage
+ @param[in] first begin of the range to parse (included)
+ @param[in] last end of the range to parse (excluded)
+ @param[in] cb a parser callback function of type @ref parser_callback_t
+ which is used to control the deserialization by filtering unwanted values
+ (optional)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value; in case of a parse error and
+ @a allow_exceptions set to `false`, the return value will be
+ value_t::discarded.
+
+ @throw parse_error.101 in case of an unexpected token
+ @throw parse_error.102 if to_unicode fails or surrogate error
+ @throw parse_error.103 if to_unicode fails
+
+ @complexity Linear in the length of the input. The parser is a predictive
+ LL(1) parser. The complexity can be higher if the parser callback function
+ @a cb has a super-linear complexity.
+
+ @note A UTF-8 byte order mark is silently ignored.
+
+ @liveexample{The example below demonstrates the `parse()` function reading
+ from an iterator range.,parse__iteratortype__parser_callback_t}
+
+ @since version 2.0.3
+ */
+ template<class IteratorType, typename std::enable_if<
+ std::is_base_of<
+ std::random_access_iterator_tag,
+ typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+ static basic_json parse(IteratorType first, IteratorType last,
+ const parser_callback_t cb = nullptr,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
+ return result;
+ }
+
+ template<class IteratorType, typename std::enable_if<
+ std::is_base_of<
+ std::random_access_iterator_tag,
+ typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+ static bool accept(IteratorType first, IteratorType last)
+ {
+ return parser(detail::input_adapter(first, last)).accept(true);
+ }
+
+ template<class IteratorType, class SAX, typename std::enable_if<
+ std::is_base_of<
+ std::random_access_iterator_tag,
+ typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
+ static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
+ {
+ return parser(detail::input_adapter(first, last)).sax_parse(sax);
+ }
+
+ /*!
+ @brief deserialize from stream
+ @deprecated This stream operator is deprecated and will be removed in
+ version 4.0.0 of the library. Please use
+ @ref operator>>(std::istream&, basic_json&)
+ instead; that is, replace calls like `j << i;` with `i >> j;`.
+ @since version 1.0.0; deprecated since version 3.0.0
+ */
+ JSON_DEPRECATED
+ friend std::istream& operator<<(basic_json& j, std::istream& i)
+ {
+ return operator>>(i, j);
+ }
+
+ /*!
+ @brief deserialize from stream
+
+ Deserializes an input stream to a JSON value.
+
+ @param[in,out] i input stream to read a serialized JSON value from
+ @param[in,out] j JSON value to write the deserialized input to
+
+ @throw parse_error.101 in case of an unexpected token
+ @throw parse_error.102 if to_unicode fails or surrogate error
+ @throw parse_error.103 if to_unicode fails
+
+ @complexity Linear in the length of the input. The parser is a predictive
+ LL(1) parser.
+
+ @note A UTF-8 byte order mark is silently ignored.
+
+ @liveexample{The example below shows how a JSON value is constructed by
+ reading a serialization from a stream.,operator_deserialize}
+
+ @sa parse(std::istream&, const parser_callback_t) for a variant with a
+ parser callback function to filter values while parsing
+
+ @since version 1.0.0
+ */
+ friend std::istream& operator>>(std::istream& i, basic_json& j)
+ {
+ parser(detail::input_adapter(i)).parse(false, j);
+ return i;
+ }
+
+ /// @}
+
+ ///////////////////////////
+ // convenience functions //
+ ///////////////////////////
+
+ /*!
+ @brief return the type as string
+
+ Returns the type name as string to be used in error messages - usually to
+ indicate that a function was called on a wrong JSON type.
+
+ @return a string representation of a the @a m_type member:
+ Value type | return value
+ ----------- | -------------
+ null | `"null"`
+ boolean | `"boolean"`
+ string | `"string"`
+ number | `"number"` (for all number types)
+ object | `"object"`
+ array | `"array"`
+ discarded | `"discarded"`
+
+ @exceptionsafety No-throw guarantee: this function never throws exceptions.
+
+ @complexity Constant.
+
+ @liveexample{The following code exemplifies `type_name()` for all JSON
+ types.,type_name}
+
+ @sa @ref type() -- return the type of the JSON value
+ @sa @ref operator value_t() -- return the type of the JSON value (implicit)
+
+ @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
+ since 3.0.0
+ */
+ const char* type_name() const noexcept
+ {
+ {
+ switch (m_type)
+ {
+ case value_t::null:
+ return "null";
+ case value_t::object:
+ return "object";
+ case value_t::array:
+ return "array";
+ case value_t::string:
+ return "string";
+ case value_t::boolean:
+ return "boolean";
+ case value_t::discarded:
+ return "discarded";
+ default:
+ return "number";
+ }
+ }
+ }
+
+
+ private:
+ //////////////////////
+ // member variables //
+ //////////////////////
+
+ /// the type of the current element
+ value_t m_type = value_t::null;
+
+ /// the value of the current element
+ json_value m_value = {};
+
+ //////////////////////////////////////////
+ // binary serialization/deserialization //
+ //////////////////////////////////////////
+
+ /// @name binary serialization/deserialization support
+ /// @{
+
+ public:
+ /*!
+ @brief create a CBOR serialization of a given JSON value
+
+ Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
+ Binary Object Representation) serialization format. CBOR is a binary
+ serialization format which aims to be more compact than JSON itself, yet
+ more efficient to parse.
+
+ The library uses the following mapping from JSON values types to
+ CBOR types according to the CBOR specification (RFC 7049):
+
+ JSON value type | value/range | CBOR type | first byte
+ --------------- | ------------------------------------------ | ---------------------------------- | ---------------
+ null | `null` | Null | 0xF6
+ boolean | `true` | True | 0xF5
+ boolean | `false` | False | 0xF4
+ number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
+ number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
+ number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
+ number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
+ number_integer | -24..-1 | Negative integer | 0x20..0x37
+ number_integer | 0..23 | Integer | 0x00..0x17
+ number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
+ number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
+ number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
+ number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
+ number_unsigned | 0..23 | Integer | 0x00..0x17
+ number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
+ number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
+ number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
+ number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
+ number_float | *any value* | Double-Precision Float | 0xFB
+ string | *length*: 0..23 | UTF-8 string | 0x60..0x77
+ string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
+ string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
+ string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
+ string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
+ array | *size*: 0..23 | array | 0x80..0x97
+ array | *size*: 23..255 | array (1 byte follow) | 0x98
+ array | *size*: 256..65535 | array (2 bytes follow) | 0x99
+ array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
+ array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
+ object | *size*: 0..23 | map | 0xA0..0xB7
+ object | *size*: 23..255 | map (1 byte follow) | 0xB8
+ object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
+ object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
+ object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
+
+ @note The mapping is **complete** in the sense that any JSON value type
+ can be converted to a CBOR value.
+
+ @note If NaN or Infinity are stored inside a JSON number, they are
+ serialized properly. This behavior differs from the @ref dump()
+ function which serializes NaN or Infinity to `null`.
+
+ @note The following CBOR types are not used in the conversion:
+ - byte strings (0x40..0x5F)
+ - UTF-8 strings terminated by "break" (0x7F)
+ - arrays terminated by "break" (0x9F)
+ - maps terminated by "break" (0xBF)
+ - date/time (0xC0..0xC1)
+ - bignum (0xC2..0xC3)
+ - decimal fraction (0xC4)
+ - bigfloat (0xC5)
+ - tagged items (0xC6..0xD4, 0xD8..0xDB)
+ - expected conversions (0xD5..0xD7)
+ - simple values (0xE0..0xF3, 0xF8)
+ - undefined (0xF7)
+ - half and single-precision floats (0xF9-0xFA)
+ - break (0xFF)
+
+ @param[in] j JSON value to serialize
+ @return MessagePack serialization as byte vector
+
+ @complexity Linear in the size of the JSON value @a j.
+
+ @liveexample{The example shows the serialization of a JSON value to a byte
+ vector in CBOR format.,to_cbor}
+
+ @sa http://cbor.io
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
+ analogous deserialization
+ @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+ @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+ related UBJSON format
+
+ @since version 2.0.9
+ */
+ static std::vector<uint8_t> to_cbor(const basic_json& j)
+ {
+ std::vector<uint8_t> result;
+ to_cbor(j, result);
+ return result;
+ }
+
+ static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
+ {
+ binary_writer<uint8_t>(o).write_cbor(j);
+ }
+
+ static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
+ {
+ binary_writer<char>(o).write_cbor(j);
+ }
+
+ /*!
+ @brief create a MessagePack serialization of a given JSON value
+
+ Serializes a given JSON value @a j to a byte vector using the MessagePack
+ serialization format. MessagePack is a binary serialization format which
+ aims to be more compact than JSON itself, yet more efficient to parse.
+
+ The library uses the following mapping from JSON values types to
+ MessagePack types according to the MessagePack specification:
+
+ JSON value type | value/range | MessagePack type | first byte
+ --------------- | --------------------------------- | ---------------- | ----------
+ null | `null` | nil | 0xC0
+ boolean | `true` | true | 0xC3
+ boolean | `false` | false | 0xC2
+ number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
+ number_integer | -2147483648..-32769 | int32 | 0xD2
+ number_integer | -32768..-129 | int16 | 0xD1
+ number_integer | -128..-33 | int8 | 0xD0
+ number_integer | -32..-1 | negative fixint | 0xE0..0xFF
+ number_integer | 0..127 | positive fixint | 0x00..0x7F
+ number_integer | 128..255 | uint 8 | 0xCC
+ number_integer | 256..65535 | uint 16 | 0xCD
+ number_integer | 65536..4294967295 | uint 32 | 0xCE
+ number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
+ number_unsigned | 0..127 | positive fixint | 0x00..0x7F
+ number_unsigned | 128..255 | uint 8 | 0xCC
+ number_unsigned | 256..65535 | uint 16 | 0xCD
+ number_unsigned | 65536..4294967295 | uint 32 | 0xCE
+ number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
+ number_float | *any value* | float 64 | 0xCB
+ string | *length*: 0..31 | fixstr | 0xA0..0xBF
+ string | *length*: 32..255 | str 8 | 0xD9
+ string | *length*: 256..65535 | str 16 | 0xDA
+ string | *length*: 65536..4294967295 | str 32 | 0xDB
+ array | *size*: 0..15 | fixarray | 0x90..0x9F
+ array | *size*: 16..65535 | array 16 | 0xDC
+ array | *size*: 65536..4294967295 | array 32 | 0xDD
+ object | *size*: 0..15 | fix map | 0x80..0x8F
+ object | *size*: 16..65535 | map 16 | 0xDE
+ object | *size*: 65536..4294967295 | map 32 | 0xDF
+
+ @note The mapping is **complete** in the sense that any JSON value type
+ can be converted to a MessagePack value.
+
+ @note The following values can **not** be converted to a MessagePack value:
+ - strings with more than 4294967295 bytes
+ - arrays with more than 4294967295 elements
+ - objects with more than 4294967295 elements
+
+ @note The following MessagePack types are not used in the conversion:
+ - bin 8 - bin 32 (0xC4..0xC6)
+ - ext 8 - ext 32 (0xC7..0xC9)
+ - float 32 (0xCA)
+ - fixext 1 - fixext 16 (0xD4..0xD8)
+
+ @note Any MessagePack output created @ref to_msgpack can be successfully
+ parsed by @ref from_msgpack.
+
+ @note If NaN or Infinity are stored inside a JSON number, they are
+ serialized properly. This behavior differs from the @ref dump()
+ function which serializes NaN or Infinity to `null`.
+
+ @param[in] j JSON value to serialize
+ @return MessagePack serialization as byte vector
+
+ @complexity Linear in the size of the JSON value @a j.
+
+ @liveexample{The example shows the serialization of a JSON value to a byte
+ vector in MessagePack format.,to_msgpack}
+
+ @sa http://msgpack.org
+ @sa @ref from_msgpack for the analogous deserialization
+ @sa @ref to_cbor(const basic_json& for the related CBOR format
+ @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+ related UBJSON format
+
+ @since version 2.0.9
+ */
+ static std::vector<uint8_t> to_msgpack(const basic_json& j)
+ {
+ std::vector<uint8_t> result;
+ to_msgpack(j, result);
+ return result;
+ }
+
+ static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
+ {
+ binary_writer<uint8_t>(o).write_msgpack(j);
+ }
+
+ static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
+ {
+ binary_writer<char>(o).write_msgpack(j);
+ }
+
+ /*!
+ @brief create a UBJSON serialization of a given JSON value
+
+ Serializes a given JSON value @a j to a byte vector using the UBJSON
+ (Universal Binary JSON) serialization format. UBJSON aims to be more compact
+ than JSON itself, yet more efficient to parse.
+
+ The library uses the following mapping from JSON values types to
+ UBJSON types according to the UBJSON specification:
+
+ JSON value type | value/range | UBJSON type | marker
+ --------------- | --------------------------------- | ----------- | ------
+ null | `null` | null | `Z`
+ boolean | `true` | true | `T`
+ boolean | `false` | false | `F`
+ number_integer | -9223372036854775808..-2147483649 | int64 | `L`
+ number_integer | -2147483648..-32769 | int32 | `l`
+ number_integer | -32768..-129 | int16 | `I`
+ number_integer | -128..127 | int8 | `i`
+ number_integer | 128..255 | uint8 | `U`
+ number_integer | 256..32767 | int16 | `I`
+ number_integer | 32768..2147483647 | int32 | `l`
+ number_integer | 2147483648..9223372036854775807 | int64 | `L`
+ number_unsigned | 0..127 | int8 | `i`
+ number_unsigned | 128..255 | uint8 | `U`
+ number_unsigned | 256..32767 | int16 | `I`
+ number_unsigned | 32768..2147483647 | int32 | `l`
+ number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
+ number_float | *any value* | float64 | `D`
+ string | *with shortest length indicator* | string | `S`
+ array | *see notes on optimized format* | array | `[`
+ object | *see notes on optimized format* | map | `{`
+
+ @note The mapping is **complete** in the sense that any JSON value type
+ can be converted to a UBJSON value.
+
+ @note The following values can **not** be converted to a UBJSON value:
+ - strings with more than 9223372036854775807 bytes (theoretical)
+ - unsigned integer numbers above 9223372036854775807
+
+ @note The following markers are not used in the conversion:
+ - `Z`: no-op values are not created.
+ - `C`: single-byte strings are serialized with `S` markers.
+
+ @note Any UBJSON output created @ref to_ubjson can be successfully parsed
+ by @ref from_ubjson.
+
+ @note If NaN or Infinity are stored inside a JSON number, they are
+ serialized properly. This behavior differs from the @ref dump()
+ function which serializes NaN or Infinity to `null`.
+
+ @note The optimized formats for containers are supported: Parameter
+ @a use_size adds size information to the beginning of a container and
+ removes the closing marker. Parameter @a use_type further checks
+ whether all elements of a container have the same type and adds the
+ type marker to the beginning of the container. The @a use_type
+ parameter must only be used together with @a use_size = true. Note
+ that @a use_size = true alone may result in larger representations -
+ the benefit of this parameter is that the receiving side is
+ immediately informed on the number of elements of the container.
+
+ @param[in] j JSON value to serialize
+ @param[in] use_size whether to add size annotations to container types
+ @param[in] use_type whether to add type annotations to container types
+ (must be combined with @a use_size = true)
+ @return UBJSON serialization as byte vector
+
+ @complexity Linear in the size of the JSON value @a j.
+
+ @liveexample{The example shows the serialization of a JSON value to a byte
+ vector in UBJSON format.,to_ubjson}
+
+ @sa http://ubjson.org
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+ analogous deserialization
+ @sa @ref to_cbor(const basic_json& for the related CBOR format
+ @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+
+ @since version 3.1.0
+ */
+ static std::vector<uint8_t> to_ubjson(const basic_json& j,
+ const bool use_size = false,
+ const bool use_type = false)
+ {
+ std::vector<uint8_t> result;
+ to_ubjson(j, result, use_size, use_type);
+ return result;
+ }
+
+ static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
+ const bool use_size = false, const bool use_type = false)
+ {
+ binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
+ }
+
+ static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
+ const bool use_size = false, const bool use_type = false)
+ {
+ binary_writer<char>(o).write_ubjson(j, use_size, use_type);
+ }
+
+
+ /*!
+ @brief Serializes the given JSON object `j` to BSON and returns a vector
+ containing the corresponding BSON-representation.
+
+ BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
+ stored as a single entity (a so-called document).
+
+ The library uses the following mapping from JSON values types to BSON types:
+
+ JSON value type | value/range | BSON type | marker
+ --------------- | --------------------------------- | ----------- | ------
+ null | `null` | null | 0x0A
+ boolean | `true`, `false` | boolean | 0x08
+ number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
+ number_integer | -2147483648..2147483647 | int32 | 0x10
+ number_integer | 2147483648..9223372036854775807 | int64 | 0x12
+ number_unsigned | 0..2147483647 | int32 | 0x10
+ number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
+ number_unsigned | 9223372036854775808..18446744073709551615| -- | --
+ number_float | *any value* | double | 0x01
+ string | *any value* | string | 0x02
+ array | *any value* | document | 0x04
+ object | *any value* | document | 0x03
+
+ @warning The mapping is **incomplete**, since only JSON-objects (and things
+ contained therein) can be serialized to BSON.
+ Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
+ and the keys may not contain U+0000, since they are serialized a
+ zero-terminated c-strings.
+
+ @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
+ @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
+ @throw type_error.317 if `!j.is_object()`
+
+ @pre The input `j` is required to be an object: `j.is_object() == true`.
+
+ @note Any BSON output created via @ref to_bson can be successfully parsed
+ by @ref from_bson.
+
+ @param[in] j JSON value to serialize
+ @return BSON serialization as byte vector
+
+ @complexity Linear in the size of the JSON value @a j.
+
+ @liveexample{The example shows the serialization of a JSON value to a byte
+ vector in BSON format.,to_bson}
+
+ @sa http://bsonspec.org/spec.html
+ @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
+ analogous deserialization
+ @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+ related UBJSON format
+ @sa @ref to_cbor(const basic_json&) for the related CBOR format
+ @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
+ */
+ static std::vector<uint8_t> to_bson(const basic_json& j)
+ {
+ std::vector<uint8_t> result;
+ to_bson(j, result);
+ return result;
+ }
+
+ /*!
+ @brief Serializes the given JSON object `j` to BSON and forwards the
+ corresponding BSON-representation to the given output_adapter `o`.
+ @param j The JSON object to convert to BSON.
+ @param o The output adapter that receives the binary BSON representation.
+ @pre The input `j` shall be an object: `j.is_object() == true`
+ @sa @ref to_bson(const basic_json&)
+ */
+ static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
+ {
+ binary_writer<uint8_t>(o).write_bson(j);
+ }
+
+ /*!
+ @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
+ */
+ static void to_bson(const basic_json& j, detail::output_adapter<char> o)
+ {
+ binary_writer<char>(o).write_bson(j);
+ }
+
+
+ /*!
+ @brief create a JSON value from an input in CBOR format
+
+ Deserializes a given input @a i to a JSON value using the CBOR (Concise
+ Binary Object Representation) serialization format.
+
+ The library maps CBOR types to JSON value types as follows:
+
+ CBOR type | JSON value type | first byte
+ ---------------------- | --------------- | ----------
+ Integer | number_unsigned | 0x00..0x17
+ Unsigned integer | number_unsigned | 0x18
+ Unsigned integer | number_unsigned | 0x19
+ Unsigned integer | number_unsigned | 0x1A
+ Unsigned integer | number_unsigned | 0x1B
+ Negative integer | number_integer | 0x20..0x37
+ Negative integer | number_integer | 0x38
+ Negative integer | number_integer | 0x39
+ Negative integer | number_integer | 0x3A
+ Negative integer | number_integer | 0x3B
+ Negative integer | number_integer | 0x40..0x57
+ UTF-8 string | string | 0x60..0x77
+ UTF-8 string | string | 0x78
+ UTF-8 string | string | 0x79
+ UTF-8 string | string | 0x7A
+ UTF-8 string | string | 0x7B
+ UTF-8 string | string | 0x7F
+ array | array | 0x80..0x97
+ array | array | 0x98
+ array | array | 0x99
+ array | array | 0x9A
+ array | array | 0x9B
+ array | array | 0x9F
+ map | object | 0xA0..0xB7
+ map | object | 0xB8
+ map | object | 0xB9
+ map | object | 0xBA
+ map | object | 0xBB
+ map | object | 0xBF
+ False | `false` | 0xF4
+ True | `true` | 0xF5
+ Null | `null` | 0xF6
+ Half-Precision Float | number_float | 0xF9
+ Single-Precision Float | number_float | 0xFA
+ Double-Precision Float | number_float | 0xFB
+
+ @warning The mapping is **incomplete** in the sense that not all CBOR
+ types can be converted to a JSON value. The following CBOR types
+ are not supported and will yield parse errors (parse_error.112):
+ - byte strings (0x40..0x5F)
+ - date/time (0xC0..0xC1)
+ - bignum (0xC2..0xC3)
+ - decimal fraction (0xC4)
+ - bigfloat (0xC5)
+ - tagged items (0xC6..0xD4, 0xD8..0xDB)
+ - expected conversions (0xD5..0xD7)
+ - simple values (0xE0..0xF3, 0xF8)
+ - undefined (0xF7)
+
+ @warning CBOR allows map keys of any type, whereas JSON only allows
+ strings as keys in object values. Therefore, CBOR maps with keys
+ other than UTF-8 strings are rejected (parse_error.113).
+
+ @note Any CBOR output created @ref to_cbor can be successfully parsed by
+ @ref from_cbor.
+
+ @param[in] i an input in CBOR format convertible to an input adapter
+ @param[in] strict whether to expect the input to be consumed until EOF
+ (true by default)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value; in case of a parse error and
+ @a allow_exceptions set to `false`, the return value will be
+ value_t::discarded.
+
+ @throw parse_error.110 if the given input ends prematurely or the end of
+ file was not reached when @a strict was set to true
+ @throw parse_error.112 if unsupported features from CBOR were
+ used in the given input @a v or if the input is not valid CBOR
+ @throw parse_error.113 if a string was expected as map key, but not found
+
+ @complexity Linear in the size of the input @a i.
+
+ @liveexample{The example shows the deserialization of a byte vector in CBOR
+ format to a JSON value.,from_cbor}
+
+ @sa http://cbor.io
+ @sa @ref to_cbor(const basic_json&) for the analogous serialization
+ @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
+ related MessagePack format
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+ related UBJSON format
+
+ @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
+ consume input adapters, removed start_index parameter, and added
+ @a strict parameter since 3.0.0; added @a allow_exceptions parameter
+ since 3.2.0
+ */
+ JSON_NODISCARD
+ static basic_json from_cbor(detail::input_adapter&& i,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
+ */
+ template<typename A1, typename A2,
+ detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+ JSON_NODISCARD
+ static basic_json from_cbor(A1 && a1, A2 && a2,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @brief create a JSON value from an input in MessagePack format
+
+ Deserializes a given input @a i to a JSON value using the MessagePack
+ serialization format.
+
+ The library maps MessagePack types to JSON value types as follows:
+
+ MessagePack type | JSON value type | first byte
+ ---------------- | --------------- | ----------
+ positive fixint | number_unsigned | 0x00..0x7F
+ fixmap | object | 0x80..0x8F
+ fixarray | array | 0x90..0x9F
+ fixstr | string | 0xA0..0xBF
+ nil | `null` | 0xC0
+ false | `false` | 0xC2
+ true | `true` | 0xC3
+ float 32 | number_float | 0xCA
+ float 64 | number_float | 0xCB
+ uint 8 | number_unsigned | 0xCC
+ uint 16 | number_unsigned | 0xCD
+ uint 32 | number_unsigned | 0xCE
+ uint 64 | number_unsigned | 0xCF
+ int 8 | number_integer | 0xD0
+ int 16 | number_integer | 0xD1
+ int 32 | number_integer | 0xD2
+ int 64 | number_integer | 0xD3
+ str 8 | string | 0xD9
+ str 16 | string | 0xDA
+ str 32 | string | 0xDB
+ array 16 | array | 0xDC
+ array 32 | array | 0xDD
+ map 16 | object | 0xDE
+ map 32 | object | 0xDF
+ negative fixint | number_integer | 0xE0-0xFF
+
+ @warning The mapping is **incomplete** in the sense that not all
+ MessagePack types can be converted to a JSON value. The following
+ MessagePack types are not supported and will yield parse errors:
+ - bin 8 - bin 32 (0xC4..0xC6)
+ - ext 8 - ext 32 (0xC7..0xC9)
+ - fixext 1 - fixext 16 (0xD4..0xD8)
+
+ @note Any MessagePack output created @ref to_msgpack can be successfully
+ parsed by @ref from_msgpack.
+
+ @param[in] i an input in MessagePack format convertible to an input
+ adapter
+ @param[in] strict whether to expect the input to be consumed until EOF
+ (true by default)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value; in case of a parse error and
+ @a allow_exceptions set to `false`, the return value will be
+ value_t::discarded.
+
+ @throw parse_error.110 if the given input ends prematurely or the end of
+ file was not reached when @a strict was set to true
+ @throw parse_error.112 if unsupported features from MessagePack were
+ used in the given input @a i or if the input is not valid MessagePack
+ @throw parse_error.113 if a string was expected as map key, but not found
+
+ @complexity Linear in the size of the input @a i.
+
+ @liveexample{The example shows the deserialization of a byte vector in
+ MessagePack format to a JSON value.,from_msgpack}
+
+ @sa http://msgpack.org
+ @sa @ref to_msgpack(const basic_json&) for the analogous serialization
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
+ related CBOR format
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
+ the related UBJSON format
+ @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
+ the related BSON format
+
+ @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
+ consume input adapters, removed start_index parameter, and added
+ @a strict parameter since 3.0.0; added @a allow_exceptions parameter
+ since 3.2.0
+ */
+ JSON_NODISCARD
+ static basic_json from_msgpack(detail::input_adapter&& i,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
+ */
+ template<typename A1, typename A2,
+ detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+ JSON_NODISCARD
+ static basic_json from_msgpack(A1 && a1, A2 && a2,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @brief create a JSON value from an input in UBJSON format
+
+ Deserializes a given input @a i to a JSON value using the UBJSON (Universal
+ Binary JSON) serialization format.
+
+ The library maps UBJSON types to JSON value types as follows:
+
+ UBJSON type | JSON value type | marker
+ ----------- | --------------------------------------- | ------
+ no-op | *no value, next value is read* | `N`
+ null | `null` | `Z`
+ false | `false` | `F`
+ true | `true` | `T`
+ float32 | number_float | `d`
+ float64 | number_float | `D`
+ uint8 | number_unsigned | `U`
+ int8 | number_integer | `i`
+ int16 | number_integer | `I`
+ int32 | number_integer | `l`
+ int64 | number_integer | `L`
+ string | string | `S`
+ char | string | `C`
+ array | array (optimized values are supported) | `[`
+ object | object (optimized values are supported) | `{`
+
+ @note The mapping is **complete** in the sense that any UBJSON value can
+ be converted to a JSON value.
+
+ @param[in] i an input in UBJSON format convertible to an input adapter
+ @param[in] strict whether to expect the input to be consumed until EOF
+ (true by default)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value; in case of a parse error and
+ @a allow_exceptions set to `false`, the return value will be
+ value_t::discarded.
+
+ @throw parse_error.110 if the given input ends prematurely or the end of
+ file was not reached when @a strict was set to true
+ @throw parse_error.112 if a parse error occurs
+ @throw parse_error.113 if a string could not be parsed successfully
+
+ @complexity Linear in the size of the input @a i.
+
+ @liveexample{The example shows the deserialization of a byte vector in
+ UBJSON format to a JSON value.,from_ubjson}
+
+ @sa http://ubjson.org
+ @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
+ analogous serialization
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
+ related CBOR format
+ @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
+ the related MessagePack format
+ @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
+ the related BSON format
+
+ @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
+ */
+ JSON_NODISCARD
+ static basic_json from_ubjson(detail::input_adapter&& i,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
+ */
+ template<typename A1, typename A2,
+ detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+ JSON_NODISCARD
+ static basic_json from_ubjson(A1 && a1, A2 && a2,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @brief Create a JSON value from an input in BSON format
+
+ Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
+ serialization format.
+
+ The library maps BSON record types to JSON value types as follows:
+
+ BSON type | BSON marker byte | JSON value type
+ --------------- | ---------------- | ---------------------------
+ double | 0x01 | number_float
+ string | 0x02 | string
+ document | 0x03 | object
+ array | 0x04 | array
+ binary | 0x05 | still unsupported
+ undefined | 0x06 | still unsupported
+ ObjectId | 0x07 | still unsupported
+ boolean | 0x08 | boolean
+ UTC Date-Time | 0x09 | still unsupported
+ null | 0x0A | null
+ Regular Expr. | 0x0B | still unsupported
+ DB Pointer | 0x0C | still unsupported
+ JavaScript Code | 0x0D | still unsupported
+ Symbol | 0x0E | still unsupported
+ JavaScript Code | 0x0F | still unsupported
+ int32 | 0x10 | number_integer
+ Timestamp | 0x11 | still unsupported
+ 128-bit decimal float | 0x13 | still unsupported
+ Max Key | 0x7F | still unsupported
+ Min Key | 0xFF | still unsupported
+
+ @warning The mapping is **incomplete**. The unsupported mappings
+ are indicated in the table above.
+
+ @param[in] i an input in BSON format convertible to an input adapter
+ @param[in] strict whether to expect the input to be consumed until EOF
+ (true by default)
+ @param[in] allow_exceptions whether to throw exceptions in case of a
+ parse error (optional, true by default)
+
+ @return deserialized JSON value; in case of a parse error and
+ @a allow_exceptions set to `false`, the return value will be
+ value_t::discarded.
+
+ @throw parse_error.114 if an unsupported BSON record type is encountered
+
+ @complexity Linear in the size of the input @a i.
+
+ @liveexample{The example shows the deserialization of a byte vector in
+ BSON format to a JSON value.,from_bson}
+
+ @sa http://bsonspec.org/spec.html
+ @sa @ref to_bson(const basic_json&) for the analogous serialization
+ @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
+ related CBOR format
+ @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
+ the related MessagePack format
+ @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
+ related UBJSON format
+ */
+ JSON_NODISCARD
+ static basic_json from_bson(detail::input_adapter&& i,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+ /*!
+ @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
+ */
+ template<typename A1, typename A2,
+ detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
+ JSON_NODISCARD
+ static basic_json from_bson(A1 && a1, A2 && a2,
+ const bool strict = true,
+ const bool allow_exceptions = true)
+ {
+ basic_json result;
+ detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
+ const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
+ return res ? result : basic_json(value_t::discarded);
+ }
+
+
+
+ /// @}
+
+ //////////////////////////
+ // JSON Pointer support //
+ //////////////////////////
+
+ /// @name JSON Pointer functions
+ /// @{
+
+ /*!
+ @brief access specified element via JSON Pointer
+
+ Uses a JSON pointer to retrieve a reference to the respective JSON value.
+ No bound checking is performed. Similar to @ref operator[](const typename
+ object_t::key_type&), `null` values are created in arrays and objects if
+ necessary.
+
+ In particular:
+ - If the JSON pointer points to an object key that does not exist, it
+ is created an filled with a `null` value before a reference to it
+ is returned.
+ - If the JSON pointer points to an array index that does not exist, it
+ is created an filled with a `null` value before a reference to it
+ is returned. All indices between the current maximum and the given
+ index are also filled with `null`.
+ - The special value `-` is treated as a synonym for the index past the
+ end.
+
+ @param[in] ptr a JSON pointer
+
+ @return reference to the element pointed to by @a ptr
+
+ @complexity Constant.
+
+ @throw parse_error.106 if an array index begins with '0'
+ @throw parse_error.109 if an array index was not a number
+ @throw out_of_range.404 if the JSON pointer can not be resolved
+
+ @liveexample{The behavior is shown in the example.,operatorjson_pointer}
+
+ @since version 2.0.0
+ */
+ reference operator[](const json_pointer& ptr)
+ {
+ return ptr.get_unchecked(this);
+ }
+
+ /*!
+ @brief access specified element via JSON Pointer
+
+ Uses a JSON pointer to retrieve a reference to the respective JSON value.
+ No bound checking is performed. The function does not change the JSON
+ value; no `null` values are created. In particular, the the special value
+ `-` yields an exception.
+
+ @param[in] ptr JSON pointer to the desired element
+
+ @return const reference to the element pointed to by @a ptr
+
+ @complexity Constant.
+
+ @throw parse_error.106 if an array index begins with '0'
+ @throw parse_error.109 if an array index was not a number
+ @throw out_of_range.402 if the array index '-' is used
+ @throw out_of_range.404 if the JSON pointer can not be resolved
+
+ @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
+
+ @since version 2.0.0
+ */
+ const_reference operator[](const json_pointer& ptr) const
+ {
+ return ptr.get_unchecked(this);
+ }
+
+ /*!
+ @brief access specified element via JSON Pointer
+
+ Returns a reference to the element at with specified JSON pointer @a ptr,
+ with bounds checking.
+
+ @param[in] ptr JSON pointer to the desired element
+
+ @return reference to the element pointed to by @a ptr
+
+ @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
+ begins with '0'. See example below.
+
+ @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
+ is not a number. See example below.
+
+ @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
+ is out of range. See example below.
+
+ @throw out_of_range.402 if the array index '-' is used in the passed JSON
+ pointer @a ptr. As `at` provides checked access (and no elements are
+ implicitly inserted), the index '-' is always invalid. See example below.
+
+ @throw out_of_range.403 if the JSON pointer describes a key of an object
+ which cannot be found. See example below.
+
+ @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
+ See example below.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Constant.
+
+ @since version 2.0.0
+
+ @liveexample{The behavior is shown in the example.,at_json_pointer}
+ */
+ reference at(const json_pointer& ptr)
+ {
+ return ptr.get_checked(this);
+ }
+
+ /*!
+ @brief access specified element via JSON Pointer
+
+ Returns a const reference to the element at with specified JSON pointer @a
+ ptr, with bounds checking.
+
+ @param[in] ptr JSON pointer to the desired element
+
+ @return reference to the element pointed to by @a ptr
+
+ @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
+ begins with '0'. See example below.
+
+ @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
+ is not a number. See example below.
+
+ @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
+ is out of range. See example below.
+
+ @throw out_of_range.402 if the array index '-' is used in the passed JSON
+ pointer @a ptr. As `at` provides checked access (and no elements are
+ implicitly inserted), the index '-' is always invalid. See example below.
+
+ @throw out_of_range.403 if the JSON pointer describes a key of an object
+ which cannot be found. See example below.
+
+ @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
+ See example below.
+
+ @exceptionsafety Strong guarantee: if an exception is thrown, there are no
+ changes in the JSON value.
+
+ @complexity Constant.
+
+ @since version 2.0.0
+
+ @liveexample{The behavior is shown in the example.,at_json_pointer_const}
+ */
+ const_reference at(const json_pointer& ptr) const
+ {
+ return ptr.get_checked(this);
+ }
+
+ /*!
+ @brief return flattened JSON value
+
+ The function creates a JSON object whose keys are JSON pointers (see [RFC
+ 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
+ primitive. The original JSON value can be restored using the @ref
+ unflatten() function.
+
+ @return an object that maps JSON pointers to primitive values
+
+ @note Empty objects and arrays are flattened to `null` and will not be
+ reconstructed correctly by the @ref unflatten() function.
+
+ @complexity Linear in the size the JSON value.
+
+ @liveexample{The following code shows how a JSON object is flattened to an
+ object whose keys consist of JSON pointers.,flatten}
+
+ @sa @ref unflatten() for the reverse function
+
+ @since version 2.0.0
+ */
+ basic_json flatten() const
+ {
+ basic_json result(value_t::object);
+ json_pointer::flatten("", *this, result);
+ return result;
+ }
+
+ /*!
+ @brief unflatten a previously flattened JSON value
+
+ The function restores the arbitrary nesting of a JSON value that has been
+ flattened before using the @ref flatten() function. The JSON value must
+ meet certain constraints:
+ 1. The value must be an object.
+ 2. The keys must be JSON pointers (see
+ [RFC 6901](https://tools.ietf.org/html/rfc6901))
+ 3. The mapped values must be primitive JSON types.
+
+ @return the original JSON from a flattened version
+
+ @note Empty objects and arrays are flattened by @ref flatten() to `null`
+ values and can not unflattened to their original type. Apart from
+ this example, for a JSON value `j`, the following is always true:
+ `j == j.flatten().unflatten()`.
+
+ @complexity Linear in the size the JSON value.
+
+ @throw type_error.314 if value is not an object
+ @throw type_error.315 if object values are not primitive
+
+ @liveexample{The following code shows how a flattened JSON object is
+ unflattened into the original nested JSON object.,unflatten}
+
+ @sa @ref flatten() for the reverse function
+
+ @since version 2.0.0
+ */
+ basic_json unflatten() const
+ {
+ return json_pointer::unflatten(*this);
+ }
+
+ /// @}
+
+ //////////////////////////
+ // JSON Patch functions //
+ //////////////////////////
+
+ /// @name JSON Patch functions
+ /// @{
+
+ /*!
+ @brief applies a JSON patch
+
+ [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
+ expressing a sequence of operations to apply to a JSON) document. With
+ this function, a JSON Patch is applied to the current JSON value by
+ executing all operations from the patch.
+
+ @param[in] json_patch JSON patch document
+ @return patched document
+
+ @note The application of a patch is atomic: Either all operations succeed
+ and the patched document is returned or an exception is thrown. In
+ any case, the original value is not changed: the patch is applied
+ to a copy of the value.
+
+ @throw parse_error.104 if the JSON patch does not consist of an array of
+ objects
+
+ @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
+ attributes are missing); example: `"operation add must have member path"`
+
+ @throw out_of_range.401 if an array index is out of range.
+
+ @throw out_of_range.403 if a JSON pointer inside the patch could not be
+ resolved successfully in the current JSON value; example: `"key baz not
+ found"`
+
+ @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
+ "move")
+
+ @throw other_error.501 if "test" operation was unsuccessful
+
+ @complexity Linear in the size of the JSON value and the length of the
+ JSON patch. As usually only a fraction of the JSON value is affected by
+ the patch, the complexity can usually be neglected.
+
+ @liveexample{The following code shows how a JSON patch is applied to a
+ value.,patch}
+
+ @sa @ref diff -- create a JSON patch by comparing two JSON values
+
+ @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
+ @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
+
+ @since version 2.0.0
+ */
+ basic_json patch(const basic_json& json_patch) const
+ {
+ // make a working copy to apply the patch to
+ basic_json result = *this;
+
+ // the valid JSON Patch operations
+ enum class patch_operations {add, remove, replace, move, copy, test, invalid};
+
+ const auto get_op = [](const std::string & op)
+ {
+ if (op == "add")
+ {
+ return patch_operations::add;
+ }
+ if (op == "remove")
+ {
+ return patch_operations::remove;
+ }
+ if (op == "replace")
+ {
+ return patch_operations::replace;
+ }
+ if (op == "move")
+ {
+ return patch_operations::move;
+ }
+ if (op == "copy")
+ {
+ return patch_operations::copy;
+ }
+ if (op == "test")
+ {
+ return patch_operations::test;
+ }
+
+ return patch_operations::invalid;
+ };
+
+ // wrapper for "add" operation; add value at ptr
+ const auto operation_add = [&result](json_pointer & ptr, basic_json val)
+ {
+ // adding to the root of the target document means replacing it
+ if (ptr.empty())
+ {
+ result = val;
+ return;
+ }
+
+ // make sure the top element of the pointer exists
+ json_pointer top_pointer = ptr.top();
+ if (top_pointer != ptr)
+ {
+ result.at(top_pointer);
+ }
+
+ // get reference to parent of JSON pointer ptr
+ const auto last_path = ptr.back();
+ ptr.pop_back();
+ basic_json& parent = result[ptr];
+
+ switch (parent.m_type)
+ {
+ case value_t::null:
+ case value_t::object:
+ {
+ // use operator[] to add value
+ parent[last_path] = val;
+ break;
+ }
+
+ case value_t::array:
+ {
+ if (last_path == "-")
+ {
+ // special case: append to back
+ parent.push_back(val);
+ }
+ else
+ {
+ const auto idx = json_pointer::array_index(last_path);
+ if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
+ {
+ // avoid undefined behavior
+ JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
+ }
+
+ // default case: insert add offset
+ parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
+ }
+ break;
+ }
+
+ // if there exists a parent it cannot be primitive
+ default: // LCOV_EXCL_LINE
+ assert(false); // LCOV_EXCL_LINE
+ }
+ };
+
+ // wrapper for "remove" operation; remove value at ptr
+ const auto operation_remove = [&result](json_pointer & ptr)
+ {
+ // get reference to parent of JSON pointer ptr
+ const auto last_path = ptr.back();
+ ptr.pop_back();
+ basic_json& parent = result.at(ptr);
+
+ // remove child
+ if (parent.is_object())
+ {
+ // perform range check
+ auto it = parent.find(last_path);
+ if (JSON_LIKELY(it != parent.end()))
+ {
+ parent.erase(it);
+ }
+ else
+ {
+ JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
+ }
+ }
+ else if (parent.is_array())
+ {
+ // note erase performs range check
+ parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
+ }
+ };
+
+ // type check: top level value must be an array
+ if (JSON_UNLIKELY(not json_patch.is_array()))
+ {
+ JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
+ }
+
+ // iterate and apply the operations
+ for (const auto& val : json_patch)
+ {
+ // wrapper to get a value for an operation
+ const auto get_value = [&val](const std::string & op,
+ const std::string & member,
+ bool string_type) -> basic_json &
+ {
+ // find value
+ auto it = val.m_value.object->find(member);
+
+ // context-sensitive error message
+ const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
+
+ // check if desired value is present
+ if (JSON_UNLIKELY(it == val.m_value.object->end()))
+ {
+ JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
+ }
+
+ // check if result is of type string
+ if (JSON_UNLIKELY(string_type and not it->second.is_string()))
+ {
+ JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
+ }
+
+ // no error: return value
+ return it->second;
+ };
+
+ // type check: every element of the array must be an object
+ if (JSON_UNLIKELY(not val.is_object()))
+ {
+ JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
+ }
+
+ // collect mandatory members
+ const std::string op = get_value("op", "op", true);
+ const std::string path = get_value(op, "path", true);
+ json_pointer ptr(path);
+
+ switch (get_op(op))
+ {
+ case patch_operations::add:
+ {
+ operation_add(ptr, get_value("add", "value", false));
+ break;
+ }
+
+ case patch_operations::remove:
+ {
+ operation_remove(ptr);
+ break;
+ }
+
+ case patch_operations::replace:
+ {
+ // the "path" location must exist - use at()
+ result.at(ptr) = get_value("replace", "value", false);
+ break;
+ }
+
+ case patch_operations::move:
+ {
+ const std::string from_path = get_value("move", "from", true);
+ json_pointer from_ptr(from_path);
+
+ // the "from" location must exist - use at()
+ basic_json v = result.at(from_ptr);
+
+ // The move operation is functionally identical to a
+ // "remove" operation on the "from" location, followed
+ // immediately by an "add" operation at the target
+ // location with the value that was just removed.
+ operation_remove(from_ptr);
+ operation_add(ptr, v);
+ break;
+ }
+
+ case patch_operations::copy:
+ {
+ const std::string from_path = get_value("copy", "from", true);
+ const json_pointer from_ptr(from_path);
+
+ // the "from" location must exist - use at()
+ basic_json v = result.at(from_ptr);
+
+ // The copy is functionally identical to an "add"
+ // operation at the target location using the value
+ // specified in the "from" member.
+ operation_add(ptr, v);
+ break;
+ }
+
+ case patch_operations::test:
+ {
+ bool success = false;
+ JSON_TRY
+ {
+ // check if "value" matches the one at "path"
+ // the "path" location must exist - use at()
+ success = (result.at(ptr) == get_value("test", "value", false));
+ }
+ JSON_INTERNAL_CATCH (out_of_range&)
+ {
+ // ignore out of range errors: success remains false
+ }
+
+ // throw an exception if test fails
+ if (JSON_UNLIKELY(not success))
+ {
+ JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
+ }
+
+ break;
+ }
+
+ default:
+ {
+ // op must be "add", "remove", "replace", "move", "copy", or
+ // "test"
+ JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /*!
+ @brief creates a diff as a JSON patch
+
+ Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
+ be changed into the value @a target by calling @ref patch function.
+
+ @invariant For two JSON values @a source and @a target, the following code
+ yields always `true`:
+ @code {.cpp}
+ source.patch(diff(source, target)) == target;
+ @endcode
+
+ @note Currently, only `remove`, `add`, and `replace` operations are
+ generated.
+
+ @param[in] source JSON value to compare from
+ @param[in] target JSON value to compare against
+ @param[in] path helper value to create JSON pointers
+
+ @return a JSON patch to convert the @a source to @a target
+
+ @complexity Linear in the lengths of @a source and @a target.
+
+ @liveexample{The following code shows how a JSON patch is created as a
+ diff for two JSON values.,diff}
+
+ @sa @ref patch -- apply a JSON patch
+ @sa @ref merge_patch -- apply a JSON Merge Patch
+
+ @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
+
+ @since version 2.0.0
+ */
+ JSON_NODISCARD
+ static basic_json diff(const basic_json& source, const basic_json& target,
+ const std::string& path = "")
+ {
+ // the patch
+ basic_json result(value_t::array);
+
+ // if the values are the same, return empty patch
+ if (source == target)
+ {
+ return result;
+ }
+
+ if (source.type() != target.type())
+ {
+ // different types: replace value
+ result.push_back(
+ {
+ {"op", "replace"}, {"path", path}, {"value", target}
+ });
+ return result;
+ }
+
+ switch (source.type())
+ {
+ case value_t::array:
+ {
+ // first pass: traverse common elements
+ std::size_t i = 0;
+ while (i < source.size() and i < target.size())
+ {
+ // recursive call to compare array values at index i
+ auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
+ result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+ ++i;
+ }
+
+ // i now reached the end of at least one array
+ // in a second pass, traverse the remaining elements
+
+ // remove my remaining elements
+ const auto end_index = static_cast<difference_type>(result.size());
+ while (i < source.size())
+ {
+ // add operations in reverse order to avoid invalid
+ // indices
+ result.insert(result.begin() + end_index, object(
+ {
+ {"op", "remove"},
+ {"path", path + "/" + std::to_string(i)}
+ }));
+ ++i;
+ }
+
+ // add other remaining elements
+ while (i < target.size())
+ {
+ result.push_back(
+ {
+ {"op", "add"},
+ {"path", path + "/" + std::to_string(i)},
+ {"value", target[i]}
+ });
+ ++i;
+ }
+
+ break;
+ }
+
+ case value_t::object:
+ {
+ // first pass: traverse this object's elements
+ for (auto it = source.cbegin(); it != source.cend(); ++it)
+ {
+ // escape the key name to be used in a JSON patch
+ const auto key = json_pointer::escape(it.key());
+
+ if (target.find(it.key()) != target.end())
+ {
+ // recursive call to compare object values at key it
+ auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
+ result.insert(result.end(), temp_diff.begin(), temp_diff.end());
+ }
+ else
+ {
+ // found a key that is not in o -> remove it
+ result.push_back(object(
+ {
+ {"op", "remove"}, {"path", path + "/" + key}
+ }));
+ }
+ }
+
+ // second pass: traverse other object's elements
+ for (auto it = target.cbegin(); it != target.cend(); ++it)
+ {
+ if (source.find(it.key()) == source.end())
+ {
+ // found a key that is not in this -> add it
+ const auto key = json_pointer::escape(it.key());
+ result.push_back(
+ {
+ {"op", "add"}, {"path", path + "/" + key},
+ {"value", it.value()}
+ });
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ // both primitive type: replace value
+ result.push_back(
+ {
+ {"op", "replace"}, {"path", path}, {"value", target}
+ });
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /// @}
+
+ ////////////////////////////////
+ // JSON Merge Patch functions //
+ ////////////////////////////////
+
+ /// @name JSON Merge Patch functions
+ /// @{
+
+ /*!
+ @brief applies a JSON Merge Patch
+
+ The merge patch format is primarily intended for use with the HTTP PATCH
+ method as a means of describing a set of modifications to a target
+ resource's content. This function applies a merge patch to the current
+ JSON value.
+
+ The function implements the following algorithm from Section 2 of
+ [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
+
+ ```
+ define MergePatch(Target, Patch):
+ if Patch is an Object:
+ if Target is not an Object:
+ Target = {} // Ignore the contents and set it to an empty Object
+ for each Name/Value pair in Patch:
+ if Value is null:
+ if Name exists in Target:
+ remove the Name/Value pair from Target
+ else:
+ Target[Name] = MergePatch(Target[Name], Value)
+ return Target
+ else:
+ return Patch
+ ```
+
+ Thereby, `Target` is the current object; that is, the patch is applied to
+ the current value.
+
+ @param[in] apply_patch the patch to apply
+
+ @complexity Linear in the lengths of @a patch.
+
+ @liveexample{The following code shows how a JSON Merge Patch is applied to
+ a JSON document.,merge_patch}
+
+ @sa @ref patch -- apply a JSON patch
+ @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
+
+ @since version 3.0.0
+ */
+ void merge_patch(const basic_json& apply_patch)
+ {
+ if (apply_patch.is_object())
+ {
+ if (not is_object())
+ {
+ *this = object();
+ }
+ for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
+ {
+ if (it.value().is_null())
+ {
+ erase(it.key());
+ }
+ else
+ {
+ operator[](it.key()).merge_patch(it.value());
+ }
+ }
+ }
+ else
+ {
+ *this = apply_patch;
+ }
+ }
+
+ /// @}
+};
+} // namespace nlohmann
+
+///////////////////////
+// nonmember support //
+///////////////////////
+
+// specialization of std::swap, and std::hash
+namespace std
+{
+
+/// hash value for JSON objects
+template<>
+struct hash<nlohmann::json>
+{
+ /*!
+ @brief return a hash value for a JSON object
+
+ @since version 1.0.0
+ */
+ std::size_t operator()(const nlohmann::json& j) const
+ {
+ // a naive hashing via the string representation
+ const auto& h = hash<nlohmann::json::string_t>();
+ return h(j.dump());
+ }
+};
+
+/// specialization for std::less<value_t>
+/// @note: do not remove the space after '<',
+/// see https://github.com/nlohmann/json/pull/679
+template<>
+struct less< ::nlohmann::detail::value_t>
+{
+ /*!
+ @brief compare two value_t enum values
+ @since version 3.0.0
+ */
+ bool operator()(nlohmann::detail::value_t lhs,
+ nlohmann::detail::value_t rhs) const noexcept
+ {
+ return nlohmann::detail::operator<(lhs, rhs);
+ }
+};
+
+/*!
+@brief exchanges the values of two JSON objects
+
+@since version 1.0.0
+*/
+template<>
+inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
+ is_nothrow_move_constructible<nlohmann::json>::value and
+ is_nothrow_move_assignable<nlohmann::json>::value
+)
+{
+ j1.swap(j2);
+}
+
+} // namespace std
+
+/*!
+@brief user-defined string literal for JSON values
+
+This operator implements a user-defined string literal for JSON objects. It
+can be used by adding `"_json"` to a string literal and returns a JSON object
+if no parse error occurred.
+
+@param[in] s a string representation of a JSON object
+@param[in] n the length of string @a s
+@return a JSON object
+
+@since version 1.0.0
+*/
+inline nlohmann::json operator "" _json(const char* s, std::size_t n)
+{
+ return nlohmann::json::parse(s, s + n);
+}
+
+/*!
+@brief user-defined string literal for JSON pointer
+
+This operator implements a user-defined string literal for JSON Pointers. It
+can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
+object if no parse error occurred.
+
+@param[in] s a string representation of a JSON Pointer
+@param[in] n the length of string @a s
+@return a JSON pointer object
+
+@since version 2.0.0
+*/
+inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
+{
+ return nlohmann::json::json_pointer(std::string(s, n));
+}
+
+// #include <nlohmann/detail/macro_unscope.hpp>
+
+
+// restore GCC/clang diagnostic settings
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+ #pragma GCC diagnostic pop
+#endif
+#if defined(__clang__)
+ #pragma GCC diagnostic pop
+#endif
+
+// clean up
+#undef JSON_INTERNAL_CATCH
+#undef JSON_CATCH
+#undef JSON_THROW
+#undef JSON_TRY
+#undef JSON_LIKELY
+#undef JSON_UNLIKELY
+#undef JSON_DEPRECATED
+#undef JSON_NODISCARD
+#undef JSON_HAS_CPP_14
+#undef JSON_HAS_CPP_17
+#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
+#undef NLOHMANN_BASIC_JSON_TPL
+
+
+#endif // INCLUDE_NLOHMANN_JSON_HPP_
diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
index 27cc408223..d8d64bcdd7 100644
--- a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
@@ -1,7 +1,7 @@
add_qtc_library(KSyntaxHighlighting STATIC
PUBLIC_INCLUDES autogenerated/ autogenerated/src/lib src/lib
PUBLIC_DEFINES KSYNTAXHIGHLIGHTING_LIBRARY
- DEPENDS Qt5::Network Qt5::Gui
+ DEPENDS Qt5::Network Qt5::Widgets
SOURCES
autogenerated/src/lib/ksyntaxhighlighting_logging.cpp autogenerated/src/lib/ksyntaxhighlighting_logging.h
autogenerated/ksyntaxhighlighting_version.h
diff --git a/src/libs/3rdparty/yaml-cpp/.clang-format b/src/libs/3rdparty/yaml-cpp/.clang-format
new file mode 100644
index 0000000000..d6d46fb416
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/.clang-format
@@ -0,0 +1,47 @@
+---
+# BasedOnStyle: Google
+AccessModifierOffset: -1
+ConstructorInitializerIndentWidth: 4
+AlignEscapedNewlinesLeft: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakTemplateDeclarations: true
+AlwaysBreakBeforeMultilineStrings: true
+BreakBeforeBinaryOperators: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BinPackParameters: true
+ColumnLimit: 80
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+DerivePointerBinding: true
+ExperimentalAutoDetectBinPacking: false
+IndentCaseLabels: true
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 60
+PenaltyBreakString: 1000
+PenaltyBreakFirstLessLess: 120
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerBindsToType: true
+SpacesBeforeTrailingComments: 2
+Cpp11BracedListStyle: true
+Standard: Cpp11
+IndentWidth: 2
+TabWidth: 8
+UseTab: Never
+BreakBeforeBraces: Attach
+IndentFunctionDeclarationAfterType: true
+SpacesInParentheses: false
+SpacesInAngles: false
+SpaceInEmptyParentheses: false
+SpacesInCStyleCastParentheses: false
+SpaceAfterControlStatementKeyword: true
+SpaceBeforeAssignmentOperators: true
+ContinuationIndentWidth: 4
+...
+
diff --git a/src/libs/3rdparty/yaml-cpp/LICENSE b/src/libs/3rdparty/yaml-cpp/LICENSE
new file mode 100644
index 0000000000..991fdbbe7d
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2008-2015 Jesse Beder.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/libs/3rdparty/yaml-cpp/README.md b/src/libs/3rdparty/yaml-cpp/README.md
new file mode 100644
index 0000000000..f33d3503a1
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/README.md
@@ -0,0 +1,51 @@
+# yaml-cpp [![Build Status](https://travis-ci.org/jbeder/yaml-cpp.svg?branch=master)](https://travis-ci.org/jbeder/yaml-cpp) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
+
+yaml-cpp is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
+
+To get a feel for how it can be used, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) or [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML). For the old API (version < 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
+
+# Problems? #
+
+If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp).
+
+# How to Build #
+
+yaml-cpp uses [CMake](http://www.cmake.org) to support cross-platform building. The basic steps to build are:
+
+1. Download and install [CMake](http://www.cmake.org) (Resources -> Download).
+
+**Note:** If you don't use the provided installer for your platform, make sure that you add CMake's bin folder to your path.
+
+2. Navigate into the source directory, and type:
+
+```
+mkdir build
+cd build
+```
+
+3. Run CMake. The basic syntax is:
+
+```
+cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
+```
+
+ * The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
+ * On Windows, you might use "Visual Studio 12 2013" to generate a Visual Studio 2013 solution or "Visual Studio 14 2015 Win64" to generate a 64-bit Visual Studio 2015 solution.
+ * On OS X, you might use "Xcode" to generate an Xcode project
+ * On a UNIX-y system, simply omit the option to generate a makefile
+
+ * yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DBUILD_SHARED_LIBS=ON`.
+
+ * For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
+
+4. Build it!
+
+5. To clean up, just remove the `build` directory.
+
+# Recent Release #
+
+[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) has been released! This release requires C++11, and no longer depends on Boost.
+
+[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API.
+
+**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases.
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h
new file mode 100644
index 0000000000..06759c724d
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/anchor.h
@@ -0,0 +1,17 @@
+#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstddef>
+
+namespace YAML {
+typedef std::size_t anchor_t;
+const anchor_t NullAnchor = 0;
+}
+
+#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h
new file mode 100644
index 0000000000..29d5dbd027
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/binary.h
@@ -0,0 +1,67 @@
+#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include <vector>
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+YAML_CPP_API std::string EncodeBase64(const unsigned char *data,
+ std::size_t size);
+YAML_CPP_API std::vector<unsigned char> DecodeBase64(const std::string &input);
+
+class YAML_CPP_API Binary {
+ public:
+ Binary() : m_unownedData(0), m_unownedSize(0) {}
+ Binary(const unsigned char *data_, std::size_t size_)
+ : m_unownedData(data_), m_unownedSize(size_) {}
+
+ bool owned() const { return !m_unownedData; }
+ std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
+ const unsigned char *data() const {
+ return owned() ? &m_data[0] : m_unownedData;
+ }
+
+ void swap(std::vector<unsigned char> &rhs) {
+ if (m_unownedData) {
+ m_data.swap(rhs);
+ rhs.clear();
+ rhs.resize(m_unownedSize);
+ std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
+ m_unownedData = 0;
+ m_unownedSize = 0;
+ } else {
+ m_data.swap(rhs);
+ }
+ }
+
+ bool operator==(const Binary &rhs) const {
+ const std::size_t s = size();
+ if (s != rhs.size())
+ return false;
+ const unsigned char *d1 = data();
+ const unsigned char *d2 = rhs.data();
+ for (std::size_t i = 0; i < s; i++) {
+ if (*d1++ != *d2++)
+ return false;
+ }
+ return true;
+ }
+
+ bool operator!=(const Binary &rhs) const { return !(*this == rhs); }
+
+ private:
+ std::vector<unsigned char> m_data;
+ const unsigned char *m_unownedData;
+ std::size_t m_unownedSize;
+};
+}
+
+#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
new file mode 100644
index 0000000000..897f1533df
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
@@ -0,0 +1,42 @@
+#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+// The following ifdef block is the standard way of creating macros which make
+// exporting from a DLL simpler. All files within this DLL are compiled with the
+// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not
+// be defined on any project that uses this DLL. This way any other project
+// whose source files include this file see YAML_CPP_API functions as being
+// imported from a DLL, whereas this DLL sees symbols defined with this macro as
+// being exported.
+#undef YAML_CPP_API
+
+#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
+ // manually)
+
+#if defined(_WIN32) || defined(WIN32)
+# define YAML_CPP_API_IMPORT __declspec(dllimport)
+# define YAML_CPP_API_EXPORT __declspec(dllexport)
+#else
+# define YAML_CPP_API_IMPORT __attribute__((visibility("default")))
+# define YAML_CPP_API_EXPORT __attribute__((visibility("default")))
+#endif
+
+#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
+ // or defined manually)
+// #pragma message( "Defining YAML_CPP_API for DLL export" )
+#define YAML_CPP_API YAML_CPP_API_EXPORT
+#else // yaml_cpp_EXPORTS
+// #pragma message( "Defining YAML_CPP_API for DLL import" )
+#define YAML_CPP_API YAML_CPP_API_IMPORT
+#endif // yaml_cpp_EXPORTS
+#else // YAML_CPP_DLL
+#define YAML_CPP_API
+#endif // YAML_CPP_DLL
+
+#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h
new file mode 100644
index 0000000000..f14b051ab0
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitfromevents.h
@@ -0,0 +1,57 @@
+#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <stack>
+
+#include "yaml-cpp/anchor.h"
+#include "yaml-cpp/emitterstyle.h"
+#include "yaml-cpp/eventhandler.h"
+
+namespace YAML {
+struct Mark;
+} // namespace YAML
+
+namespace YAML {
+class Emitter;
+
+class EmitFromEvents : public EventHandler {
+ public:
+ EmitFromEvents(Emitter& emitter);
+
+ virtual void OnDocumentStart(const Mark& mark);
+ virtual void OnDocumentEnd();
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor);
+ virtual void OnAlias(const Mark& mark, anchor_t anchor);
+ virtual void OnScalar(const Mark& mark, const std::string& tag,
+ anchor_t anchor, const std::string& value);
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style);
+ virtual void OnSequenceEnd();
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style);
+ virtual void OnMapEnd();
+
+ private:
+ void BeginNode();
+ void EmitProps(const std::string& tag, anchor_t anchor);
+
+ private:
+ Emitter& m_emitter;
+
+ struct State {
+ enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue };
+ };
+ std::stack<State::value> m_stateStack;
+};
+}
+
+#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h
new file mode 100644
index 0000000000..ef92cc4035
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitter.h
@@ -0,0 +1,254 @@
+#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstddef>
+#include <memory>
+#include <sstream>
+#include <string>
+
+#include "yaml-cpp/binary.h"
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/emitterdef.h"
+#include "yaml-cpp/emittermanip.h"
+#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/null.h"
+#include "yaml-cpp/ostream_wrapper.h"
+
+namespace YAML {
+class Binary;
+struct _Null;
+} // namespace YAML
+
+namespace YAML {
+class EmitterState;
+
+class YAML_CPP_API Emitter : private noncopyable {
+ public:
+ Emitter();
+ explicit Emitter(std::ostream& stream);
+ ~Emitter();
+
+ // output
+ const char* c_str() const;
+ std::size_t size() const;
+
+ // state checking
+ bool good() const;
+ const std::string GetLastError() const;
+
+ // global setters
+ bool SetOutputCharset(EMITTER_MANIP value);
+ bool SetStringFormat(EMITTER_MANIP value);
+ bool SetBoolFormat(EMITTER_MANIP value);
+ bool SetIntBase(EMITTER_MANIP value);
+ bool SetSeqFormat(EMITTER_MANIP value);
+ bool SetMapFormat(EMITTER_MANIP value);
+ bool SetIndent(std::size_t n);
+ bool SetPreCommentIndent(std::size_t n);
+ bool SetPostCommentIndent(std::size_t n);
+ bool SetFloatPrecision(std::size_t n);
+ bool SetDoublePrecision(std::size_t n);
+
+ // local setters
+ Emitter& SetLocalValue(EMITTER_MANIP value);
+ Emitter& SetLocalIndent(const _Indent& indent);
+ Emitter& SetLocalPrecision(const _Precision& precision);
+
+ // overloads of write
+ Emitter& Write(const std::string& str);
+ Emitter& Write(bool b);
+ Emitter& Write(char ch);
+ Emitter& Write(const _Alias& alias);
+ Emitter& Write(const _Anchor& anchor);
+ Emitter& Write(const _Tag& tag);
+ Emitter& Write(const _Comment& comment);
+ Emitter& Write(const _Null& n);
+ Emitter& Write(const Binary& binary);
+
+ template <typename T>
+ Emitter& WriteIntegralType(T value);
+
+ template <typename T>
+ Emitter& WriteStreamable(T value);
+
+ private:
+ template <typename T>
+ void SetStreamablePrecision(std::stringstream&) {}
+ std::size_t GetFloatPrecision() const;
+ std::size_t GetDoublePrecision() const;
+
+ void PrepareIntegralStream(std::stringstream& stream) const;
+ void StartedScalar();
+
+ private:
+ void EmitBeginDoc();
+ void EmitEndDoc();
+ void EmitBeginSeq();
+ void EmitEndSeq();
+ void EmitBeginMap();
+ void EmitEndMap();
+ void EmitNewline();
+ void EmitKindTag();
+ void EmitTag(bool verbatim, const _Tag& tag);
+
+ void PrepareNode(EmitterNodeType::value child);
+ void PrepareTopNode(EmitterNodeType::value child);
+ void FlowSeqPrepareNode(EmitterNodeType::value child);
+ void BlockSeqPrepareNode(EmitterNodeType::value child);
+
+ void FlowMapPrepareNode(EmitterNodeType::value child);
+
+ void FlowMapPrepareLongKey(EmitterNodeType::value child);
+ void FlowMapPrepareLongKeyValue(EmitterNodeType::value child);
+ void FlowMapPrepareSimpleKey(EmitterNodeType::value child);
+ void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child);
+
+ void BlockMapPrepareNode(EmitterNodeType::value child);
+
+ void BlockMapPrepareLongKey(EmitterNodeType::value child);
+ void BlockMapPrepareLongKeyValue(EmitterNodeType::value child);
+ void BlockMapPrepareSimpleKey(EmitterNodeType::value child);
+ void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child);
+
+ void SpaceOrIndentTo(bool requireSpace, std::size_t indent);
+
+ const char* ComputeFullBoolName(bool b) const;
+ bool CanEmitNewline() const;
+
+ private:
+ std::unique_ptr<EmitterState> m_pState;
+ ostream_wrapper m_stream;
+};
+
+template <typename T>
+inline Emitter& Emitter::WriteIntegralType(T value) {
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::Scalar);
+
+ std::stringstream stream;
+ PrepareIntegralStream(stream);
+ stream << value;
+ m_stream << stream.str();
+
+ StartedScalar();
+
+ return *this;
+}
+
+template <typename T>
+inline Emitter& Emitter::WriteStreamable(T value) {
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::Scalar);
+
+ std::stringstream stream;
+ SetStreamablePrecision<T>(stream);
+ stream << value;
+ m_stream << stream.str();
+
+ StartedScalar();
+
+ return *this;
+}
+
+template <>
+inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) {
+ stream.precision(static_cast<std::streamsize>(GetFloatPrecision()));
+}
+
+template <>
+inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
+ stream.precision(static_cast<std::streamsize>(GetDoublePrecision()));
+}
+
+// overloads of insertion
+inline Emitter& operator<<(Emitter& emitter, const std::string& v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, bool v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, char v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, unsigned char v) {
+ return emitter.Write(static_cast<char>(v));
+}
+inline Emitter& operator<<(Emitter& emitter, const _Alias& v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, const _Tag& v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, const _Comment& v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, const _Null& v) {
+ return emitter.Write(v);
+}
+inline Emitter& operator<<(Emitter& emitter, const Binary& b) {
+ return emitter.Write(b);
+}
+
+inline Emitter& operator<<(Emitter& emitter, const char* v) {
+ return emitter.Write(std::string(v));
+}
+
+inline Emitter& operator<<(Emitter& emitter, int v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, unsigned int v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, short v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, unsigned short v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, long v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, unsigned long v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, long long v) {
+ return emitter.WriteIntegralType(v);
+}
+inline Emitter& operator<<(Emitter& emitter, unsigned long long v) {
+ return emitter.WriteIntegralType(v);
+}
+
+inline Emitter& operator<<(Emitter& emitter, float v) {
+ return emitter.WriteStreamable(v);
+}
+inline Emitter& operator<<(Emitter& emitter, double v) {
+ return emitter.WriteStreamable(v);
+}
+
+inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) {
+ return emitter.SetLocalValue(value);
+}
+
+inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
+ return emitter.SetLocalIndent(indent);
+}
+
+inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
+ return emitter.SetLocalPrecision(precision);
+}
+}
+
+#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterdef.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterdef.h
new file mode 100644
index 0000000000..0b426957fa
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterdef.h
@@ -0,0 +1,16 @@
+#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace YAML {
+struct EmitterNodeType {
+ enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap };
+};
+}
+
+#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h
new file mode 100644
index 0000000000..89f7256714
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emittermanip.h
@@ -0,0 +1,137 @@
+#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+namespace YAML {
+enum EMITTER_MANIP {
+ // general manipulators
+ Auto,
+ TagByKind,
+ Newline,
+
+ // output character set
+ EmitNonAscii,
+ EscapeNonAscii,
+
+ // string manipulators
+ // Auto, // duplicate
+ SingleQuoted,
+ DoubleQuoted,
+ Literal,
+
+ // bool manipulators
+ YesNoBool, // yes, no
+ TrueFalseBool, // true, false
+ OnOffBool, // on, off
+ UpperCase, // TRUE, N
+ LowerCase, // f, yes
+ CamelCase, // No, Off
+ LongBool, // yes, On
+ ShortBool, // y, t
+
+ // int manipulators
+ Dec,
+ Hex,
+ Oct,
+
+ // document manipulators
+ BeginDoc,
+ EndDoc,
+
+ // sequence manipulators
+ BeginSeq,
+ EndSeq,
+ Flow,
+ Block,
+
+ // map manipulators
+ BeginMap,
+ EndMap,
+ Key,
+ Value,
+ // Flow, // duplicate
+ // Block, // duplicate
+ // Auto, // duplicate
+ LongKey
+};
+
+struct _Indent {
+ _Indent(int value_) : value(value_) {}
+ int value;
+};
+
+inline _Indent Indent(int value) { return _Indent(value); }
+
+struct _Alias {
+ _Alias(const std::string& content_) : content(content_) {}
+ std::string content;
+};
+
+inline _Alias Alias(const std::string content) { return _Alias(content); }
+
+struct _Anchor {
+ _Anchor(const std::string& content_) : content(content_) {}
+ std::string content;
+};
+
+inline _Anchor Anchor(const std::string content) { return _Anchor(content); }
+
+struct _Tag {
+ struct Type {
+ enum value { Verbatim, PrimaryHandle, NamedHandle };
+ };
+
+ explicit _Tag(const std::string& prefix_, const std::string& content_,
+ Type::value type_)
+ : prefix(prefix_), content(content_), type(type_) {}
+ std::string prefix;
+ std::string content;
+ Type::value type;
+};
+
+inline _Tag VerbatimTag(const std::string content) {
+ return _Tag("", content, _Tag::Type::Verbatim);
+}
+
+inline _Tag LocalTag(const std::string content) {
+ return _Tag("", content, _Tag::Type::PrimaryHandle);
+}
+
+inline _Tag LocalTag(const std::string& prefix, const std::string content) {
+ return _Tag(prefix, content, _Tag::Type::NamedHandle);
+}
+
+inline _Tag SecondaryTag(const std::string content) {
+ return _Tag("", content, _Tag::Type::NamedHandle);
+}
+
+struct _Comment {
+ _Comment(const std::string& content_) : content(content_) {}
+ std::string content;
+};
+
+inline _Comment Comment(const std::string content) { return _Comment(content); }
+
+struct _Precision {
+ _Precision(int floatPrecision_, int doublePrecision_)
+ : floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
+
+ int floatPrecision;
+ int doublePrecision;
+};
+
+inline _Precision FloatPrecision(int n) { return _Precision(n, -1); }
+
+inline _Precision DoublePrecision(int n) { return _Precision(-1, n); }
+
+inline _Precision Precision(int n) { return _Precision(n, n); }
+}
+
+#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterstyle.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterstyle.h
new file mode 100644
index 0000000000..67bb3981b1
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/emitterstyle.h
@@ -0,0 +1,16 @@
+#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace YAML {
+struct EmitterStyle {
+ enum value { Default, Block, Flow };
+};
+}
+
+#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h
new file mode 100644
index 0000000000..efe381c621
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/eventhandler.h
@@ -0,0 +1,40 @@
+#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+#include "yaml-cpp/anchor.h"
+#include "yaml-cpp/emitterstyle.h"
+
+namespace YAML {
+struct Mark;
+
+class EventHandler {
+ public:
+ virtual ~EventHandler() {}
+
+ virtual void OnDocumentStart(const Mark& mark) = 0;
+ virtual void OnDocumentEnd() = 0;
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor) = 0;
+ virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0;
+ virtual void OnScalar(const Mark& mark, const std::string& tag,
+ anchor_t anchor, const std::string& value) = 0;
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) = 0;
+ virtual void OnSequenceEnd() = 0;
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) = 0;
+ virtual void OnMapEnd() = 0;
+};
+}
+
+#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
new file mode 100644
index 0000000000..eae31968b7
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
@@ -0,0 +1,261 @@
+#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/traits.h"
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+#define YAML_CPP_NOEXCEPT noexcept
+
+namespace YAML {
+// error messages
+namespace ErrorMsg {
+const char* const YAML_DIRECTIVE_ARGS =
+ "YAML directives must have exactly one argument";
+const char* const YAML_VERSION = "bad YAML version: ";
+const char* const YAML_MAJOR_VERSION = "YAML major version too large";
+const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive";
+const char* const TAG_DIRECTIVE_ARGS =
+ "TAG directives must have exactly two arguments";
+const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
+const char* const CHAR_IN_TAG_HANDLE =
+ "illegal character found while scanning tag handle";
+const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
+const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found";
+const char* const END_OF_MAP = "end of map not found";
+const char* const END_OF_MAP_FLOW = "end of map flow not found";
+const char* const END_OF_SEQ = "end of sequence not found";
+const char* const END_OF_SEQ_FLOW = "end of sequence flow not found";
+const char* const MULTIPLE_TAGS =
+ "cannot assign multiple tags to the same node";
+const char* const MULTIPLE_ANCHORS =
+ "cannot assign multiple anchors to the same node";
+const char* const MULTIPLE_ALIASES =
+ "cannot assign multiple aliases to the same node";
+const char* const ALIAS_CONTENT =
+ "aliases can't have any content, *including* tags";
+const char* const INVALID_HEX = "bad character found while scanning hex number";
+const char* const INVALID_UNICODE = "invalid unicode: ";
+const char* const INVALID_ESCAPE = "unknown escape character: ";
+const char* const UNKNOWN_TOKEN = "unknown token";
+const char* const DOC_IN_SCALAR = "illegal document indicator in scalar";
+const char* const EOF_IN_SCALAR = "illegal EOF in scalar";
+const char* const CHAR_IN_SCALAR = "illegal character in scalar";
+const char* const TAB_IN_INDENTATION =
+ "illegal tab when looking for indentation";
+const char* const FLOW_END = "illegal flow end";
+const char* const BLOCK_ENTRY = "illegal block entry";
+const char* const MAP_KEY = "illegal map key";
+const char* const MAP_VALUE = "illegal map value";
+const char* const ALIAS_NOT_FOUND = "alias not found after *";
+const char* const ANCHOR_NOT_FOUND = "anchor not found after &";
+const char* const CHAR_IN_ALIAS =
+ "illegal character found while scanning alias";
+const char* const CHAR_IN_ANCHOR =
+ "illegal character found while scanning anchor";
+const char* const ZERO_INDENT_IN_BLOCK =
+ "cannot set zero indentation for a block scalar";
+const char* const CHAR_IN_BLOCK = "unexpected character in block scalar";
+const char* const AMBIGUOUS_ANCHOR =
+ "cannot assign the same alias to multiple nodes";
+const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
+
+const char* const INVALID_NODE =
+ "invalid node; this may result from using a map iterator as a sequence "
+ "iterator, or vice-versa";
+const char* const INVALID_SCALAR = "invalid scalar";
+const char* const KEY_NOT_FOUND = "key not found";
+const char* const BAD_CONVERSION = "bad conversion";
+const char* const BAD_DEREFERENCE = "bad dereference";
+const char* const BAD_SUBSCRIPT = "operator[] call on a scalar";
+const char* const BAD_PUSHBACK = "appending to a non-sequence";
+const char* const BAD_INSERT = "inserting in a non-convertible-to-map";
+
+const char* const UNMATCHED_GROUP_TAG = "unmatched group tag";
+const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token";
+const char* const UNEXPECTED_END_MAP = "unexpected end map token";
+const char* const SINGLE_QUOTED_CHAR =
+ "invalid character in single-quoted string";
+const char* const INVALID_ANCHOR = "invalid anchor";
+const char* const INVALID_ALIAS = "invalid alias";
+const char* const INVALID_TAG = "invalid tag";
+const char* const BAD_FILE = "bad file";
+
+template <typename T>
+inline const std::string KEY_NOT_FOUND_WITH_KEY(
+ const T&, typename disable_if<is_numeric<T>>::type* = 0) {
+ return KEY_NOT_FOUND;
+}
+
+inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
+ std::stringstream stream;
+ stream << KEY_NOT_FOUND << ": " << key;
+ return stream.str();
+}
+
+template <typename T>
+inline const std::string KEY_NOT_FOUND_WITH_KEY(
+ const T& key, typename enable_if<is_numeric<T>>::type* = 0) {
+ std::stringstream stream;
+ stream << KEY_NOT_FOUND << ": " << key;
+ return stream.str();
+}
+}
+
+class YAML_CPP_API Exception : public std::runtime_error {
+ public:
+ Exception(const Mark& mark_, const std::string& msg_)
+ : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
+ virtual ~Exception() YAML_CPP_NOEXCEPT;
+
+ Exception(const Exception&) = default;
+
+ Mark mark;
+ std::string msg;
+
+ private:
+ static const std::string build_what(const Mark& mark,
+ const std::string& msg) {
+ if (mark.is_null()) {
+ return msg.c_str();
+ }
+
+ std::stringstream output;
+ output << "yaml-cpp: error at line " << mark.line + 1 << ", column "
+ << mark.column + 1 << ": " << msg;
+ return output.str();
+ }
+};
+
+class YAML_CPP_API ParserException : public Exception {
+ public:
+ ParserException(const Mark& mark_, const std::string& msg_)
+ : Exception(mark_, msg_) {}
+ ParserException(const ParserException&) = default;
+ virtual ~ParserException() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API RepresentationException : public Exception {
+ public:
+ RepresentationException(const Mark& mark_, const std::string& msg_)
+ : Exception(mark_, msg_) {}
+ RepresentationException(const RepresentationException&) = default;
+ virtual ~RepresentationException() YAML_CPP_NOEXCEPT;
+};
+
+// representation exceptions
+class YAML_CPP_API InvalidScalar : public RepresentationException {
+ public:
+ InvalidScalar(const Mark& mark_)
+ : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
+ InvalidScalar(const InvalidScalar&) = default;
+ virtual ~InvalidScalar() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API KeyNotFound : public RepresentationException {
+ public:
+ template <typename T>
+ KeyNotFound(const Mark& mark_, const T& key_)
+ : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
+ }
+ KeyNotFound(const KeyNotFound&) = default;
+ virtual ~KeyNotFound() YAML_CPP_NOEXCEPT;
+};
+
+template <typename T>
+class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
+ public:
+ TypedKeyNotFound(const Mark& mark_, const T& key_)
+ : KeyNotFound(mark_, key_), key(key_) {}
+ virtual ~TypedKeyNotFound() YAML_CPP_NOEXCEPT {}
+
+ T key;
+};
+
+template <typename T>
+inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
+ const T& key) {
+ return TypedKeyNotFound<T>(mark, key);
+}
+
+class YAML_CPP_API InvalidNode : public RepresentationException {
+ public:
+ InvalidNode()
+ : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
+ InvalidNode(const InvalidNode&) = default;
+ virtual ~InvalidNode() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API BadConversion : public RepresentationException {
+ public:
+ explicit BadConversion(const Mark& mark_)
+ : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
+ BadConversion(const BadConversion&) = default;
+ virtual ~BadConversion() YAML_CPP_NOEXCEPT;
+};
+
+template <typename T>
+class TypedBadConversion : public BadConversion {
+ public:
+ explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {}
+};
+
+class YAML_CPP_API BadDereference : public RepresentationException {
+ public:
+ BadDereference()
+ : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
+ BadDereference(const BadDereference&) = default;
+ virtual ~BadDereference() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API BadSubscript : public RepresentationException {
+ public:
+ BadSubscript()
+ : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
+ BadSubscript(const BadSubscript&) = default;
+ virtual ~BadSubscript() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API BadPushback : public RepresentationException {
+ public:
+ BadPushback()
+ : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
+ BadPushback(const BadPushback&) = default;
+ virtual ~BadPushback() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API BadInsert : public RepresentationException {
+ public:
+ BadInsert()
+ : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
+ BadInsert(const BadInsert&) = default;
+ virtual ~BadInsert() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API EmitterException : public Exception {
+ public:
+ EmitterException(const std::string& msg_)
+ : Exception(Mark::null_mark(), msg_) {}
+ EmitterException(const EmitterException&) = default;
+ virtual ~EmitterException() YAML_CPP_NOEXCEPT;
+};
+
+class YAML_CPP_API BadFile : public Exception {
+ public:
+ BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
+ BadFile(const BadFile&) = default;
+ virtual ~BadFile() YAML_CPP_NOEXCEPT;
+};
+}
+
+#undef YAML_CPP_NOEXCEPT
+
+#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/mark.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/mark.h
new file mode 100644
index 0000000000..bf94b4f41f
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/mark.h
@@ -0,0 +1,29 @@
+#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+struct YAML_CPP_API Mark {
+ Mark() : pos(0), line(0), column(0) {}
+
+ static const Mark null_mark() { return Mark(-1, -1, -1); }
+
+ bool is_null() const { return pos == -1 && line == -1 && column == -1; }
+
+ int pos;
+ int line, column;
+
+ private:
+ Mark(int pos_, int line_, int column_)
+ : pos(pos_), line(line_), column(column_) {}
+};
+}
+
+#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h
new file mode 100644
index 0000000000..45a878ab0c
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/convert.h
@@ -0,0 +1,331 @@
+#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <array>
+#include <limits>
+#include <list>
+#include <map>
+#include <sstream>
+#include <vector>
+
+#include "yaml-cpp/binary.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/type.h"
+#include "yaml-cpp/null.h"
+
+namespace YAML {
+class Binary;
+struct _Null;
+template <typename T>
+struct convert;
+} // namespace YAML
+
+namespace YAML {
+namespace conversion {
+inline bool IsInfinity(const std::string& input) {
+ return input == ".inf" || input == ".Inf" || input == ".INF" ||
+ input == "+.inf" || input == "+.Inf" || input == "+.INF";
+}
+
+inline bool IsNegativeInfinity(const std::string& input) {
+ return input == "-.inf" || input == "-.Inf" || input == "-.INF";
+}
+
+inline bool IsNaN(const std::string& input) {
+ return input == ".nan" || input == ".NaN" || input == ".NAN";
+}
+}
+
+// Node
+template <>
+struct convert<Node> {
+ static Node encode(const Node& rhs) { return rhs; }
+
+ static bool decode(const Node& node, Node& rhs) {
+ rhs.reset(node);
+ return true;
+ }
+};
+
+// std::string
+template <>
+struct convert<std::string> {
+ static Node encode(const std::string& rhs) { return Node(rhs); }
+
+ static bool decode(const Node& node, std::string& rhs) {
+ if (!node.IsScalar())
+ return false;
+ rhs = node.Scalar();
+ return true;
+ }
+};
+
+// C-strings can only be encoded
+template <>
+struct convert<const char*> {
+ static Node encode(const char*& rhs) { return Node(rhs); }
+};
+
+template <std::size_t N>
+struct convert<const char[N]> {
+ static Node encode(const char(&rhs)[N]) { return Node(rhs); }
+};
+
+template <>
+struct convert<_Null> {
+ static Node encode(const _Null& /* rhs */) { return Node(); }
+
+ static bool decode(const Node& node, _Null& /* rhs */) {
+ return node.IsNull();
+ }
+};
+
+#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
+ template <> \
+ struct convert<type> { \
+ static Node encode(const type& rhs) { \
+ std::stringstream stream; \
+ stream.precision(std::numeric_limits<type>::digits10 + 1); \
+ stream << rhs; \
+ return Node(stream.str()); \
+ } \
+ \
+ static bool decode(const Node& node, type& rhs) { \
+ if (node.Type() != NodeType::Scalar) \
+ return false; \
+ const std::string& input = node.Scalar(); \
+ std::stringstream stream(input); \
+ stream.unsetf(std::ios::dec); \
+ if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
+ return true; \
+ if (std::numeric_limits<type>::has_infinity) { \
+ if (conversion::IsInfinity(input)) { \
+ rhs = std::numeric_limits<type>::infinity(); \
+ return true; \
+ } else if (conversion::IsNegativeInfinity(input)) { \
+ rhs = negative_op std::numeric_limits<type>::infinity(); \
+ return true; \
+ } \
+ } \
+ \
+ if (std::numeric_limits<type>::has_quiet_NaN && \
+ conversion::IsNaN(input)) { \
+ rhs = std::numeric_limits<type>::quiet_NaN(); \
+ return true; \
+ } \
+ \
+ return false; \
+ } \
+ }
+
+#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
+ YAML_DEFINE_CONVERT_STREAMABLE(type, -)
+
+#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
+ YAML_DEFINE_CONVERT_STREAMABLE(type, +)
+
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
+YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
+YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
+YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
+YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
+
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char);
+YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
+
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
+YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
+
+#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
+#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
+#undef YAML_DEFINE_CONVERT_STREAMABLE
+
+// bool
+template <>
+struct convert<bool> {
+ static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
+
+ YAML_CPP_API static bool decode(const Node& node, bool& rhs);
+};
+
+// std::map
+template <typename K, typename V>
+struct convert<std::map<K, V>> {
+ static Node encode(const std::map<K, V>& rhs) {
+ Node node(NodeType::Map);
+ for (typename std::map<K, V>::const_iterator it = rhs.begin();
+ it != rhs.end(); ++it)
+ node.force_insert(it->first, it->second);
+ return node;
+ }
+
+ static bool decode(const Node& node, std::map<K, V>& rhs) {
+ if (!node.IsMap())
+ return false;
+
+ rhs.clear();
+ for (const_iterator it = node.begin(); it != node.end(); ++it)
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs[it->first.template as<K>()] = it->second.template as<V>();
+#else
+ rhs[it->first.as<K>()] = it->second.as<V>();
+#endif
+ return true;
+ }
+};
+
+// std::vector
+template <typename T>
+struct convert<std::vector<T>> {
+ static Node encode(const std::vector<T>& rhs) {
+ Node node(NodeType::Sequence);
+ for (typename std::vector<T>::const_iterator it = rhs.begin();
+ it != rhs.end(); ++it)
+ node.push_back(*it);
+ return node;
+ }
+
+ static bool decode(const Node& node, std::vector<T>& rhs) {
+ if (!node.IsSequence())
+ return false;
+
+ rhs.clear();
+ for (const_iterator it = node.begin(); it != node.end(); ++it)
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs.push_back(it->template as<T>());
+#else
+ rhs.push_back(it->as<T>());
+#endif
+ return true;
+ }
+};
+
+// std::list
+template <typename T>
+struct convert<std::list<T>> {
+ static Node encode(const std::list<T>& rhs) {
+ Node node(NodeType::Sequence);
+ for (typename std::list<T>::const_iterator it = rhs.begin();
+ it != rhs.end(); ++it)
+ node.push_back(*it);
+ return node;
+ }
+
+ static bool decode(const Node& node, std::list<T>& rhs) {
+ if (!node.IsSequence())
+ return false;
+
+ rhs.clear();
+ for (const_iterator it = node.begin(); it != node.end(); ++it)
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs.push_back(it->template as<T>());
+#else
+ rhs.push_back(it->as<T>());
+#endif
+ return true;
+ }
+};
+
+// std::array
+template <typename T, std::size_t N>
+struct convert<std::array<T, N>> {
+ static Node encode(const std::array<T, N>& rhs) {
+ Node node(NodeType::Sequence);
+ for (const auto& element : rhs) {
+ node.push_back(element);
+ }
+ return node;
+ }
+
+ static bool decode(const Node& node, std::array<T, N>& rhs) {
+ if (!isNodeValid(node)) {
+ return false;
+ }
+
+ for (auto i = 0u; i < node.size(); ++i) {
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs[i] = node[i].template as<T>();
+#else
+ rhs[i] = node[i].as<T>();
+#endif
+ }
+ return true;
+ }
+
+ private:
+ static bool isNodeValid(const Node& node) {
+ return node.IsSequence() && node.size() == N;
+ }
+};
+
+// std::pair
+template <typename T, typename U>
+struct convert<std::pair<T, U>> {
+ static Node encode(const std::pair<T, U>& rhs) {
+ Node node(NodeType::Sequence);
+ node.push_back(rhs.first);
+ node.push_back(rhs.second);
+ return node;
+ }
+
+ static bool decode(const Node& node, std::pair<T, U>& rhs) {
+ if (!node.IsSequence())
+ return false;
+ if (node.size() != 2)
+ return false;
+
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs.first = node[0].template as<T>();
+#else
+ rhs.first = node[0].as<T>();
+#endif
+#if defined(__GNUC__) && __GNUC__ < 4
+ // workaround for GCC 3:
+ rhs.second = node[1].template as<U>();
+#else
+ rhs.second = node[1].as<U>();
+#endif
+ return true;
+ }
+};
+
+// binary
+template <>
+struct convert<Binary> {
+ static Node encode(const Binary& rhs) {
+ return Node(EncodeBase64(rhs.data(), rhs.size()));
+ }
+
+ static bool decode(const Node& node, Binary& rhs) {
+ if (!node.IsScalar())
+ return false;
+
+ std::vector<unsigned char> data = DecodeBase64(node.Scalar());
+ if (data.empty() && !node.Scalar().empty())
+ return false;
+
+ rhs.swap(data);
+ return true;
+ }
+};
+}
+
+#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h
new file mode 100644
index 0000000000..2c80705c9a
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h
@@ -0,0 +1,26 @@
+#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace YAML {
+namespace detail {
+struct unspecified_bool {
+ struct NOT_ALLOWED;
+ static void true_value(NOT_ALLOWED*) {}
+};
+typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
+}
+}
+
+#define YAML_CPP_OPERATOR_BOOL() \
+ operator YAML::detail::unspecified_bool_type() const { \
+ return this->operator!() ? 0 \
+ : &YAML::detail::unspecified_bool::true_value; \
+ }
+
+#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h
new file mode 100644
index 0000000000..09e55f838c
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/impl.h
@@ -0,0 +1,185 @@
+#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/node/detail/node_data.h"
+#include <type_traits>
+
+namespace YAML {
+namespace detail {
+template <typename Key, typename Enable = void>
+struct get_idx {
+ static node* get(const std::vector<node*>& /* sequence */,
+ const Key& /* key */, shared_memory_holder /* pMemory */) {
+ return 0;
+ }
+};
+
+template <typename Key>
+struct get_idx<Key,
+ typename std::enable_if<std::is_unsigned<Key>::value &&
+ !std::is_same<Key, bool>::value>::type> {
+ static node* get(const std::vector<node*>& sequence, const Key& key,
+ shared_memory_holder /* pMemory */) {
+ return key < sequence.size() ? sequence[key] : 0;
+ }
+
+ static node* get(std::vector<node*>& sequence, const Key& key,
+ shared_memory_holder pMemory) {
+ if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined()))
+ return 0;
+ if (key == sequence.size())
+ sequence.push_back(&pMemory->create_node());
+ return sequence[key];
+ }
+};
+
+template <typename Key>
+struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
+ static node* get(const std::vector<node*>& sequence, const Key& key,
+ shared_memory_holder pMemory) {
+ return key >= 0 ? get_idx<std::size_t>::get(
+ sequence, static_cast<std::size_t>(key), pMemory)
+ : 0;
+ }
+ static node* get(std::vector<node*>& sequence, const Key& key,
+ shared_memory_holder pMemory) {
+ return key >= 0 ? get_idx<std::size_t>::get(
+ sequence, static_cast<std::size_t>(key), pMemory)
+ : 0;
+ }
+};
+
+template <typename T>
+inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
+ T lhs;
+ if (convert<T>::decode(Node(*this, pMemory), lhs)) {
+ return lhs == rhs;
+ }
+ return false;
+}
+
+inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
+ return equals<std::string>(rhs, pMemory);
+}
+
+// indexing
+template <typename Key>
+inline node* node_data::get(const Key& key,
+ shared_memory_holder pMemory) const {
+ switch (m_type) {
+ case NodeType::Map:
+ break;
+ case NodeType::Undefined:
+ case NodeType::Null:
+ return NULL;
+ case NodeType::Sequence:
+ if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
+ return pNode;
+ return NULL;
+ case NodeType::Scalar:
+ throw BadSubscript();
+ }
+
+ for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
+ if (it->first->equals(key, pMemory)) {
+ return it->second;
+ }
+ }
+
+ return NULL;
+}
+
+template <typename Key>
+inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
+ switch (m_type) {
+ case NodeType::Map:
+ break;
+ case NodeType::Undefined:
+ case NodeType::Null:
+ case NodeType::Sequence:
+ if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
+ m_type = NodeType::Sequence;
+ return *pNode;
+ }
+
+ convert_to_map(pMemory);
+ break;
+ case NodeType::Scalar:
+ throw BadSubscript();
+ }
+
+ for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
+ if (it->first->equals(key, pMemory)) {
+ return *it->second;
+ }
+ }
+
+ node& k = convert_to_node(key, pMemory);
+ node& v = pMemory->create_node();
+ insert_map_pair(k, v);
+ return v;
+}
+
+template <typename Key>
+inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
+ if (m_type != NodeType::Map)
+ return false;
+
+ for (kv_pairs::iterator it = m_undefinedPairs.begin();
+ it != m_undefinedPairs.end();) {
+ kv_pairs::iterator jt = std::next(it);
+ if (it->first->equals(key, pMemory))
+ m_undefinedPairs.erase(it);
+ it = jt;
+ }
+
+ for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
+ if (it->first->equals(key, pMemory)) {
+ m_map.erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// map
+template <typename Key, typename Value>
+inline void node_data::force_insert(const Key& key, const Value& value,
+ shared_memory_holder pMemory) {
+ switch (m_type) {
+ case NodeType::Map:
+ break;
+ case NodeType::Undefined:
+ case NodeType::Null:
+ case NodeType::Sequence:
+ convert_to_map(pMemory);
+ break;
+ case NodeType::Scalar:
+ throw BadInsert();
+ }
+
+ node& k = convert_to_node(key, pMemory);
+ node& v = convert_to_node(value, pMemory);
+ insert_map_pair(k, v);
+}
+
+template <typename T>
+inline node& node_data::convert_to_node(const T& rhs,
+ shared_memory_holder pMemory) {
+ Node value = convert<T>::encode(rhs);
+ value.EnsureNodeExists();
+ pMemory->merge(*value.m_pMemory);
+ return *value.m_pNode;
+}
+}
+}
+
+#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h
new file mode 100644
index 0000000000..deec8fb62c
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator.h
@@ -0,0 +1,92 @@
+#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
+#include <cstddef>
+#include <iterator>
+
+namespace YAML {
+namespace detail {
+struct iterator_value;
+
+template <typename V>
+class iterator_base : public std::iterator<std::forward_iterator_tag, V,
+ std::ptrdiff_t, V*, V> {
+
+ private:
+ template <typename>
+ friend class iterator_base;
+ struct enabler {};
+ typedef node_iterator base_type;
+
+ struct proxy {
+ explicit proxy(const V& x) : m_ref(x) {}
+ V* operator->() { return std::addressof(m_ref); }
+ operator V*() { return std::addressof(m_ref); }
+
+ V m_ref;
+ };
+
+ public:
+ typedef typename iterator_base::value_type value_type;
+
+ public:
+ iterator_base() : m_iterator(), m_pMemory() {}
+ explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
+ : m_iterator(rhs), m_pMemory(pMemory) {}
+
+ template <class W>
+ iterator_base(const iterator_base<W>& rhs,
+ typename std::enable_if<std::is_convertible<W*, V*>::value,
+ enabler>::type = enabler())
+ : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {}
+
+ iterator_base<V>& operator++() {
+ ++m_iterator;
+ return *this;
+ }
+
+ iterator_base<V> operator++(int) {
+ iterator_base<V> iterator_pre(*this);
+ ++(*this);
+ return iterator_pre;
+ }
+
+ template <typename W>
+ bool operator==(const iterator_base<W>& rhs) const {
+ return m_iterator == rhs.m_iterator;
+ }
+
+ template <typename W>
+ bool operator!=(const iterator_base<W>& rhs) const {
+ return m_iterator != rhs.m_iterator;
+ }
+
+ value_type operator*() const {
+ const typename base_type::value_type& v = *m_iterator;
+ if (v.pNode)
+ return value_type(Node(*v, m_pMemory));
+ if (v.first && v.second)
+ return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
+ return value_type();
+ }
+
+ proxy operator->() const { return proxy(**this); }
+
+ private:
+ base_type m_iterator;
+ shared_memory_holder m_pMemory;
+};
+}
+}
+
+#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h
new file mode 100644
index 0000000000..5f1ffe7436
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h
@@ -0,0 +1,27 @@
+#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace YAML {
+
+namespace detail {
+struct iterator_value;
+template <typename V>
+class iterator_base;
+}
+
+typedef detail::iterator_base<detail::iterator_value> iterator;
+typedef detail::iterator_base<const detail::iterator_value> const_iterator;
+}
+
+#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h
new file mode 100644
index 0000000000..8f2bc2657a
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/memory.h
@@ -0,0 +1,46 @@
+#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <set>
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/ptr.h"
+
+namespace YAML {
+namespace detail {
+class node;
+} // namespace detail
+} // namespace YAML
+
+namespace YAML {
+namespace detail {
+class YAML_CPP_API memory {
+ public:
+ node& create_node();
+ void merge(const memory& rhs);
+
+ private:
+ typedef std::set<shared_node> Nodes;
+ Nodes m_nodes;
+};
+
+class YAML_CPP_API memory_holder {
+ public:
+ memory_holder() : m_pMemory(new memory) {}
+
+ node& create_node() { return m_pMemory->create_node(); }
+ void merge(memory_holder& rhs);
+
+ private:
+ shared_memory m_pMemory;
+};
+}
+}
+
+#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h
new file mode 100644
index 0000000000..8a776f62a9
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node.h
@@ -0,0 +1,169 @@
+#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/emitterstyle.h"
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/type.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/detail/node_ref.h"
+#include <set>
+
+namespace YAML {
+namespace detail {
+class node {
+ public:
+ node() : m_pRef(new node_ref) {}
+ node(const node&) = delete;
+ node& operator=(const node&) = delete;
+
+ bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
+ const node_ref* ref() const { return m_pRef.get(); }
+
+ bool is_defined() const { return m_pRef->is_defined(); }
+ const Mark& mark() const { return m_pRef->mark(); }
+ NodeType::value type() const { return m_pRef->type(); }
+
+ const std::string& scalar() const { return m_pRef->scalar(); }
+ const std::string& tag() const { return m_pRef->tag(); }
+ EmitterStyle::value style() const { return m_pRef->style(); }
+
+ template <typename T>
+ bool equals(const T& rhs, shared_memory_holder pMemory);
+ bool equals(const char* rhs, shared_memory_holder pMemory);
+
+ void mark_defined() {
+ if (is_defined())
+ return;
+
+ m_pRef->mark_defined();
+ for (nodes::iterator it = m_dependencies.begin();
+ it != m_dependencies.end(); ++it)
+ (*it)->mark_defined();
+ m_dependencies.clear();
+ }
+
+ void add_dependency(node& rhs) {
+ if (is_defined())
+ rhs.mark_defined();
+ else
+ m_dependencies.insert(&rhs);
+ }
+
+ void set_ref(const node& rhs) {
+ if (rhs.is_defined())
+ mark_defined();
+ m_pRef = rhs.m_pRef;
+ }
+ void set_data(const node& rhs) {
+ if (rhs.is_defined())
+ mark_defined();
+ m_pRef->set_data(*rhs.m_pRef);
+ }
+
+ void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
+
+ void set_type(NodeType::value type) {
+ if (type != NodeType::Undefined)
+ mark_defined();
+ m_pRef->set_type(type);
+ }
+ void set_null() {
+ mark_defined();
+ m_pRef->set_null();
+ }
+ void set_scalar(const std::string& scalar) {
+ mark_defined();
+ m_pRef->set_scalar(scalar);
+ }
+ void set_tag(const std::string& tag) {
+ mark_defined();
+ m_pRef->set_tag(tag);
+ }
+
+ // style
+ void set_style(EmitterStyle::value style) {
+ mark_defined();
+ m_pRef->set_style(style);
+ }
+
+ // size/iterator
+ std::size_t size() const { return m_pRef->size(); }
+
+ const_node_iterator begin() const {
+ return static_cast<const node_ref&>(*m_pRef).begin();
+ }
+ node_iterator begin() { return m_pRef->begin(); }
+
+ const_node_iterator end() const {
+ return static_cast<const node_ref&>(*m_pRef).end();
+ }
+ node_iterator end() { return m_pRef->end(); }
+
+ // sequence
+ void push_back(node& input, shared_memory_holder pMemory) {
+ m_pRef->push_back(input, pMemory);
+ input.add_dependency(*this);
+ }
+ void insert(node& key, node& value, shared_memory_holder pMemory) {
+ m_pRef->insert(key, value, pMemory);
+ key.add_dependency(*this);
+ value.add_dependency(*this);
+ }
+
+ // indexing
+ template <typename Key>
+ node* get(const Key& key, shared_memory_holder pMemory) const {
+ // NOTE: this returns a non-const node so that the top-level Node can wrap
+ // it, and returns a pointer so that it can be NULL (if there is no such
+ // key).
+ return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
+ }
+ template <typename Key>
+ node& get(const Key& key, shared_memory_holder pMemory) {
+ node& value = m_pRef->get(key, pMemory);
+ value.add_dependency(*this);
+ return value;
+ }
+ template <typename Key>
+ bool remove(const Key& key, shared_memory_holder pMemory) {
+ return m_pRef->remove(key, pMemory);
+ }
+
+ node* get(node& key, shared_memory_holder pMemory) const {
+ // NOTE: this returns a non-const node so that the top-level Node can wrap
+ // it, and returns a pointer so that it can be NULL (if there is no such
+ // key).
+ return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
+ }
+ node& get(node& key, shared_memory_holder pMemory) {
+ node& value = m_pRef->get(key, pMemory);
+ key.add_dependency(*this);
+ value.add_dependency(*this);
+ return value;
+ }
+ bool remove(node& key, shared_memory_holder pMemory) {
+ return m_pRef->remove(key, pMemory);
+ }
+
+ // map
+ template <typename Key, typename Value>
+ void force_insert(const Key& key, const Value& value,
+ shared_memory_holder pMemory) {
+ m_pRef->force_insert(key, value, pMemory);
+ }
+
+ private:
+ shared_node_ref m_pRef;
+ typedef std::set<node*> nodes;
+ nodes m_dependencies;
+};
+}
+}
+
+#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h
new file mode 100644
index 0000000000..50bcd74352
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_data.h
@@ -0,0 +1,127 @@
+#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <list>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/type.h"
+
+namespace YAML {
+namespace detail {
+class node;
+} // namespace detail
+} // namespace YAML
+
+namespace YAML {
+namespace detail {
+class YAML_CPP_API node_data {
+ public:
+ node_data();
+ node_data(const node_data&) = delete;
+ node_data& operator=(const node_data&) = delete;
+
+ void mark_defined();
+ void set_mark(const Mark& mark);
+ void set_type(NodeType::value type);
+ void set_tag(const std::string& tag);
+ void set_null();
+ void set_scalar(const std::string& scalar);
+ void set_style(EmitterStyle::value style);
+
+ bool is_defined() const { return m_isDefined; }
+ const Mark& mark() const { return m_mark; }
+ NodeType::value type() const {
+ return m_isDefined ? m_type : NodeType::Undefined;
+ }
+ const std::string& scalar() const { return m_scalar; }
+ const std::string& tag() const { return m_tag; }
+ EmitterStyle::value style() const { return m_style; }
+
+ // size/iterator
+ std::size_t size() const;
+
+ const_node_iterator begin() const;
+ node_iterator begin();
+
+ const_node_iterator end() const;
+ node_iterator end();
+
+ // sequence
+ void push_back(node& node, shared_memory_holder pMemory);
+ void insert(node& key, node& value, shared_memory_holder pMemory);
+
+ // indexing
+ template <typename Key>
+ node* get(const Key& key, shared_memory_holder pMemory) const;
+ template <typename Key>
+ node& get(const Key& key, shared_memory_holder pMemory);
+ template <typename Key>
+ bool remove(const Key& key, shared_memory_holder pMemory);
+
+ node* get(node& key, shared_memory_holder pMemory) const;
+ node& get(node& key, shared_memory_holder pMemory);
+ bool remove(node& key, shared_memory_holder pMemory);
+
+ // map
+ template <typename Key, typename Value>
+ void force_insert(const Key& key, const Value& value,
+ shared_memory_holder pMemory);
+
+ public:
+ static std::string empty_scalar;
+
+ private:
+ void compute_seq_size() const;
+ void compute_map_size() const;
+
+ void reset_sequence();
+ void reset_map();
+
+ void insert_map_pair(node& key, node& value);
+ void convert_to_map(shared_memory_holder pMemory);
+ void convert_sequence_to_map(shared_memory_holder pMemory);
+
+ template <typename T>
+ static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
+
+ private:
+ bool m_isDefined;
+ Mark m_mark;
+ NodeType::value m_type;
+ std::string m_tag;
+ EmitterStyle::value m_style;
+
+ // scalar
+ std::string m_scalar;
+
+ // sequence
+ typedef std::vector<node*> node_seq;
+ node_seq m_sequence;
+
+ mutable std::size_t m_seqSize;
+
+ // map
+ typedef std::vector<std::pair<node*, node*>> node_map;
+ node_map m_map;
+
+ typedef std::pair<node*, node*> kv_pair;
+ typedef std::list<kv_pair> kv_pairs;
+ mutable kv_pairs m_undefinedPairs;
+};
+}
+}
+
+#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h
new file mode 100644
index 0000000000..088090fe74
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h
@@ -0,0 +1,180 @@
+#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/ptr.h"
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <map>
+#include <utility>
+#include <vector>
+
+namespace YAML {
+namespace detail {
+struct iterator_type {
+ enum value { NoneType, Sequence, Map };
+};
+
+template <typename V>
+struct node_iterator_value : public std::pair<V*, V*> {
+ typedef std::pair<V*, V*> kv;
+
+ node_iterator_value() : kv(), pNode(0) {}
+ explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
+ explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {}
+
+ V& operator*() const { return *pNode; }
+ V& operator->() const { return *pNode; }
+
+ V* pNode;
+};
+
+typedef std::vector<node*> node_seq;
+typedef std::vector<std::pair<node*, node*>> node_map;
+
+template <typename V>
+struct node_iterator_type {
+ typedef node_seq::iterator seq;
+ typedef node_map::iterator map;
+};
+
+template <typename V>
+struct node_iterator_type<const V> {
+ typedef node_seq::const_iterator seq;
+ typedef node_map::const_iterator map;
+};
+
+template <typename V>
+class node_iterator_base
+ : public std::iterator<std::forward_iterator_tag, node_iterator_value<V>,
+ std::ptrdiff_t, node_iterator_value<V>*,
+ node_iterator_value<V>> {
+ private:
+ struct enabler {};
+
+ struct proxy {
+ explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
+ node_iterator_value<V>* operator->() { return std::addressof(m_ref); }
+ operator node_iterator_value<V>*() { return std::addressof(m_ref); }
+
+ node_iterator_value<V> m_ref;
+ };
+
+ public:
+ typedef typename node_iterator_type<V>::seq SeqIter;
+ typedef typename node_iterator_type<V>::map MapIter;
+ typedef node_iterator_value<V> value_type;
+
+ node_iterator_base()
+ : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
+ explicit node_iterator_base(SeqIter seqIt)
+ : m_type(iterator_type::Sequence),
+ m_seqIt(seqIt),
+ m_mapIt(),
+ m_mapEnd() {}
+ explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
+ : m_type(iterator_type::Map),
+ m_seqIt(),
+ m_mapIt(mapIt),
+ m_mapEnd(mapEnd) {
+ m_mapIt = increment_until_defined(m_mapIt);
+ }
+
+ template <typename W>
+ node_iterator_base(const node_iterator_base<W>& rhs,
+ typename std::enable_if<std::is_convertible<W*, V*>::value,
+ enabler>::type = enabler())
+ : m_type(rhs.m_type),
+ m_seqIt(rhs.m_seqIt),
+ m_mapIt(rhs.m_mapIt),
+ m_mapEnd(rhs.m_mapEnd) {}
+
+ template <typename>
+ friend class node_iterator_base;
+
+ template <typename W>
+ bool operator==(const node_iterator_base<W>& rhs) const {
+ if (m_type != rhs.m_type)
+ return false;
+
+ switch (m_type) {
+ case iterator_type::NoneType:
+ return true;
+ case iterator_type::Sequence:
+ return m_seqIt == rhs.m_seqIt;
+ case iterator_type::Map:
+ return m_mapIt == rhs.m_mapIt;
+ }
+ return true;
+ }
+
+ template <typename W>
+ bool operator!=(const node_iterator_base<W>& rhs) const {
+ return !(*this == rhs);
+ }
+
+ node_iterator_base<V>& operator++() {
+ switch (m_type) {
+ case iterator_type::NoneType:
+ break;
+ case iterator_type::Sequence:
+ ++m_seqIt;
+ break;
+ case iterator_type::Map:
+ ++m_mapIt;
+ m_mapIt = increment_until_defined(m_mapIt);
+ break;
+ }
+ return *this;
+ }
+
+ node_iterator_base<V> operator++(int) {
+ node_iterator_base<V> iterator_pre(*this);
+ ++(*this);
+ return iterator_pre;
+ }
+
+ value_type operator*() const {
+ switch (m_type) {
+ case iterator_type::NoneType:
+ return value_type();
+ case iterator_type::Sequence:
+ return value_type(**m_seqIt);
+ case iterator_type::Map:
+ return value_type(*m_mapIt->first, *m_mapIt->second);
+ }
+ return value_type();
+ }
+
+ proxy operator->() const { return proxy(**this); }
+
+ MapIter increment_until_defined(MapIter it) {
+ while (it != m_mapEnd && !is_defined(it))
+ ++it;
+ return it;
+ }
+
+ bool is_defined(MapIter it) const {
+ return it->first->is_defined() && it->second->is_defined();
+ }
+
+ private:
+ typename iterator_type::value m_type;
+
+ SeqIter m_seqIt;
+ MapIter m_mapIt, m_mapEnd;
+};
+
+typedef node_iterator_base<node> node_iterator;
+typedef node_iterator_base<const node> const_node_iterator;
+}
+}
+
+#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h
new file mode 100644
index 0000000000..d8a94f8b80
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h
@@ -0,0 +1,98 @@
+#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/type.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/detail/node_data.h"
+
+namespace YAML {
+namespace detail {
+class node_ref {
+ public:
+ node_ref() : m_pData(new node_data) {}
+ node_ref(const node_ref&) = delete;
+ node_ref& operator=(const node_ref&) = delete;
+
+ bool is_defined() const { return m_pData->is_defined(); }
+ const Mark& mark() const { return m_pData->mark(); }
+ NodeType::value type() const { return m_pData->type(); }
+ const std::string& scalar() const { return m_pData->scalar(); }
+ const std::string& tag() const { return m_pData->tag(); }
+ EmitterStyle::value style() const { return m_pData->style(); }
+
+ void mark_defined() { m_pData->mark_defined(); }
+ void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }
+
+ void set_mark(const Mark& mark) { m_pData->set_mark(mark); }
+ void set_type(NodeType::value type) { m_pData->set_type(type); }
+ void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
+ void set_null() { m_pData->set_null(); }
+ void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
+ void set_style(EmitterStyle::value style) { m_pData->set_style(style); }
+
+ // size/iterator
+ std::size_t size() const { return m_pData->size(); }
+
+ const_node_iterator begin() const {
+ return static_cast<const node_data&>(*m_pData).begin();
+ }
+ node_iterator begin() { return m_pData->begin(); }
+
+ const_node_iterator end() const {
+ return static_cast<const node_data&>(*m_pData).end();
+ }
+ node_iterator end() { return m_pData->end(); }
+
+ // sequence
+ void push_back(node& node, shared_memory_holder pMemory) {
+ m_pData->push_back(node, pMemory);
+ }
+ void insert(node& key, node& value, shared_memory_holder pMemory) {
+ m_pData->insert(key, value, pMemory);
+ }
+
+ // indexing
+ template <typename Key>
+ node* get(const Key& key, shared_memory_holder pMemory) const {
+ return static_cast<const node_data&>(*m_pData).get(key, pMemory);
+ }
+ template <typename Key>
+ node& get(const Key& key, shared_memory_holder pMemory) {
+ return m_pData->get(key, pMemory);
+ }
+ template <typename Key>
+ bool remove(const Key& key, shared_memory_holder pMemory) {
+ return m_pData->remove(key, pMemory);
+ }
+
+ node* get(node& key, shared_memory_holder pMemory) const {
+ return static_cast<const node_data&>(*m_pData).get(key, pMemory);
+ }
+ node& get(node& key, shared_memory_holder pMemory) {
+ return m_pData->get(key, pMemory);
+ }
+ bool remove(node& key, shared_memory_holder pMemory) {
+ return m_pData->remove(key, pMemory);
+ }
+
+ // map
+ template <typename Key, typename Value>
+ void force_insert(const Key& key, const Value& value,
+ shared_memory_holder pMemory) {
+ m_pData->force_insert(key, value, pMemory);
+ }
+
+ private:
+ shared_node_data m_pData;
+};
+}
+}
+
+#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/emit.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/emit.h
new file mode 100644
index 0000000000..032268c5d0
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/emit.h
@@ -0,0 +1,32 @@
+#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include <iosfwd>
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+class Emitter;
+class Node;
+
+/**
+ * Emits the node to the given {@link Emitter}. If there is an error in writing,
+ * {@link Emitter#good} will return false.
+ */
+YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node);
+
+/** Emits the node to the given output stream. */
+YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node);
+
+/** Converts the node to a YAML string. */
+YAML_CPP_API std::string Dump(const Node& node);
+} // namespace YAML
+
+#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h
new file mode 100644
index 0000000000..20c487a687
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/impl.h
@@ -0,0 +1,448 @@
+#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/detail/memory.h"
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/exceptions.h"
+#include <string>
+
+namespace YAML {
+inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
+
+inline Node::Node(NodeType::value type)
+ : m_isValid(true),
+ m_pMemory(new detail::memory_holder),
+ m_pNode(&m_pMemory->create_node()) {
+ m_pNode->set_type(type);
+}
+
+template <typename T>
+inline Node::Node(const T& rhs)
+ : m_isValid(true),
+ m_pMemory(new detail::memory_holder),
+ m_pNode(&m_pMemory->create_node()) {
+ Assign(rhs);
+}
+
+inline Node::Node(const detail::iterator_value& rhs)
+ : m_isValid(rhs.m_isValid),
+ m_pMemory(rhs.m_pMemory),
+ m_pNode(rhs.m_pNode) {}
+
+inline Node::Node(const Node& rhs)
+ : m_isValid(rhs.m_isValid),
+ m_pMemory(rhs.m_pMemory),
+ m_pNode(rhs.m_pNode) {}
+
+inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {}
+
+inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
+ : m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
+
+inline Node::~Node() {}
+
+inline void Node::EnsureNodeExists() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ if (!m_pNode) {
+ m_pMemory.reset(new detail::memory_holder);
+ m_pNode = &m_pMemory->create_node();
+ m_pNode->set_null();
+ }
+}
+
+inline bool Node::IsDefined() const {
+ if (!m_isValid) {
+ return false;
+ }
+ return m_pNode ? m_pNode->is_defined() : true;
+}
+
+inline Mark Node::Mark() const {
+ if (!m_isValid) {
+ throw InvalidNode();
+ }
+ return m_pNode ? m_pNode->mark() : Mark::null_mark();
+}
+
+inline NodeType::value Node::Type() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ return m_pNode ? m_pNode->type() : NodeType::Null;
+}
+
+// access
+
+// template helpers
+template <typename T, typename S>
+struct as_if {
+ explicit as_if(const Node& node_) : node(node_) {}
+ const Node& node;
+
+ T operator()(const S& fallback) const {
+ if (!node.m_pNode)
+ return fallback;
+
+ T t;
+ if (convert<T>::decode(node, t))
+ return t;
+ return fallback;
+ }
+};
+
+template <typename S>
+struct as_if<std::string, S> {
+ explicit as_if(const Node& node_) : node(node_) {}
+ const Node& node;
+
+ std::string operator()(const S& fallback) const {
+ if (node.Type() != NodeType::Scalar)
+ return fallback;
+ return node.Scalar();
+ }
+};
+
+template <typename T>
+struct as_if<T, void> {
+ explicit as_if(const Node& node_) : node(node_) {}
+ const Node& node;
+
+ T operator()() const {
+ if (!node.m_pNode)
+ throw TypedBadConversion<T>(node.Mark());
+
+ T t;
+ if (convert<T>::decode(node, t))
+ return t;
+ throw TypedBadConversion<T>(node.Mark());
+ }
+};
+
+template <>
+struct as_if<std::string, void> {
+ explicit as_if(const Node& node_) : node(node_) {}
+ const Node& node;
+
+ std::string operator()() const {
+ if (node.Type() != NodeType::Scalar)
+ throw TypedBadConversion<std::string>(node.Mark());
+ return node.Scalar();
+ }
+};
+
+// access functions
+template <typename T>
+inline T Node::as() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ return as_if<T, void>(*this)();
+}
+
+template <typename T, typename S>
+inline T Node::as(const S& fallback) const {
+ if (!m_isValid)
+ return fallback;
+ return as_if<T, S>(*this)(fallback);
+}
+
+inline const std::string& Node::Scalar() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
+}
+
+inline const std::string& Node::Tag() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
+}
+
+inline void Node::SetTag(const std::string& tag) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ m_pNode->set_tag(tag);
+}
+
+inline EmitterStyle::value Node::Style() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ return m_pNode ? m_pNode->style() : EmitterStyle::Default;
+}
+
+inline void Node::SetStyle(EmitterStyle::value style) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ m_pNode->set_style(style);
+}
+
+// assignment
+inline bool Node::is(const Node& rhs) const {
+ if (!m_isValid || !rhs.m_isValid)
+ throw InvalidNode();
+ if (!m_pNode || !rhs.m_pNode)
+ return false;
+ return m_pNode->is(*rhs.m_pNode);
+}
+
+template <typename T>
+inline Node& Node::operator=(const T& rhs) {
+ if (!m_isValid)
+ throw InvalidNode();
+ Assign(rhs);
+ return *this;
+}
+
+inline void Node::reset(const YAML::Node& rhs) {
+ if (!m_isValid || !rhs.m_isValid)
+ throw InvalidNode();
+ m_pMemory = rhs.m_pMemory;
+ m_pNode = rhs.m_pNode;
+}
+
+template <typename T>
+inline void Node::Assign(const T& rhs) {
+ if (!m_isValid)
+ throw InvalidNode();
+ AssignData(convert<T>::encode(rhs));
+}
+
+template <>
+inline void Node::Assign(const std::string& rhs) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ m_pNode->set_scalar(rhs);
+}
+
+inline void Node::Assign(const char* rhs) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ m_pNode->set_scalar(rhs);
+}
+
+inline void Node::Assign(char* rhs) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ m_pNode->set_scalar(rhs);
+}
+
+inline Node& Node::operator=(const Node& rhs) {
+ if (!m_isValid || !rhs.m_isValid)
+ throw InvalidNode();
+ if (is(rhs))
+ return *this;
+ AssignNode(rhs);
+ return *this;
+}
+
+inline void Node::AssignData(const Node& rhs) {
+ if (!m_isValid || !rhs.m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ rhs.EnsureNodeExists();
+
+ m_pNode->set_data(*rhs.m_pNode);
+ m_pMemory->merge(*rhs.m_pMemory);
+}
+
+inline void Node::AssignNode(const Node& rhs) {
+ if (!m_isValid || !rhs.m_isValid)
+ throw InvalidNode();
+ rhs.EnsureNodeExists();
+
+ if (!m_pNode) {
+ m_pNode = rhs.m_pNode;
+ m_pMemory = rhs.m_pMemory;
+ return;
+ }
+
+ m_pNode->set_ref(*rhs.m_pNode);
+ m_pMemory->merge(*rhs.m_pMemory);
+ m_pNode = rhs.m_pNode;
+}
+
+// size/iterator
+inline std::size_t Node::size() const {
+ if (!m_isValid)
+ throw InvalidNode();
+ return m_pNode ? m_pNode->size() : 0;
+}
+
+inline const_iterator Node::begin() const {
+ if (!m_isValid)
+ return const_iterator();
+ return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
+ : const_iterator();
+}
+
+inline iterator Node::begin() {
+ if (!m_isValid)
+ return iterator();
+ return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
+}
+
+inline const_iterator Node::end() const {
+ if (!m_isValid)
+ return const_iterator();
+ return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
+}
+
+inline iterator Node::end() {
+ if (!m_isValid)
+ return iterator();
+ return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
+}
+
+// sequence
+template <typename T>
+inline void Node::push_back(const T& rhs) {
+ if (!m_isValid)
+ throw InvalidNode();
+ push_back(Node(rhs));
+}
+
+inline void Node::push_back(const Node& rhs) {
+ if (!m_isValid || !rhs.m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ rhs.EnsureNodeExists();
+
+ m_pNode->push_back(*rhs.m_pNode, m_pMemory);
+ m_pMemory->merge(*rhs.m_pMemory);
+}
+
+// helpers for indexing
+namespace detail {
+template <typename T>
+struct to_value_t {
+ explicit to_value_t(const T& t_) : t(t_) {}
+ const T& t;
+ typedef const T& return_type;
+
+ const T& operator()() const { return t; }
+};
+
+template <>
+struct to_value_t<const char*> {
+ explicit to_value_t(const char* t_) : t(t_) {}
+ const char* t;
+ typedef std::string return_type;
+
+ const std::string operator()() const { return t; }
+};
+
+template <>
+struct to_value_t<char*> {
+ explicit to_value_t(char* t_) : t(t_) {}
+ const char* t;
+ typedef std::string return_type;
+
+ const std::string operator()() const { return t; }
+};
+
+template <std::size_t N>
+struct to_value_t<char[N]> {
+ explicit to_value_t(const char* t_) : t(t_) {}
+ const char* t;
+ typedef std::string return_type;
+
+ const std::string operator()() const { return t; }
+};
+
+// converts C-strings to std::strings so they can be copied
+template <typename T>
+inline typename to_value_t<T>::return_type to_value(const T& t) {
+ return to_value_t<T>(t)();
+}
+}
+
+// indexing
+template <typename Key>
+inline const Node Node::operator[](const Key& key) const {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ detail::node* value = static_cast<const detail::node&>(*m_pNode)
+ .get(detail::to_value(key), m_pMemory);
+ if (!value) {
+ return Node(ZombieNode);
+ }
+ return Node(*value, m_pMemory);
+}
+
+template <typename Key>
+inline Node Node::operator[](const Key& key) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
+ return Node(value, m_pMemory);
+}
+
+template <typename Key>
+inline bool Node::remove(const Key& key) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ return m_pNode->remove(detail::to_value(key), m_pMemory);
+}
+
+inline const Node Node::operator[](const Node& key) const {
+ if (!m_isValid || !key.m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ key.EnsureNodeExists();
+ m_pMemory->merge(*key.m_pMemory);
+ detail::node* value =
+ static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
+ if (!value) {
+ return Node(ZombieNode);
+ }
+ return Node(*value, m_pMemory);
+}
+
+inline Node Node::operator[](const Node& key) {
+ if (!m_isValid || !key.m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ key.EnsureNodeExists();
+ m_pMemory->merge(*key.m_pMemory);
+ detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
+ return Node(value, m_pMemory);
+}
+
+inline bool Node::remove(const Node& key) {
+ if (!m_isValid || !key.m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ key.EnsureNodeExists();
+ return m_pNode->remove(*key.m_pNode, m_pMemory);
+}
+
+// map
+template <typename Key, typename Value>
+inline void Node::force_insert(const Key& key, const Value& value) {
+ if (!m_isValid)
+ throw InvalidNode();
+ EnsureNodeExists();
+ m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
+ m_pMemory);
+}
+
+// free functions
+inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
+}
+
+#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h
new file mode 100644
index 0000000000..366a9c807f
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/iterator.h
@@ -0,0 +1,31 @@
+#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/detail/iterator_fwd.h"
+#include "yaml-cpp/node/detail/iterator.h"
+#include <list>
+#include <utility>
+#include <vector>
+
+namespace YAML {
+namespace detail {
+struct iterator_value : public Node, std::pair<Node, Node> {
+ iterator_value() {}
+ explicit iterator_value(const Node& rhs)
+ : Node(rhs),
+ std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
+ explicit iterator_value(const Node& key, const Node& value)
+ : Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
+};
+}
+}
+
+#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h
new file mode 100644
index 0000000000..1ded7d27b7
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/node.h
@@ -0,0 +1,145 @@
+#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <stdexcept>
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/emitterstyle.h"
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/node/detail/bool_type.h"
+#include "yaml-cpp/node/detail/iterator_fwd.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/type.h"
+
+namespace YAML {
+namespace detail {
+class node;
+class node_data;
+struct iterator_value;
+} // namespace detail
+} // namespace YAML
+
+namespace YAML {
+class YAML_CPP_API Node {
+ public:
+ friend class NodeBuilder;
+ friend class NodeEvents;
+ friend struct detail::iterator_value;
+ friend class detail::node;
+ friend class detail::node_data;
+ template <typename>
+ friend class detail::iterator_base;
+ template <typename T, typename S>
+ friend struct as_if;
+
+ typedef YAML::iterator iterator;
+ typedef YAML::const_iterator const_iterator;
+
+ Node();
+ explicit Node(NodeType::value type);
+ template <typename T>
+ explicit Node(const T& rhs);
+ explicit Node(const detail::iterator_value& rhs);
+ Node(const Node& rhs);
+ ~Node();
+
+ YAML::Mark Mark() const;
+ NodeType::value Type() const;
+ bool IsDefined() const;
+ bool IsNull() const { return Type() == NodeType::Null; }
+ bool IsScalar() const { return Type() == NodeType::Scalar; }
+ bool IsSequence() const { return Type() == NodeType::Sequence; }
+ bool IsMap() const { return Type() == NodeType::Map; }
+
+ // bool conversions
+ YAML_CPP_OPERATOR_BOOL()
+ bool operator!() const { return !IsDefined(); }
+
+ // access
+ template <typename T>
+ T as() const;
+ template <typename T, typename S>
+ T as(const S& fallback) const;
+ const std::string& Scalar() const;
+
+ const std::string& Tag() const;
+ void SetTag(const std::string& tag);
+
+ // style
+ // WARNING: This API might change in future releases.
+ EmitterStyle::value Style() const;
+ void SetStyle(EmitterStyle::value style);
+
+ // assignment
+ bool is(const Node& rhs) const;
+ template <typename T>
+ Node& operator=(const T& rhs);
+ Node& operator=(const Node& rhs);
+ void reset(const Node& rhs = Node());
+
+ // size/iterator
+ std::size_t size() const;
+
+ const_iterator begin() const;
+ iterator begin();
+
+ const_iterator end() const;
+ iterator end();
+
+ // sequence
+ template <typename T>
+ void push_back(const T& rhs);
+ void push_back(const Node& rhs);
+
+ // indexing
+ template <typename Key>
+ const Node operator[](const Key& key) const;
+ template <typename Key>
+ Node operator[](const Key& key);
+ template <typename Key>
+ bool remove(const Key& key);
+
+ const Node operator[](const Node& key) const;
+ Node operator[](const Node& key);
+ bool remove(const Node& key);
+
+ // map
+ template <typename Key, typename Value>
+ void force_insert(const Key& key, const Value& value);
+
+ private:
+ enum Zombie { ZombieNode };
+ explicit Node(Zombie);
+ explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
+
+ void EnsureNodeExists() const;
+
+ template <typename T>
+ void Assign(const T& rhs);
+ void Assign(const char* rhs);
+ void Assign(char* rhs);
+
+ void AssignData(const Node& rhs);
+ void AssignNode(const Node& rhs);
+
+ private:
+ bool m_isValid;
+ mutable detail::shared_memory_holder m_pMemory;
+ mutable detail::node* m_pNode;
+};
+
+YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs);
+
+YAML_CPP_API Node Clone(const Node& node);
+
+template <typename T>
+struct convert;
+}
+
+#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/parse.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/parse.h
new file mode 100644
index 0000000000..7745fd7245
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/parse.h
@@ -0,0 +1,78 @@
+#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+class Node;
+
+/**
+ * Loads the input string as a single YAML document.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ */
+YAML_CPP_API Node Load(const std::string& input);
+
+/**
+ * Loads the input string as a single YAML document.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ */
+YAML_CPP_API Node Load(const char* input);
+
+/**
+ * Loads the input stream as a single YAML document.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ */
+YAML_CPP_API Node Load(std::istream& input);
+
+/**
+ * Loads the input file as a single YAML document.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ * @throws {@link BadFile} if the file cannot be loaded.
+ */
+YAML_CPP_API Node LoadFile(const std::string& filename);
+
+/**
+ * Loads the input string as a list of YAML documents.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ */
+YAML_CPP_API std::vector<Node> LoadAll(const std::string& input);
+
+/**
+ * Loads the input string as a list of YAML documents.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ */
+YAML_CPP_API std::vector<Node> LoadAll(const char* input);
+
+/**
+ * Loads the input stream as a list of YAML documents.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ */
+YAML_CPP_API std::vector<Node> LoadAll(std::istream& input);
+
+/**
+ * Loads the input file as a list of YAML documents.
+ *
+ * @throws {@link ParserException} if it is malformed.
+ * @throws {@link BadFile} if the file cannot be loaded.
+ */
+YAML_CPP_API std::vector<Node> LoadAllFromFile(const std::string& filename);
+} // namespace YAML
+
+#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h
new file mode 100644
index 0000000000..ce085dd5cd
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/ptr.h
@@ -0,0 +1,29 @@
+#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include <memory>
+
+namespace YAML {
+namespace detail {
+class node;
+class node_ref;
+class node_data;
+class memory;
+class memory_holder;
+
+typedef std::shared_ptr<node> shared_node;
+typedef std::shared_ptr<node_ref> shared_node_ref;
+typedef std::shared_ptr<node_data> shared_node_data;
+typedef std::shared_ptr<memory_holder> shared_memory_holder;
+typedef std::shared_ptr<memory> shared_memory;
+}
+}
+
+#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/type.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/type.h
new file mode 100644
index 0000000000..9d55ca9662
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/node/type.h
@@ -0,0 +1,16 @@
+#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace YAML {
+struct NodeType {
+ enum value { Undefined, Null, Scalar, Sequence, Map };
+};
+}
+
+#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h
new file mode 100644
index 0000000000..a261040739
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/noncopyable.h
@@ -0,0 +1,25 @@
+#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+// this is basically boost::noncopyable
+class YAML_CPP_API noncopyable {
+ protected:
+ noncopyable() {}
+ ~noncopyable() {}
+
+ private:
+ noncopyable(const noncopyable&);
+ const noncopyable& operator=(const noncopyable&);
+};
+}
+
+#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/null.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/null.h
new file mode 100644
index 0000000000..b9521d488a
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/null.h
@@ -0,0 +1,26 @@
+#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/dll.h"
+#include <string>
+
+namespace YAML {
+class Node;
+
+struct YAML_CPP_API _Null {};
+inline bool operator==(const _Null&, const _Null&) { return true; }
+inline bool operator!=(const _Null&, const _Null&) { return false; }
+
+YAML_CPP_API bool IsNull(const Node& node); // old API only
+YAML_CPP_API bool IsNullString(const std::string& str);
+
+extern YAML_CPP_API _Null Null;
+}
+
+#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h
new file mode 100644
index 0000000000..09d45f39b7
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/ostream_wrapper.h
@@ -0,0 +1,72 @@
+#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include <vector>
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+class YAML_CPP_API ostream_wrapper {
+ public:
+ ostream_wrapper();
+ explicit ostream_wrapper(std::ostream& stream);
+ ~ostream_wrapper();
+
+ void write(const std::string& str);
+ void write(const char* str, std::size_t size);
+
+ void set_comment() { m_comment = true; }
+
+ const char* str() const {
+ if (m_pStream) {
+ return 0;
+ } else {
+ m_buffer[m_pos] = '\0';
+ return &m_buffer[0];
+ }
+ }
+
+ std::size_t row() const { return m_row; }
+ std::size_t col() const { return m_col; }
+ std::size_t pos() const { return m_pos; }
+ bool comment() const { return m_comment; }
+
+ private:
+ void update_pos(char ch);
+
+ private:
+ mutable std::vector<char> m_buffer;
+ std::ostream* const m_pStream;
+
+ std::size_t m_pos;
+ std::size_t m_row, m_col;
+ bool m_comment;
+};
+
+template <std::size_t N>
+inline ostream_wrapper& operator<<(ostream_wrapper& stream,
+ const char(&str)[N]) {
+ stream.write(str, N - 1);
+ return stream;
+}
+
+inline ostream_wrapper& operator<<(ostream_wrapper& stream,
+ const std::string& str) {
+ stream.write(str);
+ return stream;
+}
+
+inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
+ stream.write(&ch, 1);
+ return stream;
+}
+}
+
+#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h
new file mode 100644
index 0000000000..ceac22d026
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/parser.h
@@ -0,0 +1,86 @@
+#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <ios>
+#include <memory>
+
+#include "yaml-cpp/dll.h"
+#include "yaml-cpp/noncopyable.h"
+
+namespace YAML {
+class EventHandler;
+class Node;
+class Scanner;
+struct Directives;
+struct Token;
+
+/**
+ * A parser turns a stream of bytes into one stream of "events" per YAML
+ * document in the input stream.
+ */
+class YAML_CPP_API Parser : private noncopyable {
+ public:
+ /** Constructs an empty parser (with no input. */
+ Parser();
+
+ /**
+ * Constructs a parser from the given input stream. The input stream must
+ * live as long as the parser.
+ */
+ explicit Parser(std::istream& in);
+
+ ~Parser();
+
+ /** Evaluates to true if the parser has some valid input to be read. */
+ explicit operator bool() const;
+
+ /**
+ * Resets the parser with the given input stream. Any existing state is
+ * erased.
+ */
+ void Load(std::istream& in);
+
+ /**
+ * Handles the next document by calling events on the {@code eventHandler}.
+ *
+ * @throw a ParserException on error.
+ * @return false if there are no more documents
+ */
+ bool HandleNextDocument(EventHandler& eventHandler);
+
+ void PrintTokens(std::ostream& out);
+
+ private:
+ /**
+ * Reads any directives that are next in the queue, setting the internal
+ * {@code m_pDirectives} state.
+ */
+ void ParseDirectives();
+
+ void HandleDirective(const Token& token);
+
+ /**
+ * Handles a "YAML" directive, which should be of the form 'major.minor' (like
+ * a version number).
+ */
+ void HandleYamlDirective(const Token& token);
+
+ /**
+ * Handles a "TAG" directive, which should be of the form 'handle prefix',
+ * where 'handle' is converted to 'prefix' in the file.
+ */
+ void HandleTagDirective(const Token& token);
+
+ private:
+ std::unique_ptr<Scanner> m_pScanner;
+ std::unique_ptr<Directives> m_pDirectives;
+};
+}
+
+#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h
new file mode 100644
index 0000000000..06780c861f
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/stlemitter.h
@@ -0,0 +1,51 @@
+#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <vector>
+#include <list>
+#include <set>
+#include <map>
+
+namespace YAML {
+template <typename Seq>
+inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
+ emitter << BeginSeq;
+ for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it)
+ emitter << *it;
+ emitter << EndSeq;
+ return emitter;
+}
+
+template <typename T>
+inline Emitter& operator<<(Emitter& emitter, const std::vector<T>& v) {
+ return EmitSeq(emitter, v);
+}
+
+template <typename T>
+inline Emitter& operator<<(Emitter& emitter, const std::list<T>& v) {
+ return EmitSeq(emitter, v);
+}
+
+template <typename T>
+inline Emitter& operator<<(Emitter& emitter, const std::set<T>& v) {
+ return EmitSeq(emitter, v);
+}
+
+template <typename K, typename V>
+inline Emitter& operator<<(Emitter& emitter, const std::map<K, V>& m) {
+ typedef typename std::map<K, V> map;
+ emitter << BeginMap;
+ for (typename map::const_iterator it = m.begin(); it != m.end(); ++it)
+ emitter << Key << it->first << Value << it->second;
+ emitter << EndMap;
+ return emitter;
+}
+}
+
+#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h
new file mode 100644
index 0000000000..f33d0e1f63
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/traits.h
@@ -0,0 +1,103 @@
+#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+namespace YAML {
+template <typename>
+struct is_numeric {
+ enum { value = false };
+};
+
+template <>
+struct is_numeric<char> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<unsigned char> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<int> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<unsigned int> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<long int> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<unsigned long int> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<short int> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<unsigned short int> {
+ enum { value = true };
+};
+#if defined(_MSC_VER) && (_MSC_VER < 1310)
+template <>
+struct is_numeric<__int64> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<unsigned __int64> {
+ enum { value = true };
+};
+#else
+template <>
+struct is_numeric<long long> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<unsigned long long> {
+ enum { value = true };
+};
+#endif
+template <>
+struct is_numeric<float> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<double> {
+ enum { value = true };
+};
+template <>
+struct is_numeric<long double> {
+ enum { value = true };
+};
+
+template <bool, class T = void>
+struct enable_if_c {
+ typedef T type;
+};
+
+template <class T>
+struct enable_if_c<false, T> {};
+
+template <class Cond, class T = void>
+struct enable_if : public enable_if_c<Cond::value, T> {};
+
+template <bool, class T = void>
+struct disable_if_c {
+ typedef T type;
+};
+
+template <class T>
+struct disable_if_c<true, T> {};
+
+template <class Cond, class T = void>
+struct disable_if : public disable_if_c<Cond::value, T> {};
+}
+
+#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/yaml.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/yaml.h
new file mode 100644
index 0000000000..7f515efb96
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/yaml.h
@@ -0,0 +1,24 @@
+#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/parser.h"
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/emitterstyle.h"
+#include "yaml-cpp/stlemitter.h"
+#include "yaml-cpp/exceptions.h"
+
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/node/convert.h"
+#include "yaml-cpp/node/iterator.h"
+#include "yaml-cpp/node/detail/impl.h"
+#include "yaml-cpp/node/parse.h"
+#include "yaml-cpp/node/emit.h"
+
+#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch b/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch
new file mode 100644
index 0000000000..93bdc64f64
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/patches/0001-yaml-cpp-Strip-unneeded-sources.patch
@@ -0,0 +1,1667 @@
+From dd3d5fa32be556e54d2ee2247a06e1fc7e5c8026 Mon Sep 17 00:00:00 2001
+From: Nikolai Kosjar <nikolai.kosjar@qt.io>
+Date: Thu, 22 Aug 2019 15:00:03 +0200
+Subject: [PATCH] yaml-cpp: Strip unneeded sources
+
+Change-Id: I2f863b06c1cd42abadc64897cd6282c4a2c8a8e3
+---
+ src/libs/3rdparty/yaml-cpp/.codedocs | 50 -
+ src/libs/3rdparty/yaml-cpp/.gitignore | 1 -
+ src/libs/3rdparty/yaml-cpp/.travis.yml | 28 -
+ src/libs/3rdparty/yaml-cpp/CMakeLists.txt | 365 -
+ src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md | 26 -
+ .../include/yaml-cpp/contrib/anchordict.h | 39 -
+ .../include/yaml-cpp/contrib/graphbuilder.h | 149 -
+ src/libs/3rdparty/yaml-cpp/install.txt | 24 -
+ .../yaml-cpp/src/contrib/graphbuilder.cpp | 17 -
+ .../src/contrib/graphbuilderadapter.cpp | 94 -
+ .../src/contrib/graphbuilderadapter.h | 79 -
+ .../3rdparty/yaml-cpp/test/CMakeLists.txt | 44 -
+ .../yaml-cpp/test/create-emitter-tests.py | 211 -
+ .../yaml-cpp/test/gtest-1.8.0/.gitignore | 2 -
+ .../yaml-cpp/test/gtest-1.8.0/.travis.yml | 46 -
+ .../yaml-cpp/test/gtest-1.8.0/CMakeLists.txt | 16 -
+ .../yaml-cpp/test/gtest-1.8.0/README.md | 142 -
+ .../yaml-cpp/test/gtest-1.8.0/appveyor.yml | 71 -
+ .../test/gtest-1.8.0/googlemock/CHANGES | 126 -
+ .../gtest-1.8.0/googlemock/CMakeLists.txt | 202 -
+ .../test/gtest-1.8.0/googlemock/CONTRIBUTORS | 40 -
+ .../test/gtest-1.8.0/googlemock/LICENSE | 28 -
+ .../test/gtest-1.8.0/googlemock/README.md | 333 -
+ .../gtest-1.8.0/googlemock/build-aux/.keep | 0
+ .../test/gtest-1.8.0/googlemock/configure.ac | 146 -
+ .../gtest-1.8.0/googlemock/docs/CheatSheet.md | 562 -
+ .../gtest-1.8.0/googlemock/docs/CookBook.md | 3675 -------
+ .../gtest-1.8.0/googlemock/docs/DesignDoc.md | 280 -
+ .../gtest-1.8.0/googlemock/docs/DevGuide.md | 132 -
+ .../googlemock/docs/Documentation.md | 12 -
+ .../gtest-1.8.0/googlemock/docs/ForDummies.md | 439 -
+ .../docs/FrequentlyAskedQuestions.md | 628 --
+ .../googlemock/docs/KnownIssues.md | 19 -
+ .../googlemock/docs/v1_5/CheatSheet.md | 525 -
+ .../googlemock/docs/v1_5/CookBook.md | 3250 ------
+ .../googlemock/docs/v1_5/Documentation.md | 11 -
+ .../googlemock/docs/v1_5/ForDummies.md | 439 -
+ .../docs/v1_5/FrequentlyAskedQuestions.md | 624 --
+ .../googlemock/docs/v1_6/CheatSheet.md | 534 -
+ .../googlemock/docs/v1_6/CookBook.md | 3342 ------
+ .../googlemock/docs/v1_6/Documentation.md | 12 -
+ .../googlemock/docs/v1_6/ForDummies.md | 439 -
+ .../docs/v1_6/FrequentlyAskedQuestions.md | 628 --
+ .../googlemock/docs/v1_7/CheatSheet.md | 556 -
+ .../googlemock/docs/v1_7/CookBook.md | 3432 ------
+ .../googlemock/docs/v1_7/Documentation.md | 12 -
+ .../googlemock/docs/v1_7/ForDummies.md | 439 -
+ .../docs/v1_7/FrequentlyAskedQuestions.md | 628 --
+ .../googlemock/include/gmock/gmock-actions.h | 1205 --
+ .../include/gmock/gmock-cardinalities.h | 147 -
+ .../include/gmock/gmock-generated-actions.h | 2377 ----
+ .../gmock/gmock-generated-actions.h.pump | 794 --
+ .../gmock/gmock-generated-function-mockers.h | 1095 --
+ .../gmock-generated-function-mockers.h.pump | 291 -
+ .../include/gmock/gmock-generated-matchers.h | 2179 ----
+ .../gmock/gmock-generated-matchers.h.pump | 672 --
+ .../gmock/gmock-generated-nice-strict.h | 397 -
+ .../gmock/gmock-generated-nice-strict.h.pump | 161 -
+ .../googlemock/include/gmock/gmock-matchers.h | 4399 --------
+ .../include/gmock/gmock-more-actions.h | 246 -
+ .../include/gmock/gmock-more-matchers.h | 58 -
+ .../include/gmock/gmock-spec-builders.h | 1847 ----
+ .../googlemock/include/gmock/gmock.h | 94 -
+ .../internal/custom/gmock-generated-actions.h | 8 -
+ .../custom/gmock-generated-actions.h.pump | 10 -
+ .../gmock/internal/custom/gmock-matchers.h | 39 -
+ .../gmock/internal/custom/gmock-port.h | 46 -
+ .../internal/gmock-generated-internal-utils.h | 279 -
+ .../gmock-generated-internal-utils.h.pump | 136 -
+ .../gmock/internal/gmock-internal-utils.h | 511 -
+ .../include/gmock/internal/gmock-port.h | 91 -
+ .../googlemock/msvc/2005/gmock_config.vsprops | 15 -
+ .../googlemock/msvc/2010/gmock_config.props | 19 -
+ .../googlemock/msvc/2015/gmock_config.props | 19 -
+ .../googlemock/scripts/fuse_gmock_files.py | 240 -
+ .../googlemock/scripts/generator/LICENSE | 203 -
+ .../googlemock/scripts/generator/README | 35 -
+ .../scripts/generator/README.cppclean | 115 -
+ .../scripts/generator/cpp/__init__.py | 0
+ .../googlemock/scripts/generator/cpp/ast.py | 1733 ---
+ .../scripts/generator/cpp/gmock_class.py | 227 -
+ .../scripts/generator/cpp/gmock_class_test.py | 448 -
+ .../scripts/generator/cpp/keywords.py | 59 -
+ .../scripts/generator/cpp/tokenize.py | 287 -
+ .../googlemock/scripts/generator/cpp/utils.py | 41 -
+ .../googlemock/scripts/generator/gmock_gen.py | 31 -
+ .../googlemock/scripts/gmock-config.in | 303 -
+ .../googlemock/scripts/gmock_doctor.py | 640 --
+ .../gtest-1.8.0/googlemock/scripts/upload.py | 1387 ---
+ .../googlemock/scripts/upload_gmock.py | 78 -
+ .../gtest-1.8.0/googlemock/src/gmock-all.cc | 47 -
+ .../googlemock/src/gmock-cardinalities.cc | 156 -
+ .../googlemock/src/gmock-internal-utils.cc | 174 -
+ .../googlemock/src/gmock-matchers.cc | 498 -
+ .../googlemock/src/gmock-spec-builders.cc | 823 --
+ .../test/gtest-1.8.0/googlemock/src/gmock.cc | 183 -
+ .../gtest-1.8.0/googlemock/src/gmock_main.cc | 54 -
+ .../googlemock/test/gmock-actions_test.cc | 1411 ---
+ .../test/gmock-cardinalities_test.cc | 428 -
+ .../test/gmock-generated-actions_test.cc | 1228 ---
+ .../gmock-generated-function-mockers_test.cc | 622 --
+ .../gmock-generated-internal-utils_test.cc | 127 -
+ .../test/gmock-generated-matchers_test.cc | 1286 ---
+ .../test/gmock-internal-utils_test.cc | 699 --
+ .../googlemock/test/gmock-matchers_test.cc | 5652 ----------
+ .../test/gmock-more-actions_test.cc | 708 --
+ .../googlemock/test/gmock-nice-strict_test.cc | 424 -
+ .../googlemock/test/gmock-port_test.cc | 43 -
+ .../test/gmock-spec-builders_test.cc | 2644 -----
+ .../googlemock/test/gmock_all_test.cc | 51 -
+ .../googlemock/test/gmock_ex_test.cc | 81 -
+ .../googlemock/test/gmock_leak_test.py | 108 -
+ .../googlemock/test/gmock_leak_test_.cc | 100 -
+ .../googlemock/test/gmock_link2_test.cc | 40 -
+ .../googlemock/test/gmock_link_test.cc | 40 -
+ .../googlemock/test/gmock_link_test.h | 669 --
+ .../googlemock/test/gmock_output_test.py | 180 -
+ .../googlemock/test/gmock_output_test_.cc | 291 -
+ .../test/gmock_output_test_golden.txt | 310 -
+ .../googlemock/test/gmock_stress_test.cc | 322 -
+ .../gtest-1.8.0/googlemock/test/gmock_test.cc | 220 -
+ .../googlemock/test/gmock_test_utils.py | 112 -
+ .../test/gtest-1.8.0/googletest/.gitignore | 2 -
+ .../test/gtest-1.8.0/googletest/CHANGES | 157 -
+ .../gtest-1.8.0/googletest/CMakeLists.txt | 286 -
+ .../test/gtest-1.8.0/googletest/CONTRIBUTORS | 37 -
+ .../test/gtest-1.8.0/googletest/LICENSE | 28 -
+ .../test/gtest-1.8.0/googletest/README.md | 280 -
+ .../gtest-1.8.0/googletest/build-aux/.keep | 0
+ .../googletest/cmake/internal_utils.cmake | 254 -
+ .../googletest/codegear/gtest.cbproj | 138 -
+ .../googletest/codegear/gtest.groupproj | 54 -
+ .../googletest/codegear/gtest_all.cc | 38 -
+ .../googletest/codegear/gtest_link.cc | 40 -
+ .../googletest/codegear/gtest_main.cbproj | 82 -
+ .../googletest/codegear/gtest_unittest.cbproj | 88 -
+ .../test/gtest-1.8.0/googletest/configure.ac | 68 -
+ .../googletest/docs/AdvancedGuide.md | 2182 ----
+ .../gtest-1.8.0/googletest/docs/DevGuide.md | 126 -
+ .../googletest/docs/Documentation.md | 14 -
+ .../test/gtest-1.8.0/googletest/docs/FAQ.md | 1087 --
+ .../gtest-1.8.0/googletest/docs/Primer.md | 502 -
+ .../gtest-1.8.0/googletest/docs/PumpManual.md | 177 -
+ .../gtest-1.8.0/googletest/docs/Samples.md | 14 -
+ .../googletest/docs/V1_5_AdvancedGuide.md | 2096 ----
+ .../googletest/docs/V1_5_Documentation.md | 12 -
+ .../gtest-1.8.0/googletest/docs/V1_5_FAQ.md | 886 --
+ .../googletest/docs/V1_5_Primer.md | 497 -
+ .../googletest/docs/V1_5_PumpManual.md | 177 -
+ .../googletest/docs/V1_5_XcodeGuide.md | 93 -
+ .../googletest/docs/V1_6_AdvancedGuide.md | 2178 ----
+ .../googletest/docs/V1_6_Documentation.md | 14 -
+ .../gtest-1.8.0/googletest/docs/V1_6_FAQ.md | 1038 --
+ .../googletest/docs/V1_6_Primer.md | 501 -
+ .../googletest/docs/V1_6_PumpManual.md | 177 -
+ .../googletest/docs/V1_6_Samples.md | 14 -
+ .../googletest/docs/V1_6_XcodeGuide.md | 93 -
+ .../googletest/docs/V1_7_AdvancedGuide.md | 2181 ----
+ .../googletest/docs/V1_7_Documentation.md | 14 -
+ .../gtest-1.8.0/googletest/docs/V1_7_FAQ.md | 1082 --
+ .../googletest/docs/V1_7_Primer.md | 501 -
+ .../googletest/docs/V1_7_PumpManual.md | 177 -
+ .../googletest/docs/V1_7_Samples.md | 14 -
+ .../googletest/docs/V1_7_XcodeGuide.md | 93 -
+ .../gtest-1.8.0/googletest/docs/XcodeGuide.md | 93 -
+ .../include/gtest/gtest-death-test.h | 294 -
+ .../googletest/include/gtest/gtest-message.h | 250 -
+ .../include/gtest/gtest-param-test.h | 1444 ---
+ .../include/gtest/gtest-param-test.h.pump | 510 -
+ .../googletest/include/gtest/gtest-printers.h | 993 --
+ .../googletest/include/gtest/gtest-spi.h | 232 -
+ .../include/gtest/gtest-test-part.h | 179 -
+ .../include/gtest/gtest-typed-test.h | 263 -
+ .../googletest/include/gtest/gtest.h | 2236 ----
+ .../include/gtest/gtest_pred_impl.h | 358 -
+ .../googletest/include/gtest/gtest_prod.h | 58 -
+ .../gtest/internal/custom/gtest-port.h | 69 -
+ .../gtest/internal/custom/gtest-printers.h | 42 -
+ .../include/gtest/internal/custom/gtest.h | 41 -
+ .../internal/gtest-death-test-internal.h | 319 -
+ .../include/gtest/internal/gtest-filepath.h | 206 -
+ .../include/gtest/internal/gtest-internal.h | 1238 ---
+ .../include/gtest/internal/gtest-linked_ptr.h | 243 -
+ .../internal/gtest-param-util-generated.h | 5146 ---------
+ .../gtest-param-util-generated.h.pump | 286 -
+ .../include/gtest/internal/gtest-param-util.h | 731 --
+ .../include/gtest/internal/gtest-port-arch.h | 93 -
+ .../include/gtest/internal/gtest-port.h | 2554 -----
+ .../include/gtest/internal/gtest-string.h | 167 -
+ .../include/gtest/internal/gtest-tuple.h | 1020 --
+ .../include/gtest/internal/gtest-tuple.h.pump | 347 -
+ .../include/gtest/internal/gtest-type-util.h | 3331 ------
+ .../gtest/internal/gtest-type-util.h.pump | 297 -
+ .../gtest-1.8.0/googletest/m4/acx_pthread.m4 | 363 -
+ .../test/gtest-1.8.0/googletest/m4/gtest.m4 | 74 -
+ .../googletest/samples/prime_tables.h | 123 -
+ .../gtest-1.8.0/googletest/samples/sample1.cc | 68 -
+ .../gtest-1.8.0/googletest/samples/sample1.h | 43 -
+ .../googletest/samples/sample10_unittest.cc | 144 -
+ .../googletest/samples/sample1_unittest.cc | 153 -
+ .../gtest-1.8.0/googletest/samples/sample2.cc | 56 -
+ .../gtest-1.8.0/googletest/samples/sample2.h | 85 -
+ .../googletest/samples/sample2_unittest.cc | 109 -
+ .../googletest/samples/sample3-inl.h | 172 -
+ .../googletest/samples/sample3_unittest.cc | 151 -
+ .../gtest-1.8.0/googletest/samples/sample4.cc | 46 -
+ .../gtest-1.8.0/googletest/samples/sample4.h | 53 -
+ .../googletest/samples/sample4_unittest.cc | 45 -
+ .../googletest/samples/sample5_unittest.cc | 199 -
+ .../googletest/samples/sample6_unittest.cc | 224 -
+ .../googletest/samples/sample7_unittest.cc | 130 -
+ .../googletest/samples/sample8_unittest.cc | 173 -
+ .../googletest/samples/sample9_unittest.cc | 160 -
+ .../gtest-1.8.0/googletest/scripts/common.py | 83 -
+ .../googletest/scripts/fuse_gtest_files.py | 253 -
+ .../googletest/scripts/gen_gtest_pred_impl.py | 730 --
+ .../googletest/scripts/gtest-config.in | 274 -
+ .../gtest-1.8.0/googletest/scripts/pump.py | 855 --
+ .../googletest/scripts/release_docs.py | 158 -
+ .../gtest-1.8.0/googletest/scripts/upload.py | 1387 ---
+ .../googletest/scripts/upload_gtest.py | 78 -
+ .../gtest-1.8.0/googletest/src/gtest-all.cc | 48 -
+ .../googletest/src/gtest-death-test.cc | 1342 ---
+ .../googletest/src/gtest-filepath.cc | 387 -
+ .../googletest/src/gtest-internal-inl.h | 1183 --
+ .../gtest-1.8.0/googletest/src/gtest-port.cc | 1259 ---
+ .../googletest/src/gtest-printers.cc | 373 -
+ .../googletest/src/gtest-test-part.cc | 110 -
+ .../googletest/src/gtest-typed-test.cc | 118 -
+ .../test/gtest-1.8.0/googletest/src/gtest.cc | 5388 ---------
+ .../gtest-1.8.0/googletest/src/gtest_main.cc | 38 -
+ .../test/gtest-death-test_ex_test.cc | 93 -
+ .../googletest/test/gtest-death-test_test.cc | 1427 ---
+ .../googletest/test/gtest-filepath_test.cc | 662 --
+ .../googletest/test/gtest-linked_ptr_test.cc | 154 -
+ .../googletest/test/gtest-listener_test.cc | 311 -
+ .../googletest/test/gtest-message_test.cc | 159 -
+ .../googletest/test/gtest-options_test.cc | 215 -
+ .../googletest/test/gtest-param-test2_test.cc | 65 -
+ .../googletest/test/gtest-param-test_test.cc | 1055 --
+ .../googletest/test/gtest-param-test_test.h | 57 -
+ .../googletest/test/gtest-port_test.cc | 1304 ---
+ .../googletest/test/gtest-printers_test.cc | 1635 ---
+ .../googletest/test/gtest-test-part_test.cc | 208 -
+ .../googletest/test/gtest-tuple_test.cc | 320 -
+ .../googletest/test/gtest-typed-test2_test.cc | 45 -
+ .../googletest/test/gtest-typed-test_test.cc | 380 -
+ .../googletest/test/gtest-typed-test_test.h | 66 -
+ .../test/gtest-unittest-api_test.cc | 341 -
+ .../googletest/test/gtest_all_test.cc | 47 -
+ .../test/gtest_break_on_failure_unittest.py | 212 -
+ .../test/gtest_break_on_failure_unittest_.cc | 88 -
+ .../test/gtest_catch_exceptions_test.py | 237 -
+ .../test/gtest_catch_exceptions_test_.cc | 311 -
+ .../googletest/test/gtest_color_test.py | 130 -
+ .../googletest/test/gtest_color_test_.cc | 71 -
+ .../googletest/test/gtest_env_var_test.py | 117 -
+ .../googletest/test/gtest_env_var_test_.cc | 126 -
+ .../googletest/test/gtest_environment_test.cc | 192 -
+ .../googletest/test/gtest_filter_unittest.py | 636 --
+ .../googletest/test/gtest_filter_unittest_.cc | 140 -
+ .../googletest/test/gtest_help_test.py | 172 -
+ .../googletest/test/gtest_help_test_.cc | 46 -
+ .../test/gtest_list_tests_unittest.py | 207 -
+ .../test/gtest_list_tests_unittest_.cc | 157 -
+ .../googletest/test/gtest_main_unittest.cc | 45 -
+ .../googletest/test/gtest_no_test_unittest.cc | 56 -
+ .../googletest/test/gtest_output_test.py | 340 -
+ .../googletest/test/gtest_output_test_.cc | 1062 --
+ .../test/gtest_output_test_golden_lin.txt | 743 --
+ .../test/gtest_pred_impl_unittest.cc | 2427 ----
+ .../test/gtest_premature_exit_test.cc | 127 -
+ .../googletest/test/gtest_prod_test.cc | 57 -
+ .../googletest/test/gtest_repeat_test.cc | 253 -
+ .../googletest/test/gtest_shuffle_test.py | 325 -
+ .../googletest/test/gtest_shuffle_test_.cc | 103 -
+ .../googletest/test/gtest_sole_header_test.cc | 57 -
+ .../googletest/test/gtest_stress_test.cc | 256 -
+ .../googletest/test/gtest_test_utils.py | 320 -
+ .../test/gtest_throw_on_failure_ex_test.cc | 92 -
+ .../test/gtest_throw_on_failure_test.py | 171 -
+ .../test/gtest_throw_on_failure_test_.cc | 72 -
+ .../test/gtest_uninitialized_test.py | 70 -
+ .../test/gtest_uninitialized_test_.cc | 43 -
+ .../googletest/test/gtest_unittest.cc | 7706 -------------
+ .../test/gtest_xml_outfile1_test_.cc | 49 -
+ .../test/gtest_xml_outfile2_test_.cc | 49 -
+ .../test/gtest_xml_outfiles_test.py | 132 -
+ .../test/gtest_xml_output_unittest.py | 308 -
+ .../test/gtest_xml_output_unittest_.cc | 181 -
+ .../googletest/test/gtest_xml_test_utils.py | 194 -
+ .../gtest-1.8.0/googletest/test/production.cc | 36 -
+ .../gtest-1.8.0/googletest/test/production.h | 55 -
+ .../xcode/Config/DebugProject.xcconfig | 30 -
+ .../xcode/Config/FrameworkTarget.xcconfig | 17 -
+ .../googletest/xcode/Config/General.xcconfig | 41 -
+ .../xcode/Config/ReleaseProject.xcconfig | 32 -
+ .../xcode/Config/StaticLibraryTarget.xcconfig | 18 -
+ .../xcode/Config/TestTarget.xcconfig | 8 -
+ .../googletest/xcode/Resources/Info.plist | 30 -
+ .../xcode/Samples/FrameworkSample/Info.plist | 28 -
+ .../WidgetFramework.xcodeproj/project.pbxproj | 457 -
+ .../xcode/Samples/FrameworkSample/runtests.sh | 62 -
+ .../xcode/Samples/FrameworkSample/widget.cc | 63 -
+ .../xcode/Samples/FrameworkSample/widget.h | 59 -
+ .../Samples/FrameworkSample/widget_test.cc | 68 -
+ .../googletest/xcode/Scripts/runtests.sh | 65 -
+ .../xcode/Scripts/versiongenerate.py | 100 -
+ .../xcode/gtest.xcodeproj/project.pbxproj | 1135 --
+ .../yaml-cpp/test/gtest-1.8.0/travis.sh | 15 -
+ .../3rdparty/yaml-cpp/test/handler_test.h | 32 -
+ .../test/integration/emitter_test.cpp | 1038 --
+ .../test/integration/encoding_test.cpp | 182 -
+ .../test/integration/gen_emitter_test.cpp | 9759 -----------------
+ .../test/integration/handler_spec_test.cpp | 1611 ---
+ .../test/integration/handler_test.cpp | 76 -
+ .../test/integration/load_node_test.cpp | 241 -
+ .../test/integration/node_spec_test.cpp | 1131 --
+ src/libs/3rdparty/yaml-cpp/test/main.cpp | 6 -
+ .../yaml-cpp/test/mock_event_handler.h | 26 -
+ .../3rdparty/yaml-cpp/test/node/node_test.cpp | 517 -
+ .../yaml-cpp/test/ostream_wrapper_test.cpp | 66 -
+ .../3rdparty/yaml-cpp/test/regex_test.cpp | 177 -
+ .../3rdparty/yaml-cpp/test/specexamples.h | 846 --
+ .../3rdparty/yaml-cpp/util/CMakeLists.txt | 14 -
+ src/libs/3rdparty/yaml-cpp/util/api.cpp | 137 -
+ src/libs/3rdparty/yaml-cpp/util/parse.cpp | 61 -
+ src/libs/3rdparty/yaml-cpp/util/read.cpp | 103 -
+ src/libs/3rdparty/yaml-cpp/util/sandbox.cpp | 36 -
+ .../yaml-cpp/yaml-cpp-config-version.cmake.in | 11 -
+ .../yaml-cpp/yaml-cpp-config.cmake.in | 14 -
+ 331 files changed, 167784 deletions(-)
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/.codedocs
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/.gitignore
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/.travis.yml
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/CMakeLists.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/anchordict.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/install.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilder.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/CMakeLists.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/create-emitter-tests.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.gitignore
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.travis.yml
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/CMakeLists.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/README.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/appveyor.yml
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CHANGES
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CMakeLists.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CONTRIBUTORS
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/LICENSE
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/README.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/build-aux/.keep
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/configure.ac
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CheatSheet.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CookBook.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DesignDoc.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DevGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/ForDummies.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/KnownIssues.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-actions.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-matchers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-spec-builders.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-matchers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-port.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-internal-utils.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-port.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2005/gmock_config.vsprops
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2010/gmock_config.props
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2015/gmock_config.props
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/fuse_gmock_files.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/LICENSE
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README.cppclean
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/__init__.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/ast.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class_test.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/keywords.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/tokenize.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/utils.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/gmock_gen.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock-config.in
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock_doctor.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload_gmock.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-all.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-cardinalities.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-internal-utils.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-matchers.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-spec-builders.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock_main.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-actions_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-cardinalities_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-actions_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-function-mockers_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-internal-utils_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-matchers_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-internal-utils_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-matchers_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-more-actions_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-nice-strict_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-port_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-spec-builders_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_all_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_ex_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link2_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.h
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_golden.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_stress_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test_utils.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/.gitignore
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CHANGES
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CMakeLists.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CONTRIBUTORS
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/LICENSE
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/README.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/build-aux/.keep
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/cmake/internal_utils.cmake
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.cbproj
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.groupproj
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_all.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_link.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_main.cbproj
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_unittest.cbproj
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/configure.ac
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/AdvancedGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/DevGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/FAQ.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Primer.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/PumpManual.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Samples.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_AdvancedGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_FAQ.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Primer.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_PumpManual.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_XcodeGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_AdvancedGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_FAQ.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Primer.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_PumpManual.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Samples.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_XcodeGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_AdvancedGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Documentation.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_FAQ.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Primer.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_PumpManual.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Samples.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_XcodeGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/XcodeGuide.md
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-death-test.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-message.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-printers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-spi.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-test-part.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-typed-test.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_pred_impl.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_prod.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-port.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-printers.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-death-test-internal.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-filepath.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-internal.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-linked_ptr.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port-arch.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-string.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h.pump
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/acx_pthread.m4
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/gtest.m4
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/prime_tables.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample10_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3-inl.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample5_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample6_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample7_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample8_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample9_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/common.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/fuse_gtest_files.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gen_gtest_pred_impl.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gtest-config.in
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/pump.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/release_docs.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload_gtest.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-all.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-death-test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-filepath.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-internal-inl.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-port.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-printers.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-test-part.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-typed-test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest_main.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_ex_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-filepath_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-linked_ptr_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-listener_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-message_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-options_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test2_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-port_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-printers_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-test-part_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-tuple_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test2_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-unittest-api_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_all_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_environment_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_main_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_no_test_unittest.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_golden_lin.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_pred_impl_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_premature_exit_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_prod_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_repeat_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_sole_header_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_stress_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_test_utils.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_ex_test.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_unittest.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile1_test_.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile2_test_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfiles_test.py
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest_.cc
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_test_utils.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/DebugProject.xcconfig
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/General.xcconfig
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/TestTarget.xcconfig
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Resources/Info.plist
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/runtests.sh
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget_test.cc
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/runtests.sh
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/versiongenerate.py
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/gtest.xcodeproj/project.pbxproj
+ delete mode 100755 src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/travis.sh
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/handler_test.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/emitter_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/encoding_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/gen_emitter_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/handler_spec_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/handler_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/load_node_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/integration/node_spec_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/main.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/mock_event_handler.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/node/node_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/ostream_wrapper_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/regex_test.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/test/specexamples.h
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/util/CMakeLists.txt
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/util/api.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/util/parse.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/util/read.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/util/sandbox.cpp
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/yaml-cpp-config-version.cmake.in
+ delete mode 100644 src/libs/3rdparty/yaml-cpp/yaml-cpp-config.cmake.in
+
+diff --git a/src/libs/3rdparty/yaml-cpp/.codedocs b/src/libs/3rdparty/yaml-cpp/.codedocs
+deleted file mode 100644
+index 02e438213a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/.gitignore b/src/libs/3rdparty/yaml-cpp/.gitignore
+deleted file mode 100644
+index 567609b123..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/.travis.yml b/src/libs/3rdparty/yaml-cpp/.travis.yml
+deleted file mode 100644
+index d0b6a04efe..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/CMakeLists.txt
+deleted file mode 100644
+index d2d8810288..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md b/src/libs/3rdparty/yaml-cpp/CONTRIBUTING.md
+deleted file mode 100644
+index cd09a1aca8..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/anchordict.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/anchordict.h
+deleted file mode 100644
+index 78db9ec928..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h
+deleted file mode 100644
+index f0a38f2887..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/install.txt b/src/libs/3rdparty/yaml-cpp/install.txt
+deleted file mode 100644
+index 939236249b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilder.cpp b/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilder.cpp
+deleted file mode 100644
+index 416c1359db..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.cpp b/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.cpp
+deleted file mode 100644
+index 02a3d972a5..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.h b/src/libs/3rdparty/yaml-cpp/src/contrib/graphbuilderadapter.h
+deleted file mode 100644
+index 0d1e579208..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/CMakeLists.txt
+deleted file mode 100644
+index 3633da578b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/create-emitter-tests.py b/src/libs/3rdparty/yaml-cpp/test/create-emitter-tests.py
+deleted file mode 100644
+index 7a03c41e1b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.gitignore b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.gitignore
+deleted file mode 100644
+index ce310bc357..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.travis.yml b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/.travis.yml
+deleted file mode 100644
+index 3204dfac17..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/CMakeLists.txt
+deleted file mode 100644
+index 8d2b552ef7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/README.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/README.md
+deleted file mode 100644
+index 076484e4fa..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/appveyor.yml b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/appveyor.yml
+deleted file mode 100644
+index d613fd6027..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CHANGES b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CHANGES
+deleted file mode 100644
+index d6f2f760e3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CMakeLists.txt
+deleted file mode 100644
+index beb259a2e9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CONTRIBUTORS b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/CONTRIBUTORS
+deleted file mode 100644
+index 6e9ae362b6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/LICENSE b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/LICENSE
+deleted file mode 100644
+index 1941a11f8c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/README.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/README.md
+deleted file mode 100644
+index 332beab388..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/build-aux/.keep b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/build-aux/.keep
+deleted file mode 100644
+index e69de29bb2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/configure.ac b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/configure.ac
+deleted file mode 100644
+index 3b740f205e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CheatSheet.md
+deleted file mode 100644
+index ef4451b878..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/CookBook.md
+deleted file mode 100644
+index c52f1009d1..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DesignDoc.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DesignDoc.md
+deleted file mode 100644
+index 3f515c3b6d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DevGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/DevGuide.md
+deleted file mode 100644
+index f4bab75ca7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/Documentation.md
+deleted file mode 100644
+index 444151ee9e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/ForDummies.md
+deleted file mode 100644
+index 0da4cbe27b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/FrequentlyAskedQuestions.md
+deleted file mode 100644
+index 5eac83f4b9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/KnownIssues.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/KnownIssues.md
+deleted file mode 100644
+index adadf5144b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CheatSheet.md
+deleted file mode 100644
+index 3c7bed4c6f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/CookBook.md
+deleted file mode 100644
+index 26e153c6ba..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/Documentation.md
+deleted file mode 100644
+index 315b0a2989..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/ForDummies.md
+deleted file mode 100644
+index fcc3b56174..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_5/FrequentlyAskedQuestions.md
+deleted file mode 100644
+index 7593243c3a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CheatSheet.md
+deleted file mode 100644
+index 91de1d210e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/CookBook.md
+deleted file mode 100644
+index f5975a0035..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/Documentation.md
+deleted file mode 100644
+index dcc9156c2a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/ForDummies.md
+deleted file mode 100644
+index 19ee63ab0c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_6/FrequentlyAskedQuestions.md
+deleted file mode 100644
+index f74715d2e3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CheatSheet.md
+deleted file mode 100644
+index db421e51be..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/CookBook.md
+deleted file mode 100644
+index 419a001071..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/Documentation.md
+deleted file mode 100644
+index d9181f28e1..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/ForDummies.md
+deleted file mode 100644
+index ee03c5b989..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/docs/v1_7/FrequentlyAskedQuestions.md
+deleted file mode 100644
+index fa21233aa2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-actions.h
+deleted file mode 100644
+index b3f654af34..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-cardinalities.h
+deleted file mode 100644
+index fc315f92ab..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h
+deleted file mode 100644
+index b5a889c0c3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-actions.h.pump
+deleted file mode 100644
+index 66d9f9d551..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h
+deleted file mode 100644
+index 4fa5ca9484..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h.pump
+deleted file mode 100644
+index 811502d0ce..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h
+deleted file mode 100644
+index 57056fd91d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-matchers.h.pump
+deleted file mode 100644
+index de30c2c92b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h
+deleted file mode 100644
+index 4095f4d5bc..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-generated-nice-strict.h.pump
+deleted file mode 100644
+index 3ee1ce7f30..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-matchers.h
+deleted file mode 100644
+index 33b37a7a5d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-actions.h
+deleted file mode 100644
+index 3d387b6b7d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-more-matchers.h
+deleted file mode 100644
+index 3db899f429..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-spec-builders.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock-spec-builders.h
+deleted file mode 100644
+index fed7de66bc..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/gmock.h
+deleted file mode 100644
+index 6735c71bf8..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
+deleted file mode 100644
+index 7dc3b1ad54..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump
+deleted file mode 100644
+index d26c8a08a4..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-matchers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-matchers.h
+deleted file mode 100644
+index f2efef91db..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/custom/gmock-port.h
+deleted file mode 100644
+index 9ce8bfe06b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
+deleted file mode 100644
+index 7811e43f87..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump
+deleted file mode 100644
+index 800af17c1d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-internal-utils.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-internal-utils.h
+deleted file mode 100644
+index e2ddb05c91..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/include/gmock/internal/gmock-port.h
+deleted file mode 100644
+index 63f4a6802e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2005/gmock_config.vsprops b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2005/gmock_config.vsprops
+deleted file mode 100644
+index 9b5ff7f38a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2010/gmock_config.props b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2010/gmock_config.props
+deleted file mode 100644
+index 77bc95b192..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2015/gmock_config.props b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/msvc/2015/gmock_config.props
+deleted file mode 100644
+index 77bc95b192..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/fuse_gmock_files.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/fuse_gmock_files.py
+deleted file mode 100755
+index cb7fdf2f78..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/LICENSE b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/LICENSE
+deleted file mode 100644
+index 87ea063651..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README
+deleted file mode 100644
+index d6f95974b6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README.cppclean b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/README.cppclean
+deleted file mode 100644
+index 65431b6175..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/__init__.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/__init__.py
+deleted file mode 100755
+index e69de29bb2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/ast.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/ast.py
+deleted file mode 100755
+index 11cbe9126a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class.py
+deleted file mode 100755
+index f9966cbb4b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/gmock_class_test.py
+deleted file mode 100755
+index 018f90a650..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/keywords.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/keywords.py
+deleted file mode 100755
+index f694450e37..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/tokenize.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/tokenize.py
+deleted file mode 100755
+index 359d5562d7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/cpp/utils.py
+deleted file mode 100755
+index eab36eec33..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/gmock_gen.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/generator/gmock_gen.py
+deleted file mode 100755
+index 8cc0d135d6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock-config.in b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock-config.in
+deleted file mode 100755
+index 2baefe94d6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock_doctor.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/gmock_doctor.py
+deleted file mode 100755
+index 74992bc744..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload.py
+deleted file mode 100755
+index 6e6f9a1471..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload_gmock.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/scripts/upload_gmock.py
+deleted file mode 100755
+index 5dc484b391..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-all.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-all.cc
+deleted file mode 100644
+index 7aebce7afe..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-cardinalities.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-cardinalities.cc
+deleted file mode 100644
+index 50ec7286ee..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-internal-utils.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-internal-utils.cc
+deleted file mode 100644
+index fb5308018a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-matchers.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-matchers.cc
+deleted file mode 100644
+index e7424510fc..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-spec-builders.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock-spec-builders.cc
+deleted file mode 100644
+index 9551342070..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock.cc
+deleted file mode 100644
+index eac3d842ba..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock_main.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/src/gmock_main.cc
+deleted file mode 100644
+index bd5be03be2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-actions_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-actions_test.cc
+deleted file mode 100644
+index f470de4c55..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-cardinalities_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-cardinalities_test.cc
+deleted file mode 100644
+index 64815e57a3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-actions_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-actions_test.cc
+deleted file mode 100644
+index 5ca5bc7892..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-function-mockers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-function-mockers_test.cc
+deleted file mode 100644
+index a86a613578..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-internal-utils_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-internal-utils_test.cc
+deleted file mode 100644
+index e0a535a346..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-matchers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-generated-matchers_test.cc
+deleted file mode 100644
+index 0e9f77f5eb..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-internal-utils_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-internal-utils_test.cc
+deleted file mode 100644
+index 9d5ec60927..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-matchers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-matchers_test.cc
+deleted file mode 100644
+index 9f62c3d826..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-more-actions_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-more-actions_test.cc
+deleted file mode 100644
+index 77e15bd586..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-nice-strict_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-nice-strict_test.cc
+deleted file mode 100644
+index d0adcbbed8..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-port_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-port_test.cc
+deleted file mode 100644
+index d6a8d44466..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-spec-builders_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock-spec-builders_test.cc
+deleted file mode 100644
+index 59ea87c894..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_all_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_all_test.cc
+deleted file mode 100644
+index 56d6c49ccc..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_ex_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_ex_test.cc
+deleted file mode 100644
+index 3afed86ab9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test.py
+deleted file mode 100755
+index 997680ce1a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_leak_test_.cc
+deleted file mode 100644
+index 1d27d22f62..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link2_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link2_test.cc
+deleted file mode 100644
+index 4c310c3d83..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.cc
+deleted file mode 100644
+index 61e97d10ca..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_link_test.h
+deleted file mode 100644
+index 1f55f5bd7f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test.py
+deleted file mode 100755
+index eced8a81f2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_.cc
+deleted file mode 100644
+index 44cba342ad..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_golden.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_output_test_golden.txt
+deleted file mode 100644
+index 689d5eeb03..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_stress_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_stress_test.cc
+deleted file mode 100644
+index 0e97aeed0b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test.cc
+deleted file mode 100644
+index d8d0c57b16..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test_utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googlemock/test/gmock_test_utils.py
+deleted file mode 100755
+index 20e3d3d446..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/.gitignore b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/.gitignore
+deleted file mode 100644
+index 4b7be4b91b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CHANGES b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CHANGES
+deleted file mode 100644
+index 0552132421..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CMakeLists.txt
+deleted file mode 100644
+index 621d0f0421..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CONTRIBUTORS b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/CONTRIBUTORS
+deleted file mode 100644
+index feae2fc044..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/LICENSE b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/LICENSE
+deleted file mode 100644
+index 1941a11f8c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/README.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/README.md
+deleted file mode 100644
+index edd4408054..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/build-aux/.keep b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/build-aux/.keep
+deleted file mode 100644
+index e69de29bb2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/cmake/internal_utils.cmake b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/cmake/internal_utils.cmake
+deleted file mode 100644
+index 777b91ed4b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.cbproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.cbproj
+deleted file mode 100644
+index 285bb2a87b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.groupproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest.groupproj
+deleted file mode 100644
+index 849f4c4b81..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_all.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_all.cc
+deleted file mode 100644
+index ba7ad68ad1..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_link.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_link.cc
+deleted file mode 100644
+index b955ebf2f9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_main.cbproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_main.cbproj
+deleted file mode 100644
+index fae32cb29b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_unittest.cbproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/codegear/gtest_unittest.cbproj
+deleted file mode 100644
+index 33f7056346..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/configure.ac b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/configure.ac
+deleted file mode 100644
+index cc592e1583..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/AdvancedGuide.md
+deleted file mode 100644
+index 93a65200da..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/DevGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/DevGuide.md
+deleted file mode 100644
+index 06467a3277..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Documentation.md
+deleted file mode 100644
+index 8ca1aac759..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/FAQ.md
+deleted file mode 100644
+index 5fd6cb7238..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Primer.md
+deleted file mode 100644
+index 474c1d2ab6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/PumpManual.md
+deleted file mode 100644
+index 8184f153ca..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Samples.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/Samples.md
+deleted file mode 100644
+index f21d200567..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_AdvancedGuide.md
+deleted file mode 100644
+index 34e19c26fd..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Documentation.md
+deleted file mode 100644
+index 46bba2ec86..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_FAQ.md
+deleted file mode 100644
+index e870aff000..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_Primer.md
+deleted file mode 100644
+index 6960d2ce4c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_PumpManual.md
+deleted file mode 100644
+index 15710789dd..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_5_XcodeGuide.md
+deleted file mode 100644
+index bf24bf51bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_AdvancedGuide.md
+deleted file mode 100644
+index 78864b1667..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Documentation.md
+deleted file mode 100644
+index ca924660a3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_FAQ.md
+deleted file mode 100644
+index 2b7f784077..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Primer.md
+deleted file mode 100644
+index 8d840ef45b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_PumpManual.md
+deleted file mode 100644
+index 8184f153ca..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Samples.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_Samples.md
+deleted file mode 100644
+index f21d200567..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_6_XcodeGuide.md
+deleted file mode 100644
+index bf24bf51bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_AdvancedGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_AdvancedGuide.md
+deleted file mode 100644
+index dd4af8f366..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Documentation.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Documentation.md
+deleted file mode 100644
+index 282697a50b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_FAQ.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_FAQ.md
+deleted file mode 100644
+index 3dd914dcf1..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Primer.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Primer.md
+deleted file mode 100644
+index b1827c7355..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_PumpManual.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_PumpManual.md
+deleted file mode 100644
+index 8184f153ca..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Samples.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_Samples.md
+deleted file mode 100644
+index f21d200567..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/V1_7_XcodeGuide.md
+deleted file mode 100644
+index bf24bf51bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/XcodeGuide.md b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/docs/XcodeGuide.md
+deleted file mode 100644
+index bf24bf51bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-death-test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-death-test.h
+deleted file mode 100644
+index 957a69c6a9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-message.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-message.h
+deleted file mode 100644
+index fe879bca79..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h
+deleted file mode 100644
+index 038f9ba79e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-param-test.h.pump
+deleted file mode 100644
+index 3078d6d2a1..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-printers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-printers.h
+deleted file mode 100644
+index 8a33164cb3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-spi.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-spi.h
+deleted file mode 100644
+index f63fa9a1b2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-test-part.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-test-part.h
+deleted file mode 100644
+index 77eb844839..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-typed-test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest-typed-test.h
+deleted file mode 100644
+index 5f69d5678e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest.h
+deleted file mode 100644
+index f846c5bd66..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_pred_impl.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_pred_impl.h
+deleted file mode 100644
+index 30ae712f50..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_prod.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/gtest_prod.h
+deleted file mode 100644
+index da80ddc6c7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-port.h
+deleted file mode 100644
+index 7e744bd3bb..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-printers.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest-printers.h
+deleted file mode 100644
+index 60c1ea050b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/custom/gtest.h
+deleted file mode 100644
+index c27412a898..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-death-test-internal.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-death-test-internal.h
+deleted file mode 100644
+index 2b3a78f5bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-filepath.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-filepath.h
+deleted file mode 100644
+index 7a13b4b0de..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-internal.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-internal.h
+deleted file mode 100644
+index ebd1cf615d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-linked_ptr.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-linked_ptr.h
+deleted file mode 100644
+index 3602942217..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h
+deleted file mode 100644
+index 4d1d81d20f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util-generated.h.pump
+deleted file mode 100644
+index 5c7c47af0b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-param-util.h
+deleted file mode 100644
+index 82cab9b020..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port-arch.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port-arch.h
+deleted file mode 100644
+index 74ab949057..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-port.h
+deleted file mode 100644
+index 0094ed5077..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-string.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-string.h
+deleted file mode 100644
+index 97f1a7fdd2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h
+deleted file mode 100644
+index e9b405340a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-tuple.h.pump
+deleted file mode 100644
+index 429ddfeeca..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h
+deleted file mode 100644
+index e46f7cfcb4..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h.pump b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/include/gtest/internal/gtest-type-util.h.pump
+deleted file mode 100644
+index 251fdf025b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/acx_pthread.m4 b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/acx_pthread.m4
+deleted file mode 100644
+index 2cf20de144..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/gtest.m4 b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/m4/gtest.m4
+deleted file mode 100644
+index 6598ba75a4..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/prime_tables.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/prime_tables.h
+deleted file mode 100644
+index 92ce16a014..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.cc
+deleted file mode 100644
+index f171e2609d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1.h
+deleted file mode 100644
+index 3dfeb98c45..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample10_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample10_unittest.cc
+deleted file mode 100644
+index 0051cd5dcd..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample1_unittest.cc
+deleted file mode 100644
+index aefc4f1d86..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.cc
+deleted file mode 100644
+index 5f763b9bdf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2.h
+deleted file mode 100644
+index cb485c70fb..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample2_unittest.cc
+deleted file mode 100644
+index 4fa19b71c7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3-inl.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3-inl.h
+deleted file mode 100644
+index 7e3084d638..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample3_unittest.cc
+deleted file mode 100644
+index bf3877d013..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.cc
+deleted file mode 100644
+index ae44bda6f1..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4.h
+deleted file mode 100644
+index cd60f0dd2d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample4_unittest.cc
+deleted file mode 100644
+index fa5afc7d5a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample5_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample5_unittest.cc
+deleted file mode 100644
+index 43d8e57775..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample6_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample6_unittest.cc
+deleted file mode 100644
+index 8f2036a516..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample7_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample7_unittest.cc
+deleted file mode 100644
+index 1b651a21d6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample8_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample8_unittest.cc
+deleted file mode 100644
+index 7274334067..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample9_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/samples/sample9_unittest.cc
+deleted file mode 100644
+index b2e2079bf3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/common.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/common.py
+deleted file mode 100644
+index 3c0347a75b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/fuse_gtest_files.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/fuse_gtest_files.py
+deleted file mode 100755
+index 3f3e9f36d6..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gen_gtest_pred_impl.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gen_gtest_pred_impl.py
+deleted file mode 100755
+index 3e7ab042ea..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gtest-config.in b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/gtest-config.in
+deleted file mode 100755
+index 780f8432ef..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/pump.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/pump.py
+deleted file mode 100755
+index 5efb653c20..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/release_docs.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/release_docs.py
+deleted file mode 100755
+index 1291347f67..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload.py
+deleted file mode 100755
+index 6e6f9a1471..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload_gtest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/scripts/upload_gtest.py
+deleted file mode 100755
+index be19ae8091..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-all.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-all.cc
+deleted file mode 100644
+index 0a9cee5223..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-death-test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-death-test.cc
+deleted file mode 100644
+index a01a369830..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-filepath.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-filepath.cc
+deleted file mode 100644
+index 0292dc1195..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-internal-inl.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-internal-inl.h
+deleted file mode 100644
+index ed8a682a96..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-port.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-port.cc
+deleted file mode 100644
+index e5bf3dd2be..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-printers.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-printers.cc
+deleted file mode 100644
+index a2df412f8a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-test-part.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-test-part.cc
+deleted file mode 100644
+index fb0e35425e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-typed-test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest-typed-test.cc
+deleted file mode 100644
+index df1eef4754..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest.cc
+deleted file mode 100644
+index d882ab2e36..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest_main.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/src/gtest_main.cc
+deleted file mode 100644
+index f302822552..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_ex_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_ex_test.cc
+deleted file mode 100644
+index b50a13d5e2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-death-test_test.cc
+deleted file mode 100644
+index bb4a3d1b38..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-filepath_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-filepath_test.cc
+deleted file mode 100644
+index da72986926..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-linked_ptr_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-linked_ptr_test.cc
+deleted file mode 100644
+index 6fcf5124a8..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-listener_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-listener_test.cc
+deleted file mode 100644
+index 90747685f0..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-message_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-message_test.cc
+deleted file mode 100644
+index 175238ef4e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-options_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-options_test.cc
+deleted file mode 100644
+index 5586dc3b1b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test2_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test2_test.cc
+deleted file mode 100644
+index 4a782fe708..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.cc
+deleted file mode 100644
+index 8b278bb94b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-param-test_test.h
+deleted file mode 100644
+index 26ea122b10..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-port_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-port_test.cc
+deleted file mode 100644
+index 6ea607bc70..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-printers_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-printers_test.cc
+deleted file mode 100644
+index 3e97cc24ab..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-test-part_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-test-part_test.cc
+deleted file mode 100644
+index ca8ba933ae..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-tuple_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-tuple_test.cc
+deleted file mode 100644
+index bfaa3e0ac4..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test2_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test2_test.cc
+deleted file mode 100644
+index c284700b02..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.cc
+deleted file mode 100644
+index 93628ba080..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-typed-test_test.h
+deleted file mode 100644
+index 41d75704cf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-unittest-api_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest-unittest-api_test.cc
+deleted file mode 100644
+index b1f51688af..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_all_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_all_test.cc
+deleted file mode 100644
+index 955aa62828..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest.py
+deleted file mode 100755
+index 78f3e0f53b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_break_on_failure_unittest_.cc
+deleted file mode 100644
+index dd07478c07..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test.py
+deleted file mode 100755
+index e6fc22fd1f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_catch_exceptions_test_.cc
+deleted file mode 100644
+index d0fc82c998..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test.py
+deleted file mode 100755
+index d02a53ed85..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_color_test_.cc
+deleted file mode 100644
+index f61ebb89b8..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test.py
+deleted file mode 100755
+index 424075cfa3..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_env_var_test_.cc
+deleted file mode 100644
+index 539afc9683..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_environment_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_environment_test.cc
+deleted file mode 100644
+index 3cff19e70e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest.py
+deleted file mode 100755
+index ec0b151b11..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_filter_unittest_.cc
+deleted file mode 100644
+index 77deffc38f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test.py
+deleted file mode 100755
+index 093c838d9e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_help_test_.cc
+deleted file mode 100644
+index 31f78c2441..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest.py
+deleted file mode 100755
+index f2d2fd1b1c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_list_tests_unittest_.cc
+deleted file mode 100644
+index 907c176ba9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_main_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_main_unittest.cc
+deleted file mode 100644
+index ecd9bb876f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_no_test_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_no_test_unittest.cc
+deleted file mode 100644
+index 292599af8d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test.py
+deleted file mode 100755
+index 06dbee0980..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_.cc
+deleted file mode 100644
+index 1070a9f26f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_golden_lin.txt b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_output_test_golden_lin.txt
+deleted file mode 100644
+index 2223d560e2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_pred_impl_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_pred_impl_unittest.cc
+deleted file mode 100644
+index a84eff860a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_premature_exit_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_premature_exit_test.cc
+deleted file mode 100644
+index 3b4dc7d43f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_prod_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_prod_test.cc
+deleted file mode 100644
+index 060abce187..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_repeat_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_repeat_test.cc
+deleted file mode 100644
+index 481012adc2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test.py
+deleted file mode 100755
+index 30d0303d19..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_shuffle_test_.cc
+deleted file mode 100644
+index 6fb441bd4d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_sole_header_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_sole_header_test.cc
+deleted file mode 100644
+index ccd091a281..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_stress_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_stress_test.cc
+deleted file mode 100644
+index e7daa430df..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_test_utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_test_utils.py
+deleted file mode 100755
+index 4acd36c975..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_ex_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_ex_test.cc
+deleted file mode 100644
+index 8d46c76f16..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test.py
+deleted file mode 100755
+index 3e7740cabb..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_throw_on_failure_test_.cc
+deleted file mode 100644
+index 2b88fe3d9b..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test.py
+deleted file mode 100755
+index 4358370097..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_uninitialized_test_.cc
+deleted file mode 100644
+index 44316987fb..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_unittest.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_unittest.cc
+deleted file mode 100644
+index 88e94134b9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile1_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile1_test_.cc
+deleted file mode 100644
+index 531ced49d4..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile2_test_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfile2_test_.cc
+deleted file mode 100644
+index 7b400b2760..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfiles_test.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_outfiles_test.py
+deleted file mode 100755
+index 524e437e6c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest.py
+deleted file mode 100755
+index bcd5975991..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest_.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_output_unittest_.cc
+deleted file mode 100644
+index 48b8771b52..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_test_utils.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/gtest_xml_test_utils.py
+deleted file mode 100755
+index 341956b54d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.cc
+deleted file mode 100644
+index 8b8a40b44e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/test/production.h
+deleted file mode 100644
+index 98fd5e476c..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/DebugProject.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/DebugProject.xcconfig
+deleted file mode 100644
+index 3d68157d5d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/FrameworkTarget.xcconfig
+deleted file mode 100644
+index 357b1c8fbf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/General.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/General.xcconfig
+deleted file mode 100644
+index f23e322272..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/ReleaseProject.xcconfig
+deleted file mode 100644
+index 5349f0a04a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/StaticLibraryTarget.xcconfig
+deleted file mode 100644
+index 3922fa51d5..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/TestTarget.xcconfig b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Config/TestTarget.xcconfig
+deleted file mode 100644
+index e6652ba859..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Resources/Info.plist b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Resources/Info.plist
+deleted file mode 100644
+index 9dd28ea148..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/Info.plist
+deleted file mode 100644
+index f3852edea2..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
+deleted file mode 100644
+index 497617eb68..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/runtests.sh b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/runtests.sh
+deleted file mode 100644
+index 4a0d413e52..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.cc
+deleted file mode 100644
+index bfc4e7fcfd..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.h b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget.h
+deleted file mode 100644
+index 0c55cdc8cf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget_test.cc b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Samples/FrameworkSample/widget_test.cc
+deleted file mode 100644
+index 8725994218..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/runtests.sh b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/runtests.sh
+deleted file mode 100644
+index 3fc229f1d4..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/versiongenerate.py b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/Scripts/versiongenerate.py
+deleted file mode 100755
+index 81de8c96ac..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/gtest.xcodeproj/project.pbxproj b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/googletest/xcode/gtest.xcodeproj/project.pbxproj
+deleted file mode 100644
+index aefaa88b05..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/travis.sh b/src/libs/3rdparty/yaml-cpp/test/gtest-1.8.0/travis.sh
+deleted file mode 100755
+index bdecbd964d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/handler_test.h b/src/libs/3rdparty/yaml-cpp/test/handler_test.h
+deleted file mode 100644
+index 668a58d01e..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/emitter_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/emitter_test.cpp
+deleted file mode 100644
+index 27808380d5..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/encoding_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/encoding_test.cpp
+deleted file mode 100644
+index 9bd6586378..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/gen_emitter_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/gen_emitter_test.cpp
+deleted file mode 100644
+index e44eee6da7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/handler_spec_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/handler_spec_test.cpp
+deleted file mode 100644
+index d142a0d302..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/handler_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/handler_test.cpp
+deleted file mode 100644
+index 6011460713..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/load_node_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/load_node_test.cpp
+deleted file mode 100644
+index 02bb8fe58d..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/integration/node_spec_test.cpp b/src/libs/3rdparty/yaml-cpp/test/integration/node_spec_test.cpp
+deleted file mode 100644
+index aedf38b2bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/main.cpp b/src/libs/3rdparty/yaml-cpp/test/main.cpp
+deleted file mode 100644
+index 443e2dbb3f..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/mock_event_handler.h b/src/libs/3rdparty/yaml-cpp/test/mock_event_handler.h
+deleted file mode 100644
+index 49d1f0c334..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/node/node_test.cpp b/src/libs/3rdparty/yaml-cpp/test/node/node_test.cpp
+deleted file mode 100644
+index 485ad09e1a..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/ostream_wrapper_test.cpp b/src/libs/3rdparty/yaml-cpp/test/ostream_wrapper_test.cpp
+deleted file mode 100644
+index cdc1f05083..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/regex_test.cpp b/src/libs/3rdparty/yaml-cpp/test/regex_test.cpp
+deleted file mode 100644
+index 7589d2e4bf..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/test/specexamples.h b/src/libs/3rdparty/yaml-cpp/test/specexamples.h
+deleted file mode 100644
+index 3c81c77791..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/util/CMakeLists.txt b/src/libs/3rdparty/yaml-cpp/util/CMakeLists.txt
+deleted file mode 100644
+index 22866273c7..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/util/api.cpp b/src/libs/3rdparty/yaml-cpp/util/api.cpp
+deleted file mode 100644
+index 8ae5ff2978..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/util/parse.cpp b/src/libs/3rdparty/yaml-cpp/util/parse.cpp
+deleted file mode 100644
+index f3f0279ce5..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/util/read.cpp b/src/libs/3rdparty/yaml-cpp/util/read.cpp
+deleted file mode 100644
+index fc88f1f9b9..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/util/sandbox.cpp b/src/libs/3rdparty/yaml-cpp/util/sandbox.cpp
+deleted file mode 100644
+index 1df25bb242..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp-config-version.cmake.in b/src/libs/3rdparty/yaml-cpp/yaml-cpp-config-version.cmake.in
+deleted file mode 100644
+index 80b9c79add..0000000000
+diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp-config.cmake.in b/src/libs/3rdparty/yaml-cpp/yaml-cpp-config.cmake.in
+deleted file mode 100644
+index 7b41e3f30c..0000000000
+--
+2.17.1
+
diff --git a/src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch b/src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch
new file mode 100644
index 0000000000..90d684b9c1
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/patches/0002-yaml-cpp-Make-dll.h-compatible-with-fvisibility-hidd.patch
@@ -0,0 +1,42 @@
+From 72546402c08fc548efb248761870a83e78eb5ea3 Mon Sep 17 00:00:00 2001
+From: Nikolai Kosjar <nikolai.kosjar@qt.io>
+Date: Wed, 31 Jul 2019 09:08:55 +0200
+Subject: [PATCH] yaml-cpp: Make dll.h compatible with -fvisibility=hidden
+
+Change-Id: Ic09ace43e37102294d290768b3a7994c7a6b42c6
+---
+ src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
+index a32c06b2e3..897f1533df 100644
+--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
++++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/dll.h
+@@ -18,13 +18,22 @@
+
+ #ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
+ // manually)
++
++#if defined(_WIN32) || defined(WIN32)
++# define YAML_CPP_API_IMPORT __declspec(dllimport)
++# define YAML_CPP_API_EXPORT __declspec(dllexport)
++#else
++# define YAML_CPP_API_IMPORT __attribute__((visibility("default")))
++# define YAML_CPP_API_EXPORT __attribute__((visibility("default")))
++#endif
++
+ #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
+ // or defined manually)
+ // #pragma message( "Defining YAML_CPP_API for DLL export" )
+-#define YAML_CPP_API __declspec(dllexport)
++#define YAML_CPP_API YAML_CPP_API_EXPORT
+ #else // yaml_cpp_EXPORTS
+ // #pragma message( "Defining YAML_CPP_API for DLL import" )
+-#define YAML_CPP_API __declspec(dllimport)
++#define YAML_CPP_API YAML_CPP_API_IMPORT
+ #endif // yaml_cpp_EXPORTS
+ #else // YAML_CPP_DLL
+ #define YAML_CPP_API
+--
+2.17.1
+
diff --git a/src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch b/src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch
new file mode 100644
index 0000000000..ab7929f964
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/patches/0003-yaml-cpp-MSVC-Fix-unknown-override-specifier-for-_NO.patch
@@ -0,0 +1,52 @@
+From b6f98df7d1ebdd788e7b5029c3884dcf38a6f17d Mon Sep 17 00:00:00 2001
+From: Nikolai Kosjar <nikolai.kosjar@qt.io>
+Date: Tue, 27 Aug 2019 12:01:03 +0200
+Subject: [PATCH] yaml-cpp: MSVC: Fix "unknown override specifier" for
+ _NOEXCEPT
+
+Change-Id: If07000f7b3e8c4c1b87b683ff9cd29e57d43ab60
+---
+ src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h | 8 +-------
+ src/libs/3rdparty/yaml-cpp/src/exceptions.cpp | 8 +-------
+ 2 files changed, 2 insertions(+), 14 deletions(-)
+
+diff --git a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
+index 9c96859b2c..eae31968b7 100644
+--- a/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
++++ b/src/libs/3rdparty/yaml-cpp/include/yaml-cpp/exceptions.h
+@@ -13,13 +13,7 @@
+ #include <stdexcept>
+ #include <string>
+
+-// This is here for compatibility with older versions of Visual Studio
+-// which don't support noexcept
+-#ifdef _MSC_VER
+- #define YAML_CPP_NOEXCEPT _NOEXCEPT
+-#else
+- #define YAML_CPP_NOEXCEPT noexcept
+-#endif
++#define YAML_CPP_NOEXCEPT noexcept
+
+ namespace YAML {
+ // error messages
+diff --git a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
+index 9b6d8912c1..d5e10b23c1 100644
+--- a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
++++ b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
+@@ -1,12 +1,6 @@
+ #include "yaml-cpp/exceptions.h"
+
+-// This is here for compatibility with older versions of Visual Studio
+-// which don't support noexcept
+-#ifdef _MSC_VER
+- #define YAML_CPP_NOEXCEPT _NOEXCEPT
+-#else
+- #define YAML_CPP_NOEXCEPT noexcept
+-#endif
++#define YAML_CPP_NOEXCEPT noexcept
+
+ namespace YAML {
+
+--
+2.17.1
+
diff --git a/src/libs/3rdparty/yaml-cpp/src/binary.cpp b/src/libs/3rdparty/yaml-cpp/src/binary.cpp
new file mode 100644
index 0000000000..a7e51301b8
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/binary.cpp
@@ -0,0 +1,93 @@
+#include "yaml-cpp/binary.h"
+
+namespace YAML {
+static const char encoding[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+std::string EncodeBase64(const unsigned char *data, std::size_t size) {
+ const char PAD = '=';
+
+ std::string ret;
+ ret.resize(4 * size / 3 + 3);
+ char *out = &ret[0];
+
+ std::size_t chunks = size / 3;
+ std::size_t remainder = size % 3;
+
+ for (std::size_t i = 0; i < chunks; i++, data += 3) {
+ *out++ = encoding[data[0] >> 2];
+ *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
+ *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
+ *out++ = encoding[data[2] & 0x3f];
+ }
+
+ switch (remainder) {
+ case 0:
+ break;
+ case 1:
+ *out++ = encoding[data[0] >> 2];
+ *out++ = encoding[((data[0] & 0x3) << 4)];
+ *out++ = PAD;
+ *out++ = PAD;
+ break;
+ case 2:
+ *out++ = encoding[data[0] >> 2];
+ *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
+ *out++ = encoding[((data[1] & 0xf) << 2)];
+ *out++ = PAD;
+ break;
+ }
+
+ ret.resize(out - &ret[0]);
+ return ret;
+}
+
+static const unsigned char decoding[] = {
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
+ 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
+ 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255,
+};
+
+std::vector<unsigned char> DecodeBase64(const std::string &input) {
+ typedef std::vector<unsigned char> ret_type;
+ if (input.empty())
+ return ret_type();
+
+ ret_type ret(3 * input.size() / 4 + 1);
+ unsigned char *out = &ret[0];
+
+ unsigned value = 0;
+ for (std::size_t i = 0; i < input.size(); i++) {
+ unsigned char d = decoding[static_cast<unsigned>(input[i])];
+ if (d == 255)
+ return ret_type();
+
+ value = (value << 6) | d;
+ if (i % 4 == 3) {
+ *out++ = value >> 16;
+ if (i > 0 && input[i - 1] != '=')
+ *out++ = value >> 8;
+ if (input[i] != '=')
+ *out++ = value;
+ }
+ }
+
+ ret.resize(out - &ret[0]);
+ return ret;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/collectionstack.h b/src/libs/3rdparty/yaml-cpp/src/collectionstack.h
new file mode 100644
index 0000000000..2302786e03
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/collectionstack.h
@@ -0,0 +1,39 @@
+#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <stack>
+#include <cassert>
+
+namespace YAML {
+struct CollectionType {
+ enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
+};
+
+class CollectionStack {
+ public:
+ CollectionType::value GetCurCollectionType() const {
+ if (collectionStack.empty())
+ return CollectionType::NoCollection;
+ return collectionStack.top();
+ }
+
+ void PushCollectionType(CollectionType::value type) {
+ collectionStack.push(type);
+ }
+ void PopCollectionType(CollectionType::value type) {
+ assert(type == GetCurCollectionType());
+ collectionStack.pop();
+ }
+
+ private:
+ std::stack<CollectionType::value> collectionStack;
+};
+}
+
+#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/convert.cpp b/src/libs/3rdparty/yaml-cpp/src/convert.cpp
new file mode 100644
index 0000000000..ec05b77826
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/convert.cpp
@@ -0,0 +1,75 @@
+#include <algorithm>
+
+#include "yaml-cpp/node/convert.h"
+
+namespace {
+// we're not gonna mess with the mess that is all the isupper/etc. functions
+bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
+bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
+char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
+
+std::string tolower(const std::string& str) {
+ std::string s(str);
+ std::transform(s.begin(), s.end(), s.begin(), ToLower);
+ return s;
+}
+
+template <typename T>
+bool IsEntirely(const std::string& str, T func) {
+ for (std::size_t i = 0; i < str.size(); i++)
+ if (!func(str[i]))
+ return false;
+
+ return true;
+}
+
+// IsFlexibleCase
+// . Returns true if 'str' is:
+// . UPPERCASE
+// . lowercase
+// . Capitalized
+bool IsFlexibleCase(const std::string& str) {
+ if (str.empty())
+ return true;
+
+ if (IsEntirely(str, IsLower))
+ return true;
+
+ bool firstcaps = IsUpper(str[0]);
+ std::string rest = str.substr(1);
+ return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
+}
+}
+
+namespace YAML {
+bool convert<bool>::decode(const Node& node, bool& rhs) {
+ if (!node.IsScalar())
+ return false;
+
+ // we can't use iostream bool extraction operators as they don't
+ // recognize all possible values in the table below (taken from
+ // http://yaml.org/type/bool.html)
+ static const struct {
+ std::string truename, falsename;
+ } names[] = {
+ {"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"},
+ };
+
+ if (!IsFlexibleCase(node.Scalar()))
+ return false;
+
+ for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
+ if (names[i].truename == tolower(node.Scalar())) {
+ rhs = true;
+ return true;
+ }
+
+ if (names[i].falsename == tolower(node.Scalar())) {
+ rhs = false;
+ return true;
+ }
+ }
+
+ return false;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/directives.cpp b/src/libs/3rdparty/yaml-cpp/src/directives.cpp
new file mode 100644
index 0000000000..963bd2cd37
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/directives.cpp
@@ -0,0 +1,22 @@
+#include "directives.h"
+
+namespace YAML {
+Directives::Directives() {
+ // version
+ version.isDefault = true;
+ version.major = 1;
+ version.minor = 2;
+}
+
+const std::string Directives::TranslateTagHandle(
+ const std::string& handle) const {
+ std::map<std::string, std::string>::const_iterator it = tags.find(handle);
+ if (it == tags.end()) {
+ if (handle == "!!")
+ return "tag:yaml.org,2002:";
+ return handle;
+ }
+
+ return it->second;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/directives.h b/src/libs/3rdparty/yaml-cpp/src/directives.h
new file mode 100644
index 0000000000..333af26e37
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/directives.h
@@ -0,0 +1,29 @@
+#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include <map>
+
+namespace YAML {
+struct Version {
+ bool isDefault;
+ int major, minor;
+};
+
+struct Directives {
+ Directives();
+
+ const std::string TranslateTagHandle(const std::string& handle) const;
+
+ Version version;
+ std::map<std::string, std::string> tags;
+};
+}
+
+#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/emit.cpp b/src/libs/3rdparty/yaml-cpp/src/emit.cpp
new file mode 100644
index 0000000000..51bc791533
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emit.cpp
@@ -0,0 +1,25 @@
+#include "yaml-cpp/node/emit.h"
+#include "yaml-cpp/emitfromevents.h"
+#include "yaml-cpp/emitter.h"
+#include "nodeevents.h"
+
+namespace YAML {
+Emitter& operator<<(Emitter& out, const Node& node) {
+ EmitFromEvents emitFromEvents(out);
+ NodeEvents events(node);
+ events.Emit(emitFromEvents);
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const Node& node) {
+ Emitter emitter(out);
+ emitter << node;
+ return out;
+}
+
+std::string Dump(const Node& node) {
+ Emitter emitter;
+ emitter << node;
+ return emitter.c_str();
+}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp b/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp
new file mode 100644
index 0000000000..4832649f3c
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emitfromevents.cpp
@@ -0,0 +1,119 @@
+#include <cassert>
+#include <sstream>
+
+#include "yaml-cpp/emitfromevents.h"
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/emittermanip.h"
+#include "yaml-cpp/null.h"
+
+namespace YAML {
+struct Mark;
+} // namespace YAML
+
+namespace {
+std::string ToString(YAML::anchor_t anchor) {
+ std::stringstream stream;
+ stream << anchor;
+ return stream.str();
+}
+}
+
+namespace YAML {
+EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {}
+
+void EmitFromEvents::OnDocumentStart(const Mark&) {}
+
+void EmitFromEvents::OnDocumentEnd() {}
+
+void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) {
+ BeginNode();
+ EmitProps("", anchor);
+ m_emitter << Null;
+}
+
+void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) {
+ BeginNode();
+ m_emitter << Alias(ToString(anchor));
+}
+
+void EmitFromEvents::OnScalar(const Mark&, const std::string& tag,
+ anchor_t anchor, const std::string& value) {
+ BeginNode();
+ EmitProps(tag, anchor);
+ m_emitter << value;
+}
+
+void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
+ anchor_t anchor,
+ EmitterStyle::value style) {
+ BeginNode();
+ EmitProps(tag, anchor);
+ switch (style) {
+ case EmitterStyle::Block:
+ m_emitter << Block;
+ break;
+ case EmitterStyle::Flow:
+ m_emitter << Flow;
+ break;
+ default:
+ break;
+ }
+ m_emitter << BeginSeq;
+ m_stateStack.push(State::WaitingForSequenceEntry);
+}
+
+void EmitFromEvents::OnSequenceEnd() {
+ m_emitter << EndSeq;
+ assert(m_stateStack.top() == State::WaitingForSequenceEntry);
+ m_stateStack.pop();
+}
+
+void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) {
+ BeginNode();
+ EmitProps(tag, anchor);
+ switch (style) {
+ case EmitterStyle::Block:
+ m_emitter << Block;
+ break;
+ case EmitterStyle::Flow:
+ m_emitter << Flow;
+ break;
+ default:
+ break;
+ }
+ m_emitter << BeginMap;
+ m_stateStack.push(State::WaitingForKey);
+}
+
+void EmitFromEvents::OnMapEnd() {
+ m_emitter << EndMap;
+ assert(m_stateStack.top() == State::WaitingForKey);
+ m_stateStack.pop();
+}
+
+void EmitFromEvents::BeginNode() {
+ if (m_stateStack.empty())
+ return;
+
+ switch (m_stateStack.top()) {
+ case State::WaitingForKey:
+ m_emitter << Key;
+ m_stateStack.top() = State::WaitingForValue;
+ break;
+ case State::WaitingForValue:
+ m_emitter << Value;
+ m_stateStack.top() = State::WaitingForKey;
+ break;
+ default:
+ break;
+ }
+}
+
+void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
+ if (!tag.empty() && tag != "?" && tag != "!")
+ m_emitter << VerbatimTag(tag);
+ if (anchor)
+ m_emitter << Anchor(ToString(anchor));
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitter.cpp b/src/libs/3rdparty/yaml-cpp/src/emitter.cpp
new file mode 100644
index 0000000000..ebeb059554
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emitter.cpp
@@ -0,0 +1,911 @@
+#include <sstream>
+
+#include "emitterutils.h"
+#include "indentation.h" // IWYU pragma: keep
+#include "yaml-cpp/emitter.h"
+#include "yaml-cpp/emitterdef.h"
+#include "yaml-cpp/emittermanip.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+
+namespace YAML {
+class Binary;
+struct _Null;
+
+Emitter::Emitter() : m_pState(new EmitterState) {}
+
+Emitter::Emitter(std::ostream& stream)
+ : m_pState(new EmitterState), m_stream(stream) {}
+
+Emitter::~Emitter() {}
+
+const char* Emitter::c_str() const { return m_stream.str(); }
+
+std::size_t Emitter::size() const { return m_stream.pos(); }
+
+// state checking
+bool Emitter::good() const { return m_pState->good(); }
+
+const std::string Emitter::GetLastError() const {
+ return m_pState->GetLastError();
+}
+
+// global setters
+bool Emitter::SetOutputCharset(EMITTER_MANIP value) {
+ return m_pState->SetOutputCharset(value, FmtScope::Global);
+}
+
+bool Emitter::SetStringFormat(EMITTER_MANIP value) {
+ return m_pState->SetStringFormat(value, FmtScope::Global);
+}
+
+bool Emitter::SetBoolFormat(EMITTER_MANIP value) {
+ bool ok = false;
+ if (m_pState->SetBoolFormat(value, FmtScope::Global))
+ ok = true;
+ if (m_pState->SetBoolCaseFormat(value, FmtScope::Global))
+ ok = true;
+ if (m_pState->SetBoolLengthFormat(value, FmtScope::Global))
+ ok = true;
+ return ok;
+}
+
+bool Emitter::SetIntBase(EMITTER_MANIP value) {
+ return m_pState->SetIntFormat(value, FmtScope::Global);
+}
+
+bool Emitter::SetSeqFormat(EMITTER_MANIP value) {
+ return m_pState->SetFlowType(GroupType::Seq, value, FmtScope::Global);
+}
+
+bool Emitter::SetMapFormat(EMITTER_MANIP value) {
+ bool ok = false;
+ if (m_pState->SetFlowType(GroupType::Map, value, FmtScope::Global))
+ ok = true;
+ if (m_pState->SetMapKeyFormat(value, FmtScope::Global))
+ ok = true;
+ return ok;
+}
+
+bool Emitter::SetIndent(std::size_t n) {
+ return m_pState->SetIndent(n, FmtScope::Global);
+}
+
+bool Emitter::SetPreCommentIndent(std::size_t n) {
+ return m_pState->SetPreCommentIndent(n, FmtScope::Global);
+}
+
+bool Emitter::SetPostCommentIndent(std::size_t n) {
+ return m_pState->SetPostCommentIndent(n, FmtScope::Global);
+}
+
+bool Emitter::SetFloatPrecision(std::size_t n) {
+ return m_pState->SetFloatPrecision(n, FmtScope::Global);
+}
+
+bool Emitter::SetDoublePrecision(std::size_t n) {
+ return m_pState->SetDoublePrecision(n, FmtScope::Global);
+}
+
+// SetLocalValue
+// . Either start/end a group, or set a modifier locally
+Emitter& Emitter::SetLocalValue(EMITTER_MANIP value) {
+ if (!good())
+ return *this;
+
+ switch (value) {
+ case BeginDoc:
+ EmitBeginDoc();
+ break;
+ case EndDoc:
+ EmitEndDoc();
+ break;
+ case BeginSeq:
+ EmitBeginSeq();
+ break;
+ case EndSeq:
+ EmitEndSeq();
+ break;
+ case BeginMap:
+ EmitBeginMap();
+ break;
+ case EndMap:
+ EmitEndMap();
+ break;
+ case Key:
+ case Value:
+ // deprecated (these can be deduced by the parity of nodes in a map)
+ break;
+ case TagByKind:
+ EmitKindTag();
+ break;
+ case Newline:
+ EmitNewline();
+ break;
+ default:
+ m_pState->SetLocalValue(value);
+ break;
+ }
+ return *this;
+}
+
+Emitter& Emitter::SetLocalIndent(const _Indent& indent) {
+ m_pState->SetIndent(indent.value, FmtScope::Local);
+ return *this;
+}
+
+Emitter& Emitter::SetLocalPrecision(const _Precision& precision) {
+ if (precision.floatPrecision >= 0)
+ m_pState->SetFloatPrecision(precision.floatPrecision, FmtScope::Local);
+ if (precision.doublePrecision >= 0)
+ m_pState->SetDoublePrecision(precision.doublePrecision, FmtScope::Local);
+ return *this;
+}
+
+// EmitBeginDoc
+void Emitter::EmitBeginDoc() {
+ if (!good())
+ return;
+
+ if (m_pState->CurGroupType() != GroupType::NoType) {
+ m_pState->SetError("Unexpected begin document");
+ return;
+ }
+
+ if (m_pState->HasAnchor() || m_pState->HasTag()) {
+ m_pState->SetError("Unexpected begin document");
+ return;
+ }
+
+ if (m_stream.col() > 0)
+ m_stream << "\n";
+ m_stream << "---\n";
+
+ m_pState->StartedDoc();
+}
+
+// EmitEndDoc
+void Emitter::EmitEndDoc() {
+ if (!good())
+ return;
+
+ if (m_pState->CurGroupType() != GroupType::NoType) {
+ m_pState->SetError("Unexpected begin document");
+ return;
+ }
+
+ if (m_pState->HasAnchor() || m_pState->HasTag()) {
+ m_pState->SetError("Unexpected begin document");
+ return;
+ }
+
+ if (m_stream.col() > 0)
+ m_stream << "\n";
+ m_stream << "...\n";
+}
+
+// EmitBeginSeq
+void Emitter::EmitBeginSeq() {
+ if (!good())
+ return;
+
+ PrepareNode(m_pState->NextGroupType(GroupType::Seq));
+
+ m_pState->StartedGroup(GroupType::Seq);
+}
+
+// EmitEndSeq
+void Emitter::EmitEndSeq() {
+ if (!good())
+ return;
+
+ if (m_pState->CurGroupChildCount() == 0)
+ m_pState->ForceFlow();
+
+ if (m_pState->CurGroupFlowType() == FlowType::Flow) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(m_pState->CurIndent());
+ if (m_pState->CurGroupChildCount() == 0)
+ m_stream << "[";
+ m_stream << "]";
+ }
+
+ m_pState->EndedGroup(GroupType::Seq);
+}
+
+// EmitBeginMap
+void Emitter::EmitBeginMap() {
+ if (!good())
+ return;
+
+ PrepareNode(m_pState->NextGroupType(GroupType::Map));
+
+ m_pState->StartedGroup(GroupType::Map);
+}
+
+// EmitEndMap
+void Emitter::EmitEndMap() {
+ if (!good())
+ return;
+
+ if (m_pState->CurGroupChildCount() == 0)
+ m_pState->ForceFlow();
+
+ if (m_pState->CurGroupFlowType() == FlowType::Flow) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(m_pState->CurIndent());
+ if (m_pState->CurGroupChildCount() == 0)
+ m_stream << "{";
+ m_stream << "}";
+ }
+
+ m_pState->EndedGroup(GroupType::Map);
+}
+
+// EmitNewline
+void Emitter::EmitNewline() {
+ if (!good())
+ return;
+
+ PrepareNode(EmitterNodeType::NoType);
+ m_stream << "\n";
+ m_pState->SetNonContent();
+}
+
+bool Emitter::CanEmitNewline() const { return true; }
+
+// Put the stream in a state so we can simply write the next node
+// E.g., if we're in a sequence, write the "- "
+void Emitter::PrepareNode(EmitterNodeType::value child) {
+ switch (m_pState->CurGroupNodeType()) {
+ case EmitterNodeType::NoType:
+ PrepareTopNode(child);
+ break;
+ case EmitterNodeType::FlowSeq:
+ FlowSeqPrepareNode(child);
+ break;
+ case EmitterNodeType::BlockSeq:
+ BlockSeqPrepareNode(child);
+ break;
+ case EmitterNodeType::FlowMap:
+ FlowMapPrepareNode(child);
+ break;
+ case EmitterNodeType::BlockMap:
+ BlockMapPrepareNode(child);
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ assert(false);
+ break;
+ }
+}
+
+void Emitter::PrepareTopNode(EmitterNodeType::value child) {
+ if (child == EmitterNodeType::NoType)
+ return;
+
+ if (m_pState->CurGroupChildCount() > 0 && m_stream.col() > 0) {
+ if (child != EmitterNodeType::NoType)
+ EmitBeginDoc();
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ // TODO: if we were writing null, and
+ // we wanted it blank, we wouldn't want a space
+ SpaceOrIndentTo(m_pState->HasBegunContent(), 0);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ if (m_pState->HasBegunNode())
+ m_stream << "\n";
+ break;
+ }
+}
+
+void Emitter::FlowSeqPrepareNode(EmitterNodeType::value child) {
+ const std::size_t lastIndent = m_pState->LastIndent();
+
+ if (!m_pState->HasBegunNode()) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(lastIndent);
+ if (m_pState->CurGroupChildCount() == 0)
+ m_stream << "[";
+ else
+ m_stream << ",";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(
+ m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
+ lastIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ assert(false);
+ break;
+ }
+}
+
+void Emitter::BlockSeqPrepareNode(EmitterNodeType::value child) {
+ const std::size_t curIndent = m_pState->CurIndent();
+ const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent();
+
+ if (child == EmitterNodeType::NoType)
+ return;
+
+ if (!m_pState->HasBegunContent()) {
+ if (m_pState->CurGroupChildCount() > 0 || m_stream.comment()) {
+ m_stream << "\n";
+ }
+ m_stream << IndentTo(curIndent);
+ m_stream << "-";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(m_pState->HasBegunContent(), nextIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ m_stream << "\n";
+ break;
+ case EmitterNodeType::BlockMap:
+ if (m_pState->HasBegunContent() || m_stream.comment())
+ m_stream << "\n";
+ break;
+ }
+}
+
+void Emitter::FlowMapPrepareNode(EmitterNodeType::value child) {
+ if (m_pState->CurGroupChildCount() % 2 == 0) {
+ if (m_pState->GetMapKeyFormat() == LongKey)
+ m_pState->SetLongKey();
+
+ if (m_pState->CurGroupLongKey())
+ FlowMapPrepareLongKey(child);
+ else
+ FlowMapPrepareSimpleKey(child);
+ } else {
+ if (m_pState->CurGroupLongKey())
+ FlowMapPrepareLongKeyValue(child);
+ else
+ FlowMapPrepareSimpleKeyValue(child);
+ }
+}
+
+void Emitter::FlowMapPrepareLongKey(EmitterNodeType::value child) {
+ const std::size_t lastIndent = m_pState->LastIndent();
+
+ if (!m_pState->HasBegunNode()) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(lastIndent);
+ if (m_pState->CurGroupChildCount() == 0)
+ m_stream << "{ ?";
+ else
+ m_stream << ", ?";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(
+ m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
+ lastIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ assert(false);
+ break;
+ }
+}
+
+void Emitter::FlowMapPrepareLongKeyValue(EmitterNodeType::value child) {
+ const std::size_t lastIndent = m_pState->LastIndent();
+
+ if (!m_pState->HasBegunNode()) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(lastIndent);
+ m_stream << ":";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(
+ m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
+ lastIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ assert(false);
+ break;
+ }
+}
+
+void Emitter::FlowMapPrepareSimpleKey(EmitterNodeType::value child) {
+ const std::size_t lastIndent = m_pState->LastIndent();
+
+ if (!m_pState->HasBegunNode()) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(lastIndent);
+ if (m_pState->CurGroupChildCount() == 0)
+ m_stream << "{";
+ else
+ m_stream << ",";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(
+ m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
+ lastIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ assert(false);
+ break;
+ }
+}
+
+void Emitter::FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child) {
+ const std::size_t lastIndent = m_pState->LastIndent();
+
+ if (!m_pState->HasBegunNode()) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ m_stream << IndentTo(lastIndent);
+ m_stream << ":";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(
+ m_pState->HasBegunContent() || m_pState->CurGroupChildCount() > 0,
+ lastIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ assert(false);
+ break;
+ }
+}
+
+void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) {
+ if (m_pState->CurGroupChildCount() % 2 == 0) {
+ if (m_pState->GetMapKeyFormat() == LongKey)
+ m_pState->SetLongKey();
+ if (child == EmitterNodeType::BlockSeq ||
+ child == EmitterNodeType::BlockMap)
+ m_pState->SetLongKey();
+
+ if (m_pState->CurGroupLongKey())
+ BlockMapPrepareLongKey(child);
+ else
+ BlockMapPrepareSimpleKey(child);
+ } else {
+ if (m_pState->CurGroupLongKey())
+ BlockMapPrepareLongKeyValue(child);
+ else
+ BlockMapPrepareSimpleKeyValue(child);
+ }
+}
+
+void Emitter::BlockMapPrepareLongKey(EmitterNodeType::value child) {
+ const std::size_t curIndent = m_pState->CurIndent();
+ const std::size_t childCount = m_pState->CurGroupChildCount();
+
+ if (child == EmitterNodeType::NoType)
+ return;
+
+ if (!m_pState->HasBegunContent()) {
+ if (childCount > 0) {
+ m_stream << "\n";
+ }
+ if (m_stream.comment()) {
+ m_stream << "\n";
+ }
+ m_stream << IndentTo(curIndent);
+ m_stream << "?";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(true, curIndent + 1);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ break;
+ }
+}
+
+void Emitter::BlockMapPrepareLongKeyValue(EmitterNodeType::value child) {
+ const std::size_t curIndent = m_pState->CurIndent();
+
+ if (child == EmitterNodeType::NoType)
+ return;
+
+ if (!m_pState->HasBegunContent()) {
+ m_stream << "\n";
+ m_stream << IndentTo(curIndent);
+ m_stream << ":";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ SpaceOrIndentTo(true, curIndent + 1);
+ break;
+ }
+}
+
+void Emitter::BlockMapPrepareSimpleKey(EmitterNodeType::value child) {
+ const std::size_t curIndent = m_pState->CurIndent();
+ const std::size_t childCount = m_pState->CurGroupChildCount();
+
+ if (child == EmitterNodeType::NoType)
+ return;
+
+ if (!m_pState->HasBegunNode()) {
+ if (childCount > 0) {
+ m_stream << "\n";
+ }
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(m_pState->HasBegunContent(), curIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ break;
+ }
+}
+
+void Emitter::BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child) {
+ const std::size_t curIndent = m_pState->CurIndent();
+ const std::size_t nextIndent = curIndent + m_pState->CurGroupIndent();
+
+ if (!m_pState->HasBegunNode()) {
+ m_stream << ":";
+ }
+
+ switch (child) {
+ case EmitterNodeType::NoType:
+ break;
+ case EmitterNodeType::Property:
+ case EmitterNodeType::Scalar:
+ case EmitterNodeType::FlowSeq:
+ case EmitterNodeType::FlowMap:
+ SpaceOrIndentTo(true, nextIndent);
+ break;
+ case EmitterNodeType::BlockSeq:
+ case EmitterNodeType::BlockMap:
+ m_stream << "\n";
+ break;
+ }
+}
+
+// SpaceOrIndentTo
+// . Prepares for some more content by proper spacing
+void Emitter::SpaceOrIndentTo(bool requireSpace, std::size_t indent) {
+ if (m_stream.comment())
+ m_stream << "\n";
+ if (m_stream.col() > 0 && requireSpace)
+ m_stream << " ";
+ m_stream << IndentTo(indent);
+}
+
+void Emitter::PrepareIntegralStream(std::stringstream& stream) const {
+
+ switch (m_pState->GetIntFormat()) {
+ case Dec:
+ stream << std::dec;
+ break;
+ case Hex:
+ stream << "0x";
+ stream << std::hex;
+ break;
+ case Oct:
+ stream << "0";
+ stream << std::oct;
+ break;
+ default:
+ assert(false);
+ }
+}
+
+void Emitter::StartedScalar() { m_pState->StartedScalar(); }
+
+// *******************************************************************************************
+// overloads of Write
+
+Emitter& Emitter::Write(const std::string& str) {
+ if (!good())
+ return *this;
+
+ const bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii;
+ const StringFormat::value strFormat =
+ Utils::ComputeStringFormat(str, m_pState->GetStringFormat(),
+ m_pState->CurGroupFlowType(), escapeNonAscii);
+
+ if (strFormat == StringFormat::Literal)
+ m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local);
+
+ PrepareNode(EmitterNodeType::Scalar);
+
+ switch (strFormat) {
+ case StringFormat::Plain:
+ m_stream << str;
+ break;
+ case StringFormat::SingleQuoted:
+ Utils::WriteSingleQuotedString(m_stream, str);
+ break;
+ case StringFormat::DoubleQuoted:
+ Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii);
+ break;
+ case StringFormat::Literal:
+ Utils::WriteLiteralString(m_stream, str,
+ m_pState->CurIndent() + m_pState->GetIndent());
+ break;
+ }
+
+ StartedScalar();
+
+ return *this;
+}
+
+std::size_t Emitter::GetFloatPrecision() const {
+ return m_pState->GetFloatPrecision();
+}
+
+std::size_t Emitter::GetDoublePrecision() const {
+ return m_pState->GetDoublePrecision();
+}
+
+const char* Emitter::ComputeFullBoolName(bool b) const {
+ const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool
+ ? YesNoBool
+ : m_pState->GetBoolFormat());
+ const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat();
+ switch (mainFmt) {
+ case YesNoBool:
+ switch (caseFmt) {
+ case UpperCase:
+ return b ? "YES" : "NO";
+ case CamelCase:
+ return b ? "Yes" : "No";
+ case LowerCase:
+ return b ? "yes" : "no";
+ default:
+ break;
+ }
+ break;
+ case OnOffBool:
+ switch (caseFmt) {
+ case UpperCase:
+ return b ? "ON" : "OFF";
+ case CamelCase:
+ return b ? "On" : "Off";
+ case LowerCase:
+ return b ? "on" : "off";
+ default:
+ break;
+ }
+ break;
+ case TrueFalseBool:
+ switch (caseFmt) {
+ case UpperCase:
+ return b ? "TRUE" : "FALSE";
+ case CamelCase:
+ return b ? "True" : "False";
+ case LowerCase:
+ return b ? "true" : "false";
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return b ? "y" : "n"; // should never get here, but it can't hurt to give
+ // these answers
+}
+
+Emitter& Emitter::Write(bool b) {
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::Scalar);
+
+ const char* name = ComputeFullBoolName(b);
+ if (m_pState->GetBoolLengthFormat() == ShortBool)
+ m_stream << name[0];
+ else
+ m_stream << name;
+
+ StartedScalar();
+
+ return *this;
+}
+
+Emitter& Emitter::Write(char ch) {
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::Scalar);
+ Utils::WriteChar(m_stream, ch);
+ StartedScalar();
+
+ return *this;
+}
+
+Emitter& Emitter::Write(const _Alias& alias) {
+ if (!good())
+ return *this;
+
+ if (m_pState->HasAnchor() || m_pState->HasTag()) {
+ m_pState->SetError(ErrorMsg::INVALID_ALIAS);
+ return *this;
+ }
+
+ PrepareNode(EmitterNodeType::Scalar);
+
+ if (!Utils::WriteAlias(m_stream, alias.content)) {
+ m_pState->SetError(ErrorMsg::INVALID_ALIAS);
+ return *this;
+ }
+
+ StartedScalar();
+
+ return *this;
+}
+
+Emitter& Emitter::Write(const _Anchor& anchor) {
+ if (!good())
+ return *this;
+
+ if (m_pState->HasAnchor()) {
+ m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
+ return *this;
+ }
+
+ PrepareNode(EmitterNodeType::Property);
+
+ if (!Utils::WriteAnchor(m_stream, anchor.content)) {
+ m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
+ return *this;
+ }
+
+ m_pState->SetAnchor();
+
+ return *this;
+}
+
+Emitter& Emitter::Write(const _Tag& tag) {
+ if (!good())
+ return *this;
+
+ if (m_pState->HasTag()) {
+ m_pState->SetError(ErrorMsg::INVALID_TAG);
+ return *this;
+ }
+
+ PrepareNode(EmitterNodeType::Property);
+
+ bool success = false;
+ if (tag.type == _Tag::Type::Verbatim)
+ success = Utils::WriteTag(m_stream, tag.content, true);
+ else if (tag.type == _Tag::Type::PrimaryHandle)
+ success = Utils::WriteTag(m_stream, tag.content, false);
+ else
+ success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content);
+
+ if (!success) {
+ m_pState->SetError(ErrorMsg::INVALID_TAG);
+ return *this;
+ }
+
+ m_pState->SetTag();
+
+ return *this;
+}
+
+void Emitter::EmitKindTag() { Write(LocalTag("")); }
+
+Emitter& Emitter::Write(const _Comment& comment) {
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::NoType);
+
+ if (m_stream.col() > 0)
+ m_stream << Indentation(m_pState->GetPreCommentIndent());
+ Utils::WriteComment(m_stream, comment.content,
+ m_pState->GetPostCommentIndent());
+
+ m_pState->SetNonContent();
+
+ return *this;
+}
+
+Emitter& Emitter::Write(const _Null& /*null*/) {
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::Scalar);
+
+ m_stream << "~";
+
+ StartedScalar();
+
+ return *this;
+}
+
+Emitter& Emitter::Write(const Binary& binary) {
+ Write(SecondaryTag("binary"));
+
+ if (!good())
+ return *this;
+
+ PrepareNode(EmitterNodeType::Scalar);
+ Utils::WriteBinary(m_stream, binary);
+ StartedScalar();
+
+ return *this;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp b/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp
new file mode 100644
index 0000000000..3542aaf507
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterstate.cpp
@@ -0,0 +1,365 @@
+#include <limits>
+
+#include "emitterstate.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+
+namespace YAML {
+EmitterState::EmitterState()
+ : m_isGood(true),
+ m_curIndent(0),
+ m_hasAnchor(false),
+ m_hasTag(false),
+ m_hasNonContent(false),
+ m_docCount(0) {
+ // set default global manipulators
+ m_charset.set(EmitNonAscii);
+ m_strFmt.set(Auto);
+ m_boolFmt.set(TrueFalseBool);
+ m_boolLengthFmt.set(LongBool);
+ m_boolCaseFmt.set(LowerCase);
+ m_intFmt.set(Dec);
+ m_indent.set(2);
+ m_preCommentIndent.set(2);
+ m_postCommentIndent.set(1);
+ m_seqFmt.set(Block);
+ m_mapFmt.set(Block);
+ m_mapKeyFmt.set(Auto);
+ m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
+ m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
+}
+
+EmitterState::~EmitterState() {}
+
+// SetLocalValue
+// . We blindly tries to set all possible formatters to this value
+// . Only the ones that make sense will be accepted
+void EmitterState::SetLocalValue(EMITTER_MANIP value) {
+ SetOutputCharset(value, FmtScope::Local);
+ SetStringFormat(value, FmtScope::Local);
+ SetBoolFormat(value, FmtScope::Local);
+ SetBoolCaseFormat(value, FmtScope::Local);
+ SetBoolLengthFormat(value, FmtScope::Local);
+ SetIntFormat(value, FmtScope::Local);
+ SetFlowType(GroupType::Seq, value, FmtScope::Local);
+ SetFlowType(GroupType::Map, value, FmtScope::Local);
+ SetMapKeyFormat(value, FmtScope::Local);
+}
+
+void EmitterState::SetAnchor() { m_hasAnchor = true; }
+
+void EmitterState::SetTag() { m_hasTag = true; }
+
+void EmitterState::SetNonContent() { m_hasNonContent = true; }
+
+void EmitterState::SetLongKey() {
+ assert(!m_groups.empty());
+ if (m_groups.empty()) {
+ return;
+ }
+
+ assert(m_groups.back()->type == GroupType::Map);
+ m_groups.back()->longKey = true;
+}
+
+void EmitterState::ForceFlow() {
+ assert(!m_groups.empty());
+ if (m_groups.empty()) {
+ return;
+ }
+
+ m_groups.back()->flowType = FlowType::Flow;
+}
+
+void EmitterState::StartedNode() {
+ if (m_groups.empty()) {
+ m_docCount++;
+ } else {
+ m_groups.back()->childCount++;
+ if (m_groups.back()->childCount % 2 == 0) {
+ m_groups.back()->longKey = false;
+ }
+ }
+
+ m_hasAnchor = false;
+ m_hasTag = false;
+ m_hasNonContent = false;
+}
+
+EmitterNodeType::value EmitterState::NextGroupType(
+ GroupType::value type) const {
+ if (type == GroupType::Seq) {
+ if (GetFlowType(type) == Block)
+ return EmitterNodeType::BlockSeq;
+ else
+ return EmitterNodeType::FlowSeq;
+ } else {
+ if (GetFlowType(type) == Block)
+ return EmitterNodeType::BlockMap;
+ else
+ return EmitterNodeType::FlowMap;
+ }
+
+ // can't happen
+ assert(false);
+ return EmitterNodeType::NoType;
+}
+
+void EmitterState::StartedDoc() {
+ m_hasAnchor = false;
+ m_hasTag = false;
+ m_hasNonContent = false;
+}
+
+void EmitterState::EndedDoc() {
+ m_hasAnchor = false;
+ m_hasTag = false;
+ m_hasNonContent = false;
+}
+
+void EmitterState::StartedScalar() {
+ StartedNode();
+ ClearModifiedSettings();
+}
+
+void EmitterState::StartedGroup(GroupType::value type) {
+ StartedNode();
+
+ const std::size_t lastGroupIndent =
+ (m_groups.empty() ? 0 : m_groups.back()->indent);
+ m_curIndent += lastGroupIndent;
+
+ // TODO: Create move constructors for settings types to simplify transfer
+ std::unique_ptr<Group> pGroup(new Group(type));
+
+ // transfer settings (which last until this group is done)
+ //
+ // NB: if pGroup->modifiedSettings == m_modifiedSettings,
+ // m_modifiedSettings is not changed!
+ pGroup->modifiedSettings = std::move(m_modifiedSettings);
+
+ // set up group
+ if (GetFlowType(type) == Block) {
+ pGroup->flowType = FlowType::Block;
+ } else {
+ pGroup->flowType = FlowType::Flow;
+ }
+ pGroup->indent = GetIndent();
+
+ m_groups.push_back(std::move(pGroup));
+}
+
+void EmitterState::EndedGroup(GroupType::value type) {
+ if (m_groups.empty()) {
+ if (type == GroupType::Seq) {
+ return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
+ } else {
+ return SetError(ErrorMsg::UNEXPECTED_END_MAP);
+ }
+ }
+
+ // get rid of the current group
+ {
+ std::unique_ptr<Group> pFinishedGroup = std::move(m_groups.back());
+ m_groups.pop_back();
+ if (pFinishedGroup->type != type) {
+ return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
+ }
+ }
+
+ // reset old settings
+ std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent);
+ assert(m_curIndent >= lastIndent);
+ m_curIndent -= lastIndent;
+
+ // some global settings that we changed may have been overridden
+ // by a local setting we just popped, so we need to restore them
+ m_globalModifiedSettings.restore();
+
+ ClearModifiedSettings();
+}
+
+EmitterNodeType::value EmitterState::CurGroupNodeType() const {
+ if (m_groups.empty()) {
+ return EmitterNodeType::NoType;
+ }
+
+ return m_groups.back()->NodeType();
+}
+
+GroupType::value EmitterState::CurGroupType() const {
+ return m_groups.empty() ? GroupType::NoType : m_groups.back()->type;
+}
+
+FlowType::value EmitterState::CurGroupFlowType() const {
+ return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType;
+}
+
+std::size_t EmitterState::CurGroupIndent() const {
+ return m_groups.empty() ? 0 : m_groups.back()->indent;
+}
+
+std::size_t EmitterState::CurGroupChildCount() const {
+ return m_groups.empty() ? m_docCount : m_groups.back()->childCount;
+}
+
+bool EmitterState::CurGroupLongKey() const {
+ return m_groups.empty() ? false : m_groups.back()->longKey;
+}
+
+std::size_t EmitterState::LastIndent() const {
+ if (m_groups.size() <= 1) {
+ return 0;
+ }
+
+ return m_curIndent - m_groups[m_groups.size() - 2]->indent;
+}
+
+void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
+
+bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
+ FmtScope::value scope) {
+ switch (value) {
+ case EmitNonAscii:
+ case EscapeNonAscii:
+ _Set(m_charset, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
+ switch (value) {
+ case Auto:
+ case SingleQuoted:
+ case DoubleQuoted:
+ case Literal:
+ _Set(m_strFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
+ switch (value) {
+ case OnOffBool:
+ case TrueFalseBool:
+ case YesNoBool:
+ _Set(m_boolFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
+ FmtScope::value scope) {
+ switch (value) {
+ case LongBool:
+ case ShortBool:
+ _Set(m_boolLengthFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
+ FmtScope::value scope) {
+ switch (value) {
+ case UpperCase:
+ case LowerCase:
+ case CamelCase:
+ _Set(m_boolCaseFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
+ switch (value) {
+ case Dec:
+ case Hex:
+ case Oct:
+ _Set(m_intFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) {
+ if (value <= 1)
+ return false;
+
+ _Set(m_indent, value, scope);
+ return true;
+}
+
+bool EmitterState::SetPreCommentIndent(std::size_t value,
+ FmtScope::value scope) {
+ if (value == 0)
+ return false;
+
+ _Set(m_preCommentIndent, value, scope);
+ return true;
+}
+
+bool EmitterState::SetPostCommentIndent(std::size_t value,
+ FmtScope::value scope) {
+ if (value == 0)
+ return false;
+
+ _Set(m_postCommentIndent, value, scope);
+ return true;
+}
+
+bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
+ FmtScope::value scope) {
+ switch (value) {
+ case Block:
+ case Flow:
+ _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
+ // force flow style if we're currently in a flow
+ if (CurGroupFlowType() == FlowType::Flow)
+ return Flow;
+
+ // otherwise, go with what's asked of us
+ return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
+}
+
+bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
+ switch (value) {
+ case Auto:
+ case LongKey:
+ _Set(m_mapKeyFmt, value, scope);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
+ if (value > std::numeric_limits<float>::digits10 + 1)
+ return false;
+ _Set(m_floatPrecision, value, scope);
+ return true;
+}
+
+bool EmitterState::SetDoublePrecision(std::size_t value,
+ FmtScope::value scope) {
+ if (value > std::numeric_limits<double>::digits10 + 1)
+ return false;
+ _Set(m_doublePrecision, value, scope);
+ return true;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterstate.h b/src/libs/3rdparty/yaml-cpp/src/emitterstate.h
new file mode 100644
index 0000000000..0937f000d9
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterstate.h
@@ -0,0 +1,203 @@
+#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "setting.h"
+#include "yaml-cpp/emitterdef.h"
+#include "yaml-cpp/emittermanip.h"
+
+#include <cassert>
+#include <memory>
+#include <stack>
+#include <stdexcept>
+#include <vector>
+
+namespace YAML {
+struct FmtScope {
+ enum value { Local, Global };
+};
+struct GroupType {
+ enum value { NoType, Seq, Map };
+};
+struct FlowType {
+ enum value { NoType, Flow, Block };
+};
+
+class EmitterState {
+ public:
+ EmitterState();
+ ~EmitterState();
+
+ // basic state checking
+ bool good() const { return m_isGood; }
+ const std::string GetLastError() const { return m_lastError; }
+ void SetError(const std::string& error) {
+ m_isGood = false;
+ m_lastError = error;
+ }
+
+ // node handling
+ void SetAnchor();
+ void SetTag();
+ void SetNonContent();
+ void SetLongKey();
+ void ForceFlow();
+ void StartedDoc();
+ void EndedDoc();
+ void StartedScalar();
+ void StartedGroup(GroupType::value type);
+ void EndedGroup(GroupType::value type);
+
+ EmitterNodeType::value NextGroupType(GroupType::value type) const;
+ EmitterNodeType::value CurGroupNodeType() const;
+
+ GroupType::value CurGroupType() const;
+ FlowType::value CurGroupFlowType() const;
+ std::size_t CurGroupIndent() const;
+ std::size_t CurGroupChildCount() const;
+ bool CurGroupLongKey() const;
+
+ std::size_t LastIndent() const;
+ std::size_t CurIndent() const { return m_curIndent; }
+ bool HasAnchor() const { return m_hasAnchor; }
+ bool HasTag() const { return m_hasTag; }
+ bool HasBegunNode() const {
+ return m_hasAnchor || m_hasTag || m_hasNonContent;
+ }
+ bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
+
+ void ClearModifiedSettings();
+
+ // formatters
+ void SetLocalValue(EMITTER_MANIP value);
+
+ bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
+
+ bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
+
+ bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
+
+ bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
+
+ bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
+
+ bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
+
+ bool SetIndent(std::size_t value, FmtScope::value scope);
+ std::size_t GetIndent() const { return m_indent.get(); }
+
+ bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
+ std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
+ bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
+ std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
+
+ bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
+ FmtScope::value scope);
+ EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
+
+ bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
+ EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
+
+ bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
+ std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
+ bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
+ std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
+
+ private:
+ template <typename T>
+ void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
+
+ void StartedNode();
+
+ private:
+ // basic state ok?
+ bool m_isGood;
+ std::string m_lastError;
+
+ // other state
+ Setting<EMITTER_MANIP> m_charset;
+ Setting<EMITTER_MANIP> m_strFmt;
+ Setting<EMITTER_MANIP> m_boolFmt;
+ Setting<EMITTER_MANIP> m_boolLengthFmt;
+ Setting<EMITTER_MANIP> m_boolCaseFmt;
+ Setting<EMITTER_MANIP> m_intFmt;
+ Setting<std::size_t> m_indent;
+ Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
+ Setting<EMITTER_MANIP> m_seqFmt;
+ Setting<EMITTER_MANIP> m_mapFmt;
+ Setting<EMITTER_MANIP> m_mapKeyFmt;
+ Setting<std::size_t> m_floatPrecision;
+ Setting<std::size_t> m_doublePrecision;
+
+ SettingChanges m_modifiedSettings;
+ SettingChanges m_globalModifiedSettings;
+
+ struct Group {
+ explicit Group(GroupType::value type_)
+ : type(type_), indent(0), childCount(0), longKey(false) {}
+
+ GroupType::value type;
+ FlowType::value flowType;
+ std::size_t indent;
+ std::size_t childCount;
+ bool longKey;
+
+ SettingChanges modifiedSettings;
+
+ EmitterNodeType::value NodeType() const {
+ if (type == GroupType::Seq) {
+ if (flowType == FlowType::Flow)
+ return EmitterNodeType::FlowSeq;
+ else
+ return EmitterNodeType::BlockSeq;
+ } else {
+ if (flowType == FlowType::Flow)
+ return EmitterNodeType::FlowMap;
+ else
+ return EmitterNodeType::BlockMap;
+ }
+
+ // can't get here
+ assert(false);
+ return EmitterNodeType::NoType;
+ }
+ };
+
+ std::vector<std::unique_ptr<Group>> m_groups;
+ std::size_t m_curIndent;
+ bool m_hasAnchor;
+ bool m_hasTag;
+ bool m_hasNonContent;
+ std::size_t m_docCount;
+};
+
+template <typename T>
+void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
+ switch (scope) {
+ case FmtScope::Local:
+ m_modifiedSettings.push(fmt.set(value));
+ break;
+ case FmtScope::Global:
+ fmt.set(value);
+ m_globalModifiedSettings.push(
+ fmt.set(value)); // this pushes an identity set, so when we restore,
+ // it restores to the value here, and not the previous one
+ break;
+ default:
+ assert(false);
+ }
+}
+}
+
+#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp b/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp
new file mode 100644
index 0000000000..147738ad8a
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterutils.cpp
@@ -0,0 +1,483 @@
+#include <iomanip>
+#include <sstream>
+
+#include "emitterutils.h"
+#include "exp.h"
+#include "indentation.h"
+#include "regex_yaml.h"
+#include "regeximpl.h"
+#include "stringsource.h"
+#include "yaml-cpp/binary.h" // IWYU pragma: keep
+#include "yaml-cpp/ostream_wrapper.h"
+#include "yaml-cpp/null.h"
+
+namespace YAML {
+namespace Utils {
+namespace {
+enum { REPLACEMENT_CHARACTER = 0xFFFD };
+
+bool IsAnchorChar(int ch) { // test for ns-anchor-char
+ switch (ch) {
+ case ',':
+ case '[':
+ case ']':
+ case '{':
+ case '}': // c-flow-indicator
+ case ' ':
+ case '\t': // s-white
+ case 0xFEFF: // c-byte-order-mark
+ case 0xA:
+ case 0xD: // b-char
+ return false;
+ case 0x85:
+ return true;
+ }
+
+ if (ch < 0x20) {
+ return false;
+ }
+
+ if (ch < 0x7E) {
+ return true;
+ }
+
+ if (ch < 0xA0) {
+ return false;
+ }
+ if (ch >= 0xD800 && ch <= 0xDFFF) {
+ return false;
+ }
+ if ((ch & 0xFFFE) == 0xFFFE) {
+ return false;
+ }
+ if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) {
+ return false;
+ }
+ if (ch > 0x10FFFF) {
+ return false;
+ }
+
+ return true;
+}
+
+int Utf8BytesIndicated(char ch) {
+ int byteVal = static_cast<unsigned char>(ch);
+ switch (byteVal >> 4) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ return 1;
+ case 12:
+ case 13:
+ return 2;
+ case 14:
+ return 3;
+ case 15:
+ return 4;
+ default:
+ return -1;
+ }
+}
+
+bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; }
+
+bool GetNextCodePointAndAdvance(int& codePoint,
+ std::string::const_iterator& first,
+ std::string::const_iterator last) {
+ if (first == last)
+ return false;
+
+ int nBytes = Utf8BytesIndicated(*first);
+ if (nBytes < 1) {
+ // Bad lead byte
+ ++first;
+ codePoint = REPLACEMENT_CHARACTER;
+ return true;
+ }
+
+ if (nBytes == 1) {
+ codePoint = *first++;
+ return true;
+ }
+
+ // Gather bits from trailing bytes
+ codePoint = static_cast<unsigned char>(*first) & ~(0xFF << (7 - nBytes));
+ ++first;
+ --nBytes;
+ for (; nBytes > 0; ++first, --nBytes) {
+ if ((first == last) || !IsTrailingByte(*first)) {
+ codePoint = REPLACEMENT_CHARACTER;
+ break;
+ }
+ codePoint <<= 6;
+ codePoint |= *first & 0x3F;
+ }
+
+ // Check for illegal code points
+ if (codePoint > 0x10FFFF)
+ codePoint = REPLACEMENT_CHARACTER;
+ else if (codePoint >= 0xD800 && codePoint <= 0xDFFF)
+ codePoint = REPLACEMENT_CHARACTER;
+ else if ((codePoint & 0xFFFE) == 0xFFFE)
+ codePoint = REPLACEMENT_CHARACTER;
+ else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
+ codePoint = REPLACEMENT_CHARACTER;
+ return true;
+}
+
+void WriteCodePoint(ostream_wrapper& out, int codePoint) {
+ if (codePoint < 0 || codePoint > 0x10FFFF) {
+ codePoint = REPLACEMENT_CHARACTER;
+ }
+ if (codePoint < 0x7F) {
+ out << static_cast<char>(codePoint);
+ } else if (codePoint < 0x7FF) {
+ out << static_cast<char>(0xC0 | (codePoint >> 6))
+ << static_cast<char>(0x80 | (codePoint & 0x3F));
+ } else if (codePoint < 0xFFFF) {
+ out << static_cast<char>(0xE0 | (codePoint >> 12))
+ << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
+ << static_cast<char>(0x80 | (codePoint & 0x3F));
+ } else {
+ out << static_cast<char>(0xF0 | (codePoint >> 18))
+ << static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F))
+ << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
+ << static_cast<char>(0x80 | (codePoint & 0x3F));
+ }
+}
+
+bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
+ bool allowOnlyAscii) {
+ // check against null
+ if (IsNullString(str)) {
+ return false;
+ }
+
+ // check the start
+ const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow()
+ : Exp::PlainScalar());
+ if (!start.Matches(str)) {
+ return false;
+ }
+
+ // and check the end for plain whitespace (which can't be faithfully kept in a
+ // plain scalar)
+ if (!str.empty() && *str.rbegin() == ' ') {
+ return false;
+ }
+
+ // then check until something is disallowed
+ static const RegEx& disallowed_flow =
+ Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) ||
+ Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
+ Exp::Tab();
+ static const RegEx& disallowed_block =
+ Exp::EndScalar() || (Exp::BlankOrBreak() + Exp::Comment()) ||
+ Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
+ Exp::Tab();
+ const RegEx& disallowed =
+ flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
+
+ StringCharSource buffer(str.c_str(), str.size());
+ while (buffer) {
+ if (disallowed.Matches(buffer)) {
+ return false;
+ }
+ if (allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0]))) {
+ return false;
+ }
+ ++buffer;
+ }
+
+ return true;
+}
+
+bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
+ // TODO: check for non-printable characters?
+ for (std::size_t i = 0; i < str.size(); i++) {
+ if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
+ return false;
+ }
+ if (str[i] == '\n') {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
+ bool escapeNonAscii) {
+ if (flowType == FlowType::Flow) {
+ return false;
+ }
+
+ // TODO: check for non-printable characters?
+ for (std::size_t i = 0; i < str.size(); i++) {
+ if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
+ static const char hexDigits[] = "0123456789abcdef";
+
+ out << "\\";
+ int digits = 8;
+ if (codePoint < 0xFF) {
+ out << "x";
+ digits = 2;
+ } else if (codePoint < 0xFFFF) {
+ out << "u";
+ digits = 4;
+ } else {
+ out << "U";
+ digits = 8;
+ }
+
+ // Write digits into the escape sequence
+ for (; digits > 0; --digits)
+ out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
+}
+
+bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
+ int codePoint;
+ for (std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());) {
+ if (!IsAnchorChar(codePoint)) {
+ return false;
+ }
+
+ WriteCodePoint(out, codePoint);
+ }
+ return true;
+}
+}
+
+StringFormat::value ComputeStringFormat(const std::string& str,
+ EMITTER_MANIP strFormat,
+ FlowType::value flowType,
+ bool escapeNonAscii) {
+ switch (strFormat) {
+ case Auto:
+ if (IsValidPlainScalar(str, flowType, escapeNonAscii)) {
+ return StringFormat::Plain;
+ }
+ return StringFormat::DoubleQuoted;
+ case SingleQuoted:
+ if (IsValidSingleQuotedScalar(str, escapeNonAscii)) {
+ return StringFormat::SingleQuoted;
+ }
+ return StringFormat::DoubleQuoted;
+ case DoubleQuoted:
+ return StringFormat::DoubleQuoted;
+ case Literal:
+ if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) {
+ return StringFormat::Literal;
+ }
+ return StringFormat::DoubleQuoted;
+ default:
+ break;
+ }
+
+ return StringFormat::DoubleQuoted;
+}
+
+bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
+ out << "'";
+ int codePoint;
+ for (std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());) {
+ if (codePoint == '\n') {
+ return false; // We can't handle a new line and the attendant indentation
+ // yet
+ }
+
+ if (codePoint == '\'') {
+ out << "''";
+ } else {
+ WriteCodePoint(out, codePoint);
+ }
+ }
+ out << "'";
+ return true;
+}
+
+bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
+ bool escapeNonAscii) {
+ out << "\"";
+ int codePoint;
+ for (std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());) {
+ switch (codePoint) {
+ case '\"':
+ out << "\\\"";
+ break;
+ case '\\':
+ out << "\\\\";
+ break;
+ case '\n':
+ out << "\\n";
+ break;
+ case '\t':
+ out << "\\t";
+ break;
+ case '\r':
+ out << "\\r";
+ break;
+ case '\b':
+ out << "\\b";
+ break;
+ default:
+ if (codePoint < 0x20 ||
+ (codePoint >= 0x80 &&
+ codePoint <= 0xA0)) { // Control characters and non-breaking space
+ WriteDoubleQuoteEscapeSequence(out, codePoint);
+ } else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be
+ // escaped (YAML 1.2, sec. 5.2)
+ WriteDoubleQuoteEscapeSequence(out, codePoint);
+ } else if (escapeNonAscii && codePoint > 0x7E) {
+ WriteDoubleQuoteEscapeSequence(out, codePoint);
+ } else {
+ WriteCodePoint(out, codePoint);
+ }
+ }
+ }
+ out << "\"";
+ return true;
+}
+
+bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
+ std::size_t indent) {
+ out << "|\n";
+ out << IndentTo(indent);
+ int codePoint;
+ for (std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());) {
+ if (codePoint == '\n') {
+ out << "\n" << IndentTo(indent);
+ } else {
+ WriteCodePoint(out, codePoint);
+ }
+ }
+ return true;
+}
+
+bool WriteChar(ostream_wrapper& out, char ch) {
+ if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
+ out << ch;
+ } else if (ch == '\"') {
+ out << "\"\\\"\"";
+ } else if (ch == '\t') {
+ out << "\"\\t\"";
+ } else if (ch == '\n') {
+ out << "\"\\n\"";
+ } else if (ch == '\b') {
+ out << "\"\\b\"";
+ } else if (ch == '\\') {
+ out << "\"\\\\\"";
+ } else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ') {
+ out << "\"" << ch << "\"";
+ } else {
+ out << "\"";
+ WriteDoubleQuoteEscapeSequence(out, ch);
+ out << "\"";
+ }
+ return true;
+}
+
+bool WriteComment(ostream_wrapper& out, const std::string& str,
+ std::size_t postCommentIndent) {
+ const std::size_t curIndent = out.col();
+ out << "#" << Indentation(postCommentIndent);
+ out.set_comment();
+ int codePoint;
+ for (std::string::const_iterator i = str.begin();
+ GetNextCodePointAndAdvance(codePoint, i, str.end());) {
+ if (codePoint == '\n') {
+ out << "\n" << IndentTo(curIndent) << "#"
+ << Indentation(postCommentIndent);
+ out.set_comment();
+ } else {
+ WriteCodePoint(out, codePoint);
+ }
+ }
+ return true;
+}
+
+bool WriteAlias(ostream_wrapper& out, const std::string& str) {
+ out << "*";
+ return WriteAliasName(out, str);
+}
+
+bool WriteAnchor(ostream_wrapper& out, const std::string& str) {
+ out << "&";
+ return WriteAliasName(out, str);
+}
+
+bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
+ out << (verbatim ? "!<" : "!");
+ StringCharSource buffer(str.c_str(), str.size());
+ const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
+ while (buffer) {
+ int n = reValid.Match(buffer);
+ if (n <= 0) {
+ return false;
+ }
+
+ while (--n >= 0) {
+ out << buffer[0];
+ ++buffer;
+ }
+ }
+ if (verbatim) {
+ out << ">";
+ }
+ return true;
+}
+
+bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
+ const std::string& tag) {
+ out << "!";
+ StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
+ while (prefixBuffer) {
+ int n = Exp::URI().Match(prefixBuffer);
+ if (n <= 0) {
+ return false;
+ }
+
+ while (--n >= 0) {
+ out << prefixBuffer[0];
+ ++prefixBuffer;
+ }
+ }
+
+ out << "!";
+ StringCharSource tagBuffer(tag.c_str(), tag.size());
+ while (tagBuffer) {
+ int n = Exp::Tag().Match(tagBuffer);
+ if (n <= 0) {
+ return false;
+ }
+
+ while (--n >= 0) {
+ out << tagBuffer[0];
+ ++tagBuffer;
+ }
+ }
+ return true;
+}
+
+bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
+ WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
+ false);
+ return true;
+}
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/emitterutils.h b/src/libs/3rdparty/yaml-cpp/src/emitterutils.h
new file mode 100644
index 0000000000..6cc7319147
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/emitterutils.h
@@ -0,0 +1,50 @@
+#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+#include "emitterstate.h"
+#include "yaml-cpp/emittermanip.h"
+#include "yaml-cpp/ostream_wrapper.h"
+
+namespace YAML {
+class ostream_wrapper;
+} // namespace YAML
+
+namespace YAML {
+class Binary;
+
+struct StringFormat {
+ enum value { Plain, SingleQuoted, DoubleQuoted, Literal };
+};
+
+namespace Utils {
+StringFormat::value ComputeStringFormat(const std::string& str,
+ EMITTER_MANIP strFormat,
+ FlowType::value flowType,
+ bool escapeNonAscii);
+
+bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
+bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
+ bool escapeNonAscii);
+bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
+ std::size_t indent);
+bool WriteChar(ostream_wrapper& out, char ch);
+bool WriteComment(ostream_wrapper& out, const std::string& str,
+ std::size_t postCommentIndent);
+bool WriteAlias(ostream_wrapper& out, const std::string& str);
+bool WriteAnchor(ostream_wrapper& out, const std::string& str);
+bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim);
+bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
+ const std::string& tag);
+bool WriteBinary(ostream_wrapper& out, const Binary& binary);
+}
+}
+
+#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
new file mode 100644
index 0000000000..d5e10b23c1
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/exceptions.cpp
@@ -0,0 +1,25 @@
+#include "yaml-cpp/exceptions.h"
+
+#define YAML_CPP_NOEXCEPT noexcept
+
+namespace YAML {
+
+// These destructors are defined out-of-line so the vtable is only emitted once.
+Exception::~Exception() YAML_CPP_NOEXCEPT {}
+ParserException::~ParserException() YAML_CPP_NOEXCEPT {}
+RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT {}
+InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT {}
+KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT {}
+InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT {}
+BadConversion::~BadConversion() YAML_CPP_NOEXCEPT {}
+BadDereference::~BadDereference() YAML_CPP_NOEXCEPT {}
+BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT {}
+BadPushback::~BadPushback() YAML_CPP_NOEXCEPT {}
+BadInsert::~BadInsert() YAML_CPP_NOEXCEPT {}
+EmitterException::~EmitterException() YAML_CPP_NOEXCEPT {}
+BadFile::~BadFile() YAML_CPP_NOEXCEPT {}
+}
+
+#undef YAML_CPP_NOEXCEPT
+
+
diff --git a/src/libs/3rdparty/yaml-cpp/src/exp.cpp b/src/libs/3rdparty/yaml-cpp/src/exp.cpp
new file mode 100644
index 0000000000..695440aec0
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/exp.cpp
@@ -0,0 +1,136 @@
+#include <sstream>
+
+#include "exp.h"
+#include "stream.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+
+namespace YAML {
+struct Mark;
+} // namespace YAML
+
+namespace YAML {
+namespace Exp {
+unsigned ParseHex(const std::string& str, const Mark& mark) {
+ unsigned value = 0;
+ for (std::size_t i = 0; i < str.size(); i++) {
+ char ch = str[i];
+ int digit = 0;
+ if ('a' <= ch && ch <= 'f')
+ digit = ch - 'a' + 10;
+ else if ('A' <= ch && ch <= 'F')
+ digit = ch - 'A' + 10;
+ else if ('0' <= ch && ch <= '9')
+ digit = ch - '0';
+ else
+ throw ParserException(mark, ErrorMsg::INVALID_HEX);
+
+ value = (value << 4) + digit;
+ }
+
+ return value;
+}
+
+std::string Str(unsigned ch) { return std::string(1, static_cast<char>(ch)); }
+
+// Escape
+// . Translates the next 'codeLength' characters into a hex number and returns
+// the result.
+// . Throws if it's not actually hex.
+std::string Escape(Stream& in, int codeLength) {
+ // grab string
+ std::string str;
+ for (int i = 0; i < codeLength; i++)
+ str += in.get();
+
+ // get the value
+ unsigned value = ParseHex(str, in.mark());
+
+ // legal unicode?
+ if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
+ std::stringstream msg;
+ msg << ErrorMsg::INVALID_UNICODE << value;
+ throw ParserException(in.mark(), msg.str());
+ }
+
+ // now break it up into chars
+ if (value <= 0x7F)
+ return Str(value);
+ else if (value <= 0x7FF)
+ return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
+ else if (value <= 0xFFFF)
+ return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) +
+ Str(0x80 + (value & 0x3F));
+ else
+ return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
+ Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
+}
+
+// Escape
+// . Escapes the sequence starting 'in' (it must begin with a '\' or single
+// quote)
+// and returns the result.
+// . Throws if it's an unknown escape character.
+std::string Escape(Stream& in) {
+ // eat slash
+ char escape = in.get();
+
+ // switch on escape character
+ char ch = in.get();
+
+ // first do single quote, since it's easier
+ if (escape == '\'' && ch == '\'')
+ return "\'";
+
+ // now do the slash (we're not gonna check if it's a slash - you better pass
+ // one!)
+ switch (ch) {
+ case '0':
+ return std::string(1, '\x00');
+ case 'a':
+ return "\x07";
+ case 'b':
+ return "\x08";
+ case 't':
+ case '\t':
+ return "\x09";
+ case 'n':
+ return "\x0A";
+ case 'v':
+ return "\x0B";
+ case 'f':
+ return "\x0C";
+ case 'r':
+ return "\x0D";
+ case 'e':
+ return "\x1B";
+ case ' ':
+ return "\x20";
+ case '\"':
+ return "\"";
+ case '\'':
+ return "\'";
+ case '\\':
+ return "\\";
+ case '/':
+ return "/";
+ case 'N':
+ return "\x85";
+ case '_':
+ return "\xA0";
+ case 'L':
+ return "\xE2\x80\xA8"; // LS (#x2028)
+ case 'P':
+ return "\xE2\x80\xA9"; // PS (#x2029)
+ case 'x':
+ return Escape(in, 2);
+ case 'u':
+ return Escape(in, 4);
+ case 'U':
+ return Escape(in, 8);
+ }
+
+ std::stringstream msg;
+ throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
+}
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/exp.h b/src/libs/3rdparty/yaml-cpp/src/exp.h
new file mode 100644
index 0000000000..7c02cf6e45
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/exp.h
@@ -0,0 +1,222 @@
+#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <ios>
+#include <string>
+
+#include "regex_yaml.h"
+#include "stream.h"
+
+namespace YAML {
+////////////////////////////////////////////////////////////////////////////////
+// Here we store a bunch of expressions for matching different parts of the
+// file.
+
+namespace Exp {
+// misc
+inline const RegEx& Empty() {
+ static const RegEx e;
+ return e;
+}
+inline const RegEx& Space() {
+ static const RegEx e = RegEx(' ');
+ return e;
+}
+inline const RegEx& Tab() {
+ static const RegEx e = RegEx('\t');
+ return e;
+}
+inline const RegEx& Blank() {
+ static const RegEx e = Space() || Tab();
+ return e;
+}
+inline const RegEx& Break() {
+ static const RegEx e = RegEx('\n') || RegEx("\r\n");
+ return e;
+}
+inline const RegEx& BlankOrBreak() {
+ static const RegEx e = Blank() || Break();
+ return e;
+}
+inline const RegEx& Digit() {
+ static const RegEx e = RegEx('0', '9');
+ return e;
+}
+inline const RegEx& Alpha() {
+ static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
+ return e;
+}
+inline const RegEx& AlphaNumeric() {
+ static const RegEx e = Alpha() || Digit();
+ return e;
+}
+inline const RegEx& Word() {
+ static const RegEx e = AlphaNumeric() || RegEx('-');
+ return e;
+}
+inline const RegEx& Hex() {
+ static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
+ return e;
+}
+// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
+// 5.1)
+inline const RegEx& NotPrintable() {
+ static const RegEx e =
+ RegEx(0) ||
+ RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
+ RegEx(0x0E, 0x1F) ||
+ (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
+ return e;
+}
+inline const RegEx& Utf8_ByteOrderMark() {
+ static const RegEx e = RegEx("\xEF\xBB\xBF");
+ return e;
+}
+
+// actual tags
+
+inline const RegEx& DocStart() {
+ static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
+ return e;
+}
+inline const RegEx& DocEnd() {
+ static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
+ return e;
+}
+inline const RegEx& DocIndicator() {
+ static const RegEx e = DocStart() || DocEnd();
+ return e;
+}
+inline const RegEx& BlockEntry() {
+ static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
+ return e;
+}
+inline const RegEx& Key() {
+ static const RegEx e = RegEx('?') + BlankOrBreak();
+ return e;
+}
+inline const RegEx& KeyInFlow() {
+ static const RegEx e = RegEx('?') + BlankOrBreak();
+ return e;
+}
+inline const RegEx& Value() {
+ static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
+ return e;
+}
+inline const RegEx& ValueInFlow() {
+ static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
+ return e;
+}
+inline const RegEx& ValueInJSONFlow() {
+ static const RegEx e = RegEx(':');
+ return e;
+}
+inline const RegEx Comment() {
+ static const RegEx e = RegEx('#');
+ return e;
+}
+inline const RegEx& Anchor() {
+ static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
+ return e;
+}
+inline const RegEx& AnchorEnd() {
+ static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
+ return e;
+}
+inline const RegEx& URI() {
+ static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) ||
+ (RegEx('%') + Hex() + Hex());
+ return e;
+}
+inline const RegEx& Tag() {
+ static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) ||
+ (RegEx('%') + Hex() + Hex());
+ return e;
+}
+
+// Plain scalar rules:
+// . Cannot start with a blank.
+// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
+// . In the block context - ? : must be not be followed with a space.
+// . In the flow context ? is illegal and : and - must not be followed with a
+// space.
+inline const RegEx& PlainScalar() {
+ static const RegEx e =
+ !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) ||
+ (RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx())));
+ return e;
+}
+inline const RegEx& PlainScalarInFlow() {
+ static const RegEx e =
+ !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) ||
+ (RegEx("-:", REGEX_OR) + Blank()));
+ return e;
+}
+inline const RegEx& EndScalar() {
+ static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
+ return e;
+}
+inline const RegEx& EndScalarInFlow() {
+ static const RegEx e =
+ (RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) ||
+ RegEx(",?[]{}", REGEX_OR);
+ return e;
+}
+
+inline const RegEx& ScanScalarEndInFlow() {
+ static const RegEx e = (EndScalarInFlow() || (BlankOrBreak() + Comment()));
+ return e;
+}
+
+inline const RegEx& ScanScalarEnd() {
+ static const RegEx e = EndScalar() || (BlankOrBreak() + Comment());
+ return e;
+}
+inline const RegEx& EscSingleQuote() {
+ static const RegEx e = RegEx("\'\'");
+ return e;
+}
+inline const RegEx& EscBreak() {
+ static const RegEx e = RegEx('\\') + Break();
+ return e;
+}
+
+inline const RegEx& ChompIndicator() {
+ static const RegEx e = RegEx("+-", REGEX_OR);
+ return e;
+}
+inline const RegEx& Chomp() {
+ static const RegEx e = (ChompIndicator() + Digit()) ||
+ (Digit() + ChompIndicator()) || ChompIndicator() ||
+ Digit();
+ return e;
+}
+
+// and some functions
+std::string Escape(Stream& in);
+} // namespace Exp
+
+namespace Keys {
+const char Directive = '%';
+const char FlowSeqStart = '[';
+const char FlowSeqEnd = ']';
+const char FlowMapStart = '{';
+const char FlowMapEnd = '}';
+const char FlowEntry = ',';
+const char Alias = '*';
+const char Anchor = '&';
+const char Tag = '!';
+const char LiteralScalar = '|';
+const char FoldedScalar = '>';
+const char VerbatimTagStart = '<';
+const char VerbatimTagEnd = '>';
+} // namespace Keys
+} // namespace YAML
+
+#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/indentation.h b/src/libs/3rdparty/yaml-cpp/src/indentation.h
new file mode 100644
index 0000000000..1a2ccaea2e
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/indentation.h
@@ -0,0 +1,41 @@
+#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <iostream>
+#include <cstddef>
+
+#include "yaml-cpp/ostream_wrapper.h"
+
+namespace YAML {
+struct Indentation {
+ Indentation(std::size_t n_) : n(n_) {}
+ std::size_t n;
+};
+
+inline ostream_wrapper& operator<<(ostream_wrapper& out,
+ const Indentation& indent) {
+ for (std::size_t i = 0; i < indent.n; i++)
+ out << ' ';
+ return out;
+}
+
+struct IndentTo {
+ IndentTo(std::size_t n_) : n(n_) {}
+ std::size_t n;
+};
+
+inline ostream_wrapper& operator<<(ostream_wrapper& out,
+ const IndentTo& indent) {
+ while (out.col() < indent.n)
+ out << ' ';
+ return out;
+}
+}
+
+#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/memory.cpp b/src/libs/3rdparty/yaml-cpp/src/memory.cpp
new file mode 100644
index 0000000000..e5f8a9d3f8
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/memory.cpp
@@ -0,0 +1,26 @@
+#include "yaml-cpp/node/detail/memory.h"
+#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
+#include "yaml-cpp/node/ptr.h"
+
+namespace YAML {
+namespace detail {
+
+void memory_holder::merge(memory_holder& rhs) {
+ if (m_pMemory == rhs.m_pMemory)
+ return;
+
+ m_pMemory->merge(*rhs.m_pMemory);
+ rhs.m_pMemory = m_pMemory;
+}
+
+node& memory::create_node() {
+ shared_node pNode(new node);
+ m_nodes.insert(pNode);
+ return *pNode;
+}
+
+void memory::merge(const memory& rhs) {
+ m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
+}
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/node.cpp b/src/libs/3rdparty/yaml-cpp/src/node.cpp
new file mode 100644
index 0000000000..2088e13c9a
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/node.cpp
@@ -0,0 +1,12 @@
+#include "yaml-cpp/node/node.h"
+#include "nodebuilder.h"
+#include "nodeevents.h"
+
+namespace YAML {
+Node Clone(const Node& node) {
+ NodeEvents events(node);
+ NodeBuilder builder;
+ events.Emit(builder);
+ return builder.Root();
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/node_data.cpp b/src/libs/3rdparty/yaml-cpp/src/node_data.cpp
new file mode 100644
index 0000000000..77cd465780
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/node_data.cpp
@@ -0,0 +1,300 @@
+#include <assert.h>
+#include <iterator>
+#include <sstream>
+
+#include "yaml-cpp/exceptions.h"
+#include "yaml-cpp/node/detail/memory.h"
+#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep
+#include "yaml-cpp/node/detail/node_data.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
+#include "yaml-cpp/node/ptr.h"
+#include "yaml-cpp/node/type.h"
+
+namespace YAML {
+namespace detail {
+
+std::string node_data::empty_scalar;
+
+node_data::node_data()
+ : m_isDefined(false),
+ m_mark(Mark::null_mark()),
+ m_type(NodeType::Null),
+ m_style(EmitterStyle::Default),
+ m_seqSize(0) {}
+
+void node_data::mark_defined() {
+ if (m_type == NodeType::Undefined)
+ m_type = NodeType::Null;
+ m_isDefined = true;
+}
+
+void node_data::set_mark(const Mark& mark) { m_mark = mark; }
+
+void node_data::set_type(NodeType::value type) {
+ if (type == NodeType::Undefined) {
+ m_type = type;
+ m_isDefined = false;
+ return;
+ }
+
+ m_isDefined = true;
+ if (type == m_type)
+ return;
+
+ m_type = type;
+
+ switch (m_type) {
+ case NodeType::Null:
+ break;
+ case NodeType::Scalar:
+ m_scalar.clear();
+ break;
+ case NodeType::Sequence:
+ reset_sequence();
+ break;
+ case NodeType::Map:
+ reset_map();
+ break;
+ case NodeType::Undefined:
+ assert(false);
+ break;
+ }
+}
+
+void node_data::set_tag(const std::string& tag) { m_tag = tag; }
+
+void node_data::set_style(EmitterStyle::value style) { m_style = style; }
+
+void node_data::set_null() {
+ m_isDefined = true;
+ m_type = NodeType::Null;
+}
+
+void node_data::set_scalar(const std::string& scalar) {
+ m_isDefined = true;
+ m_type = NodeType::Scalar;
+ m_scalar = scalar;
+}
+
+// size/iterator
+std::size_t node_data::size() const {
+ if (!m_isDefined)
+ return 0;
+
+ switch (m_type) {
+ case NodeType::Sequence:
+ compute_seq_size();
+ return m_seqSize;
+ case NodeType::Map:
+ compute_map_size();
+ return m_map.size() - m_undefinedPairs.size();
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+void node_data::compute_seq_size() const {
+ while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
+ m_seqSize++;
+}
+
+void node_data::compute_map_size() const {
+ kv_pairs::iterator it = m_undefinedPairs.begin();
+ while (it != m_undefinedPairs.end()) {
+ kv_pairs::iterator jt = std::next(it);
+ if (it->first->is_defined() && it->second->is_defined())
+ m_undefinedPairs.erase(it);
+ it = jt;
+ }
+}
+
+const_node_iterator node_data::begin() const {
+ if (!m_isDefined)
+ return const_node_iterator();
+
+ switch (m_type) {
+ case NodeType::Sequence:
+ return const_node_iterator(m_sequence.begin());
+ case NodeType::Map:
+ return const_node_iterator(m_map.begin(), m_map.end());
+ default:
+ return const_node_iterator();
+ }
+}
+
+node_iterator node_data::begin() {
+ if (!m_isDefined)
+ return node_iterator();
+
+ switch (m_type) {
+ case NodeType::Sequence:
+ return node_iterator(m_sequence.begin());
+ case NodeType::Map:
+ return node_iterator(m_map.begin(), m_map.end());
+ default:
+ return node_iterator();
+ }
+}
+
+const_node_iterator node_data::end() const {
+ if (!m_isDefined)
+ return const_node_iterator();
+
+ switch (m_type) {
+ case NodeType::Sequence:
+ return const_node_iterator(m_sequence.end());
+ case NodeType::Map:
+ return const_node_iterator(m_map.end(), m_map.end());
+ default:
+ return const_node_iterator();
+ }
+}
+
+node_iterator node_data::end() {
+ if (!m_isDefined)
+ return node_iterator();
+
+ switch (m_type) {
+ case NodeType::Sequence:
+ return node_iterator(m_sequence.end());
+ case NodeType::Map:
+ return node_iterator(m_map.end(), m_map.end());
+ default:
+ return node_iterator();
+ }
+}
+
+// sequence
+void node_data::push_back(node& node, shared_memory_holder /* pMemory */) {
+ if (m_type == NodeType::Undefined || m_type == NodeType::Null) {
+ m_type = NodeType::Sequence;
+ reset_sequence();
+ }
+
+ if (m_type != NodeType::Sequence)
+ throw BadPushback();
+
+ m_sequence.push_back(&node);
+}
+
+void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
+ switch (m_type) {
+ case NodeType::Map:
+ break;
+ case NodeType::Undefined:
+ case NodeType::Null:
+ case NodeType::Sequence:
+ convert_to_map(pMemory);
+ break;
+ case NodeType::Scalar:
+ throw BadSubscript();
+ }
+
+ insert_map_pair(key, value);
+}
+
+// indexing
+node* node_data::get(node& key, shared_memory_holder /* pMemory */) const {
+ if (m_type != NodeType::Map) {
+ return NULL;
+ }
+
+ for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
+ if (it->first->is(key))
+ return it->second;
+ }
+
+ return NULL;
+}
+
+node& node_data::get(node& key, shared_memory_holder pMemory) {
+ switch (m_type) {
+ case NodeType::Map:
+ break;
+ case NodeType::Undefined:
+ case NodeType::Null:
+ case NodeType::Sequence:
+ convert_to_map(pMemory);
+ break;
+ case NodeType::Scalar:
+ throw BadSubscript();
+ }
+
+ for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
+ if (it->first->is(key))
+ return *it->second;
+ }
+
+ node& value = pMemory->create_node();
+ insert_map_pair(key, value);
+ return value;
+}
+
+bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
+ if (m_type != NodeType::Map)
+ return false;
+
+ for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
+ if (it->first->is(key)) {
+ m_map.erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void node_data::reset_sequence() {
+ m_sequence.clear();
+ m_seqSize = 0;
+}
+
+void node_data::reset_map() {
+ m_map.clear();
+ m_undefinedPairs.clear();
+}
+
+void node_data::insert_map_pair(node& key, node& value) {
+ m_map.emplace_back(&key, &value);
+
+ if (!key.is_defined() || !value.is_defined())
+ m_undefinedPairs.emplace_back(&key, &value);
+}
+
+void node_data::convert_to_map(shared_memory_holder pMemory) {
+ switch (m_type) {
+ case NodeType::Undefined:
+ case NodeType::Null:
+ reset_map();
+ m_type = NodeType::Map;
+ break;
+ case NodeType::Sequence:
+ convert_sequence_to_map(pMemory);
+ break;
+ case NodeType::Map:
+ break;
+ case NodeType::Scalar:
+ assert(false);
+ break;
+ }
+}
+
+void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
+ assert(m_type == NodeType::Sequence);
+
+ reset_map();
+ for (std::size_t i = 0; i < m_sequence.size(); i++) {
+ std::stringstream stream;
+ stream << i;
+
+ node& key = pMemory->create_node();
+ key.set_scalar(stream.str());
+ insert_map_pair(key, *m_sequence[i]);
+ }
+
+ reset_sequence();
+ m_type = NodeType::Map;
+}
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp
new file mode 100644
index 0000000000..093d2efeb7
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.cpp
@@ -0,0 +1,130 @@
+#include <assert.h>
+#include <cassert>
+
+#include "nodebuilder.h"
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/type.h"
+
+namespace YAML {
+struct Mark;
+
+NodeBuilder::NodeBuilder()
+ : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) {
+ m_anchors.push_back(0); // since the anchors start at 1
+}
+
+NodeBuilder::~NodeBuilder() {}
+
+Node NodeBuilder::Root() {
+ if (!m_pRoot)
+ return Node();
+
+ return Node(*m_pRoot, m_pMemory);
+}
+
+void NodeBuilder::OnDocumentStart(const Mark&) {}
+
+void NodeBuilder::OnDocumentEnd() {}
+
+void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) {
+ detail::node& node = Push(mark, anchor);
+ node.set_null();
+ Pop();
+}
+
+void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
+ detail::node& node = *m_anchors[anchor];
+ Push(node);
+ Pop();
+}
+
+void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag,
+ anchor_t anchor, const std::string& value) {
+ detail::node& node = Push(mark, anchor);
+ node.set_scalar(value);
+ node.set_tag(tag);
+ Pop();
+}
+
+void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) {
+ detail::node& node = Push(mark, anchor);
+ node.set_tag(tag);
+ node.set_type(NodeType::Sequence);
+ node.set_style(style);
+}
+
+void NodeBuilder::OnSequenceEnd() { Pop(); }
+
+void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style) {
+ detail::node& node = Push(mark, anchor);
+ node.set_type(NodeType::Map);
+ node.set_tag(tag);
+ node.set_style(style);
+ m_mapDepth++;
+}
+
+void NodeBuilder::OnMapEnd() {
+ assert(m_mapDepth > 0);
+ m_mapDepth--;
+ Pop();
+}
+
+detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) {
+ detail::node& node = m_pMemory->create_node();
+ node.set_mark(mark);
+ RegisterAnchor(anchor, node);
+ Push(node);
+ return node;
+}
+
+void NodeBuilder::Push(detail::node& node) {
+ const bool needsKey =
+ (!m_stack.empty() && m_stack.back()->type() == NodeType::Map &&
+ m_keys.size() < m_mapDepth);
+
+ m_stack.push_back(&node);
+ if (needsKey)
+ m_keys.push_back(PushedKey(&node, false));
+}
+
+void NodeBuilder::Pop() {
+ assert(!m_stack.empty());
+ if (m_stack.size() == 1) {
+ m_pRoot = m_stack[0];
+ m_stack.pop_back();
+ return;
+ }
+
+ detail::node& node = *m_stack.back();
+ m_stack.pop_back();
+
+ detail::node& collection = *m_stack.back();
+
+ if (collection.type() == NodeType::Sequence) {
+ collection.push_back(node, m_pMemory);
+ } else if (collection.type() == NodeType::Map) {
+ assert(!m_keys.empty());
+ PushedKey& key = m_keys.back();
+ if (key.second) {
+ collection.insert(*key.first, node, m_pMemory);
+ m_keys.pop_back();
+ } else {
+ key.second = true;
+ }
+ } else {
+ assert(false);
+ m_stack.clear();
+ }
+}
+
+void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
+ if (anchor) {
+ assert(anchor == m_anchors.size());
+ m_anchors.push_back(&node);
+ }
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h
new file mode 100644
index 0000000000..a6a47f007b
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/nodebuilder.h
@@ -0,0 +1,70 @@
+#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <vector>
+
+#include "yaml-cpp/anchor.h"
+#include "yaml-cpp/emitterstyle.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/node/ptr.h"
+
+namespace YAML {
+namespace detail {
+class node;
+} // namespace detail
+struct Mark;
+} // namespace YAML
+
+namespace YAML {
+class Node;
+
+class NodeBuilder : public EventHandler {
+ public:
+ NodeBuilder();
+ virtual ~NodeBuilder();
+
+ Node Root();
+
+ virtual void OnDocumentStart(const Mark& mark);
+ virtual void OnDocumentEnd();
+
+ virtual void OnNull(const Mark& mark, anchor_t anchor);
+ virtual void OnAlias(const Mark& mark, anchor_t anchor);
+ virtual void OnScalar(const Mark& mark, const std::string& tag,
+ anchor_t anchor, const std::string& value);
+
+ virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style);
+ virtual void OnSequenceEnd();
+
+ virtual void OnMapStart(const Mark& mark, const std::string& tag,
+ anchor_t anchor, EmitterStyle::value style);
+ virtual void OnMapEnd();
+
+ private:
+ detail::node& Push(const Mark& mark, anchor_t anchor);
+ void Push(detail::node& node);
+ void Pop();
+ void RegisterAnchor(anchor_t anchor, detail::node& node);
+
+ private:
+ detail::shared_memory_holder m_pMemory;
+ detail::node* m_pRoot;
+
+ typedef std::vector<detail::node*> Nodes;
+ Nodes m_stack;
+ Nodes m_anchors;
+
+ typedef std::pair<detail::node*, bool> PushedKey;
+ std::vector<PushedKey> m_keys;
+ std::size_t m_mapDepth;
+};
+}
+
+#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp b/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp
new file mode 100644
index 0000000000..82261feb05
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/nodeevents.cpp
@@ -0,0 +1,101 @@
+#include "nodeevents.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/node/detail/node.h"
+#include "yaml-cpp/node/detail/node_iterator.h"
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/type.h"
+
+namespace YAML {
+void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
+ m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
+}
+
+anchor_t NodeEvents::AliasManager::LookupAnchor(
+ const detail::node& node) const {
+ AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
+ if (it == m_anchorByIdentity.end())
+ return 0;
+ return it->second;
+}
+
+NodeEvents::NodeEvents(const Node& node)
+ : m_pMemory(node.m_pMemory), m_root(node.m_pNode) {
+ if (m_root)
+ Setup(*m_root);
+}
+
+void NodeEvents::Setup(const detail::node& node) {
+ int& refCount = m_refCount[node.ref()];
+ refCount++;
+ if (refCount > 1)
+ return;
+
+ if (node.type() == NodeType::Sequence) {
+ for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it)
+ Setup(**it);
+ } else if (node.type() == NodeType::Map) {
+ for (detail::const_node_iterator it = node.begin(); it != node.end();
+ ++it) {
+ Setup(*it->first);
+ Setup(*it->second);
+ }
+ }
+}
+
+void NodeEvents::Emit(EventHandler& handler) {
+ AliasManager am;
+
+ handler.OnDocumentStart(Mark());
+ if (m_root)
+ Emit(*m_root, handler, am);
+ handler.OnDocumentEnd();
+}
+
+void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
+ AliasManager& am) const {
+ anchor_t anchor = NullAnchor;
+ if (IsAliased(node)) {
+ anchor = am.LookupAnchor(node);
+ if (anchor) {
+ handler.OnAlias(Mark(), anchor);
+ return;
+ }
+
+ am.RegisterReference(node);
+ anchor = am.LookupAnchor(node);
+ }
+
+ switch (node.type()) {
+ case NodeType::Undefined:
+ break;
+ case NodeType::Null:
+ handler.OnNull(Mark(), anchor);
+ break;
+ case NodeType::Scalar:
+ handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
+ break;
+ case NodeType::Sequence:
+ handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
+ for (detail::const_node_iterator it = node.begin(); it != node.end();
+ ++it)
+ Emit(**it, handler, am);
+ handler.OnSequenceEnd();
+ break;
+ case NodeType::Map:
+ handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
+ for (detail::const_node_iterator it = node.begin(); it != node.end();
+ ++it) {
+ Emit(*it->first, handler, am);
+ Emit(*it->second, handler, am);
+ }
+ handler.OnMapEnd();
+ break;
+ }
+}
+
+bool NodeEvents::IsAliased(const detail::node& node) const {
+ RefCount::const_iterator it = m_refCount.find(node.ref());
+ return it != m_refCount.end() && it->second > 1;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/nodeevents.h b/src/libs/3rdparty/yaml-cpp/src/nodeevents.h
new file mode 100644
index 0000000000..49c18eb854
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/nodeevents.h
@@ -0,0 +1,64 @@
+#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <map>
+#include <vector>
+
+#include "yaml-cpp/anchor.h"
+#include "yaml-cpp/node/ptr.h"
+
+namespace YAML {
+namespace detail {
+class node;
+} // namespace detail
+} // namespace YAML
+
+namespace YAML {
+class EventHandler;
+class Node;
+
+class NodeEvents {
+ public:
+ explicit NodeEvents(const Node& node);
+
+ void Emit(EventHandler& handler);
+
+ private:
+ class AliasManager {
+ public:
+ AliasManager() : m_curAnchor(0) {}
+
+ void RegisterReference(const detail::node& node);
+ anchor_t LookupAnchor(const detail::node& node) const;
+
+ private:
+ anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
+
+ private:
+ typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
+ AnchorByIdentity m_anchorByIdentity;
+
+ anchor_t m_curAnchor;
+ };
+
+ void Setup(const detail::node& node);
+ void Emit(const detail::node& node, EventHandler& handler,
+ AliasManager& am) const;
+ bool IsAliased(const detail::node& node) const;
+
+ private:
+ detail::shared_memory_holder m_pMemory;
+ detail::node* m_root;
+
+ typedef std::map<const detail::node_ref*, int> RefCount;
+ RefCount m_refCount;
+};
+}
+
+#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/null.cpp b/src/libs/3rdparty/yaml-cpp/src/null.cpp
new file mode 100644
index 0000000000..d12dd08ce4
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/null.cpp
@@ -0,0 +1,10 @@
+#include "yaml-cpp/null.h"
+
+namespace YAML {
+_Null Null;
+
+bool IsNullString(const std::string& str) {
+ return str.empty() || str == "~" || str == "null" || str == "Null" ||
+ str == "NULL";
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp b/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp
new file mode 100644
index 0000000000..357fc0094c
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/ostream_wrapper.cpp
@@ -0,0 +1,57 @@
+#include "yaml-cpp/ostream_wrapper.h"
+
+#include <algorithm>
+#include <cstring>
+#include <iostream>
+
+namespace YAML {
+ostream_wrapper::ostream_wrapper()
+ : m_buffer(1, '\0'),
+ m_pStream(0),
+ m_pos(0),
+ m_row(0),
+ m_col(0),
+ m_comment(false) {}
+
+ostream_wrapper::ostream_wrapper(std::ostream& stream)
+ : m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {}
+
+ostream_wrapper::~ostream_wrapper() {}
+
+void ostream_wrapper::write(const std::string& str) {
+ if (m_pStream) {
+ m_pStream->write(str.c_str(), str.size());
+ } else {
+ m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1));
+ std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos);
+ }
+
+ for (std::size_t i = 0; i < str.size(); i++) {
+ update_pos(str[i]);
+ }
+}
+
+void ostream_wrapper::write(const char* str, std::size_t size) {
+ if (m_pStream) {
+ m_pStream->write(str, size);
+ } else {
+ m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1));
+ std::copy(str, str + size, m_buffer.begin() + m_pos);
+ }
+
+ for (std::size_t i = 0; i < size; i++) {
+ update_pos(str[i]);
+ }
+}
+
+void ostream_wrapper::update_pos(char ch) {
+ m_pos++;
+ m_col++;
+
+ if (ch == '\n') {
+ m_row++;
+ m_col = 0;
+ m_comment = false;
+ }
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/parse.cpp b/src/libs/3rdparty/yaml-cpp/src/parse.cpp
new file mode 100644
index 0000000000..0b2ae4a4f6
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/parse.cpp
@@ -0,0 +1,72 @@
+#include "yaml-cpp/node/parse.h"
+
+#include <fstream>
+#include <sstream>
+
+#include "yaml-cpp/node/node.h"
+#include "yaml-cpp/node/impl.h"
+#include "yaml-cpp/parser.h"
+#include "nodebuilder.h"
+
+namespace YAML {
+Node Load(const std::string& input) {
+ std::stringstream stream(input);
+ return Load(stream);
+}
+
+Node Load(const char* input) {
+ std::stringstream stream(input);
+ return Load(stream);
+}
+
+Node Load(std::istream& input) {
+ Parser parser(input);
+ NodeBuilder builder;
+ if (!parser.HandleNextDocument(builder)) {
+ return Node();
+ }
+
+ return builder.Root();
+}
+
+Node LoadFile(const std::string& filename) {
+ std::ifstream fin(filename.c_str());
+ if (!fin) {
+ throw BadFile();
+ }
+ return Load(fin);
+}
+
+std::vector<Node> LoadAll(const std::string& input) {
+ std::stringstream stream(input);
+ return LoadAll(stream);
+}
+
+std::vector<Node> LoadAll(const char* input) {
+ std::stringstream stream(input);
+ return LoadAll(stream);
+}
+
+std::vector<Node> LoadAll(std::istream& input) {
+ std::vector<Node> docs;
+
+ Parser parser(input);
+ while (1) {
+ NodeBuilder builder;
+ if (!parser.HandleNextDocument(builder)) {
+ break;
+ }
+ docs.push_back(builder.Root());
+ }
+
+ return docs;
+}
+
+std::vector<Node> LoadAllFromFile(const std::string& filename) {
+ std::ifstream fin(filename.c_str());
+ if (!fin) {
+ throw BadFile();
+ }
+ return LoadAll(fin);
+}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/parser.cpp b/src/libs/3rdparty/yaml-cpp/src/parser.cpp
new file mode 100644
index 0000000000..cd69f39fce
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/parser.cpp
@@ -0,0 +1,129 @@
+#include <cstdio>
+#include <sstream>
+
+#include "directives.h" // IWYU pragma: keep
+#include "scanner.h" // IWYU pragma: keep
+#include "singledocparser.h"
+#include "token.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+#include "yaml-cpp/parser.h"
+
+namespace YAML {
+class EventHandler;
+
+Parser::Parser() {}
+
+Parser::Parser(std::istream& in) { Load(in); }
+
+Parser::~Parser() {}
+
+Parser::operator bool() const {
+ return m_pScanner.get() && !m_pScanner->empty();
+}
+
+void Parser::Load(std::istream& in) {
+ m_pScanner.reset(new Scanner(in));
+ m_pDirectives.reset(new Directives);
+}
+
+bool Parser::HandleNextDocument(EventHandler& eventHandler) {
+ if (!m_pScanner.get())
+ return false;
+
+ ParseDirectives();
+ if (m_pScanner->empty()) {
+ return false;
+ }
+
+ SingleDocParser sdp(*m_pScanner, *m_pDirectives);
+ sdp.HandleDocument(eventHandler);
+ return true;
+}
+
+void Parser::ParseDirectives() {
+ bool readDirective = false;
+
+ while (1) {
+ if (m_pScanner->empty()) {
+ break;
+ }
+
+ Token& token = m_pScanner->peek();
+ if (token.type != Token::DIRECTIVE) {
+ break;
+ }
+
+ // we keep the directives from the last document if none are specified;
+ // but if any directives are specific, then we reset them
+ if (!readDirective) {
+ m_pDirectives.reset(new Directives);
+ }
+
+ readDirective = true;
+ HandleDirective(token);
+ m_pScanner->pop();
+ }
+}
+
+void Parser::HandleDirective(const Token& token) {
+ if (token.value == "YAML") {
+ HandleYamlDirective(token);
+ } else if (token.value == "TAG") {
+ HandleTagDirective(token);
+ }
+}
+
+void Parser::HandleYamlDirective(const Token& token) {
+ if (token.params.size() != 1) {
+ throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
+ }
+
+ if (!m_pDirectives->version.isDefault) {
+ throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
+ }
+
+ std::stringstream str(token.params[0]);
+ str >> m_pDirectives->version.major;
+ str.get();
+ str >> m_pDirectives->version.minor;
+ if (!str || str.peek() != EOF) {
+ throw ParserException(
+ token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
+ }
+
+ if (m_pDirectives->version.major > 1) {
+ throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
+ }
+
+ m_pDirectives->version.isDefault = false;
+ // TODO: warning on major == 1, minor > 2?
+}
+
+void Parser::HandleTagDirective(const Token& token) {
+ if (token.params.size() != 2)
+ throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
+
+ const std::string& handle = token.params[0];
+ const std::string& prefix = token.params[1];
+ if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) {
+ throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
+ }
+
+ m_pDirectives->tags[handle] = prefix;
+}
+
+void Parser::PrintTokens(std::ostream& out) {
+ if (!m_pScanner.get()) {
+ return;
+ }
+
+ while (1) {
+ if (m_pScanner->empty()) {
+ break;
+ }
+
+ out << m_pScanner->peek() << "\n";
+ m_pScanner->pop();
+ }
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h b/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h
new file mode 100644
index 0000000000..955aebd8d5
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/ptr_vector.h
@@ -0,0 +1,43 @@
+#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstddef>
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+#include "yaml-cpp/noncopyable.h"
+
+namespace YAML {
+
+// TODO: This class is no longer needed
+template <typename T>
+class ptr_vector : private YAML::noncopyable {
+ public:
+ ptr_vector() {}
+
+ void clear() { m_data.clear(); }
+
+ std::size_t size() const { return m_data.size(); }
+ bool empty() const { return m_data.empty(); }
+
+ void push_back(std::unique_ptr<T>&& t) { m_data.push_back(std::move(t)); }
+ T& operator[](std::size_t i) { return *m_data[i]; }
+ const T& operator[](std::size_t i) const { return *m_data[i]; }
+
+ T& back() { return *(m_data.back().get()); }
+
+ const T& back() const { return *(m_data.back().get()); }
+
+ private:
+ std::vector<std::unique_ptr<T>> m_data;
+};
+}
+
+#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp
new file mode 100644
index 0000000000..20b772051d
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.cpp
@@ -0,0 +1,45 @@
+#include "regex_yaml.h"
+
+namespace YAML {
+// constructors
+RegEx::RegEx() : m_op(REGEX_EMPTY) {}
+
+RegEx::RegEx(REGEX_OP op) : m_op(op) {}
+
+RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {}
+
+RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {}
+
+RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) {
+ for (std::size_t i = 0; i < str.size(); i++)
+ m_params.push_back(RegEx(str[i]));
+}
+
+// combination constructors
+RegEx operator!(const RegEx& ex) {
+ RegEx ret(REGEX_NOT);
+ ret.m_params.push_back(ex);
+ return ret;
+}
+
+RegEx operator||(const RegEx& ex1, const RegEx& ex2) {
+ RegEx ret(REGEX_OR);
+ ret.m_params.push_back(ex1);
+ ret.m_params.push_back(ex2);
+ return ret;
+}
+
+RegEx operator&&(const RegEx& ex1, const RegEx& ex2) {
+ RegEx ret(REGEX_AND);
+ ret.m_params.push_back(ex1);
+ ret.m_params.push_back(ex2);
+ return ret;
+}
+
+RegEx operator+(const RegEx& ex1, const RegEx& ex2) {
+ RegEx ret(REGEX_SEQ);
+ ret.m_params.push_back(ex1);
+ ret.m_params.push_back(ex2);
+ return ret;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h
new file mode 100644
index 0000000000..8f28b852a2
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/regex_yaml.h
@@ -0,0 +1,87 @@
+#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include <vector>
+
+#include "yaml-cpp/dll.h"
+
+namespace YAML {
+class Stream;
+
+enum REGEX_OP {
+ REGEX_EMPTY,
+ REGEX_MATCH,
+ REGEX_RANGE,
+ REGEX_OR,
+ REGEX_AND,
+ REGEX_NOT,
+ REGEX_SEQ
+};
+
+// simplified regular expressions
+// . Only straightforward matches (no repeated characters)
+// . Only matches from start of string
+class YAML_CPP_API RegEx {
+ public:
+ RegEx();
+ RegEx(char ch);
+ RegEx(char a, char z);
+ RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
+ ~RegEx() {}
+
+ friend YAML_CPP_API RegEx operator!(const RegEx& ex);
+ friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2);
+ friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2);
+ friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2);
+
+ bool Matches(char ch) const;
+ bool Matches(const std::string& str) const;
+ bool Matches(const Stream& in) const;
+ template <typename Source>
+ bool Matches(const Source& source) const;
+
+ int Match(const std::string& str) const;
+ int Match(const Stream& in) const;
+ template <typename Source>
+ int Match(const Source& source) const;
+
+ private:
+ RegEx(REGEX_OP op);
+
+ template <typename Source>
+ bool IsValidSource(const Source& source) const;
+ template <typename Source>
+ int MatchUnchecked(const Source& source) const;
+
+ template <typename Source>
+ int MatchOpEmpty(const Source& source) const;
+ template <typename Source>
+ int MatchOpMatch(const Source& source) const;
+ template <typename Source>
+ int MatchOpRange(const Source& source) const;
+ template <typename Source>
+ int MatchOpOr(const Source& source) const;
+ template <typename Source>
+ int MatchOpAnd(const Source& source) const;
+ template <typename Source>
+ int MatchOpNot(const Source& source) const;
+ template <typename Source>
+ int MatchOpSeq(const Source& source) const;
+
+ private:
+ REGEX_OP m_op;
+ char m_a, m_z;
+ std::vector<RegEx> m_params;
+};
+}
+
+#include "regeximpl.h"
+
+#endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/regeximpl.h b/src/libs/3rdparty/yaml-cpp/src/regeximpl.h
new file mode 100644
index 0000000000..709124f008
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/regeximpl.h
@@ -0,0 +1,186 @@
+#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "stream.h"
+#include "stringsource.h"
+#include "streamcharsource.h"
+
+namespace YAML {
+// query matches
+inline bool RegEx::Matches(char ch) const {
+ std::string str;
+ str += ch;
+ return Matches(str);
+}
+
+inline bool RegEx::Matches(const std::string& str) const {
+ return Match(str) >= 0;
+}
+
+inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; }
+
+template <typename Source>
+inline bool RegEx::Matches(const Source& source) const {
+ return Match(source) >= 0;
+}
+
+// Match
+// . Matches the given string against this regular expression.
+// . Returns the number of characters matched.
+// . Returns -1 if no characters were matched (the reason for
+// not returning zero is that we may have an empty regex
+// which is ALWAYS successful at matching zero characters).
+// . REMEMBER that we only match from the start of the buffer!
+inline int RegEx::Match(const std::string& str) const {
+ StringCharSource source(str.c_str(), str.size());
+ return Match(source);
+}
+
+inline int RegEx::Match(const Stream& in) const {
+ StreamCharSource source(in);
+ return Match(source);
+}
+
+template <typename Source>
+inline bool RegEx::IsValidSource(const Source& source) const {
+ return source;
+}
+
+template <>
+inline bool RegEx::IsValidSource<StringCharSource>(
+ const StringCharSource& source) const {
+ switch (m_op) {
+ case REGEX_MATCH:
+ case REGEX_RANGE:
+ return source;
+ default:
+ return true;
+ }
+}
+
+template <typename Source>
+inline int RegEx::Match(const Source& source) const {
+ return IsValidSource(source) ? MatchUnchecked(source) : -1;
+}
+
+template <typename Source>
+inline int RegEx::MatchUnchecked(const Source& source) const {
+ switch (m_op) {
+ case REGEX_EMPTY:
+ return MatchOpEmpty(source);
+ case REGEX_MATCH:
+ return MatchOpMatch(source);
+ case REGEX_RANGE:
+ return MatchOpRange(source);
+ case REGEX_OR:
+ return MatchOpOr(source);
+ case REGEX_AND:
+ return MatchOpAnd(source);
+ case REGEX_NOT:
+ return MatchOpNot(source);
+ case REGEX_SEQ:
+ return MatchOpSeq(source);
+ }
+
+ return -1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Operators
+// Note: the convention MatchOp*<Source> is that we can assume
+// IsSourceValid(source).
+// So we do all our checks *before* we call these functions
+
+// EmptyOperator
+template <typename Source>
+inline int RegEx::MatchOpEmpty(const Source& source) const {
+ return source[0] == Stream::eof() ? 0 : -1;
+}
+
+template <>
+inline int RegEx::MatchOpEmpty<StringCharSource>(
+ const StringCharSource& source) const {
+ return !source
+ ? 0
+ : -1; // the empty regex only is successful on the empty string
+}
+
+// MatchOperator
+template <typename Source>
+inline int RegEx::MatchOpMatch(const Source& source) const {
+ if (source[0] != m_a)
+ return -1;
+ return 1;
+}
+
+// RangeOperator
+template <typename Source>
+inline int RegEx::MatchOpRange(const Source& source) const {
+ if (m_a > source[0] || m_z < source[0])
+ return -1;
+ return 1;
+}
+
+// OrOperator
+template <typename Source>
+inline int RegEx::MatchOpOr(const Source& source) const {
+ for (std::size_t i = 0; i < m_params.size(); i++) {
+ int n = m_params[i].MatchUnchecked(source);
+ if (n >= 0)
+ return n;
+ }
+ return -1;
+}
+
+// AndOperator
+// Note: 'AND' is a little funny, since we may be required to match things
+// of different lengths. If we find a match, we return the length of
+// the FIRST entry on the list.
+template <typename Source>
+inline int RegEx::MatchOpAnd(const Source& source) const {
+ int first = -1;
+ for (std::size_t i = 0; i < m_params.size(); i++) {
+ int n = m_params[i].MatchUnchecked(source);
+ if (n == -1)
+ return -1;
+ if (i == 0)
+ first = n;
+ }
+ return first;
+}
+
+// NotOperator
+template <typename Source>
+inline int RegEx::MatchOpNot(const Source& source) const {
+ if (m_params.empty())
+ return -1;
+ if (m_params[0].MatchUnchecked(source) >= 0)
+ return -1;
+ return 1;
+}
+
+// SeqOperator
+template <typename Source>
+inline int RegEx::MatchOpSeq(const Source& source) const {
+ int offset = 0;
+ for (std::size_t i = 0; i < m_params.size(); i++) {
+ int n = m_params[i].Match(source + offset); // note Match, not
+ // MatchUnchecked because we
+ // need to check validity after
+ // the offset
+ if (n == -1)
+ return -1;
+ offset += n;
+ }
+
+ return offset;
+}
+}
+
+#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanner.cpp b/src/libs/3rdparty/yaml-cpp/src/scanner.cpp
new file mode 100644
index 0000000000..b5cfcc12b2
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scanner.cpp
@@ -0,0 +1,386 @@
+#include <cassert>
+#include <memory>
+
+#include "exp.h"
+#include "scanner.h"
+#include "token.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+
+namespace YAML {
+Scanner::Scanner(std::istream& in)
+ : INPUT(in),
+ m_startedStream(false),
+ m_endedStream(false),
+ m_simpleKeyAllowed(false),
+ m_canBeJSONFlow(false) {}
+
+Scanner::~Scanner() {}
+
+bool Scanner::empty() {
+ EnsureTokensInQueue();
+ return m_tokens.empty();
+}
+
+void Scanner::pop() {
+ EnsureTokensInQueue();
+ if (!m_tokens.empty())
+ m_tokens.pop();
+}
+
+Token& Scanner::peek() {
+ EnsureTokensInQueue();
+ assert(!m_tokens.empty()); // should we be asserting here? I mean, we really
+ // just be checking
+ // if it's empty before peeking.
+
+#if 0
+ static Token *pLast = 0;
+ if(pLast != &m_tokens.front())
+ std::cerr << "peek: " << m_tokens.front() << "\n";
+ pLast = &m_tokens.front();
+#endif
+
+ return m_tokens.front();
+}
+
+Mark Scanner::mark() const { return INPUT.mark(); }
+
+void Scanner::EnsureTokensInQueue() {
+ while (1) {
+ if (!m_tokens.empty()) {
+ Token& token = m_tokens.front();
+
+ // if this guy's valid, then we're done
+ if (token.status == Token::VALID) {
+ return;
+ }
+
+ // here's where we clean up the impossible tokens
+ if (token.status == Token::INVALID) {
+ m_tokens.pop();
+ continue;
+ }
+
+ // note: what's left are the unverified tokens
+ }
+
+ // no token? maybe we've actually finished
+ if (m_endedStream) {
+ return;
+ }
+
+ // no? then scan...
+ ScanNextToken();
+ }
+}
+
+void Scanner::ScanNextToken() {
+ if (m_endedStream) {
+ return;
+ }
+
+ if (!m_startedStream) {
+ return StartStream();
+ }
+
+ // get rid of whitespace, etc. (in between tokens it should be irrelevent)
+ ScanToNextToken();
+
+ // maybe need to end some blocks
+ PopIndentToHere();
+
+ // *****
+ // And now branch based on the next few characters!
+ // *****
+
+ // end of stream
+ if (!INPUT) {
+ return EndStream();
+ }
+
+ if (INPUT.column() == 0 && INPUT.peek() == Keys::Directive) {
+ return ScanDirective();
+ }
+
+ // document token
+ if (INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) {
+ return ScanDocStart();
+ }
+
+ if (INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) {
+ return ScanDocEnd();
+ }
+
+ // flow start/end/entry
+ if (INPUT.peek() == Keys::FlowSeqStart ||
+ INPUT.peek() == Keys::FlowMapStart) {
+ return ScanFlowStart();
+ }
+
+ if (INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) {
+ return ScanFlowEnd();
+ }
+
+ if (INPUT.peek() == Keys::FlowEntry) {
+ return ScanFlowEntry();
+ }
+
+ // block/map stuff
+ if (Exp::BlockEntry().Matches(INPUT)) {
+ return ScanBlockEntry();
+ }
+
+ if ((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) {
+ return ScanKey();
+ }
+
+ if (GetValueRegex().Matches(INPUT)) {
+ return ScanValue();
+ }
+
+ // alias/anchor
+ if (INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) {
+ return ScanAnchorOrAlias();
+ }
+
+ // tag
+ if (INPUT.peek() == Keys::Tag) {
+ return ScanTag();
+ }
+
+ // special scalars
+ if (InBlockContext() && (INPUT.peek() == Keys::LiteralScalar ||
+ INPUT.peek() == Keys::FoldedScalar)) {
+ return ScanBlockScalar();
+ }
+
+ if (INPUT.peek() == '\'' || INPUT.peek() == '\"') {
+ return ScanQuotedScalar();
+ }
+
+ // plain scalars
+ if ((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow())
+ .Matches(INPUT)) {
+ return ScanPlainScalar();
+ }
+
+ // don't know what it is!
+ throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
+}
+
+void Scanner::ScanToNextToken() {
+ while (1) {
+ // first eat whitespace
+ while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
+ if (InBlockContext() && Exp::Tab().Matches(INPUT)) {
+ m_simpleKeyAllowed = false;
+ }
+ INPUT.eat(1);
+ }
+
+ // then eat a comment
+ if (Exp::Comment().Matches(INPUT)) {
+ // eat until line break
+ while (INPUT && !Exp::Break().Matches(INPUT)) {
+ INPUT.eat(1);
+ }
+ }
+
+ // if it's NOT a line break, then we're done!
+ if (!Exp::Break().Matches(INPUT)) {
+ break;
+ }
+
+ // otherwise, let's eat the line break and keep going
+ int n = Exp::Break().Match(INPUT);
+ INPUT.eat(n);
+
+ // oh yeah, and let's get rid of that simple key
+ InvalidateSimpleKey();
+
+ // new line - we may be able to accept a simple key now
+ if (InBlockContext()) {
+ m_simpleKeyAllowed = true;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+// Misc. helpers
+
+// IsWhitespaceToBeEaten
+// . We can eat whitespace if it's a space or tab
+// . Note: originally tabs in block context couldn't be eaten
+// "where a simple key could be allowed
+// (i.e., not at the beginning of a line, or following '-', '?', or
+// ':')"
+// I think this is wrong, since tabs can be non-content whitespace; it's just
+// that they can't contribute to indentation, so once you've seen a tab in a
+// line, you can't start a simple key
+bool Scanner::IsWhitespaceToBeEaten(char ch) {
+ if (ch == ' ') {
+ return true;
+ }
+
+ if (ch == '\t') {
+ return true;
+ }
+
+ return false;
+}
+
+const RegEx& Scanner::GetValueRegex() const {
+ if (InBlockContext()) {
+ return Exp::Value();
+ }
+
+ return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow();
+}
+
+void Scanner::StartStream() {
+ m_startedStream = true;
+ m_simpleKeyAllowed = true;
+ std::unique_ptr<IndentMarker> pIndent(
+ new IndentMarker(-1, IndentMarker::NONE));
+ m_indentRefs.push_back(std::move(pIndent));
+ m_indents.push(&m_indentRefs.back());
+}
+
+void Scanner::EndStream() {
+ // force newline
+ if (INPUT.column() > 0) {
+ INPUT.ResetColumn();
+ }
+
+ PopAllIndents();
+ PopAllSimpleKeys();
+
+ m_simpleKeyAllowed = false;
+ m_endedStream = true;
+}
+
+Token* Scanner::PushToken(Token::TYPE type) {
+ m_tokens.push(Token(type, INPUT.mark()));
+ return &m_tokens.back();
+}
+
+Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const {
+ switch (type) {
+ case IndentMarker::SEQ:
+ return Token::BLOCK_SEQ_START;
+ case IndentMarker::MAP:
+ return Token::BLOCK_MAP_START;
+ case IndentMarker::NONE:
+ assert(false);
+ break;
+ }
+ assert(false);
+ throw std::runtime_error("yaml-cpp: internal error, invalid indent type");
+}
+
+Scanner::IndentMarker* Scanner::PushIndentTo(int column,
+ IndentMarker::INDENT_TYPE type) {
+ // are we in flow?
+ if (InFlowContext()) {
+ return 0;
+ }
+
+ std::unique_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
+ IndentMarker& indent = *pIndent;
+ const IndentMarker& lastIndent = *m_indents.top();
+
+ // is this actually an indentation?
+ if (indent.column < lastIndent.column) {
+ return 0;
+ }
+ if (indent.column == lastIndent.column &&
+ !(indent.type == IndentMarker::SEQ &&
+ lastIndent.type == IndentMarker::MAP)) {
+ return 0;
+ }
+
+ // push a start token
+ indent.pStartToken = PushToken(GetStartTokenFor(type));
+
+ // and then the indent
+ m_indents.push(&indent);
+ m_indentRefs.push_back(std::move(pIndent));
+ return &m_indentRefs.back();
+}
+
+void Scanner::PopIndentToHere() {
+ // are we in flow?
+ if (InFlowContext()) {
+ return;
+ }
+
+ // now pop away
+ while (!m_indents.empty()) {
+ const IndentMarker& indent = *m_indents.top();
+ if (indent.column < INPUT.column()) {
+ break;
+ }
+ if (indent.column == INPUT.column() &&
+ !(indent.type == IndentMarker::SEQ &&
+ !Exp::BlockEntry().Matches(INPUT))) {
+ break;
+ }
+
+ PopIndent();
+ }
+
+ while (!m_indents.empty() &&
+ m_indents.top()->status == IndentMarker::INVALID) {
+ PopIndent();
+ }
+}
+
+void Scanner::PopAllIndents() {
+ // are we in flow?
+ if (InFlowContext()) {
+ return;
+ }
+
+ // now pop away
+ while (!m_indents.empty()) {
+ const IndentMarker& indent = *m_indents.top();
+ if (indent.type == IndentMarker::NONE) {
+ break;
+ }
+
+ PopIndent();
+ }
+}
+
+void Scanner::PopIndent() {
+ const IndentMarker& indent = *m_indents.top();
+ m_indents.pop();
+
+ if (indent.status != IndentMarker::VALID) {
+ InvalidateSimpleKey();
+ return;
+ }
+
+ if (indent.type == IndentMarker::SEQ) {
+ m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
+ } else if (indent.type == IndentMarker::MAP) {
+ m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
+ }
+}
+
+int Scanner::GetTopIndent() const {
+ if (m_indents.empty()) {
+ return 0;
+ }
+ return m_indents.top()->column;
+}
+
+void Scanner::ThrowParserException(const std::string& msg) const {
+ Mark mark = Mark::null_mark();
+ if (!m_tokens.empty()) {
+ const Token& token = m_tokens.front();
+ mark = token.mark;
+ }
+ throw ParserException(mark, msg);
+}
+} // namespace YAML
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanner.h b/src/libs/3rdparty/yaml-cpp/src/scanner.h
new file mode 100644
index 0000000000..7bb2ccc71a
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scanner.h
@@ -0,0 +1,190 @@
+#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstddef>
+#include <ios>
+#include <map>
+#include <queue>
+#include <set>
+#include <stack>
+#include <string>
+
+#include "ptr_vector.h"
+#include "stream.h"
+#include "token.h"
+#include "yaml-cpp/mark.h"
+
+namespace YAML {
+class Node;
+class RegEx;
+
+/**
+ * A scanner transforms a stream of characters into a stream of tokens.
+ */
+class Scanner {
+ public:
+ explicit Scanner(std::istream &in);
+ ~Scanner();
+
+ /** Returns true if there are no more tokens to be read. */
+ bool empty();
+
+ /** Removes the next token in the queue. */
+ void pop();
+
+ /** Returns, but does not remove, the next token in the queue. */
+ Token &peek();
+
+ /** Returns the current mark in the input stream. */
+ Mark mark() const;
+
+ private:
+ struct IndentMarker {
+ enum INDENT_TYPE { MAP, SEQ, NONE };
+ enum STATUS { VALID, INVALID, UNKNOWN };
+ IndentMarker(int column_, INDENT_TYPE type_)
+ : column(column_), type(type_), status(VALID), pStartToken(0) {}
+
+ int column;
+ INDENT_TYPE type;
+ STATUS status;
+ Token *pStartToken;
+ };
+
+ enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ };
+
+ private:
+ // scanning
+
+ /**
+ * Scans until there's a valid token at the front of the queue, or the queue
+ * is empty. The state can be checked by {@link #empty}, and the next token
+ * retrieved by {@link #peek}.
+ */
+ void EnsureTokensInQueue();
+
+ /**
+ * The main scanning function; this method branches out to scan whatever the
+ * next token should be.
+ */
+ void ScanNextToken();
+
+ /** Eats the input stream until it reaches the next token-like thing. */
+ void ScanToNextToken();
+
+ /** Sets the initial conditions for starting a stream. */
+ void StartStream();
+
+ /** Closes out the stream, finish up, etc. */
+ void EndStream();
+
+ Token *PushToken(Token::TYPE type);
+
+ bool InFlowContext() const { return !m_flows.empty(); }
+ bool InBlockContext() const { return m_flows.empty(); }
+ std::size_t GetFlowLevel() const { return m_flows.size(); }
+
+ Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const;
+
+ /**
+ * Pushes an indentation onto the stack, and enqueues the proper token
+ * (sequence start or mapping start).
+ *
+ * @return the indent marker it generates (if any).
+ */
+ IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
+
+ /**
+ * Pops indentations off the stack until it reaches the current indentation
+ * level, and enqueues the proper token each time. Then pops all invalid
+ * indentations off.
+ */
+ void PopIndentToHere();
+
+ /**
+ * Pops all indentations (except for the base empty one) off the stack, and
+ * enqueues the proper token each time.
+ */
+ void PopAllIndents();
+
+ /** Pops a single indent, pushing the proper token. */
+ void PopIndent();
+ int GetTopIndent() const;
+
+ // checking input
+ bool CanInsertPotentialSimpleKey() const;
+ bool ExistsActiveSimpleKey() const;
+ void InsertPotentialSimpleKey();
+ void InvalidateSimpleKey();
+ bool VerifySimpleKey();
+ void PopAllSimpleKeys();
+
+ /**
+ * Throws a ParserException with the current token location (if available),
+ * and does not parse any more tokens.
+ */
+ void ThrowParserException(const std::string &msg) const;
+
+ bool IsWhitespaceToBeEaten(char ch);
+
+ /**
+ * Returns the appropriate regex to check if the next token is a value token.
+ */
+ const RegEx &GetValueRegex() const;
+
+ struct SimpleKey {
+ SimpleKey(const Mark &mark_, std::size_t flowLevel_);
+
+ void Validate();
+ void Invalidate();
+
+ Mark mark;
+ std::size_t flowLevel;
+ IndentMarker *pIndent;
+ Token *pMapStart, *pKey;
+ };
+
+ // and the tokens
+ void ScanDirective();
+ void ScanDocStart();
+ void ScanDocEnd();
+ void ScanBlockSeqStart();
+ void ScanBlockMapSTart();
+ void ScanBlockEnd();
+ void ScanBlockEntry();
+ void ScanFlowStart();
+ void ScanFlowEnd();
+ void ScanFlowEntry();
+ void ScanKey();
+ void ScanValue();
+ void ScanAnchorOrAlias();
+ void ScanTag();
+ void ScanPlainScalar();
+ void ScanQuotedScalar();
+ void ScanBlockScalar();
+
+ private:
+ // the stream
+ Stream INPUT;
+
+ // the output (tokens)
+ std::queue<Token> m_tokens;
+
+ // state info
+ bool m_startedStream, m_endedStream;
+ bool m_simpleKeyAllowed;
+ bool m_canBeJSONFlow;
+ std::stack<SimpleKey> m_simpleKeys;
+ std::stack<IndentMarker *> m_indents;
+ ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection"
+ std::stack<FLOW_MARKER> m_flows;
+};
+}
+
+#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp b/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp
new file mode 100644
index 0000000000..10e359d446
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scanscalar.cpp
@@ -0,0 +1,250 @@
+#include "scanscalar.h"
+
+#include <algorithm>
+
+#include "exp.h"
+#include "regeximpl.h"
+#include "stream.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+
+namespace YAML {
+// ScanScalar
+// . This is where the scalar magic happens.
+//
+// . We do the scanning in three phases:
+// 1. Scan until newline
+// 2. Eat newline
+// 3. Scan leading blanks.
+//
+// . Depending on the parameters given, we store or stop
+// and different places in the above flow.
+std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
+ bool foundNonEmptyLine = false;
+ bool pastOpeningBreak = (params.fold == FOLD_FLOW);
+ bool emptyLine = false, moreIndented = false;
+ int foldedNewlineCount = 0;
+ bool foldedNewlineStartedMoreIndented = false;
+ std::size_t lastEscapedChar = std::string::npos;
+ std::string scalar;
+ params.leadingSpaces = false;
+
+ if (!params.end) {
+ params.end = &Exp::Empty();
+ }
+
+ while (INPUT) {
+ // ********************************
+ // Phase #1: scan until line ending
+
+ std::size_t lastNonWhitespaceChar = scalar.size();
+ bool escapedNewline = false;
+ while (!params.end->Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
+ if (!INPUT) {
+ break;
+ }
+
+ // document indicator?
+ if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
+ if (params.onDocIndicator == BREAK) {
+ break;
+ } else if (params.onDocIndicator == THROW) {
+ throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
+ }
+ }
+
+ foundNonEmptyLine = true;
+ pastOpeningBreak = true;
+
+ // escaped newline? (only if we're escaping on slash)
+ if (params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) {
+ // eat escape character and get out (but preserve trailing whitespace!)
+ INPUT.get();
+ lastNonWhitespaceChar = scalar.size();
+ lastEscapedChar = scalar.size();
+ escapedNewline = true;
+ break;
+ }
+
+ // escape this?
+ if (INPUT.peek() == params.escape) {
+ scalar += Exp::Escape(INPUT);
+ lastNonWhitespaceChar = scalar.size();
+ lastEscapedChar = scalar.size();
+ continue;
+ }
+
+ // otherwise, just add the damn character
+ char ch = INPUT.get();
+ scalar += ch;
+ if (ch != ' ' && ch != '\t') {
+ lastNonWhitespaceChar = scalar.size();
+ }
+ }
+
+ // eof? if we're looking to eat something, then we throw
+ if (!INPUT) {
+ if (params.eatEnd) {
+ throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR);
+ }
+ break;
+ }
+
+ // doc indicator?
+ if (params.onDocIndicator == BREAK && INPUT.column() == 0 &&
+ Exp::DocIndicator().Matches(INPUT)) {
+ break;
+ }
+
+ // are we done via character match?
+ int n = params.end->Match(INPUT);
+ if (n >= 0) {
+ if (params.eatEnd) {
+ INPUT.eat(n);
+ }
+ break;
+ }
+
+ // do we remove trailing whitespace?
+ if (params.fold == FOLD_FLOW)
+ scalar.erase(lastNonWhitespaceChar);
+
+ // ********************************
+ // Phase #2: eat line ending
+ n = Exp::Break().Match(INPUT);
+ INPUT.eat(n);
+
+ // ********************************
+ // Phase #3: scan initial spaces
+
+ // first the required indentation
+ while (INPUT.peek() == ' ' &&
+ (INPUT.column() < params.indent ||
+ (params.detectIndent && !foundNonEmptyLine)) &&
+ !params.end->Matches(INPUT)) {
+ INPUT.eat(1);
+ }
+
+ // update indent if we're auto-detecting
+ if (params.detectIndent && !foundNonEmptyLine) {
+ params.indent = std::max(params.indent, INPUT.column());
+ }
+
+ // and then the rest of the whitespace
+ while (Exp::Blank().Matches(INPUT)) {
+ // we check for tabs that masquerade as indentation
+ if (INPUT.peek() == '\t' && INPUT.column() < params.indent &&
+ params.onTabInIndentation == THROW) {
+ throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
+ }
+
+ if (!params.eatLeadingWhitespace) {
+ break;
+ }
+
+ if (params.end->Matches(INPUT)) {
+ break;
+ }
+
+ INPUT.eat(1);
+ }
+
+ // was this an empty line?
+ bool nextEmptyLine = Exp::Break().Matches(INPUT);
+ bool nextMoreIndented = Exp::Blank().Matches(INPUT);
+ if (params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
+ foldedNewlineStartedMoreIndented = moreIndented;
+
+ // for block scalars, we always start with a newline, so we should ignore it
+ // (not fold or keep)
+ if (pastOpeningBreak) {
+ switch (params.fold) {
+ case DONT_FOLD:
+ scalar += "\n";
+ break;
+ case FOLD_BLOCK:
+ if (!emptyLine && !nextEmptyLine && !moreIndented &&
+ !nextMoreIndented && INPUT.column() >= params.indent) {
+ scalar += " ";
+ } else if (nextEmptyLine) {
+ foldedNewlineCount++;
+ } else {
+ scalar += "\n";
+ }
+
+ if (!nextEmptyLine && foldedNewlineCount > 0) {
+ scalar += std::string(foldedNewlineCount - 1, '\n');
+ if (foldedNewlineStartedMoreIndented ||
+ nextMoreIndented | !foundNonEmptyLine) {
+ scalar += "\n";
+ }
+ foldedNewlineCount = 0;
+ }
+ break;
+ case FOLD_FLOW:
+ if (nextEmptyLine) {
+ scalar += "\n";
+ } else if (!emptyLine && !nextEmptyLine && !escapedNewline) {
+ scalar += " ";
+ }
+ break;
+ }
+ }
+
+ emptyLine = nextEmptyLine;
+ moreIndented = nextMoreIndented;
+ pastOpeningBreak = true;
+
+ // are we done via indentation?
+ if (!emptyLine && INPUT.column() < params.indent) {
+ params.leadingSpaces = true;
+ break;
+ }
+ }
+
+ // post-processing
+ if (params.trimTrailingSpaces) {
+ std::size_t pos = scalar.find_last_not_of(' ');
+ if (lastEscapedChar != std::string::npos) {
+ if (pos < lastEscapedChar || pos == std::string::npos) {
+ pos = lastEscapedChar;
+ }
+ }
+ if (pos < scalar.size()) {
+ scalar.erase(pos + 1);
+ }
+ }
+
+ switch (params.chomp) {
+ case CLIP: {
+ std::size_t pos = scalar.find_last_not_of('\n');
+ if (lastEscapedChar != std::string::npos) {
+ if (pos < lastEscapedChar || pos == std::string::npos) {
+ pos = lastEscapedChar;
+ }
+ }
+ if (pos == std::string::npos) {
+ scalar.erase();
+ } else if (pos + 1 < scalar.size()) {
+ scalar.erase(pos + 2);
+ }
+ } break;
+ case STRIP: {
+ std::size_t pos = scalar.find_last_not_of('\n');
+ if (lastEscapedChar != std::string::npos) {
+ if (pos < lastEscapedChar || pos == std::string::npos) {
+ pos = lastEscapedChar;
+ }
+ }
+ if (pos == std::string::npos) {
+ scalar.erase();
+ } else if (pos < scalar.size()) {
+ scalar.erase(pos + 1);
+ }
+ } break;
+ default:
+ break;
+ }
+
+ return scalar;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/scanscalar.h b/src/libs/3rdparty/yaml-cpp/src/scanscalar.h
new file mode 100644
index 0000000000..c3a574ad9b
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scanscalar.h
@@ -0,0 +1,63 @@
+#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+#include "regex_yaml.h"
+#include "stream.h"
+
+namespace YAML {
+enum CHOMP { STRIP = -1, CLIP, KEEP };
+enum ACTION { NONE, BREAK, THROW };
+enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW };
+
+struct ScanScalarParams {
+ ScanScalarParams()
+ : end(nullptr),
+ eatEnd(false),
+ indent(0),
+ detectIndent(false),
+ eatLeadingWhitespace(0),
+ escape(0),
+ fold(DONT_FOLD),
+ trimTrailingSpaces(0),
+ chomp(CLIP),
+ onDocIndicator(NONE),
+ onTabInIndentation(NONE),
+ leadingSpaces(false) {}
+
+ // input:
+ const RegEx* end; // what condition ends this scalar?
+ // unowned.
+ bool eatEnd; // should we eat that condition when we see it?
+ int indent; // what level of indentation should be eaten and ignored?
+ bool detectIndent; // should we try to autodetect the indent?
+ bool eatLeadingWhitespace; // should we continue eating this delicious
+ // indentation after 'indent' spaces?
+ char escape; // what character do we escape on (i.e., slash or single quote)
+ // (0 for none)
+ FOLD fold; // how do we fold line ends?
+ bool trimTrailingSpaces; // do we remove all trailing spaces (at the very
+ // end)
+ CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very
+ // end)
+ // Note: strip means kill all, clip means keep at most one, keep means keep
+ // all
+ ACTION onDocIndicator; // what do we do if we see a document indicator?
+ ACTION onTabInIndentation; // what do we do if we see a tab where we should
+ // be seeing indentation spaces
+
+ // output:
+ bool leadingSpaces;
+};
+
+std::string ScanScalar(Stream& INPUT, ScanScalarParams& info);
+}
+
+#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/scantag.cpp b/src/libs/3rdparty/yaml-cpp/src/scantag.cpp
new file mode 100644
index 0000000000..c5b39652ad
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scantag.cpp
@@ -0,0 +1,81 @@
+#include "exp.h"
+#include "regex_yaml.h"
+#include "regeximpl.h"
+#include "stream.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+#include "yaml-cpp/mark.h"
+
+namespace YAML {
+const std::string ScanVerbatimTag(Stream& INPUT) {
+ std::string tag;
+
+ // eat the start character
+ INPUT.get();
+
+ while (INPUT) {
+ if (INPUT.peek() == Keys::VerbatimTagEnd) {
+ // eat the end character
+ INPUT.get();
+ return tag;
+ }
+
+ int n = Exp::URI().Match(INPUT);
+ if (n <= 0)
+ break;
+
+ tag += INPUT.get(n);
+ }
+
+ throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
+}
+
+const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) {
+ std::string tag;
+ canBeHandle = true;
+ Mark firstNonWordChar;
+
+ while (INPUT) {
+ if (INPUT.peek() == Keys::Tag) {
+ if (!canBeHandle)
+ throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
+ break;
+ }
+
+ int n = 0;
+ if (canBeHandle) {
+ n = Exp::Word().Match(INPUT);
+ if (n <= 0) {
+ canBeHandle = false;
+ firstNonWordChar = INPUT.mark();
+ }
+ }
+
+ if (!canBeHandle)
+ n = Exp::Tag().Match(INPUT);
+
+ if (n <= 0)
+ break;
+
+ tag += INPUT.get(n);
+ }
+
+ return tag;
+}
+
+const std::string ScanTagSuffix(Stream& INPUT) {
+ std::string tag;
+
+ while (INPUT) {
+ int n = Exp::Tag().Match(INPUT);
+ if (n <= 0)
+ break;
+
+ tag += INPUT.get(n);
+ }
+
+ if (tag.empty())
+ throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
+
+ return tag;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/scantag.h b/src/libs/3rdparty/yaml-cpp/src/scantag.h
new file mode 100644
index 0000000000..522ba5495e
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scantag.h
@@ -0,0 +1,19 @@
+#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+#include "stream.h"
+
+namespace YAML {
+const std::string ScanVerbatimTag(Stream& INPUT);
+const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle);
+const std::string ScanTagSuffix(Stream& INPUT);
+}
+
+#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp b/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp
new file mode 100644
index 0000000000..fd8758d781
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/scantoken.cpp
@@ -0,0 +1,437 @@
+#include <sstream>
+
+#include "exp.h"
+#include "regex_yaml.h"
+#include "regeximpl.h"
+#include "scanner.h"
+#include "scanscalar.h"
+#include "scantag.h" // IWYU pragma: keep
+#include "tag.h" // IWYU pragma: keep
+#include "token.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+#include "yaml-cpp/mark.h"
+
+namespace YAML {
+///////////////////////////////////////////////////////////////////////
+// Specialization for scanning specific tokens
+
+// Directive
+// . Note: no semantic checking is done here (that's for the parser to do)
+void Scanner::ScanDirective() {
+ std::string name;
+ std::vector<std::string> params;
+
+ // pop indents and simple keys
+ PopAllIndents();
+ PopAllSimpleKeys();
+
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // store pos and eat indicator
+ Token token(Token::DIRECTIVE, INPUT.mark());
+ INPUT.eat(1);
+
+ // read name
+ while (INPUT && !Exp::BlankOrBreak().Matches(INPUT))
+ token.value += INPUT.get();
+
+ // read parameters
+ while (1) {
+ // first get rid of whitespace
+ while (Exp::Blank().Matches(INPUT))
+ INPUT.eat(1);
+
+ // break on newline or comment
+ if (!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT))
+ break;
+
+ // now read parameter
+ std::string param;
+ while (INPUT && !Exp::BlankOrBreak().Matches(INPUT))
+ param += INPUT.get();
+
+ token.params.push_back(param);
+ }
+
+ m_tokens.push(token);
+}
+
+// DocStart
+void Scanner::ScanDocStart() {
+ PopAllIndents();
+ PopAllSimpleKeys();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(3);
+ m_tokens.push(Token(Token::DOC_START, mark));
+}
+
+// DocEnd
+void Scanner::ScanDocEnd() {
+ PopAllIndents();
+ PopAllSimpleKeys();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(3);
+ m_tokens.push(Token(Token::DOC_END, mark));
+}
+
+// FlowStart
+void Scanner::ScanFlowStart() {
+ // flows can be simple keys
+ InsertPotentialSimpleKey();
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ char ch = INPUT.get();
+ FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP);
+ m_flows.push(flowType);
+ Token::TYPE type =
+ (flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START);
+ m_tokens.push(Token(type, mark));
+}
+
+// FlowEnd
+void Scanner::ScanFlowEnd() {
+ if (InBlockContext())
+ throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
+
+ // we might have a solo entry in the flow context
+ if (InFlowContext()) {
+ if (m_flows.top() == FLOW_MAP && VerifySimpleKey())
+ m_tokens.push(Token(Token::VALUE, INPUT.mark()));
+ else if (m_flows.top() == FLOW_SEQ)
+ InvalidateSimpleKey();
+ }
+
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = true;
+
+ // eat
+ Mark mark = INPUT.mark();
+ char ch = INPUT.get();
+
+ // check that it matches the start
+ FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP);
+ if (m_flows.top() != flowType)
+ throw ParserException(mark, ErrorMsg::FLOW_END);
+ m_flows.pop();
+
+ Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END);
+ m_tokens.push(Token(type, mark));
+}
+
+// FlowEntry
+void Scanner::ScanFlowEntry() {
+ // we might have a solo entry in the flow context
+ if (InFlowContext()) {
+ if (m_flows.top() == FLOW_MAP && VerifySimpleKey())
+ m_tokens.push(Token(Token::VALUE, INPUT.mark()));
+ else if (m_flows.top() == FLOW_SEQ)
+ InvalidateSimpleKey();
+ }
+
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::FLOW_ENTRY, mark));
+}
+
+// BlockEntry
+void Scanner::ScanBlockEntry() {
+ // we better be in the block context!
+ if (InFlowContext())
+ throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
+
+ // can we put it here?
+ if (!m_simpleKeyAllowed)
+ throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
+
+ PushIndentTo(INPUT.column(), IndentMarker::SEQ);
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::BLOCK_ENTRY, mark));
+}
+
+// Key
+void Scanner::ScanKey() {
+ // handle keys diffently in the block context (and manage indents)
+ if (InBlockContext()) {
+ if (!m_simpleKeyAllowed)
+ throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY);
+
+ PushIndentTo(INPUT.column(), IndentMarker::MAP);
+ }
+
+ // can only put a simple key here if we're in block context
+ m_simpleKeyAllowed = InBlockContext();
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::KEY, mark));
+}
+
+// Value
+void Scanner::ScanValue() {
+ // and check that simple key
+ bool isSimpleKey = VerifySimpleKey();
+ m_canBeJSONFlow = false;
+
+ if (isSimpleKey) {
+ // can't follow a simple key with another simple key (dunno why, though - it
+ // seems fine)
+ m_simpleKeyAllowed = false;
+ } else {
+ // handle values diffently in the block context (and manage indents)
+ if (InBlockContext()) {
+ if (!m_simpleKeyAllowed)
+ throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
+
+ PushIndentTo(INPUT.column(), IndentMarker::MAP);
+ }
+
+ // can only put a simple key here if we're in block context
+ m_simpleKeyAllowed = InBlockContext();
+ }
+
+ // eat
+ Mark mark = INPUT.mark();
+ INPUT.eat(1);
+ m_tokens.push(Token(Token::VALUE, mark));
+}
+
+// AnchorOrAlias
+void Scanner::ScanAnchorOrAlias() {
+ bool alias;
+ std::string name;
+
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ // eat the indicator
+ Mark mark = INPUT.mark();
+ char indicator = INPUT.get();
+ alias = (indicator == Keys::Alias);
+
+ // now eat the content
+ while (INPUT && Exp::Anchor().Matches(INPUT))
+ name += INPUT.get();
+
+ // we need to have read SOMETHING!
+ if (name.empty())
+ throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND
+ : ErrorMsg::ANCHOR_NOT_FOUND);
+
+ // and needs to end correctly
+ if (INPUT && !Exp::AnchorEnd().Matches(INPUT))
+ throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS
+ : ErrorMsg::CHAR_IN_ANCHOR);
+
+ // and we're done
+ Token token(alias ? Token::ALIAS : Token::ANCHOR, mark);
+ token.value = name;
+ m_tokens.push(token);
+}
+
+// Tag
+void Scanner::ScanTag() {
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = false;
+
+ Token token(Token::TAG, INPUT.mark());
+
+ // eat the indicator
+ INPUT.get();
+
+ if (INPUT && INPUT.peek() == Keys::VerbatimTagStart) {
+ std::string tag = ScanVerbatimTag(INPUT);
+
+ token.value = tag;
+ token.data = Tag::VERBATIM;
+ } else {
+ bool canBeHandle;
+ token.value = ScanTagHandle(INPUT, canBeHandle);
+ if (!canBeHandle && token.value.empty())
+ token.data = Tag::NON_SPECIFIC;
+ else if (token.value.empty())
+ token.data = Tag::SECONDARY_HANDLE;
+ else
+ token.data = Tag::PRIMARY_HANDLE;
+
+ // is there a suffix?
+ if (canBeHandle && INPUT.peek() == Keys::Tag) {
+ // eat the indicator
+ INPUT.get();
+ token.params.push_back(ScanTagSuffix(INPUT));
+ token.data = Tag::NAMED_HANDLE;
+ }
+ }
+
+ m_tokens.push(token);
+}
+
+// PlainScalar
+void Scanner::ScanPlainScalar() {
+ std::string scalar;
+
+ // set up the scanning parameters
+ ScanScalarParams params;
+ params.end =
+ (InFlowContext() ? &Exp::ScanScalarEndInFlow() : &Exp::ScanScalarEnd());
+ params.eatEnd = false;
+ params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
+ params.fold = FOLD_FLOW;
+ params.eatLeadingWhitespace = true;
+ params.trimTrailingSpaces = true;
+ params.chomp = STRIP;
+ params.onDocIndicator = BREAK;
+ params.onTabInIndentation = THROW;
+
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+
+ Mark mark = INPUT.mark();
+ scalar = ScanScalar(INPUT, params);
+
+ // can have a simple key only if we ended the scalar by starting a new line
+ m_simpleKeyAllowed = params.leadingSpaces;
+ m_canBeJSONFlow = false;
+
+ // finally, check and see if we ended on an illegal character
+ // if(Exp::IllegalCharInScalar.Matches(INPUT))
+ // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
+
+ Token token(Token::PLAIN_SCALAR, mark);
+ token.value = scalar;
+ m_tokens.push(token);
+}
+
+// QuotedScalar
+void Scanner::ScanQuotedScalar() {
+ std::string scalar;
+
+ // peek at single or double quote (don't eat because we need to preserve (for
+ // the time being) the input position)
+ char quote = INPUT.peek();
+ bool single = (quote == '\'');
+
+ // setup the scanning parameters
+ ScanScalarParams params;
+ RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
+ params.end = &end;
+ params.eatEnd = true;
+ params.escape = (single ? '\'' : '\\');
+ params.indent = 0;
+ params.fold = FOLD_FLOW;
+ params.eatLeadingWhitespace = true;
+ params.trimTrailingSpaces = false;
+ params.chomp = CLIP;
+ params.onDocIndicator = THROW;
+
+ // insert a potential simple key
+ InsertPotentialSimpleKey();
+
+ Mark mark = INPUT.mark();
+
+ // now eat that opening quote
+ INPUT.get();
+
+ // and scan
+ scalar = ScanScalar(INPUT, params);
+ m_simpleKeyAllowed = false;
+ m_canBeJSONFlow = true;
+
+ Token token(Token::NON_PLAIN_SCALAR, mark);
+ token.value = scalar;
+ m_tokens.push(token);
+}
+
+// BlockScalarToken
+// . These need a little extra processing beforehand.
+// . We need to scan the line where the indicator is (this doesn't count as part
+// of the scalar),
+// and then we need to figure out what level of indentation we'll be using.
+void Scanner::ScanBlockScalar() {
+ std::string scalar;
+
+ ScanScalarParams params;
+ params.indent = 1;
+ params.detectIndent = true;
+
+ // eat block indicator ('|' or '>')
+ Mark mark = INPUT.mark();
+ char indicator = INPUT.get();
+ params.fold = (indicator == Keys::FoldedScalar ? FOLD_BLOCK : DONT_FOLD);
+
+ // eat chomping/indentation indicators
+ params.chomp = CLIP;
+ int n = Exp::Chomp().Match(INPUT);
+ for (int i = 0; i < n; i++) {
+ char ch = INPUT.get();
+ if (ch == '+')
+ params.chomp = KEEP;
+ else if (ch == '-')
+ params.chomp = STRIP;
+ else if (Exp::Digit().Matches(ch)) {
+ if (ch == '0')
+ throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
+
+ params.indent = ch - '0';
+ params.detectIndent = false;
+ }
+ }
+
+ // now eat whitespace
+ while (Exp::Blank().Matches(INPUT))
+ INPUT.eat(1);
+
+ // and comments to the end of the line
+ if (Exp::Comment().Matches(INPUT))
+ while (INPUT && !Exp::Break().Matches(INPUT))
+ INPUT.eat(1);
+
+ // if it's not a line break, then we ran into a bad character inline
+ if (INPUT && !Exp::Break().Matches(INPUT))
+ throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
+
+ // set the initial indentation
+ if (GetTopIndent() >= 0)
+ params.indent += GetTopIndent();
+
+ params.eatLeadingWhitespace = false;
+ params.trimTrailingSpaces = false;
+ params.onTabInIndentation = THROW;
+
+ scalar = ScanScalar(INPUT, params);
+
+ // simple keys always ok after block scalars (since we're gonna start a new
+ // line anyways)
+ m_simpleKeyAllowed = true;
+ m_canBeJSONFlow = false;
+
+ Token token(Token::NON_PLAIN_SCALAR, mark);
+ token.value = scalar;
+ m_tokens.push(token);
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/setting.h b/src/libs/3rdparty/yaml-cpp/src/setting.h
new file mode 100644
index 0000000000..b78d40e2e8
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/setting.h
@@ -0,0 +1,95 @@
+#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <memory>
+#include <vector>
+#include "yaml-cpp/noncopyable.h"
+
+namespace YAML {
+class SettingChangeBase;
+
+template <typename T>
+class Setting {
+ public:
+ Setting() : m_value() {}
+
+ const T get() const { return m_value; }
+ std::unique_ptr<SettingChangeBase> set(const T& value);
+ void restore(const Setting<T>& oldSetting) { m_value = oldSetting.get(); }
+
+ private:
+ T m_value;
+};
+
+class SettingChangeBase {
+ public:
+ virtual ~SettingChangeBase() {}
+ virtual void pop() = 0;
+};
+
+template <typename T>
+class SettingChange : public SettingChangeBase {
+ public:
+ SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) {
+ // copy old setting to save its state
+ m_oldSetting = *pSetting;
+ }
+
+ virtual void pop() { m_pCurSetting->restore(m_oldSetting); }
+
+ private:
+ Setting<T>* m_pCurSetting;
+ Setting<T> m_oldSetting;
+};
+
+template <typename T>
+inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
+ std::unique_ptr<SettingChangeBase> pChange(new SettingChange<T>(this));
+ m_value = value;
+ return pChange;
+}
+
+class SettingChanges : private noncopyable {
+ public:
+ SettingChanges() {}
+ ~SettingChanges() { clear(); }
+
+ void clear() {
+ restore();
+ m_settingChanges.clear();
+ }
+
+ void restore() {
+ for (setting_changes::const_iterator it = m_settingChanges.begin();
+ it != m_settingChanges.end(); ++it)
+ (*it)->pop();
+ }
+
+ void push(std::unique_ptr<SettingChangeBase> pSettingChange) {
+ m_settingChanges.push_back(std::move(pSettingChange));
+ }
+
+ // like std::unique_ptr - assignment is transfer of ownership
+ SettingChanges& operator=(SettingChanges&& rhs) {
+ if (this == &rhs)
+ return *this;
+
+ clear();
+ std::swap(m_settingChanges, rhs.m_settingChanges);
+
+ return *this;
+ }
+
+ private:
+ typedef std::vector<std::unique_ptr<SettingChangeBase>> setting_changes;
+ setting_changes m_settingChanges;
+};
+}
+
+#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp b/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp
new file mode 100644
index 0000000000..70f56b6ae4
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/simplekey.cpp
@@ -0,0 +1,128 @@
+#include "scanner.h"
+#include "token.h"
+
+namespace YAML {
+struct Mark;
+
+Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_)
+ : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {}
+
+void Scanner::SimpleKey::Validate() {
+ // Note: pIndent will *not* be garbage here;
+ // we "garbage collect" them so we can
+ // always refer to them
+ if (pIndent)
+ pIndent->status = IndentMarker::VALID;
+ if (pMapStart)
+ pMapStart->status = Token::VALID;
+ if (pKey)
+ pKey->status = Token::VALID;
+}
+
+void Scanner::SimpleKey::Invalidate() {
+ if (pIndent)
+ pIndent->status = IndentMarker::INVALID;
+ if (pMapStart)
+ pMapStart->status = Token::INVALID;
+ if (pKey)
+ pKey->status = Token::INVALID;
+}
+
+// CanInsertPotentialSimpleKey
+bool Scanner::CanInsertPotentialSimpleKey() const {
+ if (!m_simpleKeyAllowed)
+ return false;
+
+ return !ExistsActiveSimpleKey();
+}
+
+// ExistsActiveSimpleKey
+// . Returns true if there's a potential simple key at our flow level
+// (there's allowed at most one per flow level, i.e., at the start of the flow
+// start token)
+bool Scanner::ExistsActiveSimpleKey() const {
+ if (m_simpleKeys.empty())
+ return false;
+
+ const SimpleKey& key = m_simpleKeys.top();
+ return key.flowLevel == GetFlowLevel();
+}
+
+// InsertPotentialSimpleKey
+// . If we can, add a potential simple key to the queue,
+// and save it on a stack.
+void Scanner::InsertPotentialSimpleKey() {
+ if (!CanInsertPotentialSimpleKey())
+ return;
+
+ SimpleKey key(INPUT.mark(), GetFlowLevel());
+
+ // first add a map start, if necessary
+ if (InBlockContext()) {
+ key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
+ if (key.pIndent) {
+ key.pIndent->status = IndentMarker::UNKNOWN;
+ key.pMapStart = key.pIndent->pStartToken;
+ key.pMapStart->status = Token::UNVERIFIED;
+ }
+ }
+
+ // then add the (now unverified) key
+ m_tokens.push(Token(Token::KEY, INPUT.mark()));
+ key.pKey = &m_tokens.back();
+ key.pKey->status = Token::UNVERIFIED;
+
+ m_simpleKeys.push(key);
+}
+
+// InvalidateSimpleKey
+// . Automatically invalidate the simple key in our flow level
+void Scanner::InvalidateSimpleKey() {
+ if (m_simpleKeys.empty())
+ return;
+
+ // grab top key
+ SimpleKey& key = m_simpleKeys.top();
+ if (key.flowLevel != GetFlowLevel())
+ return;
+
+ key.Invalidate();
+ m_simpleKeys.pop();
+}
+
+// VerifySimpleKey
+// . Determines whether the latest simple key to be added is valid,
+// and if so, makes it valid.
+bool Scanner::VerifySimpleKey() {
+ if (m_simpleKeys.empty())
+ return false;
+
+ // grab top key
+ SimpleKey key = m_simpleKeys.top();
+
+ // only validate if we're in the correct flow level
+ if (key.flowLevel != GetFlowLevel())
+ return false;
+
+ m_simpleKeys.pop();
+
+ bool isValid = true;
+
+ // needs to be less than 1024 characters and inline
+ if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024)
+ isValid = false;
+
+ // invalidate key
+ if (isValid)
+ key.Validate();
+ else
+ key.Invalidate();
+
+ return isValid;
+}
+
+void Scanner::PopAllSimpleKeys() {
+ while (!m_simpleKeys.empty())
+ m_simpleKeys.pop();
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp b/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp
new file mode 100644
index 0000000000..a27c1c3b04
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/singledocparser.cpp
@@ -0,0 +1,414 @@
+#include <algorithm>
+#include <cstdio>
+#include <sstream>
+
+#include "collectionstack.h" // IWYU pragma: keep
+#include "scanner.h"
+#include "singledocparser.h"
+#include "tag.h"
+#include "token.h"
+#include "yaml-cpp/emitterstyle.h"
+#include "yaml-cpp/eventhandler.h"
+#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
+#include "yaml-cpp/mark.h"
+#include "yaml-cpp/null.h"
+
+namespace YAML {
+SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives)
+ : m_scanner(scanner),
+ m_directives(directives),
+ m_pCollectionStack(new CollectionStack),
+ m_curAnchor(0) {}
+
+SingleDocParser::~SingleDocParser() {}
+
+// HandleDocument
+// . Handles the next document
+// . Throws a ParserException on error.
+void SingleDocParser::HandleDocument(EventHandler& eventHandler) {
+ assert(!m_scanner.empty()); // guaranteed that there are tokens
+ assert(!m_curAnchor);
+
+ eventHandler.OnDocumentStart(m_scanner.peek().mark);
+
+ // eat doc start
+ if (m_scanner.peek().type == Token::DOC_START)
+ m_scanner.pop();
+
+ // recurse!
+ HandleNode(eventHandler);
+
+ eventHandler.OnDocumentEnd();
+
+ // and finally eat any doc ends we see
+ while (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
+ m_scanner.pop();
+}
+
+void SingleDocParser::HandleNode(EventHandler& eventHandler) {
+ // an empty node *is* a possibility
+ if (m_scanner.empty()) {
+ eventHandler.OnNull(m_scanner.mark(), NullAnchor);
+ return;
+ }
+
+ // save location
+ Mark mark = m_scanner.peek().mark;
+
+ // special case: a value node by itself must be a map, with no header
+ if (m_scanner.peek().type == Token::VALUE) {
+ eventHandler.OnMapStart(mark, "?", NullAnchor, EmitterStyle::Default);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ }
+
+ // special case: an alias node
+ if (m_scanner.peek().type == Token::ALIAS) {
+ eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
+ m_scanner.pop();
+ return;
+ }
+
+ std::string tag;
+ anchor_t anchor;
+ ParseProperties(tag, anchor);
+
+ const Token& token = m_scanner.peek();
+
+ if (token.type == Token::PLAIN_SCALAR && IsNullString(token.value)) {
+ eventHandler.OnNull(mark, anchor);
+ m_scanner.pop();
+ return;
+ }
+
+ // add non-specific tags
+ if (tag.empty())
+ tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
+
+ // now split based on what kind of node we should be
+ switch (token.type) {
+ case Token::PLAIN_SCALAR:
+ case Token::NON_PLAIN_SCALAR:
+ eventHandler.OnScalar(mark, tag, anchor, token.value);
+ m_scanner.pop();
+ return;
+ case Token::FLOW_SEQ_START:
+ eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Flow);
+ HandleSequence(eventHandler);
+ eventHandler.OnSequenceEnd();
+ return;
+ case Token::BLOCK_SEQ_START:
+ eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Block);
+ HandleSequence(eventHandler);
+ eventHandler.OnSequenceEnd();
+ return;
+ case Token::FLOW_MAP_START:
+ eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ case Token::BLOCK_MAP_START:
+ eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Block);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ case Token::KEY:
+ // compact maps can only go in a flow sequence
+ if (m_pCollectionStack->GetCurCollectionType() ==
+ CollectionType::FlowSeq) {
+ eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow);
+ HandleMap(eventHandler);
+ eventHandler.OnMapEnd();
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (tag == "?")
+ eventHandler.OnNull(mark, anchor);
+ else
+ eventHandler.OnScalar(mark, tag, anchor, "");
+}
+
+void SingleDocParser::HandleSequence(EventHandler& eventHandler) {
+ // split based on start token
+ switch (m_scanner.peek().type) {
+ case Token::BLOCK_SEQ_START:
+ HandleBlockSequence(eventHandler);
+ break;
+ case Token::FLOW_SEQ_START:
+ HandleFlowSequence(eventHandler);
+ break;
+ default:
+ break;
+ }
+}
+
+void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
+
+ while (1) {
+ if (m_scanner.empty())
+ throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ);
+
+ Token token = m_scanner.peek();
+ if (token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
+ throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
+
+ m_scanner.pop();
+ if (token.type == Token::BLOCK_SEQ_END)
+ break;
+
+ // check for null
+ if (!m_scanner.empty()) {
+ const Token& token = m_scanner.peek();
+ if (token.type == Token::BLOCK_ENTRY ||
+ token.type == Token::BLOCK_SEQ_END) {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ continue;
+ }
+ }
+
+ HandleNode(eventHandler);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
+}
+
+void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
+
+ while (1) {
+ if (m_scanner.empty())
+ throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
+
+ // first check for end
+ if (m_scanner.peek().type == Token::FLOW_SEQ_END) {
+ m_scanner.pop();
+ break;
+ }
+
+ // then read the node
+ HandleNode(eventHandler);
+
+ if (m_scanner.empty())
+ throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
+
+ // now eat the separator (or could be a sequence end, which we ignore - but
+ // if it's neither, then it's a bad node)
+ Token& token = m_scanner.peek();
+ if (token.type == Token::FLOW_ENTRY)
+ m_scanner.pop();
+ else if (token.type != Token::FLOW_SEQ_END)
+ throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
+}
+
+void SingleDocParser::HandleMap(EventHandler& eventHandler) {
+ // split based on start token
+ switch (m_scanner.peek().type) {
+ case Token::BLOCK_MAP_START:
+ HandleBlockMap(eventHandler);
+ break;
+ case Token::FLOW_MAP_START:
+ HandleFlowMap(eventHandler);
+ break;
+ case Token::KEY:
+ HandleCompactMap(eventHandler);
+ break;
+ case Token::VALUE:
+ HandleCompactMapWithNoKey(eventHandler);
+ break;
+ default:
+ break;
+ }
+}
+
+void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
+
+ while (1) {
+ if (m_scanner.empty())
+ throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP);
+
+ Token token = m_scanner.peek();
+ if (token.type != Token::KEY && token.type != Token::VALUE &&
+ token.type != Token::BLOCK_MAP_END)
+ throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
+
+ if (token.type == Token::BLOCK_MAP_END) {
+ m_scanner.pop();
+ break;
+ }
+
+ // grab key (if non-null)
+ if (token.type == Token::KEY) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ }
+
+ // now grab value (optional)
+ if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(token.mark, NullAnchor);
+ }
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
+}
+
+void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) {
+ // eat start token
+ m_scanner.pop();
+ m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
+
+ while (1) {
+ if (m_scanner.empty())
+ throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
+
+ Token& token = m_scanner.peek();
+ const Mark mark = token.mark;
+ // first check for end
+ if (token.type == Token::FLOW_MAP_END) {
+ m_scanner.pop();
+ break;
+ }
+
+ // grab key (if non-null)
+ if (token.type == Token::KEY) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(mark, NullAnchor);
+ }
+
+ // now grab value (optional)
+ if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(mark, NullAnchor);
+ }
+
+ if (m_scanner.empty())
+ throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
+
+ // now eat the separator (or could be a map end, which we ignore - but if
+ // it's neither, then it's a bad node)
+ Token& nextToken = m_scanner.peek();
+ if (nextToken.type == Token::FLOW_ENTRY)
+ m_scanner.pop();
+ else if (nextToken.type != Token::FLOW_MAP_END)
+ throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
+}
+
+// . Single "key: value" pair in a flow sequence
+void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) {
+ m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
+
+ // grab key
+ Mark mark = m_scanner.peek().mark;
+ m_scanner.pop();
+ HandleNode(eventHandler);
+
+ // now grab value (optional)
+ if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
+ m_scanner.pop();
+ HandleNode(eventHandler);
+ } else {
+ eventHandler.OnNull(mark, NullAnchor);
+ }
+
+ m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
+}
+
+// . Single ": value" pair in a flow sequence
+void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) {
+ m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
+
+ // null key
+ eventHandler.OnNull(m_scanner.peek().mark, NullAnchor);
+
+ // grab value
+ m_scanner.pop();
+ HandleNode(eventHandler);
+
+ m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
+}
+
+// ParseProperties
+// . Grabs any tag or anchor tokens and deals with them.
+void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) {
+ tag.clear();
+ anchor = NullAnchor;
+
+ while (1) {
+ if (m_scanner.empty())
+ return;
+
+ switch (m_scanner.peek().type) {
+ case Token::TAG:
+ ParseTag(tag);
+ break;
+ case Token::ANCHOR:
+ ParseAnchor(anchor);
+ break;
+ default:
+ return;
+ }
+ }
+}
+
+void SingleDocParser::ParseTag(std::string& tag) {
+ Token& token = m_scanner.peek();
+ if (!tag.empty())
+ throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
+
+ Tag tagInfo(token);
+ tag = tagInfo.Translate(m_directives);
+ m_scanner.pop();
+}
+
+void SingleDocParser::ParseAnchor(anchor_t& anchor) {
+ Token& token = m_scanner.peek();
+ if (anchor)
+ throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
+
+ anchor = RegisterAnchor(token.value);
+ m_scanner.pop();
+}
+
+anchor_t SingleDocParser::RegisterAnchor(const std::string& name) {
+ if (name.empty())
+ return NullAnchor;
+
+ return m_anchors[name] = ++m_curAnchor;
+}
+
+anchor_t SingleDocParser::LookupAnchor(const Mark& mark,
+ const std::string& name) const {
+ Anchors::const_iterator it = m_anchors.find(name);
+ if (it == m_anchors.end())
+ throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
+
+ return it->second;
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/singledocparser.h b/src/libs/3rdparty/yaml-cpp/src/singledocparser.h
new file mode 100644
index 0000000000..2b92067cdd
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/singledocparser.h
@@ -0,0 +1,65 @@
+#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "yaml-cpp/anchor.h"
+#include "yaml-cpp/noncopyable.h"
+
+namespace YAML {
+class CollectionStack;
+class EventHandler;
+class Node;
+class Scanner;
+struct Directives;
+struct Mark;
+struct Token;
+
+class SingleDocParser : private noncopyable {
+ public:
+ SingleDocParser(Scanner& scanner, const Directives& directives);
+ ~SingleDocParser();
+
+ void HandleDocument(EventHandler& eventHandler);
+
+ private:
+ void HandleNode(EventHandler& eventHandler);
+
+ void HandleSequence(EventHandler& eventHandler);
+ void HandleBlockSequence(EventHandler& eventHandler);
+ void HandleFlowSequence(EventHandler& eventHandler);
+
+ void HandleMap(EventHandler& eventHandler);
+ void HandleBlockMap(EventHandler& eventHandler);
+ void HandleFlowMap(EventHandler& eventHandler);
+ void HandleCompactMap(EventHandler& eventHandler);
+ void HandleCompactMapWithNoKey(EventHandler& eventHandler);
+
+ void ParseProperties(std::string& tag, anchor_t& anchor);
+ void ParseTag(std::string& tag);
+ void ParseAnchor(anchor_t& anchor);
+
+ anchor_t RegisterAnchor(const std::string& name);
+ anchor_t LookupAnchor(const Mark& mark, const std::string& name) const;
+
+ private:
+ Scanner& m_scanner;
+ const Directives& m_directives;
+ std::unique_ptr<CollectionStack> m_pCollectionStack;
+
+ typedef std::map<std::string, anchor_t> Anchors;
+ Anchors m_anchors;
+
+ anchor_t m_curAnchor;
+};
+}
+
+#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/stream.cpp b/src/libs/3rdparty/yaml-cpp/src/stream.cpp
new file mode 100644
index 0000000000..3b013cfa7d
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/stream.cpp
@@ -0,0 +1,448 @@
+#include <iostream>
+
+#include "stream.h"
+
+#ifndef YAML_PREFETCH_SIZE
+#define YAML_PREFETCH_SIZE 2048
+#endif
+
+#define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
+#define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A))
+
+#define CP_REPLACEMENT_CHARACTER (0xFFFD)
+
+namespace YAML {
+enum UtfIntroState {
+ uis_start,
+ uis_utfbe_b1,
+ uis_utf32be_b2,
+ uis_utf32be_bom3,
+ uis_utf32be,
+ uis_utf16be,
+ uis_utf16be_bom1,
+ uis_utfle_bom1,
+ uis_utf16le_bom2,
+ uis_utf32le_bom3,
+ uis_utf16le,
+ uis_utf32le,
+ uis_utf8_imp,
+ uis_utf16le_imp,
+ uis_utf32le_imp3,
+ uis_utf8_bom1,
+ uis_utf8_bom2,
+ uis_utf8,
+ uis_error
+};
+
+enum UtfIntroCharType {
+ uict00,
+ uictBB,
+ uictBF,
+ uictEF,
+ uictFE,
+ uictFF,
+ uictAscii,
+ uictOther,
+ uictMax
+};
+
+static bool s_introFinalState[] = {
+ false, // uis_start
+ false, // uis_utfbe_b1
+ false, // uis_utf32be_b2
+ false, // uis_utf32be_bom3
+ true, // uis_utf32be
+ true, // uis_utf16be
+ false, // uis_utf16be_bom1
+ false, // uis_utfle_bom1
+ false, // uis_utf16le_bom2
+ false, // uis_utf32le_bom3
+ true, // uis_utf16le
+ true, // uis_utf32le
+ false, // uis_utf8_imp
+ false, // uis_utf16le_imp
+ false, // uis_utf32le_imp3
+ false, // uis_utf8_bom1
+ false, // uis_utf8_bom2
+ true, // uis_utf8
+ true, // uis_error
+};
+
+static UtfIntroState s_introTransitions[][uictMax] = {
+ // uict00, uictBB, uictBF, uictEF,
+ // uictFE, uictFF, uictAscii, uictOther
+ {uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1,
+ uis_utfle_bom1, uis_utf8_imp, uis_utf8},
+ {uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
+ uis_utf16be, uis_utf8},
+ {uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8,
+ uis_utf8, uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8,
+ uis_utf8},
+ {uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be,
+ uis_utf32be, uis_utf32be, uis_utf32be},
+ {uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be,
+ uis_utf16be, uis_utf16be, uis_utf16be},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8,
+ uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8,
+ uis_utf8, uis_utf8},
+ {uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
+ uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
+ uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
+ uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le,
+ uis_utf32le, uis_utf32le, uis_utf32le},
+ {uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
+ uis_utf8, uis_utf8},
+ {uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
+ uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
+ uis_utf16le, uis_utf16le, uis_utf16le},
+ {uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
+ uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
+ uis_utf8},
+ {uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
+ uis_utf8},
+};
+
+static char s_introUngetCount[][uictMax] = {
+ // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
+ {0, 1, 1, 0, 0, 0, 0, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2},
+ {3, 3, 3, 3, 0, 3, 3, 3},
+ {4, 4, 4, 4, 4, 0, 4, 4},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {2, 2, 2, 2, 2, 0, 2, 2},
+ {2, 2, 2, 2, 0, 2, 2, 2},
+ {0, 1, 1, 1, 1, 1, 1, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ {0, 2, 2, 2, 2, 2, 2, 2},
+ {0, 3, 3, 3, 3, 3, 3, 3},
+ {4, 4, 4, 4, 4, 4, 4, 4},
+ {2, 0, 2, 2, 2, 2, 2, 2},
+ {3, 3, 0, 3, 3, 3, 3, 3},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+};
+
+inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
+ if (std::istream::traits_type::eof() == ch) {
+ return uictOther;
+ }
+
+ switch (ch) {
+ case 0:
+ return uict00;
+ case 0xBB:
+ return uictBB;
+ case 0xBF:
+ return uictBF;
+ case 0xEF:
+ return uictEF;
+ case 0xFE:
+ return uictFE;
+ case 0xFF:
+ return uictFF;
+ }
+
+ if ((ch > 0) && (ch < 0xFF)) {
+ return uictAscii;
+ }
+
+ return uictOther;
+}
+
+inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits,
+ unsigned char rshift) {
+ const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits);
+ const unsigned char mask = (0xFF >> (lead_bits + 1));
+ return static_cast<char>(
+ static_cast<unsigned char>(header | ((ch >> rshift) & mask)));
+}
+
+inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) {
+ // We are not allowed to queue the Stream::eof() codepoint, so
+ // replace it with CP_REPLACEMENT_CHARACTER
+ if (static_cast<unsigned long>(Stream::eof()) == ch) {
+ ch = CP_REPLACEMENT_CHARACTER;
+ }
+
+ if (ch < 0x80) {
+ q.push_back(Utf8Adjust(ch, 0, 0));
+ } else if (ch < 0x800) {
+ q.push_back(Utf8Adjust(ch, 2, 6));
+ q.push_back(Utf8Adjust(ch, 1, 0));
+ } else if (ch < 0x10000) {
+ q.push_back(Utf8Adjust(ch, 3, 12));
+ q.push_back(Utf8Adjust(ch, 1, 6));
+ q.push_back(Utf8Adjust(ch, 1, 0));
+ } else {
+ q.push_back(Utf8Adjust(ch, 4, 18));
+ q.push_back(Utf8Adjust(ch, 1, 12));
+ q.push_back(Utf8Adjust(ch, 1, 6));
+ q.push_back(Utf8Adjust(ch, 1, 0));
+ }
+}
+
+Stream::Stream(std::istream& input)
+ : m_input(input),
+ m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
+ m_nPrefetchedAvailable(0),
+ m_nPrefetchedUsed(0) {
+ typedef std::istream::traits_type char_traits;
+
+ if (!input)
+ return;
+
+ // Determine (or guess) the character-set by reading the BOM, if any. See
+ // the YAML specification for the determination algorithm.
+ char_traits::int_type intro[4];
+ int nIntroUsed = 0;
+ UtfIntroState state = uis_start;
+ for (; !s_introFinalState[state];) {
+ std::istream::int_type ch = input.get();
+ intro[nIntroUsed++] = ch;
+ UtfIntroCharType charType = IntroCharTypeOf(ch);
+ UtfIntroState newState = s_introTransitions[state][charType];
+ int nUngets = s_introUngetCount[state][charType];
+ if (nUngets > 0) {
+ input.clear();
+ for (; nUngets > 0; --nUngets) {
+ if (char_traits::eof() != intro[--nIntroUsed])
+ input.putback(char_traits::to_char_type(intro[nIntroUsed]));
+ }
+ }
+ state = newState;
+ }
+
+ switch (state) {
+ case uis_utf8:
+ m_charSet = utf8;
+ break;
+ case uis_utf16le:
+ m_charSet = utf16le;
+ break;
+ case uis_utf16be:
+ m_charSet = utf16be;
+ break;
+ case uis_utf32le:
+ m_charSet = utf32le;
+ break;
+ case uis_utf32be:
+ m_charSet = utf32be;
+ break;
+ default:
+ m_charSet = utf8;
+ break;
+ }
+
+ ReadAheadTo(0);
+}
+
+Stream::~Stream() { delete[] m_pPrefetched; }
+
+char Stream::peek() const {
+ if (m_readahead.empty()) {
+ return Stream::eof();
+ }
+
+ return m_readahead[0];
+}
+
+Stream::operator bool() const {
+ return m_input.good() ||
+ (!m_readahead.empty() && m_readahead[0] != Stream::eof());
+}
+
+// get
+// . Extracts a character from the stream and updates our position
+char Stream::get() {
+ char ch = peek();
+ AdvanceCurrent();
+ m_mark.column++;
+
+ if (ch == '\n') {
+ m_mark.column = 0;
+ m_mark.line++;
+ }
+
+ return ch;
+}
+
+// get
+// . Extracts 'n' characters from the stream and updates our position
+std::string Stream::get(int n) {
+ std::string ret;
+ ret.reserve(n);
+ for (int i = 0; i < n; i++)
+ ret += get();
+ return ret;
+}
+
+// eat
+// . Eats 'n' characters and updates our position.
+void Stream::eat(int n) {
+ for (int i = 0; i < n; i++)
+ get();
+}
+
+void Stream::AdvanceCurrent() {
+ if (!m_readahead.empty()) {
+ m_readahead.pop_front();
+ m_mark.pos++;
+ }
+
+ ReadAheadTo(0);
+}
+
+bool Stream::_ReadAheadTo(size_t i) const {
+ while (m_input.good() && (m_readahead.size() <= i)) {
+ switch (m_charSet) {
+ case utf8:
+ StreamInUtf8();
+ break;
+ case utf16le:
+ StreamInUtf16();
+ break;
+ case utf16be:
+ StreamInUtf16();
+ break;
+ case utf32le:
+ StreamInUtf32();
+ break;
+ case utf32be:
+ StreamInUtf32();
+ break;
+ }
+ }
+
+ // signal end of stream
+ if (!m_input.good())
+ m_readahead.push_back(Stream::eof());
+
+ return m_readahead.size() > i;
+}
+
+void Stream::StreamInUtf8() const {
+ unsigned char b = GetNextByte();
+ if (m_input.good()) {
+ m_readahead.push_back(b);
+ }
+}
+
+void Stream::StreamInUtf16() const {
+ unsigned long ch = 0;
+ unsigned char bytes[2];
+ int nBigEnd = (m_charSet == utf16be) ? 0 : 1;
+
+ bytes[0] = GetNextByte();
+ bytes[1] = GetNextByte();
+ if (!m_input.good()) {
+ return;
+ }
+ ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
+ static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
+
+ if (ch >= 0xDC00 && ch < 0xE000) {
+ // Trailing (low) surrogate...ugh, wrong order
+ QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
+ return;
+ } else if (ch >= 0xD800 && ch < 0xDC00) {
+ // ch is a leading (high) surrogate
+
+ // Four byte UTF-8 code point
+
+ // Read the trailing (low) surrogate
+ for (;;) {
+ bytes[0] = GetNextByte();
+ bytes[1] = GetNextByte();
+ if (!m_input.good()) {
+ QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
+ return;
+ }
+ unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
+ static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
+ if (chLow < 0xDC00 || chLow >= 0xE000) {
+ // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the
+ // stream.
+ QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
+
+ // Deal with the next UTF-16 unit
+ if (chLow < 0xD800 || chLow >= 0xE000) {
+ // Easiest case: queue the codepoint and return
+ QueueUnicodeCodepoint(m_readahead, ch);
+ return;
+ } else {
+ // Start the loop over with the new high surrogate
+ ch = chLow;
+ continue;
+ }
+ }
+
+ // Select the payload bits from the high surrogate
+ ch &= 0x3FF;
+ ch <<= 10;
+
+ // Include bits from low surrogate
+ ch |= (chLow & 0x3FF);
+
+ // Add the surrogacy offset
+ ch += 0x10000;
+ break;
+ }
+ }
+
+ QueueUnicodeCodepoint(m_readahead, ch);
+}
+
+inline char* ReadBuffer(unsigned char* pBuffer) {
+ return reinterpret_cast<char*>(pBuffer);
+}
+
+unsigned char Stream::GetNextByte() const {
+ if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) {
+ std::streambuf* pBuf = m_input.rdbuf();
+ m_nPrefetchedAvailable = static_cast<std::size_t>(
+ pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE));
+ m_nPrefetchedUsed = 0;
+ if (!m_nPrefetchedAvailable) {
+ m_input.setstate(std::ios_base::eofbit);
+ }
+
+ if (0 == m_nPrefetchedAvailable) {
+ return 0;
+ }
+ }
+
+ return m_pPrefetched[m_nPrefetchedUsed++];
+}
+
+void Stream::StreamInUtf32() const {
+ static int indexes[2][4] = {{3, 2, 1, 0}, {0, 1, 2, 3}};
+
+ unsigned long ch = 0;
+ unsigned char bytes[4];
+ int* pIndexes = (m_charSet == utf32be) ? indexes[1] : indexes[0];
+
+ bytes[0] = GetNextByte();
+ bytes[1] = GetNextByte();
+ bytes[2] = GetNextByte();
+ bytes[3] = GetNextByte();
+ if (!m_input.good()) {
+ return;
+ }
+
+ for (int i = 0; i < 4; ++i) {
+ ch <<= 8;
+ ch |= bytes[pIndexes[i]];
+ }
+
+ QueueUnicodeCodepoint(m_readahead, ch);
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/stream.h b/src/libs/3rdparty/yaml-cpp/src/stream.h
new file mode 100644
index 0000000000..42d542d5b1
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/stream.h
@@ -0,0 +1,76 @@
+#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/noncopyable.h"
+#include "yaml-cpp/mark.h"
+#include <cstddef>
+#include <deque>
+#include <ios>
+#include <iostream>
+#include <set>
+#include <string>
+
+namespace YAML {
+class Stream : private noncopyable {
+ public:
+ friend class StreamCharSource;
+
+ Stream(std::istream& input);
+ ~Stream();
+
+ operator bool() const;
+ bool operator!() const { return !static_cast<bool>(*this); }
+
+ char peek() const;
+ char get();
+ std::string get(int n);
+ void eat(int n = 1);
+
+ static char eof() { return 0x04; }
+
+ const Mark mark() const { return m_mark; }
+ int pos() const { return m_mark.pos; }
+ int line() const { return m_mark.line; }
+ int column() const { return m_mark.column; }
+ void ResetColumn() { m_mark.column = 0; }
+
+ private:
+ enum CharacterSet { utf8, utf16le, utf16be, utf32le, utf32be };
+
+ std::istream& m_input;
+ Mark m_mark;
+
+ CharacterSet m_charSet;
+ mutable std::deque<char> m_readahead;
+ unsigned char* const m_pPrefetched;
+ mutable size_t m_nPrefetchedAvailable;
+ mutable size_t m_nPrefetchedUsed;
+
+ void AdvanceCurrent();
+ char CharAt(size_t i) const;
+ bool ReadAheadTo(size_t i) const;
+ bool _ReadAheadTo(size_t i) const;
+ void StreamInUtf8() const;
+ void StreamInUtf16() const;
+ void StreamInUtf32() const;
+ unsigned char GetNextByte() const;
+};
+
+// CharAt
+// . Unchecked access
+inline char Stream::CharAt(size_t i) const { return m_readahead[i]; }
+
+inline bool Stream::ReadAheadTo(size_t i) const {
+ if (m_readahead.size() > i)
+ return true;
+ return _ReadAheadTo(i);
+}
+}
+
+#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h b/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h
new file mode 100644
index 0000000000..624599e65d
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/streamcharsource.h
@@ -0,0 +1,48 @@
+#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/noncopyable.h"
+#include <cstddef>
+
+namespace YAML {
+class StreamCharSource {
+ public:
+ StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {}
+ StreamCharSource(const StreamCharSource& source)
+ : m_offset(source.m_offset), m_stream(source.m_stream) {}
+ ~StreamCharSource() {}
+
+ operator bool() const;
+ char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); }
+ bool operator!() const { return !static_cast<bool>(*this); }
+
+ const StreamCharSource operator+(int i) const;
+
+ private:
+ std::size_t m_offset;
+ const Stream& m_stream;
+
+ StreamCharSource& operator=(const StreamCharSource&); // non-assignable
+};
+
+inline StreamCharSource::operator bool() const {
+ return m_stream.ReadAheadTo(m_offset);
+}
+
+inline const StreamCharSource StreamCharSource::operator+(int i) const {
+ StreamCharSource source(*this);
+ if (static_cast<int>(source.m_offset) + i >= 0)
+ source.m_offset += i;
+ else
+ source.m_offset = 0;
+ return source;
+}
+}
+
+#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/stringsource.h b/src/libs/3rdparty/yaml-cpp/src/stringsource.h
new file mode 100644
index 0000000000..6fee44bb28
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/stringsource.h
@@ -0,0 +1,48 @@
+#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <cstddef>
+
+namespace YAML {
+class StringCharSource {
+ public:
+ StringCharSource(const char* str, std::size_t size)
+ : m_str(str), m_size(size), m_offset(0) {}
+
+ operator bool() const { return m_offset < m_size; }
+ char operator[](std::size_t i) const { return m_str[m_offset + i]; }
+ bool operator!() const { return !static_cast<bool>(*this); }
+
+ const StringCharSource operator+(int i) const {
+ StringCharSource source(*this);
+ if (static_cast<int>(source.m_offset) + i >= 0)
+ source.m_offset += i;
+ else
+ source.m_offset = 0;
+ return source;
+ }
+
+ StringCharSource& operator++() {
+ ++m_offset;
+ return *this;
+ }
+
+ StringCharSource& operator+=(std::size_t offset) {
+ m_offset += offset;
+ return *this;
+ }
+
+ private:
+ const char* m_str;
+ std::size_t m_size;
+ std::size_t m_offset;
+};
+}
+
+#endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/tag.cpp b/src/libs/3rdparty/yaml-cpp/src/tag.cpp
new file mode 100644
index 0000000000..51435520e4
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/tag.cpp
@@ -0,0 +1,49 @@
+#include <cassert>
+#include <stdexcept>
+
+#include "directives.h" // IWYU pragma: keep
+#include "tag.h"
+#include "token.h"
+
+namespace YAML {
+Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) {
+ switch (type) {
+ case VERBATIM:
+ value = token.value;
+ break;
+ case PRIMARY_HANDLE:
+ value = token.value;
+ break;
+ case SECONDARY_HANDLE:
+ value = token.value;
+ break;
+ case NAMED_HANDLE:
+ handle = token.value;
+ value = token.params[0];
+ break;
+ case NON_SPECIFIC:
+ break;
+ default:
+ assert(false);
+ }
+}
+
+const std::string Tag::Translate(const Directives& directives) {
+ switch (type) {
+ case VERBATIM:
+ return value;
+ case PRIMARY_HANDLE:
+ return directives.TranslateTagHandle("!") + value;
+ case SECONDARY_HANDLE:
+ return directives.TranslateTagHandle("!!") + value;
+ case NAMED_HANDLE:
+ return directives.TranslateTagHandle("!" + handle + "!") + value;
+ case NON_SPECIFIC:
+ // TODO:
+ return "!";
+ default:
+ assert(false);
+ }
+ throw std::runtime_error("yaml-cpp: internal error, bad tag type");
+}
+}
diff --git a/src/libs/3rdparty/yaml-cpp/src/tag.h b/src/libs/3rdparty/yaml-cpp/src/tag.h
new file mode 100644
index 0000000000..ac30673b9e
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/tag.h
@@ -0,0 +1,33 @@
+#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include <string>
+
+namespace YAML {
+struct Directives;
+struct Token;
+
+struct Tag {
+ enum TYPE {
+ VERBATIM,
+ PRIMARY_HANDLE,
+ SECONDARY_HANDLE,
+ NAMED_HANDLE,
+ NON_SPECIFIC
+ };
+
+ Tag(const Token& token);
+ const std::string Translate(const Directives& directives);
+
+ TYPE type;
+ std::string handle, value;
+};
+}
+
+#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/src/token.h b/src/libs/3rdparty/yaml-cpp/src/token.h
new file mode 100644
index 0000000000..ad0b7d0a00
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/src/token.h
@@ -0,0 +1,69 @@
+#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+#define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+
+#if defined(_MSC_VER) || \
+ (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
+ (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
+#pragma once
+#endif
+
+#include "yaml-cpp/mark.h"
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace YAML {
+const std::string TokenNames[] = {
+ "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START", "BLOCK_MAP_START",
+ "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY", "FLOW_SEQ_START",
+ "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END", "FLOW_MAP_COMPACT",
+ "FLOW_ENTRY", "KEY", "VALUE", "ANCHOR", "ALIAS", "TAG", "SCALAR"};
+
+struct Token {
+ // enums
+ enum STATUS { VALID, INVALID, UNVERIFIED };
+ enum TYPE {
+ DIRECTIVE,
+ DOC_START,
+ DOC_END,
+ BLOCK_SEQ_START,
+ BLOCK_MAP_START,
+ BLOCK_SEQ_END,
+ BLOCK_MAP_END,
+ BLOCK_ENTRY,
+ FLOW_SEQ_START,
+ FLOW_MAP_START,
+ FLOW_SEQ_END,
+ FLOW_MAP_END,
+ FLOW_MAP_COMPACT,
+ FLOW_ENTRY,
+ KEY,
+ VALUE,
+ ANCHOR,
+ ALIAS,
+ TAG,
+ PLAIN_SCALAR,
+ NON_PLAIN_SCALAR
+ };
+
+ // data
+ Token(TYPE type_, const Mark& mark_)
+ : status(VALID), type(type_), mark(mark_), data(0) {}
+
+ friend std::ostream& operator<<(std::ostream& out, const Token& token) {
+ out << TokenNames[token.type] << std::string(": ") << token.value;
+ for (std::size_t i = 0; i < token.params.size(); i++)
+ out << std::string(" ") << token.params[i];
+ return out;
+ }
+
+ STATUS status;
+ TYPE type;
+ Mark mark;
+ std::string value;
+ std::vector<std::string> params;
+ int data;
+};
+}
+
+#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake
new file mode 100644
index 0000000000..3db7962eaf
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pc.cmake
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+includedir=${prefix}/@INCLUDE_INSTALL_ROOT_DIR@
+libdir=${exec_prefix}/@LIB_INSTALL_DIR@
+
+Name: Yaml-cpp
+Description: A YAML parser and emitter for C++
+Version: @YAML_CPP_VERSION@
+Requires:
+Libs: -L${libdir} -lyaml-cpp
+Cflags: -I${includedir}
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp.pri b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pri
new file mode 100644
index 0000000000..e7416275b9
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pri
@@ -0,0 +1,89 @@
+INCLUDEPATH += $$PWD/include/
+
+HEADERS += \
+ $$PWD/include/yaml-cpp/anchor.h \
+ $$PWD/include/yaml-cpp/binary.h \
+ $$PWD/include/yaml-cpp/dll.h \
+ $$PWD/include/yaml-cpp/emitfromevents.h \
+ $$PWD/include/yaml-cpp/emitter.h \
+ $$PWD/include/yaml-cpp/emitterdef.h \
+ $$PWD/include/yaml-cpp/emittermanip.h \
+ $$PWD/include/yaml-cpp/emitterstyle.h \
+ $$PWD/include/yaml-cpp/eventhandler.h \
+ $$PWD/include/yaml-cpp/exceptions.h \
+ $$PWD/include/yaml-cpp/mark.h \
+ $$PWD/include/yaml-cpp/node/convert.h \
+ $$PWD/include/yaml-cpp/node/detail/bool_type.h \
+ $$PWD/include/yaml-cpp/node/detail/impl.h \
+ $$PWD/include/yaml-cpp/node/detail/iterator.h \
+ $$PWD/include/yaml-cpp/node/detail/iterator_fwd.h \
+ $$PWD/include/yaml-cpp/node/detail/memory.h \
+ $$PWD/include/yaml-cpp/node/detail/node.h \
+ $$PWD/include/yaml-cpp/node/detail/node_data.h \
+ $$PWD/include/yaml-cpp/node/detail/node_iterator.h \
+ $$PWD/include/yaml-cpp/node/detail/node_ref.h \
+ $$PWD/include/yaml-cpp/node/emit.h \
+ $$PWD/include/yaml-cpp/node/impl.h \
+ $$PWD/include/yaml-cpp/node/iterator.h \
+ $$PWD/include/yaml-cpp/node/node.h \
+ $$PWD/include/yaml-cpp/node/parse.h \
+ $$PWD/include/yaml-cpp/node/ptr.h \
+ $$PWD/include/yaml-cpp/node/type.h \
+ $$PWD/include/yaml-cpp/noncopyable.h \
+ $$PWD/include/yaml-cpp/null.h \
+ $$PWD/include/yaml-cpp/ostream_wrapper.h \
+ $$PWD/include/yaml-cpp/parser.h \
+ $$PWD/include/yaml-cpp/stlemitter.h \
+ $$PWD/include/yaml-cpp/traits.h \
+ $$PWD/include/yaml-cpp/yaml.h \
+ $$PWD/src/collectionstack.h \
+ $$PWD/src/directives.h \
+ $$PWD/src/emitterstate.h \
+ $$PWD/src/emitterutils.h \
+ $$PWD/src/exp.h \
+ $$PWD/src/indentation.h \
+ $$PWD/src/nodebuilder.h \
+ $$PWD/src/nodeevents.h \
+ $$PWD/src/ptr_vector.h \
+ $$PWD/src/regex_yaml.h \
+ $$PWD/src/regeximpl.h \
+ $$PWD/src/scanner.h \
+ $$PWD/src/scanscalar.h \
+ $$PWD/src/scantag.h \
+ $$PWD/src/setting.h \
+ $$PWD/src/singledocparser.h \
+ $$PWD/src/stream.h \
+ $$PWD/src/streamcharsource.h \
+ $$PWD/src/stringsource.h \
+ $$PWD/src/tag.h \
+ $$PWD/src/token.h \
+
+SOURCES += \
+ $$PWD/src/binary.cpp \
+ $$PWD/src/convert.cpp \
+ $$PWD/src/directives.cpp \
+ $$PWD/src/emit.cpp \
+ $$PWD/src/emitfromevents.cpp \
+ $$PWD/src/emitter.cpp \
+ $$PWD/src/emitterstate.cpp \
+ $$PWD/src/emitterutils.cpp \
+ $$PWD/src/exceptions.cpp \
+ $$PWD/src/exp.cpp \
+ $$PWD/src/memory.cpp \
+ $$PWD/src/node.cpp \
+ $$PWD/src/node_data.cpp \
+ $$PWD/src/nodebuilder.cpp \
+ $$PWD/src/nodeevents.cpp \
+ $$PWD/src/null.cpp \
+ $$PWD/src/ostream_wrapper.cpp \
+ $$PWD/src/parse.cpp \
+ $$PWD/src/parser.cpp \
+ $$PWD/src/regex_yaml.cpp \
+ $$PWD/src/scanner.cpp \
+ $$PWD/src/scanscalar.cpp \
+ $$PWD/src/scantag.cpp \
+ $$PWD/src/scantoken.cpp \
+ $$PWD/src/simplekey.cpp \
+ $$PWD/src/singledocparser.cpp \
+ $$PWD/src/stream.cpp \
+ $$PWD/src/tag.cpp \
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp.pro b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pro
new file mode 100644
index 0000000000..dc21db2dd7
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/yaml-cpp.pro
@@ -0,0 +1,5 @@
+include(../../../qtcreatorlibrary.pri)
+include(yaml-cpp.pri)
+
+DEFINES += YAML_CPP_DLL yaml_cpp_EXPORTS
+
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs b/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs
new file mode 100644
index 0000000000..9a2d3f96a0
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/yaml-cpp.qbs
@@ -0,0 +1,105 @@
+import qbs 1.0
+
+Project {
+ QtcLibrary {
+ name: "yaml-cpp"
+
+ cpp.defines: base.concat(["YAML_CPP_DLL", "yaml_cpp_EXPORTS"])
+ cpp.includePaths: [product.sourceDirectory + "/include/"]
+
+ files: [
+ "include/yaml-cpp/anchor.h",
+ "include/yaml-cpp/binary.h",
+ "include/yaml-cpp/dll.h",
+ "include/yaml-cpp/emitfromevents.h",
+ "include/yaml-cpp/emitter.h",
+ "include/yaml-cpp/emitterdef.h",
+ "include/yaml-cpp/emittermanip.h",
+ "include/yaml-cpp/emitterstyle.h",
+ "include/yaml-cpp/eventhandler.h",
+ "include/yaml-cpp/exceptions.h",
+ "include/yaml-cpp/mark.h",
+ "include/yaml-cpp/node",
+ "include/yaml-cpp/node/convert.h",
+ "include/yaml-cpp/node/detail",
+ "include/yaml-cpp/node/detail/bool_type.h",
+ "include/yaml-cpp/node/detail/impl.h",
+ "include/yaml-cpp/node/detail/iterator.h",
+ "include/yaml-cpp/node/detail/iterator_fwd.h",
+ "include/yaml-cpp/node/detail/memory.h",
+ "include/yaml-cpp/node/detail/node.h",
+ "include/yaml-cpp/node/detail/node_data.h",
+ "include/yaml-cpp/node/detail/node_iterator.h",
+ "include/yaml-cpp/node/detail/node_ref.h",
+ "include/yaml-cpp/node/emit.h",
+ "include/yaml-cpp/node/impl.h",
+ "include/yaml-cpp/node/iterator.h",
+ "include/yaml-cpp/node/node.h",
+ "include/yaml-cpp/node/parse.h",
+ "include/yaml-cpp/node/ptr.h",
+ "include/yaml-cpp/node/type.h",
+ "include/yaml-cpp/noncopyable.h",
+ "include/yaml-cpp/null.h",
+ "include/yaml-cpp/ostream_wrapper.h",
+ "include/yaml-cpp/parser.h",
+ "include/yaml-cpp/stlemitter.h",
+ "include/yaml-cpp/traits.h",
+ "include/yaml-cpp/yaml.h",
+ "src/binary.cpp",
+ "src/collectionstack.h",
+ "src/convert.cpp",
+ "src/directives.cpp",
+ "src/directives.h",
+ "src/emit.cpp",
+ "src/emitfromevents.cpp",
+ "src/emitter.cpp",
+ "src/emitterstate.cpp",
+ "src/emitterstate.h",
+ "src/emitterutils.cpp",
+ "src/emitterutils.h",
+ "src/exceptions.cpp",
+ "src/exp.cpp",
+ "src/exp.h",
+ "src/indentation.h",
+ "src/memory.cpp",
+ "src/node.cpp",
+ "src/node_data.cpp",
+ "src/nodebuilder.cpp",
+ "src/nodebuilder.h",
+ "src/nodeevents.cpp",
+ "src/nodeevents.h",
+ "src/null.cpp",
+ "src/ostream_wrapper.cpp",
+ "src/parse.cpp",
+ "src/parser.cpp",
+ "src/ptr_vector.h",
+ "src/regex_yaml.cpp",
+ "src/regex_yaml.h",
+ "src/regeximpl.h",
+ "src/scanner.cpp",
+ "src/scanner.h",
+ "src/scanscalar.cpp",
+ "src/scanscalar.h",
+ "src/scantag.cpp",
+ "src/scantag.h",
+ "src/scantoken.cpp",
+ "src/setting.h",
+ "src/simplekey.cpp",
+ "src/singledocparser.cpp",
+ "src/singledocparser.h",
+ "src/stream.cpp",
+ "src/stream.h",
+ "src/streamcharsource.h",
+ "src/stringsource.h",
+ "src/tag.cpp",
+ "src/tag.h",
+ "src/token.h",
+ ]
+
+ Export {
+ Depends { name: "cpp" }
+ cpp.includePaths: [product.sourceDirectory + "/include/"]
+ cpp.defines: base.concat(["YAML_CPP_DLL"])
+ }
+ }
+}
diff --git a/src/libs/3rdparty/yaml-cpp/yaml-cpp_dependencies.pri b/src/libs/3rdparty/yaml-cpp/yaml-cpp_dependencies.pri
new file mode 100644
index 0000000000..e93a856869
--- /dev/null
+++ b/src/libs/3rdparty/yaml-cpp/yaml-cpp_dependencies.pri
@@ -0,0 +1,2 @@
+QTC_LIB_NAME = yaml-cpp
+INCLUDEPATH *= $$PWD/include
diff --git a/src/libs/clangsupport/CMakeLists.txt b/src/libs/clangsupport/CMakeLists.txt
index 213dbeaadb..af8bfc2342 100644
--- a/src/libs/clangsupport/CMakeLists.txt
+++ b/src/libs/clangsupport/CMakeLists.txt
@@ -1,6 +1,7 @@
set(CLANG_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH})
add_qtc_library(ClangSupport
+ DEPENDS Threads::Threads
PUBLIC_DEPENDS Utils Sqlite Qt5::Core Qt5::Network
PUBLIC_DEFINES
CLANG_VERSION="${CLANG_VERSION}"
diff --git a/src/libs/clangsupport/clangpathwatcher.h b/src/libs/clangsupport/clangpathwatcher.h
index 5ce02458c4..27f7646271 100644
--- a/src/libs/clangsupport/clangpathwatcher.h
+++ b/src/libs/clangsupport/clangpathwatcher.h
@@ -390,9 +390,7 @@ public:
FilePathIds watchedPaths(const WatcherEntries &entries) const
{
- auto filePathIds = Utils::transform<FilePathIds>(entries, [](WatcherEntry entry) {
- return entry.filePathId;
- });
+ auto filePathIds = Utils::transform<FilePathIds>(entries, &WatcherEntry::filePathId);
std::sort(filePathIds.begin(), filePathIds.end());
@@ -412,7 +410,7 @@ public:
for (WatcherEntry entry : foundEntries) {
if (idPaths.empty() || idPaths.back().id != entry.id)
- idPaths.push_back({entry.id, {}});
+ idPaths.emplace_back(entry.id, FilePathIds{});
idPaths.back().filePathIds.push_back(entry.filePathId);
}
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index 18896c0ea0..fa4a06fe77 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -118,6 +118,7 @@ HEADERS += \
$$PWD/projectpartid.h \
$$PWD/projectpartsstorage.h \
$$PWD/projectpartsstorageinterface.h \
+ $$PWD/projectpartstoragestructs.h \
$$PWD/requestcompletionsmessage.h \
$$PWD/echomessage.h \
$$PWD/endmessage.h \
@@ -156,6 +157,7 @@ HEADERS += \
$$PWD/refactoringserverproxy.h \
$$PWD/referencesmessage.h \
$$PWD/set_algorithm.h \
+ $$PWD/stringcacheentry.h \
$$PWD/unsavedfilesupdatedmessage.h \
$$PWD/removeprojectpartsmessage.h \
$$PWD/requestannotationsmessage.h \
diff --git a/src/libs/clangsupport/clangsupport_global.h b/src/libs/clangsupport/clangsupport_global.h
index 57ce18e195..7b63feb381 100644
--- a/src/libs/clangsupport/clangsupport_global.h
+++ b/src/libs/clangsupport/clangsupport_global.h
@@ -201,15 +201,14 @@ struct HighlightingTypes {
MixinHighlightingTypes mixinHighlightingTypes;
};
-enum class SourceLocationKind : uchar
-{
- None = 0,
+enum class SourceLocationKind : uchar {
+ Definition = 1,
Declaration,
DeclarationReference,
- Definition,
MacroDefinition = 128,
+ MacroUndefinition,
MacroUsage,
- MacroUndefinition
+ None = 255,
};
enum class SymbolKind : uchar
diff --git a/src/libs/clangsupport/clangsupportdebugutils.h b/src/libs/clangsupport/clangsupportdebugutils.h
index 5f1751aeac..0e4a6da9a8 100644
--- a/src/libs/clangsupport/clangsupportdebugutils.h
+++ b/src/libs/clangsupport/clangsupportdebugutils.h
@@ -40,7 +40,7 @@ Utf8String debugId(const FileContainer &fileContainer);
class CLANGSUPPORT_EXPORT VerboseScopeDurationTimer
{
public:
- VerboseScopeDurationTimer(const char *id = 0);
+ VerboseScopeDurationTimer(const char *id = nullptr);
~VerboseScopeDurationTimer();
private:
diff --git a/src/libs/clangsupport/filecontainerv2.h b/src/libs/clangsupport/filecontainerv2.h
index aa7248fb5e..e6e8c6622f 100644
--- a/src/libs/clangsupport/filecontainerv2.h
+++ b/src/libs/clangsupport/filecontainerv2.h
@@ -27,6 +27,7 @@
#include "clangsupport_global.h"
#include "filepath.h"
+#include "filepathid.h"
#include <vector>
@@ -39,13 +40,15 @@ public:
FileContainer() = default;
FileContainer(FilePath &&filePath,
+ FilePathId filePathId,
Utils::SmallString &&unsavedFileContent,
Utils::SmallStringVector &&commandLineArguments = {},
quint32 documentRevision = 0)
- : filePath(std::move(filePath)),
- unsavedFileContent(std::move(unsavedFileContent)),
- commandLineArguments(std::move(commandLineArguments)),
- documentRevision(documentRevision)
+ : filePath(std::move(filePath))
+ , filePathId(filePathId)
+ , unsavedFileContent(std::move(unsavedFileContent))
+ , commandLineArguments(std::move(commandLineArguments))
+ , documentRevision(documentRevision)
{
}
@@ -81,16 +84,11 @@ public:
< std::tie(second.filePath, second.documentRevision, second.unsavedFileContent, second.commandLineArguments);
}
- FileContainer clone() const
- {
- return FileContainer(filePath.clone(),
- unsavedFileContent.clone(),
- commandLineArguments.clone(),
- documentRevision);
- }
+ FileContainer clone() const { return *this; }
public:
FilePath filePath;
+ FilePathId filePathId;
Utils::SmallString unsavedFileContent;
Utils::SmallStringVector commandLineArguments;
quint32 documentRevision = 0;
diff --git a/src/libs/clangsupport/filepathcache.h b/src/libs/clangsupport/filepathcache.h
index 4845416d22..541769b0b5 100644
--- a/src/libs/clangsupport/filepathcache.h
+++ b/src/libs/clangsupport/filepathcache.h
@@ -29,94 +29,69 @@
#include "filepath.h"
#include "filepathexceptions.h"
#include "filepathid.h"
+#include "filepathstoragesources.h"
#include "filepathview.h"
#include "stringcache.h"
+#include <sqlitetransaction.h>
+
#include <algorithm>
namespace ClangBackEnd {
-template <typename FilePathStorage>
+template<typename FilePathStorage, typename Mutex = SharedMutex>
class CLANGSUPPORT_GCCEXPORT FilePathCache
{
- class FileNameView
- {
- public:
- friend bool operator==(const FileNameView &first, const FileNameView &second)
- {
- return first.directoryId == second.directoryId
- && first.fileName == second.fileName;
- }
-
- static
- int compare(FileNameView first, FileNameView second) noexcept
- {
- int directoryDifference = first.directoryId - second.directoryId;
-
- if (directoryDifference)
- return directoryDifference;
-
- return Utils::compare(first.fileName, second.fileName);
- }
-
- public:
- Utils::SmallStringView fileName;
- int directoryId;
- };
-
- class FileNameEntry
- {
- public:
- FileNameEntry(Utils::SmallStringView fileName, int directoryId)
- : fileName(fileName),
- directoryId(directoryId)
- {}
-
- FileNameEntry(FileNameView view)
- : fileName(view.fileName),
- directoryId(view.directoryId)
- {}
-
- friend bool operator==(const FileNameEntry &first, const FileNameEntry &second)
- {
- return first.directoryId == second.directoryId
- && first.fileName == second.fileName;
- }
-
- operator FileNameView() const
- {
- return {fileName, directoryId};
- }
-
- operator Utils::SmallString() &&
- {
- return std::move(fileName);
- }
+ FilePathCache(const FilePathCache &) = default;
+ FilePathCache &operator=(const FilePathCache &) = default;
- public:
- Utils::SmallString fileName;
- int directoryId;
- };
+ template<typename Storage, typename M>
+ friend class FilePathCache;
+public:
using DirectoryPathCache = StringCache<Utils::PathString,
Utils::SmallStringView,
int,
- SharedMutex,
+ Mutex,
decltype(&Utils::reverseCompare),
- Utils::reverseCompare>;
+ Utils::reverseCompare,
+ Sources::Directory>;
using FileNameCache = StringCache<FileNameEntry,
FileNameView,
int,
- SharedMutex,
+ Mutex,
decltype(&FileNameView::compare),
- FileNameView::compare>;
-public:
+ FileNameView::compare,
+ Sources::Source>;
+
FilePathCache(FilePathStorage &filePathStorage)
: m_filePathStorage(filePathStorage)
- {}
+ {
+ populateIfEmpty();
+ }
- FilePathCache(const FilePathCache &) = delete;
- FilePathCache &operator=(const FilePathCache &) = delete;
+ FilePathCache(FilePathCache &&) = default;
+ FilePathCache &operator=(FilePathCache &&) = default;
+
+ void populateIfEmpty()
+ {
+ if (m_fileNameCache.isEmpty()) {
+ m_directoryPathCache.populate(m_filePathStorage.fetchAllDirectories());
+ m_fileNameCache.populate(m_filePathStorage.fetchAllSources());
+ }
+ }
+
+ template<typename Cache>
+ Cache clone()
+ {
+ using DirectoryPathCache = typename Cache::DirectoryPathCache;
+ using FileNameCache = typename Cache::FileNameCache;
+ Cache cache{m_filePathStorage};
+ cache.m_directoryPathCache = m_directoryPathCache.template clone<DirectoryPathCache>();
+ cache.m_fileNameCache = m_fileNameCache.template clone<FileNameCache>();
+
+ return cache;
+ }
FilePathId filePathId(FilePathView filePath) const
{
@@ -158,8 +133,7 @@ public:
return FileNameEntry{entry.sourceName, entry.directoryId};
};
- FileNameEntry entry = m_fileNameCache.string(filePathId.filePathId,
- fetchSoureNameAndDirectoryId);
+ auto entry = m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId);
auto fetchDirectoryPath = [&] (int id) { return m_filePathStorage.fetchDirectoryPath(id); };
@@ -189,12 +163,40 @@ public:
return FileNameEntry{entry.sourceName, entry.directoryId};
};
- FileNameEntry entry = m_fileNameCache.string(filePathId.filePathId,
- fetchSoureNameAndDirectoryId);
-
return m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId).directoryId;
}
+ template<typename Container>
+ void addFilePaths(Container &&filePaths)
+ {
+ auto directoryPaths = Utils::transform<std::vector<Utils::SmallStringView>>(
+ filePaths, [](FilePathView filePath) { return filePath.directory(); });
+
+ std::unique_ptr<Sqlite::DeferredTransaction> transaction;
+
+ m_directoryPathCache.addStrings(std::move(directoryPaths), [&](Utils::SmallStringView directoryPath) {
+ if (!transaction)
+ transaction = std::make_unique<Sqlite::DeferredTransaction>(
+ m_filePathStorage.database());
+ return m_filePathStorage.fetchDirectoryIdUnguarded(directoryPath);
+ });
+
+ auto sourcePaths = Utils::transform<std::vector<FileNameView>>(filePaths, [&](FilePathView filePath) {
+ return FileNameView{filePath.name(), m_directoryPathCache.stringId(filePath.directory())};
+ });
+
+ m_fileNameCache.addStrings(std::move(sourcePaths), [&](FileNameView fileNameView) {
+ if (!transaction)
+ transaction = std::make_unique<Sqlite::DeferredTransaction>(
+ m_filePathStorage.database());
+ return m_filePathStorage.fetchSourceIdUnguarded(fileNameView.directoryId,
+ fileNameView.fileName);
+ });
+
+ if (transaction)
+ transaction->commit();
+ }
+
private:
mutable DirectoryPathCache m_directoryPathCache;
mutable FileNameCache m_fileNameCache;
diff --git a/src/libs/clangsupport/filepathcaching.cpp b/src/libs/clangsupport/filepathcaching.cpp
index 372ed86bd3..f6d9ba9691 100644
--- a/src/libs/clangsupport/filepathcaching.cpp
+++ b/src/libs/clangsupport/filepathcaching.cpp
@@ -52,4 +52,49 @@ DirectoryPathId FilePathCaching::directoryPathId(FilePathId filePathId) const
return m_cache.directoryPathId(filePathId);
}
+void FilePathCaching::addFilePaths(const FilePaths &filePaths)
+{
+ m_cache.addFilePaths(filePaths);
+}
+
+void FilePathCaching::populateIfEmpty()
+{
+ m_cache.populateIfEmpty();
+}
+
+FilePathId CopyableFilePathCaching::filePathId(FilePathView filePath) const
+{
+ return m_cache.filePathId(filePath);
+}
+
+FilePath CopyableFilePathCaching::filePath(FilePathId filePathId) const
+{
+ return m_cache.filePath(filePathId);
+}
+
+DirectoryPathId CopyableFilePathCaching::directoryPathId(Utils::SmallStringView directoryPath) const
+{
+ return m_cache.directoryPathId(directoryPath);
+}
+
+Utils::PathString CopyableFilePathCaching::directoryPath(DirectoryPathId directoryPathId) const
+{
+ return m_cache.directoryPath(directoryPathId);
+}
+
+DirectoryPathId CopyableFilePathCaching::directoryPathId(FilePathId filePathId) const
+{
+ return m_cache.directoryPathId(filePathId);
+}
+
+void CopyableFilePathCaching::addFilePaths(const FilePaths &filePaths)
+{
+ m_cache.addFilePaths(filePaths);
+}
+
+void CopyableFilePathCaching::populateIfEmpty()
+{
+ m_cache.populateIfEmpty();
+}
+
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filepathcaching.h b/src/libs/clangsupport/filepathcaching.h
index f69b940b15..7c1f343401 100644
--- a/src/libs/clangsupport/filepathcaching.h
+++ b/src/libs/clangsupport/filepathcaching.h
@@ -40,9 +40,11 @@ namespace ClangBackEnd {
class CLANGSUPPORT_EXPORT FilePathCaching final : public FilePathCachingInterface
{
+ friend class CopyableFilePathCaching;
using Factory = FilePathStorageSqliteStatementFactory<Sqlite::Database>;
using Storage = FilePathStorage<Factory>;
using Cache = FilePathCache<Storage>;
+
public:
FilePathCaching(Sqlite::Database &database)
: m_factory(database)
@@ -53,6 +55,8 @@ public:
DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const override;
Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
DirectoryPathId directoryPathId(FilePathId filePathId) const override;
+ void addFilePaths(const ClangBackEnd::FilePaths &filePaths) override;
+ void populateIfEmpty() override;
private:
Factory m_factory;
@@ -60,4 +64,27 @@ private:
Cache m_cache{m_storage};
};
+class CLANGSUPPORT_EXPORT CopyableFilePathCaching final : public FilePathCachingInterface
+{
+ using Factory = FilePathStorageSqliteStatementFactory<Sqlite::Database>;
+ using Storage = FilePathStorage<Factory>;
+ using Cache = FilePathCache<Storage, NonLockingMutex>;
+
+public:
+ CopyableFilePathCaching(FilePathCaching &cache)
+ : m_cache(cache.m_cache.clone<Cache>())
+ {}
+
+ FilePathId filePathId(FilePathView filePath) const override;
+ FilePath filePath(FilePathId filePathId) const override;
+ DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const override;
+ Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
+ DirectoryPathId directoryPathId(FilePathId filePathId) const override;
+ void addFilePaths(const ClangBackEnd::FilePaths &filePaths) override;
+ void populateIfEmpty() override;
+
+private:
+ Cache m_cache;
+};
+
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filepathcachinginterface.h b/src/libs/clangsupport/filepathcachinginterface.h
index 098fd39ca9..69be405d37 100644
--- a/src/libs/clangsupport/filepathcachinginterface.h
+++ b/src/libs/clangsupport/filepathcachinginterface.h
@@ -44,6 +44,8 @@ public:
virtual DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const = 0;
virtual DirectoryPathId directoryPathId(FilePathId filePathId) const = 0;
virtual Utils::PathString directoryPath(DirectoryPathId directoryPathId) const = 0;
+ virtual void addFilePaths(const ClangBackEnd::FilePaths &filePaths) = 0;
+ virtual void populateIfEmpty() = 0;
template<typename Container>
FilePathIds filePathIds(Container &&filePaths) const
@@ -56,6 +58,8 @@ public:
std::back_inserter(filePathIds),
[&] (const auto &filePath) { return this->filePathId(filePath); });
+ std::sort(filePathIds.begin(), filePathIds.end());
+
return filePathIds;
}
diff --git a/src/libs/clangsupport/filepathstorage.h b/src/libs/clangsupport/filepathstorage.h
index 8aba2ef6d2..083782fec2 100644
--- a/src/libs/clangsupport/filepathstorage.h
+++ b/src/libs/clangsupport/filepathstorage.h
@@ -48,6 +48,16 @@ public:
: m_statementFactory(statementFactory)
{}
+ int fetchDirectoryIdUnguarded(Utils::SmallStringView directoryPath)
+ {
+ Utils::optional<int> optionalDirectoryId = readDirectoryId(directoryPath);
+
+ if (optionalDirectoryId)
+ return optionalDirectoryId.value();
+
+ return writeDirectoryId(directoryPath);
+ }
+
int fetchDirectoryId(Utils::SmallStringView directoryPath)
{
try {
@@ -125,19 +135,22 @@ public:
}
}
+ int fetchSourceIdUnguarded(int directoryId, Utils::SmallStringView sourceName)
+ {
+ Utils::optional<int> optionalSourceId = readSourceId(directoryId, sourceName);
+
+ if (optionalSourceId)
+ return optionalSourceId.value();
+
+ return writeSourceId(directoryId, sourceName);
+ }
+
int fetchSourceId(int directoryId, Utils::SmallStringView sourceName)
{
try {
Sqlite::DeferredTransaction transaction{m_statementFactory.database};
- Utils::optional<int> optionalSourceId = readSourceId(directoryId, sourceName);
-
- int sourceId = -1;
-
- if (optionalSourceId)
- sourceId = optionalSourceId.value();
- else
- sourceId = writeSourceId(directoryId, sourceName);
+ int sourceId = fetchSourceIdUnguarded(directoryId, sourceName);
transaction.commit();
@@ -212,7 +225,7 @@ public:
ReadStatement &statement = m_statementFactory.selectAllSources;
- auto sources = statement.template values<Sources::Source, 2>(8192);
+ auto sources = statement.template values<Sources::Source, 3>(8192);
transaction.commit();
@@ -222,6 +235,8 @@ public:
}
}
+ Database &database() { return m_statementFactory.database; }
+
private:
StatementFactory &m_statementFactory;
};
diff --git a/src/libs/clangsupport/filepathstoragesources.h b/src/libs/clangsupport/filepathstoragesources.h
index e76cb3b2cf..23293be1f7 100644
--- a/src/libs/clangsupport/filepathstoragesources.h
+++ b/src/libs/clangsupport/filepathstoragesources.h
@@ -25,6 +25,8 @@
#pragma once
+#include "stringcacheentry.h"
+
#include <utils/smallstring.h>
#include <cstdint>
@@ -33,41 +35,90 @@
#include <unordered_map>
namespace ClangBackEnd {
-namespace Sources {
-class Directory
+
+class FileNameView
{
public:
- Directory(int directoryId, Utils::PathString &&directoryPath)
- : directoryId(directoryId), directoryPath(std::move(directoryPath))
- {}
+ friend bool operator==(const FileNameView &first, const FileNameView &second)
+ {
+ return first.directoryId == second.directoryId && first.fileName == second.fileName;
+ }
- friend
- bool operator==(const Directory &first, const Directory &second)
+ static int compare(FileNameView first, FileNameView second) noexcept
{
- return first.directoryId == second.directoryId && first.directoryPath == second.directoryPath;
+ int directoryDifference = first.directoryId - second.directoryId;
+
+ if (directoryDifference)
+ return directoryDifference;
+
+ return Utils::compare(first.fileName, second.fileName);
}
public:
+ Utils::SmallStringView fileName;
int directoryId;
- Utils::PathString directoryPath;
};
-class Source
+class FileNameEntry
{
public:
- Source(int sourceId, Utils::PathString &&sourceName)
- : sourceId(sourceId), sourceName(std::move(sourceName))
+ FileNameEntry(Utils::SmallStringView fileName, int directoryId)
+ : fileName(fileName)
+ , directoryId(directoryId)
{}
- friend
- bool operator==(const Source &first, const Source &second)
+ FileNameEntry(FileNameView view)
+ : fileName(view.fileName)
+ , directoryId(view.directoryId)
+ {}
+
+ friend bool operator==(const FileNameEntry &first, const FileNameEntry &second)
+ {
+ return first.directoryId == second.directoryId && first.fileName == second.fileName;
+ }
+
+ friend bool operator!=(const FileNameEntry &first, const FileNameEntry &second)
+ {
+ return !(first == second);
+ }
+
+ operator FileNameView() const { return {fileName, directoryId}; }
+
+ operator Utils::SmallString() && { return std::move(fileName); }
+
+public:
+ Utils::SmallString fileName;
+ int directoryId;
+};
+
+namespace Sources {
+class Directory : public StringCacheEntry<Utils::PathString, Utils::SmallStringView, int>
+{
+ using Base = StringCacheEntry<Utils::PathString, Utils::SmallStringView, int>;
+
+public:
+ using Base::Base;
+
+ friend bool operator==(const Directory &first, const Directory &second)
{
- return first.sourceId == second.sourceId && first.sourceName == second.sourceName;
+ return first.id == second.id && first.string == second.string;
}
+};
+
+class Source : public StringCacheEntry<FileNameEntry, FileNameView, int>
+{
+ using Base = StringCacheEntry<FileNameEntry, FileNameView, int>;
public:
- int sourceId;
- Utils::PathString sourceName;
+ using Base::Base;
+ Source(Utils::SmallStringView sourceName, int directoryId, int sourceId)
+ : Base{{sourceName, directoryId}, sourceId}
+ {}
+
+ friend bool operator==(const Source &first, const Source &second)
+ {
+ return first.id == second.id && first.string == second.string;
+ }
};
class SourceNameAndDirectoryId
diff --git a/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h b/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h
index 27296a1df6..f0d261dd49 100644
--- a/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h
+++ b/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h
@@ -50,13 +50,8 @@ public:
database
};
ReadStatement selectDirectoryPathFromDirectoriesByDirectoryId{
- "SELECT directoryPath FROM directories WHERE directoryId = ?",
- database
- };
- ReadStatement selectAllDirectories{
- "SELECT directoryId, directoryPath FROM directories",
- database
- };
+ "SELECT directoryPath FROM directories WHERE directoryId = ?", database};
+ ReadStatement selectAllDirectories{"SELECT directoryPath, directoryId FROM directories", database};
WriteStatement insertIntoDirectories{
"INSERT INTO directories(directoryPath) VALUES (?)",
database
@@ -75,10 +70,7 @@ public:
"INSERT INTO sources(directoryId, sourceName) VALUES (?,?)",
database
};
- ReadStatement selectAllSources{
- "SELECT sourceId, sourceName FROM sources",
- database
- };
+ ReadStatement selectAllSources{"SELECT sourceName, directoryId, sourceId FROM sources", database};
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filesystem.cpp b/src/libs/clangsupport/filesystem.cpp
index 5b8c037f80..db79ddda31 100644
--- a/src/libs/clangsupport/filesystem.cpp
+++ b/src/libs/clangsupport/filesystem.cpp
@@ -55,7 +55,10 @@ long long FileSystem::lastModified(FilePathId filePathId) const
fileInfo.refresh();
- return fileInfo.lastModified().toMSecsSinceEpoch() / 1000;
+ if (fileInfo.exists())
+ return fileInfo.lastModified().toMSecsSinceEpoch() / 1000;
+
+ return 0;
}
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/generatedfiles.cpp b/src/libs/clangsupport/generatedfiles.cpp
index 644137886b..22b1e8044a 100644
--- a/src/libs/clangsupport/generatedfiles.cpp
+++ b/src/libs/clangsupport/generatedfiles.cpp
@@ -53,7 +53,7 @@ void GeneratedFiles::update(const V2::FileContainers &fileContainers)
V2::FileContainers unionFileContainers;
unionFileContainers.reserve(m_fileContainers.size() + fileContainers.size());
- auto compare = [] (const V2::FileContainer &first, const V2::FileContainer &second) {
+ auto compare = [](const V2::FileContainer &first, const V2::FileContainer &second) {
return first.filePath < second.filePath;
};
@@ -69,10 +69,7 @@ void GeneratedFiles::update(const V2::FileContainers &fileContainers)
class Compare {
public:
- bool operator()(const FilePath &first, const FilePath &second)
- {
- return first < second;
- }
+ bool operator()(const FilePath &first, const FilePath &second) { return first < second; }
bool operator()(const V2::FileContainer &first, const V2::FileContainer &second)
{
return first.filePath < second.filePath;
@@ -116,4 +113,16 @@ const V2::FileContainers &GeneratedFiles::fileContainers() const
return m_fileContainers;
}
+FilePathIds GeneratedFiles::filePathIds() const
+{
+ auto ids = Utils::transform<FilePathIds>(m_fileContainers,
+ [](const V2::FileContainer &fileContainer) {
+ return fileContainer.filePathId;
+ });
+
+ std::sort(ids.begin(), ids.end());
+
+ return ids;
+}
+
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/generatedfiles.h b/src/libs/clangsupport/generatedfiles.h
index 933b0d111b..3e87048be9 100644
--- a/src/libs/clangsupport/generatedfiles.h
+++ b/src/libs/clangsupport/generatedfiles.h
@@ -38,6 +38,7 @@ public:
bool isValid() const;
const V2::FileContainers &fileContainers() const;
+ FilePathIds filePathIds() const;
private:
V2::FileContainers m_fileContainers;
diff --git a/src/libs/clangsupport/generatedfilesinterface.h b/src/libs/clangsupport/generatedfilesinterface.h
index 85a50ffa38..72a1dfccfb 100644
--- a/src/libs/clangsupport/generatedfilesinterface.h
+++ b/src/libs/clangsupport/generatedfilesinterface.h
@@ -38,6 +38,7 @@ public:
virtual bool isValid() const = 0;
virtual const V2::FileContainers &fileContainers() const = 0;
+ virtual FilePathIds filePathIds() const = 0;
protected:
~GeneratedFilesInterface() = default;
diff --git a/src/libs/clangsupport/idpaths.h b/src/libs/clangsupport/idpaths.h
index d0945f7ff5..8410bbbbd5 100644
--- a/src/libs/clangsupport/idpaths.h
+++ b/src/libs/clangsupport/idpaths.h
@@ -70,13 +70,23 @@ public:
class IdPaths
{
public:
- ProjectChunkId id;
- FilePathIds filePathIds;
+ IdPaths(ProjectPartId projectPartId, SourceType sourceType, FilePathIds &&filePathIds)
+ : id{projectPartId, sourceType}
+ , filePathIds(std::move(filePathIds))
+ {}
+ IdPaths(ProjectChunkId projectChunkId, FilePathIds &&filePathIds)
+ : id(projectChunkId)
+ , filePathIds(std::move(filePathIds))
+ {}
friend bool operator==(IdPaths first, IdPaths second)
{
return first.id == second.id && first.filePathIds == second.filePathIds;
}
+
+public:
+ ProjectChunkId id;
+ FilePathIds filePathIds;
};
using ProjectChunkIds = std::vector<ProjectChunkId>;
diff --git a/src/libs/clangsupport/modifiedtimechecker.h b/src/libs/clangsupport/modifiedtimechecker.h
index 00e8e3ebac..58d1307daa 100644
--- a/src/libs/clangsupport/modifiedtimechecker.h
+++ b/src/libs/clangsupport/modifiedtimechecker.h
@@ -44,14 +44,14 @@ public:
: m_fileSystem(fileSystem)
{}
- bool isUpToDate(const SourceEntries &sourceEntries) const
+ bool isUpToDate(const SourceEntries &sourceEntries) const override
{
if (sourceEntries.empty())
return false;
updateCurrentSourceTimeStamps(sourceEntries);
- return compareEntries(sourceEntries) && notReseted(sourceEntries);
+ return compareEntries(sourceEntries);
}
void pathsChanged(const FilePathIds &filePathIds) override
@@ -66,29 +66,15 @@ public:
}));
}
- void reset(const FilePathIds &filePathIds)
- {
- FilePathIds newResetFilePathIds;
- newResetFilePathIds.reserve(newResetFilePathIds.size() + m_resetFilePathIds.size());
-
- std::set_union(m_resetFilePathIds.begin(),
- m_resetFilePathIds.end(),
- filePathIds.begin(),
- filePathIds.end(),
- std::back_inserter(newResetFilePathIds));
-
- m_resetFilePathIds = std::move(newResetFilePathIds);
- }
-
private:
bool compareEntries(const SourceEntries &sourceEntries) const
{
- return set_intersection_compare(
+ return !set_intersection_compare(
m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(),
sourceEntries.begin(),
sourceEntries.end(),
- [](auto first, auto second) { return second.timeStamp > first.timeStamp; },
+ [](auto first, auto second) { return first.timeStamp > second.timeStamp; },
[](auto first, auto second) { return first.sourceId < second.sourceId; });
}
@@ -118,33 +104,13 @@ private:
m_fileSystem.lastModified(
sourceEntry.sourceId));
}),
- [](auto first, auto second) {
- return first.sourceId < second.sourceId && first.timeStamp > 0;
- });
+ [](auto first, auto second) { return first.sourceId < second.sourceId; });
return newTimeStamps;
}
- bool notReseted(const SourceEntries &sourceEntries) const
- {
- auto oldSize = m_resetFilePathIds.size();
- FilePathIds newResetFilePathIds;
- newResetFilePathIds.reserve(newResetFilePathIds.size());
-
- std::set_difference(m_resetFilePathIds.begin(),
- m_resetFilePathIds.end(),
- sourceEntries.begin(),
- sourceEntries.end(),
- std::back_inserter(newResetFilePathIds));
-
- m_resetFilePathIds = std::move(newResetFilePathIds);
-
- return oldSize == m_resetFilePathIds.size();
- }
-
private:
mutable SourceTimeStamps m_currentSourceTimeStamps;
- mutable FilePathIds m_resetFilePathIds;
FileSystemInterface &m_fileSystem;
};
diff --git a/src/libs/clangsupport/processcreator.cpp b/src/libs/clangsupport/processcreator.cpp
index 22b52793e3..ad0d4b7884 100644
--- a/src/libs/clangsupport/processcreator.cpp
+++ b/src/libs/clangsupport/processcreator.cpp
@@ -173,8 +173,10 @@ QProcessEnvironment ProcessCreator::processEnvironment() const
}
const Utils::Environment &env = m_environment;
- for (auto it = env.constBegin(); it != env.constEnd(); ++it)
- processEnvironment.insert(it.key(), it.value());
+ for (auto it = env.constBegin(); it != env.constEnd(); ++it) {
+ if (env.isEnabled(it))
+ processEnvironment.insert(env.key(it), env.expandedValueForKey(env.key(it)));
+ }
return processEnvironment;
}
diff --git a/src/libs/clangsupport/projectpartcontainer.h b/src/libs/clangsupport/projectpartcontainer.h
index b2133dcaa2..caededee5c 100644
--- a/src/libs/clangsupport/projectpartcontainer.h
+++ b/src/libs/clangsupport/projectpartcontainer.h
@@ -32,6 +32,7 @@
#include "includesearchpath.h"
#include "projectpartartefact.h"
#include "projectpartid.h"
+#include "sourceentry.h"
#include <utils/cpplanguage_details.h>
#include <utils/smallstringio.h>
@@ -126,12 +127,12 @@ public:
friend bool operator==(const ProjectPartContainer &first, const ProjectPartContainer &second)
{
return first.projectPartId == second.projectPartId
- && first.toolChainArguments == second.toolChainArguments
- && first.compilerMacros == second.compilerMacros
- && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
- && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
- && first.headerPathIds == second.headerPathIds
- && first.sourcePathIds == second.sourcePathIds&& first.language == second.language
+ && first.toolChainArguments == second.toolChainArguments
+ && first.compilerMacros == second.compilerMacros
+ && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
+ && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
+ && first.headerPathIds == second.headerPathIds
+ && first.sourcePathIds == second.sourcePathIds && first.language == second.language
&& first.languageVersion == second.languageVersion
&& first.languageExtension == second.languageExtension;
}
@@ -148,7 +149,7 @@ public:
first.language,
first.languageVersion,
first.languageExtension,
- first.hasPrecompiledHeader)
+ first.preCompiledHeaderWasGenerated)
< std::tie(second.projectPartId,
second.toolChainArguments,
second.compilerMacros,
@@ -159,7 +160,7 @@ public:
second.language,
second.languageVersion,
second.languageExtension,
- second.hasPrecompiledHeader);
+ second.preCompiledHeaderWasGenerated);
}
ProjectPartContainer clone() const
@@ -171,7 +172,7 @@ public:
FilePathIds headerPathIds;
FilePathIds sourcePathIds;
bool updateIsDeferred = false;
- bool hasPrecompiledHeader = true;
+ bool preCompiledHeaderWasGenerated = true;
};
using ProjectPartContainerReference = std::reference_wrapper<ProjectPartContainer>;
diff --git a/src/libs/clangsupport/projectpartid.h b/src/libs/clangsupport/projectpartid.h
index fc5f659605..335a0f0cc5 100644
--- a/src/libs/clangsupport/projectpartid.h
+++ b/src/libs/clangsupport/projectpartid.h
@@ -31,6 +31,15 @@ namespace ClangBackEnd {
class ProjectPartId
{
+ template<typename StringType,
+ typename StringViewType,
+ typename IndexType,
+ typename Mutex,
+ typename Compare,
+ Compare compare,
+ typename CacheEntry>
+ friend class StringCache;
+
public:
constexpr ProjectPartId() = default;
@@ -47,6 +56,11 @@ public:
return first.isValid() && first.projectPathId == second.projectPathId;
}
+ friend bool operator==(ProjectPartId first, int second)
+ {
+ return first == ProjectPartId{second};
+ }
+
friend bool operator!=(ProjectPartId first, ProjectPartId second) { return !(first == second); }
friend bool operator<(ProjectPartId first, ProjectPartId second)
@@ -68,6 +82,10 @@ public:
return in;
}
+private:
+ operator int() const { return projectPathId; }
+ ProjectPartId operator++() { return ++projectPathId; }
+
public:
int projectPathId = -1;
};
diff --git a/src/libs/clangsupport/projectpartsstorage.h b/src/libs/clangsupport/projectpartsstorage.h
index e71bb0d51e..6363ae708f 100644
--- a/src/libs/clangsupport/projectpartsstorage.h
+++ b/src/libs/clangsupport/projectpartsstorage.h
@@ -74,12 +74,12 @@ public:
.template values<FilePathId>(1024, projectPartId.projectPathId);
}
- bool hasPrecompiledHeader(ProjectPartId projectPartId) const
+ bool preCompiledHeaderWasGenerated(ProjectPartId projectPartId) const
{
- auto value = fetchProjectPrecompiledHeaderPathStatement.template value<Utils::SmallString>(
+ auto value = fetchProjectPrecompiledHeaderBuildTimeStatement.template value<long long>(
projectPartId.projectPathId);
- return value && value->hasContent();
+ return value && *value > 0;
}
ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const override
@@ -96,7 +96,7 @@ public:
if (value) {
value->headerPathIds = fetchHeaders(projectPartId);
value->sourcePathIds = fetchSources(projectPartId);
- value->hasPrecompiledHeader = hasPrecompiledHeader(projectPartId);
+ value->preCompiledHeaderWasGenerated = preCompiledHeaderWasGenerated(projectPartId);
projectParts.push_back(*std::move(value));
}
}
@@ -109,26 +109,33 @@ public:
}
}
+ ProjectPartId fetchProjectPartIdUnguarded(Utils::SmallStringView projectPartName) const override
+ {
+ auto optionalProjectPartId = fetchProjectPartIdStatement.template value<ProjectPartId>(
+ projectPartName);
+
+ if (optionalProjectPartId) {
+ return *optionalProjectPartId;
+ } else {
+ insertProjectPartNameStatement.write(projectPartName);
+
+ return static_cast<int>(database.lastInsertedRowId());
+ }
+
+ return {};
+ }
+
ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const override
{
try {
Sqlite::DeferredTransaction transaction{database};
- ProjectPartId projectPartId;
- auto optionalProjectPartId = fetchProjectPartIdStatement.template value<ProjectPartId>(
- projectPartName);
-
- if (optionalProjectPartId) {
- projectPartId = *optionalProjectPartId;
- } else {
- insertProjectPartNameStatement.write(projectPartName);
-
- projectPartId = static_cast<int>(database.lastInsertedRowId());
- }
+ ProjectPartId projectPartId = fetchProjectPartIdUnguarded(projectPartName);
transaction.commit();
return projectPartId;
+
} catch (const Sqlite::StatementIsBusy &) {
return fetchProjectPartId(projectPartName);
}
@@ -233,16 +240,36 @@ public:
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const override
{
- ReadStatement &statement = getProjectPartArtefactsBySourceId;
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ ReadStatement &statement = getProjectPartArtefactsBySourceId;
+
+ auto value = statement.template value<ProjectPartArtefact, 8>(sourceId.filePathId);
+
+ transaction.commit();
- return statement.template value<ProjectPartArtefact, 8>(sourceId.filePathId);
+ return value;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchProjectPartArtefact(sourceId);
+ }
}
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(ProjectPartId projectPartId) const override
{
- ReadStatement &statement = getProjectPartArtefactsByProjectPartId;
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ ReadStatement &statement = getProjectPartArtefactsByProjectPartId;
- return statement.template value<ProjectPartArtefact, 8>(projectPartId.projectPathId);
+ auto value = statement.template value<ProjectPartArtefact, 8>(projectPartId.projectPathId);
+
+ transaction.commit();
+
+ return value;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchProjectPartArtefact(projectPartId);
+ }
}
void resetIndexingTimeStamps(const ProjectPartContainers &projectsParts) override
@@ -310,6 +337,23 @@ public:
Utils::SmallString::number(projectPartId.projectPathId));
}
+ Internal::ProjectPartNameIds fetchAllProjectPartNamesAndIds() const override
+ {
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ ReadStatement &statement = fetchAllProjectPartNamesAndIdsStatement;
+
+ auto values = statement.template values<Internal::ProjectPartNameId, 2>(256);
+
+ transaction.commit();
+
+ return values;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchAllProjectPartNamesAndIds();
+ }
+ }
+
public:
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
Database &database;
@@ -354,16 +398,16 @@ public:
WriteStatement insertProjectPartsSourcesStatement{
"INSERT INTO projectPartsSources(projectPartId, sourceId) VALUES (?,?)", database};
mutable ReadStatement fetchProjectPartsHeadersByIdStatement{
- "SELECT sourceId FROM projectPartsHeaders WHERE projectPartId = ?", database};
+ "SELECT sourceId FROM projectPartsHeaders WHERE projectPartId = ? ORDER BY sourceId",
+ database};
mutable ReadStatement fetchProjectPartsSourcesByIdStatement{
- "SELECT sourceId FROM projectPartsSources WHERE projectPartId = ?", database};
- mutable ReadStatement fetchProjectPrecompiledHeaderPathStatement{
- "SELECT projectPchPath FROM precompiledHeaders WHERE projectPartId = ?", database};
- WriteStatement resetDependentIndexingTimeStampsStatement{
- "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT "
- "dependencySourceId FROM sourceDependencies, collectedDependencies WHERE "
- "sourceDependencies.sourceId == collectedDependencies.sourceId) UPDATE fileStatuses SET "
- "indexingTimeStamp = NULL WHERE sourceId IN (SELECT sourceId FROM collectedDependencies)",
+ "SELECT sourceId FROM projectPartsSources WHERE projectPartId = ? ORDER BY sourceId",
database};
+ mutable ReadStatement fetchProjectPrecompiledHeaderBuildTimeStatement{
+ "SELECT projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?", database};
+ WriteStatement resetDependentIndexingTimeStampsStatement{
+ "UPDATE fileStatuses SET indexingTimeStamp = NULL WHERE sourceId = ?", database};
+ mutable ReadStatement fetchAllProjectPartNamesAndIdsStatement{
+ "SELECT projectPartName, projectPartId FROM projectParts", database};
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartsstorageinterface.h b/src/libs/clangsupport/projectpartsstorageinterface.h
index 2d0675e657..ec1ce65dd0 100644
--- a/src/libs/clangsupport/projectpartsstorageinterface.h
+++ b/src/libs/clangsupport/projectpartsstorageinterface.h
@@ -25,7 +25,8 @@
#pragma once
-#include <projectpartcontainer.h>
+#include "projectpartcontainer.h"
+#include "projectpartstoragestructs.h"
#include <sqlitetransaction.h>
#include <utils/optional.h>
@@ -46,8 +47,10 @@ public:
virtual ProjectPartContainers fetchProjectParts() const = 0;
virtual ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const = 0;
+ virtual ProjectPartId fetchProjectPartIdUnguarded(Utils::SmallStringView projectPartName) const = 0;
virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) const = 0;
virtual Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const = 0;
+ virtual Internal::ProjectPartNameIds fetchAllProjectPartNamesAndIds() const = 0;
virtual void updateProjectPart(ProjectPartId projectPartId,
const Utils::SmallStringVector &commandLineArguments,
const CompilerMacros &compilerMacros,
diff --git a/src/libs/clangsupport/projectpartstoragestructs.h b/src/libs/clangsupport/projectpartstoragestructs.h
new file mode 100644
index 0000000000..b575d31240
--- /dev/null
+++ b/src/libs/clangsupport/projectpartstoragestructs.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "projectpartid.h"
+#include "stringcacheentry.h"
+
+#include <utils/smallstring.h>
+
+#include <vector>
+
+namespace ClangBackEnd {
+
+namespace Internal {
+
+class ProjectPartNameId
+ : public StringCacheEntry<Utils::PathString, Utils::SmallStringView, ProjectPartId>
+{
+ using Base = StringCacheEntry<Utils::PathString, Utils::SmallStringView, ProjectPartId>;
+
+public:
+ using Base::Base;
+
+ ProjectPartNameId(Utils::SmallStringView projectPartName, int projectPartId)
+ : Base(projectPartName, projectPartId)
+ {}
+};
+
+using ProjectPartNameIds = std::vector<ProjectPartNameId>;
+} // namespace Internal
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index 6042264a5d..426485a1fd 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -82,13 +82,15 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("locations");
- table.addColumn("symbolId", Sqlite::ColumnType::Integer);
+ const Sqlite::Column &symbolIdColumn = table.addColumn("symbolId",
+ Sqlite::ColumnType::Integer);
const Sqlite::Column &lineColumn = table.addColumn("line", Sqlite::ColumnType::Integer);
const Sqlite::Column &columnColumn = table.addColumn("column", Sqlite::ColumnType::Integer);
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
const Sqlite::Column &locationKindColumn = table.addColumn("locationKind", Sqlite::ColumnType::Integer);
table.addUniqueIndex({sourceIdColumn, lineColumn, columnColumn});
table.addIndex({sourceIdColumn, locationKindColumn});
+ table.addIndex({symbolIdColumn});
table.initialize(database);
}
diff --git a/src/libs/clangsupport/set_algorithm.h b/src/libs/clangsupport/set_algorithm.h
index 39bd3a2055..6a17fe6f45 100644
--- a/src/libs/clangsupport/set_algorithm.h
+++ b/src/libs/clangsupport/set_algorithm.h
@@ -89,13 +89,31 @@ bool set_intersection_compare(
++first1;
} else {
if (!comp(*first2, *first1)) {
- if (call(*first2, *first1++))
- return false;
+ if (call(*first1++, *first2))
+ return true;
}
++first2;
}
}
- return true;
+ return false;
+}
+
+template<typename InputIt1, typename InputIt2, typename BinaryPredicate, typename Callable, typename Value>
+Value mismatch_collect(InputIt1 first1,
+ InputIt1 last1,
+ InputIt2 first2,
+ InputIt2 last2,
+ Value value,
+ BinaryPredicate predicate,
+ Callable callable)
+{
+ while (first1 != last1 && first2 != last2) {
+ if (predicate(*first1, *first2))
+ value = callable(*first1, *first2, value);
+ ++first1, ++first2;
+ }
+
+ return value;
}
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/sourceentry.h b/src/libs/clangsupport/sourceentry.h
index 5e8769d14f..4912b367c3 100644
--- a/src/libs/clangsupport/sourceentry.h
+++ b/src/libs/clangsupport/sourceentry.h
@@ -59,6 +59,19 @@ public:
int64 value = -1;
};
+class PrecompiledHeaderTimeStamps
+{
+public:
+ PrecompiledHeaderTimeStamps() = default;
+ PrecompiledHeaderTimeStamps(long long projectTimeStamp, long long systemTimeStamp)
+ : project(projectTimeStamp)
+ , system(systemTimeStamp)
+ {}
+
+ TimeStamp project;
+ TimeStamp system;
+};
+
class SourceTimeStamp
{
using int64 = long long;
diff --git a/src/libs/clangsupport/sourcelocationcontainer.h b/src/libs/clangsupport/sourcelocationcontainer.h
index a975b1b2f4..1c205755b1 100644
--- a/src/libs/clangsupport/sourcelocationcontainer.h
+++ b/src/libs/clangsupport/sourcelocationcontainer.h
@@ -36,8 +36,8 @@ class CLANGSUPPORT_EXPORT SourceLocationContainer
public:
SourceLocationContainer() = default;
SourceLocationContainer(const Utf8String &filePath,
- uint line,
- uint column)
+ int line,
+ int column)
: filePath(filePath),
line(line),
column(column)
@@ -46,8 +46,8 @@ public:
public:
Utf8String filePath;
- uint line = 0;
- uint column = 0;
+ int line = 0;
+ int column = 0;
};
CLANGSUPPORT_EXPORT QDataStream &operator<<(QDataStream &out, const SourceLocationContainer &container);
diff --git a/src/libs/clangsupport/sourcerangecontainer.h b/src/libs/clangsupport/sourcerangecontainer.h
index d8ea0ce02c..603143e210 100644
--- a/src/libs/clangsupport/sourcerangecontainer.h
+++ b/src/libs/clangsupport/sourcerangecontainer.h
@@ -42,7 +42,7 @@ public:
{
}
- bool contains(unsigned line, unsigned column) const
+ bool contains(int line, int column) const
{
if (line < start.line || line > end.line)
return false;
diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h
index 9192b46aa5..3185494cf3 100644
--- a/src/libs/clangsupport/stringcache.h
+++ b/src/libs/clangsupport/stringcache.h
@@ -25,9 +25,12 @@
#pragma once
+#include "set_algorithm.h"
#include "stringcachealgorithms.h"
+#include "stringcacheentry.h"
#include "stringcachefwd.h"
+#include <utils/algorithm.h>
#include <utils/optional.h>
#include <utils/smallstringfwd.h>
@@ -90,42 +93,24 @@ private:
QReadWriteLock m_mutex;
};
-template <typename StringType,
- typename StringViewType,
- typename IndexType>
-class StringCacheEntry
+template<typename StringType,
+ typename StringViewType,
+ typename IndexType,
+ typename Mutex,
+ typename Compare,
+ Compare compare = Utils::compare,
+ typename CacheEntry = StringCacheEntry<StringType, StringViewType, IndexType>>
+class StringCache
{
-public:
- StringCacheEntry(StringType &&string, IndexType id)
- : string(std::move(string)),
- id(id)
- {}
-
- operator StringViewType() const
- {
- return string;
- }
+ template<typename T, typename V, typename I, typename M, typename C, C c, typename CE>
+ friend class StringCache;
- StringType string;
- IndexType id;
-};
+ using StringResultType = std::
+ conditional_t<std::is_base_of<NonLockingMutex, Mutex>::value, StringViewType, StringType>;
-template <typename StringType,
- typename StringViewType,
- typename IndexType>
-using StringCacheEntries = std::vector<StringCacheEntry<StringType, StringViewType, IndexType>>;
-
-template <typename StringType,
- typename StringViewType,
- typename IndexType,
- typename Mutex,
- typename Compare,
- Compare compare = Utils::compare>
-class StringCache
-{
public:
- using CacheEntry = StringCacheEntry<StringType, StringViewType, IndexType>;
- using CacheEntries = StringCacheEntries<StringType, StringViewType, IndexType>;
+ using MutexType = Mutex;
+ using CacheEntries = std::vector<CacheEntry>;
using const_iterator = typename CacheEntries::const_iterator;
using Found = ClangBackEnd::Found<const_iterator>;
@@ -135,8 +120,33 @@ public:
m_indices.reserve(reserveSize);
}
- StringCache(const StringCache &) = delete;
- StringCache &operator=(const StringCache &) = delete;
+ StringCache(const StringCache &other)
+ : m_strings(other.m_strings)
+ , m_indices(other.m_indices)
+ {}
+
+ template<typename Cache>
+ Cache clone()
+ {
+ Cache cache;
+ cache.m_strings = m_strings;
+ cache.m_indices = m_indices;
+
+ return cache;
+ }
+
+ StringCache(StringCache &&other)
+ : m_strings(std::move(other.m_strings))
+ , m_indices(std::move(other.m_indices))
+ {}
+
+ StringCache &operator=(StringCache &&other)
+ {
+ m_strings = std::move(other.m_strings);
+ m_indices = std::move(other.m_indices);
+
+ return *this;
+ }
void populate(CacheEntries &&entries)
{
@@ -147,20 +157,79 @@ public:
void uncheckedPopulate(CacheEntries &&entries)
{
- std::sort(entries.begin(),
- entries.end(),
- [] (StringViewType first, StringViewType second) {
+ std::sort(entries.begin(), entries.end(), [](StringViewType first, StringViewType second) {
return compare(first, second) < 0;
});
m_strings = std::move(entries);
- m_indices.resize(m_strings.size());
- auto begin = m_strings.cbegin();
- for (auto current = begin; current != m_strings.end(); ++current)
- m_indices.at(current->id) = std::distance(begin, current);
+ int max_id = 0;
+
+ auto found = std::max_element(m_strings.begin(),
+ m_strings.end(),
+ [](const auto &first, const auto &second) {
+ return first.id < second.id;
+ });
+
+ if (found != m_strings.end())
+ max_id = found->id + 1;
+
+ m_indices.resize(max_id, -1);
+
+ updateIndices();
}
+ template<typename Function>
+ void addStrings(std::vector<StringViewType> &&strings, Function storageFunction)
+ {
+ auto less = [](StringViewType first, StringViewType second) {
+ return compare(first, second) < 0;
+ };
+
+ std::sort(strings.begin(), strings.end(), less);
+
+ strings.erase(std::unique(strings.begin(), strings.end()), strings.end());
+
+ CacheEntries newCacheEntries;
+ newCacheEntries.reserve(strings.size());
+
+ std::set_difference(strings.begin(),
+ strings.end(),
+ m_strings.begin(),
+ m_strings.end(),
+ make_iterator([&](StringViewType newString) {
+ IndexType index = storageFunction(newString);
+ newCacheEntries.emplace_back(newString, index);
+ }),
+ less);
+
+ if (newCacheEntries.size()) {
+ auto found = std::max_element(newCacheEntries.begin(),
+ newCacheEntries.end(),
+ [](const auto &first, const auto &second) {
+ return first.id < second.id;
+ });
+
+ int max_id = found->id + 1;
+
+ if (max_id > int(m_indices.size()))
+ m_indices.resize(max_id, -1);
+
+ CacheEntries mergedCacheEntries;
+ mergedCacheEntries.reserve(newCacheEntries.size() + m_strings.size());
+
+ std::merge(std::make_move_iterator(m_strings.begin()),
+ std::make_move_iterator(m_strings.end()),
+ std::make_move_iterator(newCacheEntries.begin()),
+ std::make_move_iterator(newCacheEntries.end()),
+ std::back_inserter(mergedCacheEntries),
+ less);
+
+ m_strings = std::move(mergedCacheEntries);
+
+ updateIndices();
+ }
+ }
IndexType stringId(StringViewType stringView)
{
@@ -173,10 +242,11 @@ public:
sharedLock.unlock();
std::lock_guard<Mutex> exclusiveLock(m_mutex);
- found = find(stringView);
+ if (!std::is_base_of<NonLockingMutex, Mutex>::value)
+ found = find(stringView);
if (!found.wasFound) {
IndexType index = insertString(found.iterator, stringView, IndexType(m_indices.size()));
- found.iterator = m_strings.begin() + index;;
+ found.iterator = m_strings.begin() + index;
}
return found.iterator->id;
@@ -196,12 +266,33 @@ public:
return ids;
}
+ template<typename Container, typename Function>
+ std::vector<IndexType> stringIds(const Container &strings, Function storageFunction)
+ {
+ std::vector<IndexType> ids;
+ ids.reserve(strings.size());
+
+ std::transform(strings.begin(),
+ strings.end(),
+ std::back_inserter(ids),
+ [&](const auto &string) { return this->stringId(string, storageFunction); });
+
+ return ids;
+ }
+
std::vector<IndexType> stringIds(std::initializer_list<StringType> strings)
{
return stringIds<std::initializer_list<StringType>>(strings);
}
- StringType string(IndexType id) const
+ template<typename Function>
+ std::vector<IndexType> stringIds(std::initializer_list<StringType> strings,
+ Function storageFunction)
+ {
+ return stringIds<std::initializer_list<StringType>>(strings, storageFunction);
+ }
+
+ StringResultType string(IndexType id) const
{
std::shared_lock<Mutex> sharedLock(m_mutex);
@@ -209,7 +300,7 @@ public:
}
template<typename Function>
- StringType string(IndexType id, Function storageFunction)
+ StringResultType string(IndexType id, Function storageFunction)
{
std::shared_lock<Mutex> sharedLock(m_mutex);
@@ -227,17 +318,15 @@ public:
return m_strings[index].string;
}
- std::vector<StringType> strings(const std::vector<IndexType> &ids) const
+ std::vector<StringResultType> strings(const std::vector<IndexType> &ids) const
{
std::shared_lock<Mutex> sharedLock(m_mutex);
- std::vector<StringType> strings;
+ std::vector<StringResultType> strings;
strings.reserve(ids.size());
- std::transform(ids.begin(),
- ids.end(),
- std::back_inserter(strings),
- [&] (IndexType id) { return m_strings.at(m_indices.at(id)).string; });
+ for (IndexType id : ids)
+ strings.emplace_back(m_strings.at(m_indices.at(id)).string);
return strings;
}
@@ -260,7 +349,8 @@ public:
sharedLock.unlock();
std::lock_guard<Mutex> exclusiveLock(m_mutex);
- found = find(stringView);
+ if (!std::is_base_of<NonLockingMutex, Mutex>::value)
+ found = find(stringView);
if (!found.wasFound) {
IndexType index = insertString(found.iterator, stringView, storageFunction(stringView));
found.iterator = m_strings.begin() + index;
@@ -275,6 +365,13 @@ public:
}
private:
+ void updateIndices()
+ {
+ auto begin = m_strings.cbegin();
+ for (auto current = begin; current != m_strings.cend(); ++current)
+ m_indices[current->id] = std::distance(begin, current);
+ }
+
Found find(StringViewType stringView)
{
return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare);
@@ -300,7 +397,7 @@ private:
StringViewType stringView,
IndexType id)
{
- auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id);
+ auto inserted = m_strings.emplace(beforeIterator, stringView, id);
auto newIndex = IndexType(std::distance(m_strings.begin(), inserted));
diff --git a/src/libs/clangsupport/stringcacheentry.h b/src/libs/clangsupport/stringcacheentry.h
new file mode 100644
index 0000000000..bbffcdc873
--- /dev/null
+++ b/src/libs/clangsupport/stringcacheentry.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+namespace ClangBackEnd {
+
+template<typename StringType, typename StringViewType, typename IndexType>
+class StringCacheEntry
+{
+public:
+ StringCacheEntry(StringViewType string, IndexType id)
+ : string(string)
+ , id(id)
+ {}
+
+ operator StringViewType() const { return string; }
+ friend bool operator==(const StringCacheEntry &first, const StringCacheEntry &second)
+ {
+ return first.id == second.id && first.string == second.string;
+ }
+
+public:
+ StringType string;
+ IndexType id;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/stringcachefwd.h b/src/libs/clangsupport/stringcachefwd.h
index adc00ff1f5..2059b503b6 100644
--- a/src/libs/clangsupport/stringcachefwd.h
+++ b/src/libs/clangsupport/stringcachefwd.h
@@ -31,12 +31,7 @@ namespace ClangBackEnd {
class NonLockingMutex;
-template <typename StringType,
- typename StringViewType,
- typename IndexType,
- typename Mutex,
- typename Compare,
- Compare compare>
+template<typename StringType, typename StringViewType, typename IndexType, typename Mutex, typename Compare, Compare compare, typename CacheEntry>
class StringCache;
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/tokeninfocontainer.h b/src/libs/clangsupport/tokeninfocontainer.h
index 2b8e01e769..c819268fb9 100644
--- a/src/libs/clangsupport/tokeninfocontainer.h
+++ b/src/libs/clangsupport/tokeninfocontainer.h
@@ -103,7 +103,7 @@ class TokenInfoContainer
{
public:
TokenInfoContainer() = default;
- TokenInfoContainer(uint line, uint column, uint length, HighlightingTypes types)
+ TokenInfoContainer(int line, int column, int length, HighlightingTypes types)
: line(line)
, column(column)
, length(length)
@@ -111,7 +111,7 @@ public:
{
}
- TokenInfoContainer(uint line, uint column, uint length, HighlightingTypes types,
+ TokenInfoContainer(int line, int column, int length, HighlightingTypes types,
const ExtraInfo &extraInfo)
: line(line)
, column(column)
@@ -184,9 +184,9 @@ public:
&& first.extraInfo == second.extraInfo;
}
- uint line = 0;
- uint column = 0;
- uint length = 0;
+ int line = 0;
+ int column = 0;
+ int length = 0;
HighlightingTypes types;
ExtraInfo extraInfo;
bool noExtraInfo = true;
diff --git a/src/libs/cplusplus/ASTPath.cpp b/src/libs/cplusplus/ASTPath.cpp
index 3acec43c42..277a7d0838 100644
--- a/src/libs/cplusplus/ASTPath.cpp
+++ b/src/libs/cplusplus/ASTPath.cpp
@@ -67,12 +67,12 @@ bool ASTPath::preVisit(AST *ast)
if (lastToken <= firstToken)
return false;
- unsigned startLine, startColumn;
+ int startLine, startColumn;
getTokenStartPosition(firstToken, &startLine, &startColumn);
if (_line > startLine || (_line == startLine && _column >= startColumn)) {
- unsigned endLine, endColumn;
+ int endLine, endColumn;
getTokenEndPosition(lastToken - 1, &endLine, &endColumn);
if (_line < endLine || (_line == endLine && _column <= endColumn)) {
diff --git a/src/libs/cplusplus/ASTPath.h b/src/libs/cplusplus/ASTPath.h
index e7dfab7fad..6e199ca853 100644
--- a/src/libs/cplusplus/ASTPath.h
+++ b/src/libs/cplusplus/ASTPath.h
@@ -64,8 +64,8 @@ private:
private:
Document::Ptr _doc;
- unsigned _line;
- unsigned _column;
+ int _line;
+ int _column;
QList<AST *> _nodes;
};
diff --git a/src/libs/cplusplus/AlreadyConsideredClassContainer.h b/src/libs/cplusplus/AlreadyConsideredClassContainer.h
index fd35291c2a..01260c0348 100644
--- a/src/libs/cplusplus/AlreadyConsideredClassContainer.h
+++ b/src/libs/cplusplus/AlreadyConsideredClassContainer.h
@@ -35,7 +35,7 @@ template<typename T>
class AlreadyConsideredClassContainer
{
public:
- AlreadyConsideredClassContainer() : _class(0) {}
+ AlreadyConsideredClassContainer() : _class(nullptr) {}
void insert(const T *item)
{
if (_container.isEmpty())
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 73cc06f26a..578a6a117f 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -61,19 +61,19 @@ namespace {
class LastVisibleSymbolAt: protected SymbolVisitor
{
Symbol *root;
- unsigned line;
- unsigned column;
+ int line;
+ int column;
Symbol *symbol;
public:
LastVisibleSymbolAt(Symbol *root)
- : root(root), line(0), column(0), symbol(0) {}
+ : root(root), line(0), column(0), symbol(nullptr) {}
- Symbol *operator()(unsigned line, unsigned column)
+ Symbol *operator()(int line, int column)
{
this->line = line;
this->column = column;
- this->symbol = 0;
+ this->symbol = nullptr;
accept(root);
if (! symbol)
symbol = root;
@@ -97,14 +97,14 @@ protected:
class FindScopeAt: protected SymbolVisitor
{
TranslationUnit *_unit;
- unsigned _line;
- unsigned _column;
+ int _line;
+ int _column;
Scope *_scope;
public:
/** line and column should be 1-based */
- FindScopeAt(TranslationUnit *unit, unsigned line, unsigned column)
- : _unit(unit), _line(line), _column(column), _scope(0) {}
+ FindScopeAt(TranslationUnit *unit, int line, int column)
+ : _unit(unit), _line(line), _column(column), _scope(nullptr) {}
Scope *operator()(Symbol *symbol)
{
@@ -118,18 +118,18 @@ protected:
if (! _scope) {
Scope *scope = symbol;
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
accept(scope->memberAt(i));
if (_scope)
return false;
}
- unsigned startLine, startColumn;
+ int startLine, startColumn;
_unit->getPosition(scope->startOffset(), &startLine, &startColumn);
if (_line > startLine || (_line == startLine && _column >= startColumn)) {
- unsigned endLine, endColumn;
+ int endLine, endColumn;
_unit->getPosition(scope->endOffset(), &endLine, &endColumn);
if (_line < endLine || (_line == endLine && _column < endColumn))
@@ -211,7 +211,7 @@ public:
void report(int level,
const StringLiteral *fileId,
- unsigned line, unsigned column,
+ int line, int column,
const char *format, va_list ap) override
{
if (level == Error) {
@@ -265,7 +265,7 @@ private:
Document::Document(const QString &fileName)
: _fileName(QDir::cleanPath(fileName)),
- _globalNamespace(0),
+ _globalNamespace(nullptr),
_revision(0),
_editorRevision(0),
_checkMode(0)
@@ -284,12 +284,12 @@ Document::Document(const QString &fileName)
Document::~Document()
{
delete _translationUnit;
- _translationUnit = 0;
+ _translationUnit = nullptr;
if (_control) {
delete _control->diagnosticClient();
delete _control;
}
- _control = 0;
+ _control = nullptr;
}
Control *Document::control() const
@@ -308,7 +308,7 @@ Control *Document::swapControl(Control *newControl)
_translationUnit = newTranslationUnit;
} else {
delete _translationUnit;
- _translationUnit = 0;
+ _translationUnit = nullptr;
}
Control *oldControl = _control;
@@ -375,9 +375,9 @@ void Document::appendMacro(const Macro &macro)
}
void Document::addMacroUse(const Macro &macro,
- unsigned bytesOffset, unsigned bytesLength,
- unsigned utf16charsOffset, unsigned utf16charLength,
- unsigned beginLine,
+ int bytesOffset, int bytesLength,
+ int utf16charsOffset, int utf16charLength,
+ int beginLine,
const QVector<MacroArgumentReference> &actuals)
{
MacroUse use(macro,
@@ -397,7 +397,7 @@ void Document::addMacroUse(const Macro &macro,
}
void Document::addUndefinedMacroUse(const QByteArray &name,
- unsigned bytesOffset, unsigned utf16charsOffset)
+ int bytesOffset, int utf16charsOffset)
{
QByteArray copy(name.data(), name.size());
UndefinedMacroUse use(copy, bytesOffset, utf16charsOffset);
@@ -468,7 +468,7 @@ void Document::setSkipFunctionBody(bool skipFunctionBody)
_translationUnit->setSkipFunctionBody(skipFunctionBody);
}
-unsigned Document::globalSymbolCount() const
+int Document::globalSymbolCount() const
{
if (! _globalNamespace)
return 0;
@@ -476,7 +476,7 @@ unsigned Document::globalSymbolCount() const
return _globalNamespace->memberCount();
}
-Symbol *Document::globalSymbolAt(unsigned index) const
+Symbol *Document::globalSymbolAt(int index) const
{
return _globalNamespace->memberAt(index);
}
@@ -527,23 +527,17 @@ QString Document::functionAt(int line, int column, int *lineOpeningDeclaratorPar
return QString();
// We found the function scope
- if (lineOpeningDeclaratorParenthesis) {
- unsigned line;
- translationUnit()->getPosition(scope->startOffset(), &line);
- *lineOpeningDeclaratorParenthesis = static_cast<int>(line);
- }
+ if (lineOpeningDeclaratorParenthesis)
+ translationUnit()->getPosition(scope->startOffset(), lineOpeningDeclaratorParenthesis);
- if (lineClosingBrace) {
- unsigned line;
- translationUnit()->getPosition(scope->endOffset(), &line);
- *lineClosingBrace = static_cast<int>(line);
- }
+ if (lineClosingBrace)
+ translationUnit()->getPosition(scope->endOffset(), lineClosingBrace);
const QList<const Name *> fullyQualifiedName = LookupContext::fullyQualifiedName(scope);
return Overview().prettyName(fullyQualifiedName);
}
-Scope *Document::scopeAt(unsigned line, unsigned column)
+Scope *Document::scopeAt(int line, int column)
{
FindScopeAt findScopeAt(_translationUnit, line, column);
if (Scope *scope = findScopeAt(_globalNamespace))
@@ -551,22 +545,22 @@ Scope *Document::scopeAt(unsigned line, unsigned column)
return globalNamespace();
}
-Symbol *Document::lastVisibleSymbolAt(unsigned line, unsigned column) const
+Symbol *Document::lastVisibleSymbolAt(int line, int column) const
{
LastVisibleSymbolAt lastVisibleSymbolAt(globalNamespace());
return lastVisibleSymbolAt(line, column);
}
-const Macro *Document::findMacroDefinitionAt(unsigned line) const
+const Macro *Document::findMacroDefinitionAt(int line) const
{
foreach (const Macro &macro, _definedMacros) {
if (macro.line() == line)
return &macro;
}
- return 0;
+ return nullptr;
}
-const Document::MacroUse *Document::findMacroUseAt(unsigned utf16charsOffset) const
+const Document::MacroUse *Document::findMacroUseAt(int utf16charsOffset) const
{
foreach (const Document::MacroUse &use, _macroUses) {
if (use.containsUtf16charOffset(utf16charsOffset)
@@ -574,10 +568,10 @@ const Document::MacroUse *Document::findMacroUseAt(unsigned utf16charsOffset) co
return &use;
}
}
- return 0;
+ return nullptr;
}
-const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned utf16charsOffset) const
+const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(int utf16charsOffset) const
{
foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) {
if (use.containsUtf16charOffset(utf16charsOffset)
@@ -585,7 +579,7 @@ const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned ut
+ QString::fromUtf8(use.name(), use.name().size()).length()))
return &use;
}
- return 0;
+ return nullptr;
}
Document::Ptr Document::create(const QString &fileName)
@@ -616,17 +610,17 @@ void Document::setLanguageFeatures(LanguageFeatures features)
tu->setLanguageFeatures(features);
}
-void Document::startSkippingBlocks(unsigned utf16charsOffset)
+void Document::startSkippingBlocks(int utf16charsOffset)
{
_skippedBlocks.append(Block(0, 0, utf16charsOffset, 0));
}
-void Document::stopSkippingBlocks(unsigned utf16charsOffset)
+void Document::stopSkippingBlocks(int utf16charsOffset)
{
if (_skippedBlocks.isEmpty())
return;
- unsigned start = _skippedBlocks.back().utf16charsBegin();
+ int start = _skippedBlocks.back().utf16charsBegin();
if (start > utf16charsOffset)
_skippedBlocks.removeLast(); // Ignore this block, it's invalid.
else
@@ -783,7 +777,7 @@ static QList<Macro> macrosDefinedUntilLine(const QList<Macro> &macros, int line)
QList<Macro> filtered;
foreach (const Macro &macro, macros) {
- if (macro.line() <= unsigned(line))
+ if (macro.line() <= line)
filtered.append(macro);
else
break;
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index 74205f1625..94c16be742 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -71,11 +71,11 @@ public:
void appendMacro(const Macro &macro);
void addMacroUse(const Macro &macro,
- unsigned bytesOffset, unsigned bytesLength,
- unsigned utf16charsOffset, unsigned utf16charLength,
- unsigned beginLine, const QVector<MacroArgumentReference> &range);
+ int bytesOffset, int bytesLength,
+ int utf16charsOffset, int utf16charLength,
+ int beginLine, const QVector<MacroArgumentReference> &range);
void addUndefinedMacroUse(const QByteArray &name,
- unsigned bytesOffset, unsigned utf16charsOffset);
+ int bytesOffset, int utf16charsOffset);
Control *control() const;
Control *swapControl(Control *newControl);
@@ -84,8 +84,8 @@ public:
bool skipFunctionBody() const;
void setSkipFunctionBody(bool skipFunctionBody);
- unsigned globalSymbolCount() const;
- Symbol *globalSymbolAt(unsigned index) const;
+ int globalSymbolCount() const;
+ Symbol *globalSymbolAt(int index) const;
Namespace *globalNamespace() const;
void setGlobalNamespace(Namespace *globalNamespace); // ### internal
@@ -93,10 +93,10 @@ public:
QList<Macro> definedMacros() const
{ return _definedMacros; }
- QString functionAt(int line, int column, int *lineOpeningDeclaratorParenthesis = 0,
- int *lineClosingBrace = 0) const;
- Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const;
- Scope *scopeAt(unsigned line, unsigned column = 0);
+ QString functionAt(int line, int column, int *lineOpeningDeclaratorParenthesis = nullptr,
+ int *lineClosingBrace = nullptr) const;
+ Symbol *lastVisibleSymbolAt(int line, int column = 0) const;
+ Scope *scopeAt(int line, int column = 0);
QByteArray utf8Source() const;
void setUtf8Source(const QByteArray &utf8Source);
@@ -108,8 +108,8 @@ public:
LanguageFeatures languageFeatures() const;
void setLanguageFeatures(LanguageFeatures features);
- void startSkippingBlocks(unsigned utf16charsOffset);
- void stopSkippingBlocks(unsigned utf16charsOffset);
+ void startSkippingBlocks(int utf16charsOffset);
+ void stopSkippingBlocks(int utf16charsOffset);
enum ParseMode { // ### keep in sync with CPlusPlus::TranslationUnit
ParseTranlationUnit,
@@ -146,9 +146,9 @@ public:
public:
DiagnosticMessage(int level, const QString &fileName,
- unsigned line, unsigned column,
+ int line, int column,
const QString &text,
- unsigned length = 0)
+ int length = 0)
: _level(level),
_line(line),
_fileName(fileName),
@@ -172,13 +172,13 @@ public:
QString fileName() const
{ return _fileName; }
- unsigned line() const
+ int line() const
{ return _line; }
- unsigned column() const
+ int column() const
{ return _column; }
- unsigned length() const
+ int length() const
{ return _length; }
QString text() const
@@ -189,10 +189,10 @@ public:
private:
int _level;
- unsigned _line;
+ int _line;
QString _fileName;
- unsigned _column;
- unsigned _length;
+ int _column;
+ int _length;
QString _text;
};
@@ -207,44 +207,44 @@ public:
class Block
{
- unsigned _bytesBegin;
- unsigned _bytesEnd;
- unsigned _utf16charsBegin;
- unsigned _utf16charsEnd;
+ int _bytesBegin;
+ int _bytesEnd;
+ int _utf16charsBegin;
+ int _utf16charsEnd;
public:
- inline Block(unsigned bytesBegin = 0, unsigned bytesEnd = 0,
- unsigned utf16charsBegin = 0, unsigned utf16charsEnd = 0)
+ inline Block(int bytesBegin = 0, int bytesEnd = 0,
+ int utf16charsBegin = 0, int utf16charsEnd = 0)
: _bytesBegin(bytesBegin),
_bytesEnd(bytesEnd),
_utf16charsBegin(utf16charsBegin),
_utf16charsEnd(utf16charsEnd)
{}
- inline unsigned bytesBegin() const
+ inline int bytesBegin() const
{ return _bytesBegin; }
- inline unsigned bytesEnd() const
+ inline int bytesEnd() const
{ return _bytesEnd; }
- inline unsigned utf16charsBegin() const
+ inline int utf16charsBegin() const
{ return _utf16charsBegin; }
- inline unsigned utf16charsEnd() const
+ inline int utf16charsEnd() const
{ return _utf16charsEnd; }
- bool containsUtf16charOffset(unsigned utf16charOffset) const
+ bool containsUtf16charOffset(int utf16charOffset) const
{ return utf16charOffset >= _utf16charsBegin && utf16charOffset < _utf16charsEnd; }
};
class Include {
QString _resolvedFileName;
QString _unresolvedFileName;
- unsigned _line;
+ int _line;
Client::IncludeType _type;
public:
- Include(const QString &unresolvedFileName, const QString &resolvedFileName, unsigned line,
+ Include(const QString &unresolvedFileName, const QString &resolvedFileName, int line,
Client::IncludeType type)
: _resolvedFileName(resolvedFileName)
, _unresolvedFileName(unresolvedFileName)
@@ -258,7 +258,7 @@ public:
QString unresolvedFileName() const
{ return _unresolvedFileName; }
- unsigned line() const
+ int line() const
{ return _line; }
Client::IncludeType type() const
@@ -268,13 +268,13 @@ public:
class MacroUse: public Block {
Macro _macro;
QVector<Block> _arguments;
- unsigned _beginLine;
+ int _beginLine;
public:
inline MacroUse(const Macro &macro,
- unsigned bytesBegin, unsigned bytesEnd,
- unsigned utf16charsBegin, unsigned utf16charsEnd,
- unsigned beginLine)
+ int bytesBegin, int bytesEnd,
+ int utf16charsBegin, int utf16charsEnd,
+ int beginLine)
: Block(bytesBegin, bytesEnd, utf16charsBegin, utf16charsEnd),
_macro(macro),
_beginLine(beginLine)
@@ -289,7 +289,7 @@ public:
QVector<Block> arguments() const
{ return _arguments; }
- unsigned beginLine() const
+ int beginLine() const
{ return _beginLine; }
private:
@@ -308,8 +308,8 @@ public:
public:
inline UndefinedMacroUse(
const QByteArray &name,
- unsigned bytesBegin,
- unsigned utf16charsBegin)
+ int bytesBegin,
+ int utf16charsBegin)
: Block(bytesBegin,
bytesBegin + name.length(),
utf16charsBegin,
@@ -346,9 +346,9 @@ public:
QByteArray includeGuardMacroName() const
{ return _includeGuardMacroName; }
- const Macro *findMacroDefinitionAt(unsigned line) const;
- const MacroUse *findMacroUseAt(unsigned utf16charsOffset) const;
- const UndefinedMacroUse *findUndefinedMacroUseAt(unsigned utf16charsOffset) const;
+ const Macro *findMacroDefinitionAt(int line) const;
+ const MacroUse *findMacroUseAt(int utf16charsOffset) const;
+ const UndefinedMacroUse *findUndefinedMacroUseAt(int utf16charsOffset) const;
void keepSourceAndAST();
void releaseSourceAndAST();
@@ -397,7 +397,7 @@ public:
typedef Base::const_iterator iterator;
typedef Base::const_iterator const_iterator;
- typedef QPair<Document::Ptr, unsigned> IncludeLocation;
+ typedef QPair<Document::Ptr, int> IncludeLocation;
int size() const; // ### remove
bool isEmpty() const;
diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp
index aec22d8248..fdb5de3851 100644
--- a/src/libs/cplusplus/CppRewriter.cpp
+++ b/src/libs/cplusplus/CppRewriter.cpp
@@ -131,7 +131,7 @@ public:
void visit(Function *type) override
{
- Function *funTy = control()->newFunction(0, 0);
+ Function *funTy = control()->newFunction(0, nullptr);
funTy->copy(type);
funTy->setConst(type->isConst());
funTy->setVolatile(type->isVolatile());
@@ -144,7 +144,7 @@ public:
for (unsigned i = 0, argc = type->argumentCount(); i < argc; ++i) {
Symbol *arg = type->argumentAt(i);
- Argument *newArg = control()->newArgument(0, 0);
+ Argument *newArg = control()->newArgument(0, nullptr);
newArg->copy(arg);
newArg->setName(rewrite->rewriteName(arg->name()));
newArg->setType(rewrite->rewriteType(arg->type()));
@@ -225,7 +225,7 @@ public:
const Identifier *identifier(const Identifier *other) const
{
if (! other)
- return 0;
+ return nullptr;
return control()->identifier(other->chars(), other->size());
}
@@ -236,7 +236,7 @@ public:
const Name *operator()(const Name *name)
{
if (! name)
- return 0;
+ return nullptr;
accept(name);
return (!temps.isEmpty()) ? temps.takeLast() : name;
@@ -257,7 +257,7 @@ public:
void visit(const TemplateNameId *name) override
{
QVarLengthArray<FullySpecifiedType, 8> args(name->templateArgumentCount());
- for (unsigned i = 0; i < name->templateArgumentCount(); ++i)
+ for (int i = 0; i < name->templateArgumentCount(); ++i)
args[i] = rewrite->rewriteType(name->templateArgumentAt(i));
temps.append(control()->templateNameId(identifier(name->identifier()), name->isSpecialization(),
args.data(), args.size()));
@@ -282,7 +282,7 @@ public:
void visit(const SelectorNameId *name) override
{
QVarLengthArray<const Name *, 8> names(name->nameCount());
- for (unsigned i = 0; i < name->nameCount(); ++i)
+ for (int i = 0; i < name->nameCount(); ++i)
names[i] = rewrite->rewriteName(name->nameAt(i));
temps.append(control()->selectorNameId(names.constData(), names.size(), name->hasArguments()));
}
@@ -296,7 +296,7 @@ public: // attributes
};
SubstitutionEnvironment::SubstitutionEnvironment()
- : _scope(0)
+ : _scope(nullptr)
{
}
@@ -415,7 +415,7 @@ FullySpecifiedType UseMinimalNames::apply(const Name *name, Rewrite *rewrite) co
UseQualifiedNames::UseQualifiedNames()
- : UseMinimalNames(0)
+ : UseMinimalNames(nullptr)
{
}
diff --git a/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp b/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp
index db39d0b20d..d3653137b3 100644
--- a/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp
+++ b/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp
@@ -136,7 +136,7 @@ private:
fun->setReturnType(q->apply(funTy->returnType()));
- for (unsigned i = 0, argc = funTy->argumentCount(); i < argc; ++i) {
+ for (int i = 0, argc = funTy->argumentCount(); i < argc; ++i) {
Argument *originalArgument = funTy->argumentAt(i)->asArgument();
Argument *arg = control()->newArgument(/*sourceLocation*/ 0,
originalArgument->name());
@@ -243,7 +243,7 @@ private:
void visit(const TemplateNameId *name) override
{
QVarLengthArray<FullySpecifiedType, 8> arguments(name->templateArgumentCount());
- for (unsigned i = 0; i < name->templateArgumentCount(); ++i) {
+ for (int i = 0; i < name->templateArgumentCount(); ++i) {
FullySpecifiedType argTy = name->templateArgumentAt(i);
arguments[i] = q->apply(argTy);
}
@@ -266,7 +266,7 @@ private:
} else if (const TemplateNameId *templId = name->asTemplateNameId()) {
QVarLengthArray<FullySpecifiedType, 8> arguments(templId->templateArgumentCount());
- for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount();
+ for (int templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount();
++templateArgIndex) {
FullySpecifiedType argTy = templId->templateArgumentAt(templateArgIndex);
arguments[templateArgIndex] = q->apply(argTy);
@@ -291,7 +291,7 @@ private:
}
- return 0;
+ return nullptr;
}
void visit(const QualifiedNameId *name) override
@@ -362,7 +362,7 @@ FullySpecifiedType ApplySubstitution::apply(const FullySpecifiedType &type)
int ApplySubstitution::findSubstitution(const Identifier *id) const
{
- Q_ASSERT(id != 0);
+ Q_ASSERT(id != nullptr);
for (int index = 0; index < substitution.size(); ++index) {
QPair<const Identifier *, FullySpecifiedType> s = substitution.at(index);
@@ -403,7 +403,7 @@ FullySpecifiedType DeprecatedGenTemplateInstance::instantiate(const Name *classN
if (Template *templ = candidate->enclosingTemplate()) {
DeprecatedGenTemplateInstance::Substitution subst;
- for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
+ for (int i = 0; i < templId->templateArgumentCount(); ++i) {
FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
if (i < templ->templateParameterCount()) {
diff --git a/src/libs/cplusplus/FastPreprocessor.cpp b/src/libs/cplusplus/FastPreprocessor.cpp
index 78a25826cc..be63dea9a2 100644
--- a/src/libs/cplusplus/FastPreprocessor.cpp
+++ b/src/libs/cplusplus/FastPreprocessor.cpp
@@ -70,7 +70,7 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc,
return preprocessed;
}
-void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType mode,
+void FastPreprocessor::sourceNeeded(int line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes)
{
Q_UNUSED(initialIncludes)
@@ -115,8 +115,8 @@ static const Macro revision(const Snapshot &s, const Macro &m)
return m;
}
-void FastPreprocessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro)
+void FastPreprocessor::passedMacroDefinitionCheck(int bytesOffset, int utf16charsOffset,
+ int line, const Macro &macro)
{
Q_ASSERT(_currentDoc);
@@ -126,7 +126,7 @@ void FastPreprocessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned
line, QVector<MacroArgumentReference>());
}
-void FastPreprocessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
+void FastPreprocessor::failedMacroDefinitionCheck(int bytesOffset, int utf16charsOffset,
const ByteArrayRef &name)
{
Q_ASSERT(_currentDoc);
@@ -135,8 +135,8 @@ void FastPreprocessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsigned
bytesOffset, utf16charsOffset);
}
-void FastPreprocessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro)
+void FastPreprocessor::notifyMacroReference(int bytesOffset, int utf16charsOffset,
+ int line, const Macro &macro)
{
Q_ASSERT(_currentDoc);
@@ -146,8 +146,8 @@ void FastPreprocessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16
line, QVector<MacroArgumentReference>());
}
-void FastPreprocessor::startExpandingMacro(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro,
+void FastPreprocessor::startExpandingMacro(int bytesOffset, int utf16charsOffset,
+ int line, const Macro &macro,
const QVector<MacroArgumentReference> &actuals)
{
Q_ASSERT(_currentDoc);
diff --git a/src/libs/cplusplus/FastPreprocessor.h b/src/libs/cplusplus/FastPreprocessor.h
index da63bdd59b..bebe3da4d2 100644
--- a/src/libs/cplusplus/FastPreprocessor.h
+++ b/src/libs/cplusplus/FastPreprocessor.h
@@ -55,26 +55,26 @@ public:
bool mergeDefinedMacrosOfDocument = false);
// CPlusPlus::Client
- virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode,
+ virtual void sourceNeeded(int line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes = QStringList());
virtual void macroAdded(const Macro &);
- virtual void passedMacroDefinitionCheck(unsigned, unsigned, unsigned, const Macro &);
- virtual void failedMacroDefinitionCheck(unsigned, unsigned, const ByteArrayRef &);
+ virtual void passedMacroDefinitionCheck(int, int, int, const Macro &);
+ virtual void failedMacroDefinitionCheck(int, int, const ByteArrayRef &);
- virtual void notifyMacroReference(unsigned, unsigned, unsigned, const Macro &);
+ virtual void notifyMacroReference(int, int, int, const Macro &);
- virtual void startExpandingMacro(unsigned,
- unsigned,
- unsigned,
+ virtual void startExpandingMacro(int,
+ int,
+ int,
const Macro &,
const QVector<MacroArgumentReference> &);
- virtual void stopExpandingMacro(unsigned, const Macro &) {}
+ virtual void stopExpandingMacro(int, const Macro &) {}
virtual void markAsIncludeGuard(const QByteArray &macroName);
- virtual void startSkippingBlocks(unsigned) {}
- virtual void stopSkippingBlocks(unsigned) {}
+ virtual void startSkippingBlocks(int) {}
+ virtual void stopSkippingBlocks(int) {}
};
} // namespace CPlusPlus
diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index 638fba451b..addaac7134 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -98,7 +98,7 @@ void FindUsages::operator()(Symbol *symbol)
void FindUsages::reportResult(unsigned tokenIndex, const Name *name, Scope *scope)
{
- if (! (tokenIndex && name != 0))
+ if (! (tokenIndex && name != nullptr))
return;
if (name->identifier() != _id)
@@ -157,10 +157,10 @@ void FindUsages::reportResult(unsigned tokenIndex)
_processed.insert(tokenIndex);
- unsigned line, col;
+ int line, col;
getTokenStartPosition(tokenIndex, &line, &col);
QString lineText;
- if (line < _sourceLineEnds.size())
+ if (line < int(_sourceLineEnds.size()))
lineText = fetchLine(line);
else
lineText = matchingLine(tk);
@@ -298,7 +298,7 @@ const Name *FindUsages::name(NameAST *ast)
return ast->name;
}
- return 0;
+ return nullptr;
}
void FindUsages::specifier(SpecifierAST *ast)
@@ -1867,7 +1867,7 @@ bool FindUsages::visit(QualifiedNameAST *ast)
if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
- TemplateIdAST *template_id = 0;
+ TemplateIdAST *template_id = nullptr;
if (! simple_name) {
template_id = class_or_namespace_name->asTemplateId();
@@ -1897,7 +1897,7 @@ bool FindUsages::visit(QualifiedNameAST *ast)
else if (DestructorNameAST *dtor = unqualified_name->asDestructorName())
identifier_token = dtor->unqualified_name->firstToken();
- TemplateIdAST *template_id = 0;
+ TemplateIdAST *template_id = nullptr;
if (! identifier_token) {
template_id = unqualified_name->asTemplateId();
diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h
index 2b6880a55c..3fd13a30a2 100644
--- a/src/libs/cplusplus/FindUsages.h
+++ b/src/libs/cplusplus/FindUsages.h
@@ -69,13 +69,13 @@ protected:
QString matchingLine(const Token &tk) const;
- void reportResult(unsigned tokenIndex, const Name *name, Scope *scope = 0);
- void reportResult(unsigned tokenIndex, const Identifier *id, Scope *scope = 0);
+ void reportResult(unsigned tokenIndex, const Name *name, Scope *scope = nullptr);
+ void reportResult(unsigned tokenIndex, const Identifier *id, Scope *scope = nullptr);
void reportResult(unsigned tokenIndex, const QList<LookupItem> &candidates);
void reportResult(unsigned tokenIndex);
bool checkCandidates(const QList<LookupItem> &candidates) const;
- void checkExpression(unsigned startToken, unsigned endToken, Scope *scope = 0);
+ void checkExpression(unsigned startToken, unsigned endToken, Scope *scope = nullptr);
static bool isLocalScope(Scope *scope);
@@ -90,7 +90,7 @@ protected:
void objCSelectorArgument(ObjCSelectorArgumentAST *ast);
void attribute(GnuAttributeAST *ast);
- void declarator(DeclaratorAST *ast, Scope *symbol = 0);
+ void declarator(DeclaratorAST *ast, Scope *symbol = nullptr);
void qtPropertyDeclarationItem(QtPropertyDeclarationItemAST *ast);
void qtInterfaceName(QtInterfaceNameAST *ast);
void baseSpecifier(BaseSpecifierAST *ast);
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 5a187e4f1d..451e3d3a78 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -234,7 +234,7 @@ static bool symbolIdentical(Symbol *s1, Symbol *s2)
static const Name *toName(const QList<const Name *> &names, Control *control)
{
- const Name *n = 0;
+ const Name *n = nullptr;
for (int i = names.size() - 1; i >= 0; --i) {
if (! n)
n = names.at(i);
@@ -260,7 +260,7 @@ static bool isInlineNamespace(ClassOrNamespace *con, const Name *name)
const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target, Control *control)
{
- const Name *n = 0;
+ const Name *n = nullptr;
QList<const Name *> names = LookupContext::fullyQualifiedName(symbol);
for (int i = names.size() - 1; i >= 0; --i) {
@@ -299,7 +299,7 @@ QList<LookupItem> LookupContext::lookupByUsing(const Name *name,
if (name->isNameId() || name->isTemplateNameId()) {
foreach (Symbol *s, bindingScope->symbols()) {
if (Scope *scope = s->asScope()) {
- for (unsigned i = 0, count = scope->memberCount(); i < count; ++i) {
+ for (int i = 0, count = scope->memberCount(); i < count; ++i) {
if (UsingDeclaration *u = scope->memberAt(i)->asUsingDeclaration()) {
if (const Name *usingDeclarationName = u->name()) {
if (const QualifiedNameId *q
@@ -360,9 +360,9 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
QSet<const Declaration *> typedefsBeingResolved) const
{
if (! scope || ! name) {
- return 0;
+ return nullptr;
} else if (Block *block = scope->asBlock()) {
- for (unsigned i = 0; i < block->memberCount(); ++i) {
+ for (int i = 0; i < block->memberCount(); ++i) {
Symbol *m = block->memberAt(i);
if (UsingNamespaceDirective *u = m->asUsingNamespaceDirective()) {
if (ClassOrNamespace *uu = lookupType(u->name(), scope->enclosingNamespace())) {
@@ -379,8 +379,8 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
if (const NamedType *namedTy = d->type()->asNamedType()) {
// Stop on recursive typedef declarations
if (typedefsBeingResolved.contains(d))
- return 0;
- return lookupType(namedTy->name(), scope, 0,
+ return nullptr;
+ return lookupType(namedTy->name(), scope, nullptr,
QSet<const Declaration *>(typedefsBeingResolved)
<< d);
}
@@ -421,7 +421,7 @@ ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope,
}
}
- return 0;
+ return nullptr;
}
ClassOrNamespace *LookupContext::lookupType(Symbol *symbol,
@@ -438,8 +438,8 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
return candidates;
for (; scope; scope = scope->enclosingScope()) {
- if (name->identifier() != 0 && scope->isBlock()) {
- bindings()->lookupInScope(name, scope, &candidates, /*templateId = */ 0, /*binding=*/ 0);
+ if (name->identifier() != nullptr && scope->isBlock()) {
+ bindings()->lookupInScope(name, scope, &candidates, /*templateId = */ nullptr, /*binding=*/ nullptr);
if (! candidates.isEmpty()) {
// it's a local.
@@ -450,7 +450,7 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
break;
}
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
if (UsingNamespaceDirective *u = scope->memberAt(i)->asUsingNamespaceDirective()) {
if (ClassOrNamespace *uu = lookupType(u->name(), scope->enclosingNamespace())) {
candidates = uu->find(name);
@@ -475,7 +475,7 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
}
} else if (Function *fun = scope->asFunction()) {
- bindings()->lookupInScope(name, fun, &candidates, /*templateId = */ 0, /*binding=*/ 0);
+ bindings()->lookupInScope(name, fun, &candidates, /*templateId = */ nullptr, /*binding=*/ nullptr);
if (! candidates.isEmpty()) {
// it's an argument or a template parameter.
@@ -507,13 +507,13 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const
// continue, and look at the enclosing scope.
} else if (ObjCMethod *method = scope->asObjCMethod()) {
- bindings()->lookupInScope(name, method, &candidates, /*templateId = */ 0, /*binding=*/ 0);
+ bindings()->lookupInScope(name, method, &candidates, /*templateId = */ nullptr, /*binding=*/ nullptr);
if (! candidates.isEmpty())
break; // it's a formal argument.
} else if (Template *templ = scope->asTemplate()) {
- bindings()->lookupInScope(name, templ, &candidates, /*templateId = */ 0, /*binding=*/ 0);
+ bindings()->lookupInScope(name, templ, &candidates, /*templateId = */ nullptr, /*binding=*/ nullptr);
if (! candidates.isEmpty()) {
// it's a template parameter.
@@ -569,7 +569,7 @@ ClassOrNamespace *LookupContext::lookupParent(Symbol *symbol) const
foreach (const Name *name, fqName) {
binding = binding->findType(name);
if (!binding)
- return 0;
+ return nullptr;
}
return binding;
@@ -578,11 +578,11 @@ ClassOrNamespace *LookupContext::lookupParent(Symbol *symbol) const
ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent)
: _factory(factory)
, _parent(parent)
- , _scopeLookupCache(0)
- , _templateId(0)
- , _instantiationOrigin(0)
- , _rootClass(0)
- , _name(0)
+ , _scopeLookupCache(nullptr)
+ , _templateId(nullptr)
+ , _instantiationOrigin(nullptr)
+ , _rootClass(nullptr)
+ , _name(nullptr)
{
Q_ASSERT(factory);
}
@@ -667,7 +667,7 @@ QList<LookupItem> ClassOrNamespace::lookup_helper(const Name *name, bool searchI
// It's also possible that there are matches in the parent binding through
// a qualified name. For instance, a nested class which is forward declared
// in the class but defined outside it - we should capture both.
- Symbol *match = 0;
+ Symbol *match = nullptr;
QSet<ClassOrNamespace *> processed;
for (ClassOrNamespace *parentBinding = binding->parent();
parentBinding && !match;
@@ -696,7 +696,7 @@ QList<LookupItem> ClassOrNamespace::lookup_helper(const Name *name, bool searchI
if (processedOwnParents.contains(binding))
break;
processedOwnParents.insert(binding);
- lookup_helper(name, binding, &result, &processed, /*templateId = */ 0);
+ lookup_helper(name, binding, &result, &processed, /*templateId = */ nullptr);
binding = binding->_parent;
} while (searchInEnclosingScope && binding);
}
@@ -829,7 +829,7 @@ void CreateBindings::lookupInScope(const Name *name, Scope *scope,
ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name)
{
if (! name)
- return 0;
+ return nullptr;
QSet<ClassOrNamespace *> processed;
return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true, this);
@@ -857,7 +857,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name, Block *block)
return foundNestedBlock;
}
- return 0;
+ return nullptr;
}
ClassOrNamespace *ClassOrNamespace::findType(const Name *name)
@@ -889,7 +889,7 @@ ClassOrNamespace *ClassOrNamespace::findBlock_helper(Block *block,
if (!searchInEnclosingScope)
break;
}
- return 0;
+ return nullptr;
}
ClassOrNamespace *ClassOrNamespace::findBlock(Block *block)
@@ -905,7 +905,7 @@ Symbol *ClassOrNamespace::lookupInScope(const QList<const Name *> &fullName)
for (int j = 0; j < symbols().size(); ++j) {
if (Scope *scope = symbols().at(j)->asScope()) {
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
Symbol *s = scope->memberAt(i);
_scopeLookupCache->insert(LookupContext::fullyQualifiedName(s), s);
}
@@ -935,7 +935,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
if (ClassOrNamespace *binding = lookupType_helper(q->base(), processed, true, origin))
return binding->lookupType_helper(q->name(), &innerProcessed, false, origin);
- return 0;
+ return nullptr;
} else if (! processed->contains(this)) {
processed->insert(this);
@@ -985,7 +985,7 @@ ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name,
return _parent->lookupType_helper(name, processed, searchInEnclosingScope, origin);
}
- return 0;
+ return nullptr;
}
static ClassOrNamespace *findSpecializationWithMatchingTemplateArgument(const Name *argumentName,
@@ -994,9 +994,9 @@ static ClassOrNamespace *findSpecializationWithMatchingTemplateArgument(const Na
foreach (Symbol *s, reference->symbols()) {
if (Class *clazz = s->asClass()) {
if (Template *templateSpecialization = clazz->enclosingTemplate()) {
- const unsigned argumentCountOfSpecialization
+ const int argumentCountOfSpecialization
= templateSpecialization->templateParameterCount();
- for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
+ for (int i = 0; i < argumentCountOfSpecialization; ++i) {
if (TypenameArgument *tParam
= templateSpecialization->templateParameterAt(i)->asTypenameArgument()) {
if (const Name *name = tParam->name()) {
@@ -1008,7 +1008,7 @@ static ClassOrNamespace *findSpecializationWithMatchingTemplateArgument(const Na
}
}
}
- return 0;
+ return nullptr;
}
ClassOrNamespace *ClassOrNamespace::findSpecialization(const TemplateNameId *templId,
@@ -1018,14 +1018,14 @@ ClassOrNamespace *ClassOrNamespace::findSpecialization(const TemplateNameId *tem
for (TemplateNameIdTable::const_iterator cit = specializations.begin();
cit != specializations.end(); ++cit) {
const TemplateNameId *specializationNameId = cit->first;
- const unsigned specializationTemplateArgumentCount
+ const int specializationTemplateArgumentCount
= specializationNameId->templateArgumentCount();
- const unsigned initializationTemplateArgumentCount
+ const int initializationTemplateArgumentCount
= templId->templateArgumentCount();
// for now it works only when we have the same number of arguments in specialization
// and initialization(in future it should be more clever)
if (specializationTemplateArgumentCount == initializationTemplateArgumentCount) {
- for (unsigned i = 0; i < initializationTemplateArgumentCount; ++i) {
+ for (int i = 0; i < initializationTemplateArgumentCount; ++i) {
const FullySpecifiedType &specializationTemplateArgument
= specializationNameId->templateArgumentAt(i);
const FullySpecifiedType &initializationTemplateArgument
@@ -1057,7 +1057,7 @@ ClassOrNamespace *ClassOrNamespace::findSpecialization(const TemplateNameId *tem
}
}
- return 0;
+ return nullptr;
}
ClassOrNamespace *ClassOrNamespace::findOrCreateNestedAnonymousType(
@@ -1080,7 +1080,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
QSet<ClassOrNamespace *> *processed,
ClassOrNamespace *origin)
{
- Q_ASSERT(name != 0);
+ Q_ASSERT(name != nullptr);
Q_ASSERT(name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId());
const_cast<ClassOrNamespace *>(this)->flush();
@@ -1090,7 +1090,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
Table::const_iterator it = _classOrNamespaces.find(name);
if (it == _classOrNamespaces.end())
- return 0;
+ return nullptr;
ClassOrNamespace *reference = it->second;
ClassOrNamespace *baseTemplateClassReference = reference;
@@ -1151,11 +1151,11 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
// are templates. We need to collect them now. First, we track the bases which are already
// part of the binding so we can identify the missings ones later.
- Class *referenceClass = 0;
+ Class *referenceClass = nullptr;
QList<const Name *> allBases;
foreach (Symbol *s, reference->symbols()) {
if (Class *clazz = s->asClass()) {
- for (unsigned i = 0; i < clazz->baseClassCount(); ++i) {
+ for (int i = 0; i < clazz->baseClassCount(); ++i) {
BaseClass *baseClass = clazz->baseClassAt(i);
if (baseClass->name())
allBases.append(baseClass->name());
@@ -1207,18 +1207,18 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
// It gets a bit complicated if the reference is actually a class template because we
// now must worry about dependent names in base classes.
if (Template *templateSpecialization = referenceClass->enclosingTemplate()) {
- const unsigned argumentCountOfInitialization = templId->templateArgumentCount();
- const unsigned argumentCountOfSpecialization
+ const int argumentCountOfInitialization = templId->templateArgumentCount();
+ const int argumentCountOfSpecialization
= templateSpecialization->templateParameterCount();
Subst subst(_control.data());
if (_factory->expandTemplates()) {
const TemplateNameId *templSpecId
= templateSpecialization->name()->asTemplateNameId();
- const unsigned templSpecArgumentCount = templSpecId ?
+ const int templSpecArgumentCount = templSpecId ?
templSpecId->templateArgumentCount() : 0;
Clone cloner(_control.data());
- for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
+ for (int i = 0; i < argumentCountOfSpecialization; ++i) {
const TypenameArgument *tParam
= templateSpecialization->templateParameterAt(i)->asTypenameArgument();
if (!tParam)
@@ -1251,8 +1251,8 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
oo.showTemplateParameters = true;
qDebug() << "cloned" << oo(clone->type());
if (Class *klass = clone->asClass()) {
- const unsigned klassMemberCount = klass->memberCount();
- for (unsigned i = 0; i < klassMemberCount; ++i){
+ const int klassMemberCount = klass->memberCount();
+ for (int i = 0; i < klassMemberCount; ++i){
Symbol *klassMemberAsSymbol = klass->memberAt(i);
if (klassMemberAsSymbol->isTypedef()) {
if (Declaration *declaration = klassMemberAsSymbol->asDeclaration())
@@ -1267,18 +1267,18 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
instantiation->_symbols.append(reference->symbols());
}
- QHash<const Name*, unsigned> templParams;
- for (unsigned i = 0; i < argumentCountOfSpecialization; ++i)
+ QHash<const Name*, int> templParams;
+ for (int i = 0; i < argumentCountOfSpecialization; ++i)
templParams.insert(templateSpecialization->templateParameterAt(i)->name(), i);
foreach (const Name *baseName, allBases) {
- ClassOrNamespace *baseBinding = 0;
+ ClassOrNamespace *baseBinding = nullptr;
if (const Identifier *nameId = baseName->asNameId()) {
// This is the simple case in which a template parameter is itself a base.
// Ex.: template <class T> class A : public T {};
if (templParams.contains(nameId)) {
- const unsigned parameterIndex = templParams.value(nameId);
+ const int parameterIndex = templParams.value(nameId);
if (parameterIndex < argumentCountOfInitialization) {
const FullySpecifiedType &fullType =
templId->templateArgumentAt(parameterIndex);
@@ -1297,7 +1297,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
}
} else {
SubstitutionMap map;
- for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
+ for (int i = 0; i < argumentCountOfSpecialization; ++i) {
const Name *name = templateSpecialization->templateParameterAt(i)->name();
FullySpecifiedType ty = (i < argumentCountOfInitialization) ?
templId->templateArgumentAt(i):
@@ -1354,7 +1354,7 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name,
if (const QualifiedNameId *qBaseName = baseName->asQualifiedNameId()) {
if (const Name *qualification = qBaseName->base())
binding = lookupType(qualification);
- else if (binding->parent() != 0)
+ else if (binding->parent() != nullptr)
//if this is global identifier we take global namespace
//Ex: class A{}; namespace NS { class A: public ::A{}; }
binding = binding->globalNamespace();
@@ -1471,7 +1471,7 @@ NamedType *ClassOrNamespace::NestedClassInstantiator::findNamedType(Type *member
else if (ReferenceType *referenceType = memberType->asReferenceType())
return findNamedType(referenceType->elementType().type());
- return 0;
+ return nullptr;
}
void ClassOrNamespace::flush()
@@ -1539,7 +1539,7 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa
return e;
}
- return 0;
+ return nullptr;
}
CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot)
@@ -1547,7 +1547,7 @@ CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snaps
, _control(QSharedPointer<Control>(new Control))
, _expandTemplates(false)
{
- _globalNamespace = allocClassOrNamespace(/*parent = */ 0);
+ _globalNamespace = allocClassOrNamespace(/*parent = */ nullptr);
_currentClassOrNamespace = _globalNamespace;
process(thisDocument);
@@ -1636,7 +1636,7 @@ void CreateBindings::process(Document::Ptr doc)
ClassOrNamespace *CreateBindings::enterClassOrNamespaceBinding(Symbol *symbol)
{
- ClassOrNamespace *entity = _currentClassOrNamespace->findOrCreateType(symbol->name(), 0,
+ ClassOrNamespace *entity = _currentClassOrNamespace->findOrCreateType(symbol->name(), nullptr,
symbol->asClass());
entity->addSymbol(symbol);
@@ -1645,7 +1645,7 @@ ClassOrNamespace *CreateBindings::enterClassOrNamespaceBinding(Symbol *symbol)
ClassOrNamespace *CreateBindings::enterGlobalClassOrNamespace(Symbol *symbol)
{
- ClassOrNamespace *entity = _globalNamespace->findOrCreateType(symbol->name(), 0,
+ ClassOrNamespace *entity = _globalNamespace->findOrCreateType(symbol->name(), nullptr,
symbol->asClass());
entity->addSymbol(symbol);
@@ -1664,7 +1664,7 @@ bool CreateBindings::visit(Namespace *ns)
{
ClassOrNamespace *previous = enterClassOrNamespaceBinding(ns);
- for (unsigned i = 0; i < ns->memberCount(); ++i)
+ for (int i = 0; i < ns->memberCount(); ++i)
process(ns->memberAt(i));
if (ns->isInline() && previous)
@@ -1678,21 +1678,21 @@ bool CreateBindings::visit(Namespace *ns)
bool CreateBindings::visit(Class *klass)
{
ClassOrNamespace *previous = _currentClassOrNamespace;
- ClassOrNamespace *binding = 0;
+ ClassOrNamespace *binding = nullptr;
if (klass->name() && klass->name()->isQualifiedNameId())
binding = _currentClassOrNamespace->lookupType(klass->name());
if (! binding)
- binding = _currentClassOrNamespace->findOrCreateType(klass->name(), 0, klass);
+ binding = _currentClassOrNamespace->findOrCreateType(klass->name(), nullptr, klass);
_currentClassOrNamespace = binding;
_currentClassOrNamespace->addSymbol(klass);
- for (unsigned i = 0; i < klass->baseClassCount(); ++i)
+ for (int i = 0; i < klass->baseClassCount(); ++i)
process(klass->baseClassAt(i));
- for (unsigned i = 0; i < klass->memberCount(); ++i)
+ for (int i = 0; i < klass->memberCount(); ++i)
process(klass->memberAt(i));
_currentClassOrNamespace = previous;
@@ -1737,7 +1737,7 @@ bool CreateBindings::visit(Declaration *decl)
} else if (Class *klass = ty->asClassType()) {
if (const Identifier *nameId = decl->name()->asNameId()) {
ClassOrNamespace *binding
- = _currentClassOrNamespace->findOrCreateType(nameId, 0, klass);
+ = _currentClassOrNamespace->findOrCreateType(nameId, nullptr, klass);
binding->addSymbol(klass);
}
}
@@ -1759,7 +1759,7 @@ bool CreateBindings::visit(Function *function)
if (!binding)
return false;
_currentClassOrNamespace = binding;
- for (unsigned i = 0, count = function->memberCount(); i < count; ++i) {
+ for (int i = 0, count = function->memberCount(); i < count; ++i) {
Symbol *s = function->memberAt(i);
if (Block *b = s->asBlock())
visit(b);
@@ -1778,7 +1778,7 @@ bool CreateBindings::visit(Block *block)
_currentClassOrNamespace = binding;
_currentClassOrNamespace->addSymbol(block);
- for (unsigned i = 0; i < block->memberCount(); ++i)
+ for (int i = 0; i < block->memberCount(); ++i)
// we cannot use lazy processing here, because we have to know
// does this block contain any other blocks or classOrNamespaces
process(block->memberAt(i), _currentClassOrNamespace);
@@ -1794,7 +1794,7 @@ bool CreateBindings::visit(Block *block)
_entities.append(binding);
} else {
delete binding;
- binding = 0;
+ binding = nullptr;
}
_currentClassOrNamespace = previous;
@@ -1862,10 +1862,10 @@ bool CreateBindings::visit(ObjCClass *klass)
process(klass->baseClass());
- for (unsigned i = 0; i < klass->protocolCount(); ++i)
+ for (int i = 0; i < klass->protocolCount(); ++i)
process(klass->protocolAt(i));
- for (unsigned i = 0; i < klass->memberCount(); ++i)
+ for (int i = 0; i < klass->memberCount(); ++i)
process(klass->memberAt(i));
_currentClassOrNamespace = previous;
@@ -1894,10 +1894,10 @@ bool CreateBindings::visit(ObjCProtocol *proto)
{
ClassOrNamespace *previous = enterGlobalClassOrNamespace(proto);
- for (unsigned i = 0; i < proto->protocolCount(); ++i)
+ for (int i = 0; i < proto->protocolCount(); ++i)
process(proto->protocolAt(i));
- for (unsigned i = 0; i < proto->memberCount(); ++i)
+ for (int i = 0; i < proto->memberCount(); ++i)
process(proto->memberAt(i));
_currentClassOrNamespace = previous;
@@ -1930,12 +1930,12 @@ bool CreateBindings::visit(ObjCMethod *)
Symbol *CreateBindings::instantiateTemplateFunction(const TemplateNameId *instantiation,
Template *specialization) const
{
- const unsigned argumentCountOfInitialization = instantiation->templateArgumentCount();
- const unsigned argumentCountOfSpecialization = specialization->templateParameterCount();
+ const int argumentCountOfInitialization = instantiation->templateArgumentCount();
+ const int argumentCountOfSpecialization = specialization->templateParameterCount();
Clone cloner(_control.data());
Subst subst(_control.data());
- for (unsigned i = 0; i < argumentCountOfSpecialization; ++i) {
+ for (int i = 0; i < argumentCountOfSpecialization; ++i) {
const TypenameArgument *tParam
= specialization->templateParameterAt(i)->asTypenameArgument();
if (!tParam)
diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h
index b13df5da29..22035362fd 100644
--- a/src/libs/cplusplus/LookupContext.h
+++ b/src/libs/cplusplus/LookupContext.h
@@ -97,8 +97,8 @@ private:
void flush();
/// \internal
- ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = 0,
- Class *clazz = 0);
+ ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = nullptr,
+ Class *clazz = nullptr);
ClassOrNamespace *findOrCreateNestedAnonymousType(const AnonymousNameId *anonymousNameId);
@@ -196,9 +196,9 @@ public:
ClassOrNamespace *globalNamespace() const;
/// Finds the binding associated to the given symbol.
- ClassOrNamespace *lookupType(Symbol *symbol, ClassOrNamespace *enclosingBinding = 0);
+ ClassOrNamespace *lookupType(Symbol *symbol, ClassOrNamespace *enclosingBinding = nullptr);
ClassOrNamespace *lookupType(const QList<const Name *> &path,
- ClassOrNamespace *enclosingBinding = 0);
+ ClassOrNamespace *enclosingBinding = nullptr);
/// Returns the Control that must be used to create temporary symbols.
/// \internal
@@ -303,11 +303,11 @@ public:
QList<LookupItem> lookup(const Name *name, Scope *scope) const;
ClassOrNamespace *lookupType(const Name *name, Scope *scope,
- ClassOrNamespace *enclosingBinding = 0,
+ ClassOrNamespace *enclosingBinding = nullptr,
QSet<const Declaration *> typedefsBeingResolved
= QSet<const Declaration *>()) const;
ClassOrNamespace *lookupType(Symbol *symbol,
- ClassOrNamespace *enclosingBinding = 0) const;
+ ClassOrNamespace *enclosingBinding = nullptr) const;
ClassOrNamespace *lookupParent(Symbol *symbol) const;
/// \internal
diff --git a/src/libs/cplusplus/LookupItem.cpp b/src/libs/cplusplus/LookupItem.cpp
index 5890664051..7fc73ba240 100644
--- a/src/libs/cplusplus/LookupItem.cpp
+++ b/src/libs/cplusplus/LookupItem.cpp
@@ -41,7 +41,7 @@ uint CPlusPlus::qHash(const LookupItem &key)
}
LookupItem::LookupItem()
- : _scope(0), _declaration(0), _binding(0)
+ : _scope(nullptr), _declaration(nullptr), _binding(nullptr)
{ }
FullySpecifiedType LookupItem::type() const
diff --git a/src/libs/cplusplus/Macro.cpp b/src/libs/cplusplus/Macro.cpp
index 6e1a46c8a0..d0c905edf1 100644
--- a/src/libs/cplusplus/Macro.cpp
+++ b/src/libs/cplusplus/Macro.cpp
@@ -48,7 +48,7 @@
using namespace CPlusPlus;
Macro::Macro()
- : _next(0),
+ : _next(nullptr),
_hashcode(0),
_fileRevision(0),
_line(0),
diff --git a/src/libs/cplusplus/Macro.h b/src/libs/cplusplus/Macro.h
index f54df57458..ba510109a8 100644
--- a/src/libs/cplusplus/Macro.h
+++ b/src/libs/cplusplus/Macro.h
@@ -100,10 +100,10 @@ public:
void setFileRevision(unsigned fileRevision)
{ _fileRevision = fileRevision; }
- unsigned line() const
+ int line() const
{ return _line; }
- void setLine(unsigned line)
+ void setLine(int line)
{ _line = line; }
unsigned bytesOffset() const
@@ -165,7 +165,7 @@ private:
QString _fileName;
unsigned _hashcode;
unsigned _fileRevision;
- unsigned _line;
+ int _line;
unsigned _bytesOffset;
unsigned _utf16charsOffset;
unsigned _length;
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index 59440813a7..9e1ffdecb8 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -128,7 +128,7 @@ static int countSkippedChars(const QString &blockText, const QString &textToProc
return skippedChars;
}
-static const Token tokenAtPosition(const Tokens &tokens, const unsigned pos)
+static const Token tokenAtPosition(const Tokens &tokens, const int pos)
{
for (int i = tokens.size() - 1; i >= 0; --i) {
const Token tk = tokens.at(i);
@@ -145,6 +145,7 @@ static LanguageFeatures languageFeatures()
features.qtKeywordsEnabled = false;
features.qtMocRunEnabled = false;
features.cxx11Enabled = true;
+ features.cxx14Enabled = true;
features.cxxEnabled = true;
features.c99Enabled = true;
features.objCEnabled = true;
@@ -449,7 +450,7 @@ bool MatchingText::contextAllowsElectricCharacters(const QTextCursor &cursor)
return false;
if (token.isStringLiteral() || token.isCharLiteral()) {
- const unsigned pos = cursor.selectionEnd() - cursor.block().position();
+ const int pos = cursor.selectionEnd() - cursor.block().position();
if (pos <= token.utf16charsEnd())
return false;
}
@@ -484,7 +485,7 @@ bool MatchingText::isInCommentHelper(const QTextCursor &cursor, Token *retToken)
int prevState = 0;
const Tokens tokens = getTokens(cursor, prevState);
- const unsigned pos = cursor.selectionEnd() - cursor.block().position();
+ const int pos = cursor.selectionEnd() - cursor.block().position();
if (tokens.isEmpty() || pos < tokens.first().utf16charsBegin())
return prevState > 0;
@@ -509,7 +510,7 @@ Kind MatchingText::stringKindAtCursor(const QTextCursor &cursor)
int prevState = 0;
const Tokens tokens = getTokens(cursor, prevState);
- const unsigned pos = cursor.selectionEnd() - cursor.block().position();
+ const int pos = cursor.selectionEnd() - cursor.block().position();
if (tokens.isEmpty() || pos <= tokens.first().utf16charsBegin())
return T_EOF_SYMBOL;
diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h
index b394e342af..aab8365e15 100644
--- a/src/libs/cplusplus/MatchingText.h
+++ b/src/libs/cplusplus/MatchingText.h
@@ -53,7 +53,7 @@ public:
static bool shouldInsertMatchingText(const QTextCursor &tc);
static bool shouldInsertMatchingText(QChar lookAhead);
- static bool isInCommentHelper(const QTextCursor &currsor, Token *retToken = 0);
+ static bool isInCommentHelper(const QTextCursor &currsor, Token *retToken = nullptr);
static CPlusPlus::Kind stringKindAtCursor(const QTextCursor &cursor);
static QString insertMatchingBrace(const QTextCursor &tc, const QString &text,
diff --git a/src/libs/cplusplus/NamePrettyPrinter.cpp b/src/libs/cplusplus/NamePrettyPrinter.cpp
index 3870763d0c..5d9c5770e0 100644
--- a/src/libs/cplusplus/NamePrettyPrinter.cpp
+++ b/src/libs/cplusplus/NamePrettyPrinter.cpp
@@ -76,7 +76,7 @@ void NamePrettyPrinter::visit(const TemplateNameId *name)
else
_name = QLatin1String("anonymous");
_name += QLatin1Char('<');
- for (unsigned index = 0; index < name->templateArgumentCount(); ++index) {
+ for (int index = 0; index < name->templateArgumentCount(); ++index) {
if (index != 0)
_name += QLatin1String(", ");
@@ -253,7 +253,7 @@ void NamePrettyPrinter::visit(const QualifiedNameId *name)
void NamePrettyPrinter::visit(const SelectorNameId *name)
{
- for (unsigned i = 0; i < name->nameCount(); ++i) {
+ for (int i = 0; i < name->nameCount(); ++i) {
const Name *n = name->nameAt(i);
if (!n)
continue;
diff --git a/src/libs/cplusplus/Overview.h b/src/libs/cplusplus/Overview.h
index eeef87212e..243390cd8a 100644
--- a/src/libs/cplusplus/Overview.h
+++ b/src/libs/cplusplus/Overview.h
@@ -43,12 +43,12 @@ public:
QString operator()(const QList<const Name *> &fullyQualifiedName) const
{ return prettyName(fullyQualifiedName); }
- QString operator()(const FullySpecifiedType &type, const Name *name = 0) const
+ QString operator()(const FullySpecifiedType &type, const Name *name = nullptr) const
{ return prettyType(type, name); }
QString prettyName(const Name *name) const;
QString prettyName(const QList<const Name *> &fullyQualifiedName) const;
- QString prettyType(const FullySpecifiedType &type, const Name *name = 0) const;
+ QString prettyType(const FullySpecifiedType &type, const Name *name = nullptr) const;
QString prettyType(const FullySpecifiedType &type, const QString &name) const;
public:
@@ -70,7 +70,7 @@ public:
bool showEnclosingTemplate: 1;
bool includeWhiteSpaceInOperatorName: 1; /// "operator =()" vs "operator=()"
- unsigned markedArgument;
+ int markedArgument;
int markedArgumentBegin;
int markedArgumentEnd;
};
diff --git a/src/libs/cplusplus/PreprocessorClient.cpp b/src/libs/cplusplus/PreprocessorClient.cpp
index 1b2595651c..68be342821 100644
--- a/src/libs/cplusplus/PreprocessorClient.cpp
+++ b/src/libs/cplusplus/PreprocessorClient.cpp
@@ -40,7 +40,7 @@ using namespace CPlusPlus;
*/
/*!
- \fn void Client::passedMacroDefinitionCheck(unsigned offset, unsigned line, const Macro &macro)
+ \fn void Client::passedMacroDefinitionCheck(int offset, int line, const Macro &macro)
Called when the preprocessor checks whether a macro is defined or not and the
result is positive.
@@ -49,7 +49,7 @@ using namespace CPlusPlus;
*/
/*!
- \fn void Client::failedMacroDefinitionCheck(unsigned offset, const ByteArrayRef &name)
+ \fn void Client::failedMacroDefinitionCheck(int offset, const ByteArrayRef &name)
Called when the preprocessor checks whether a macro is defined or not and the
result is negative.
@@ -58,8 +58,8 @@ using namespace CPlusPlus;
*/
/*!
- \fn void Client::startExpandingMacro(unsigned offset,
- unsigned line,
+ \fn void Client::startExpandingMacro(int offset,
+ int line,
const Macro &macro,
const QVector<MacroArgumentReference> &actuals
= QVector<MacroArgumentReference>())
diff --git a/src/libs/cplusplus/PreprocessorClient.h b/src/libs/cplusplus/PreprocessorClient.h
index accccdab1f..97d3cc8efb 100644
--- a/src/libs/cplusplus/PreprocessorClient.h
+++ b/src/libs/cplusplus/PreprocessorClient.h
@@ -41,30 +41,30 @@ class Macro;
class CPLUSPLUS_EXPORT MacroArgumentReference
{
- unsigned _bytesOffset;
- unsigned _bytesLength;
- unsigned _utf16charsOffset;
- unsigned _utf16charsLength;
+ int _bytesOffset;
+ int _bytesLength;
+ int _utf16charsOffset;
+ int _utf16charsLength;
public:
- explicit MacroArgumentReference(unsigned bytesOffset = 0, unsigned bytesLength = 0,
- unsigned utf16charsOffset = 0, unsigned utf16charsLength = 0)
+ explicit MacroArgumentReference(int bytesOffset = 0, int bytesLength = 0,
+ int utf16charsOffset = 0, int utf16charsLength = 0)
: _bytesOffset(bytesOffset)
, _bytesLength(bytesLength)
, _utf16charsOffset(utf16charsOffset)
, _utf16charsLength(utf16charsLength)
{ }
- unsigned bytesOffset() const
+ int bytesOffset() const
{ return _bytesOffset; }
- unsigned bytesLength() const
+ int bytesLength() const
{ return _bytesLength; }
- unsigned utf16charsOffset() const
+ int utf16charsOffset() const
{ return _utf16charsOffset; }
- unsigned utf16charsLength() const
+ int utf16charsLength() const
{ return _utf16charsLength; }
};
@@ -86,28 +86,28 @@ public:
virtual void macroAdded(const Macro &macro) = 0;
- virtual void passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro) = 0;
- virtual void failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
+ virtual void passedMacroDefinitionCheck(int bytesOffset, int utf16charsOffset,
+ int line, const Macro &macro) = 0;
+ virtual void failedMacroDefinitionCheck(int bytesOffset, int utf16charsOffset,
const ByteArrayRef &name) = 0;
- virtual void notifyMacroReference(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro) = 0;
+ virtual void notifyMacroReference(int bytesOffset, int utf16charsOffset,
+ int line, const Macro &macro) = 0;
- virtual void startExpandingMacro(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const Macro &macro,
+ virtual void startExpandingMacro(int bytesOffset, int utf16charsOffset,
+ int line, const Macro &macro,
const QVector<MacroArgumentReference> &actuals
= QVector<MacroArgumentReference>()) = 0;
- virtual void stopExpandingMacro(unsigned bytesOffset, const Macro &macro) = 0; // TODO: ?!
+ virtual void stopExpandingMacro(int bytesOffset, const Macro &macro) = 0; // TODO: ?!
/// Mark the given macro name as the include guard for the current file.
virtual void markAsIncludeGuard(const QByteArray &macroName) = 0;
/// Start skipping from the given utf16charsOffset.
- virtual void startSkippingBlocks(unsigned utf16charsOffset) = 0;
- virtual void stopSkippingBlocks(unsigned utf16charsOffset) = 0;
+ virtual void startSkippingBlocks(int utf16charsOffset) = 0;
+ virtual void stopSkippingBlocks(int utf16charsOffset) = 0;
- virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode,
+ virtual void sourceNeeded(int line, const QString &fileName, IncludeType mode,
const QStringList &initialIncludes = QStringList()) = 0;
static inline bool isInjectedFile(const QString &fileName)
diff --git a/src/libs/cplusplus/PreprocessorEnvironment.cpp b/src/libs/cplusplus/PreprocessorEnvironment.cpp
index 6d7464d799..4ffc127a19 100644
--- a/src/libs/cplusplus/PreprocessorEnvironment.cpp
+++ b/src/libs/cplusplus/PreprocessorEnvironment.cpp
@@ -67,10 +67,10 @@ static unsigned hashCode(const char *str, int length)
Environment::Environment()
: currentLine(0),
hideNext(false),
- _macros(0),
+ _macros(nullptr),
_allocated_macros(0),
_macro_count(-1),
- _hash(0),
+ _hash(nullptr),
_hash_count(401)
{
}
@@ -153,10 +153,10 @@ void Environment::reset()
if (_hash)
free(_hash);
- _macros = 0;
+ _macros = nullptr;
_allocated_macros = 0;
_macro_count = -1;
- _hash = 0;
+ _hash = nullptr;
_hash_count = 401;
}
@@ -230,14 +230,14 @@ Environment::iterator Environment::lastMacro() const
Macro *Environment::resolve(const ByteArrayRef &name) const
{
if (! _macros)
- return 0;
+ return nullptr;
Macro *it = _hash[hashCode(name.start(), name.size()) % _hash_count];
for (; it; it = it->_next) {
if (it->name() != name)
continue;
else if (it->isHidden())
- return 0;
+ return nullptr;
else break;
}
return it;
diff --git a/src/libs/cplusplus/PreprocessorEnvironment.h b/src/libs/cplusplus/PreprocessorEnvironment.h
index a6db2d0c7f..6f085ed519 100644
--- a/src/libs/cplusplus/PreprocessorEnvironment.h
+++ b/src/libs/cplusplus/PreprocessorEnvironment.h
@@ -88,7 +88,7 @@ private:
public:
QString currentFile;
QByteArray currentFileUtf8;
- unsigned currentLine;
+ int currentLine;
bool hideNext;
private:
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 034ea6fcc1..2eca9b53f3 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -83,7 +83,7 @@ public:
// use an "alreadyResolved" container. FIXME: We might overcome this by resolving the
// template parameters.
unsigned maxDepth = 15;
- for (NamedType *namedTy = 0; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) {
+ for (NamedType *namedTy = nullptr; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) {
QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, _binding);
if (Q_UNLIKELY(debug))
@@ -125,9 +125,9 @@ private:
QList<LookupItem> results;
if (!scope)
return results;
- Scope *enclosingBlockScope = 0;
+ Scope *enclosingBlockScope = nullptr;
for (Block *block = scope->asBlock(); block;
- block = enclosingBlockScope ? enclosingBlockScope->asBlock() : 0) {
+ block = enclosingBlockScope ? enclosingBlockScope->asBlock() : nullptr) {
const unsigned memberCount = block->memberCount();
for (unsigned i = 0; i < memberCount; ++i) {
Symbol *symbol = block->memberAt(i);
@@ -233,7 +233,7 @@ static int evaluateFunctionArgument(const FullySpecifiedType &actualTy,
ResolveExpression::ResolveExpression(const LookupContext &context,
const QSet<const Declaration *> &autoDeclarationsBeingResolved)
: ASTVisitor(context.expressionDocument()->translationUnit()),
- _scope(0),
+ _scope(nullptr),
_context(context),
bind(context.expressionDocument()->translationUnit()),
_autoDeclarationsBeingResolved(autoDeclarationsBeingResolved),
@@ -314,9 +314,9 @@ bool ResolveExpression::visit(IdExpressionAST *ast)
bool ResolveExpression::visit(BinaryExpressionAST *ast)
{
- if (tokenKind(ast->binary_op_token) == T_COMMA && ast->right_expression && ast->right_expression->asQtMethod() != 0) {
+ if (tokenKind(ast->binary_op_token) == T_COMMA && ast->right_expression && ast->right_expression->asQtMethod() != nullptr) {
- if (ast->left_expression && ast->left_expression->asQtMethod() != 0)
+ if (ast->left_expression && ast->left_expression->asQtMethod() != nullptr)
thisObject();
else
accept(ast->left_expression);
@@ -404,7 +404,7 @@ bool ResolveExpression::visit(TypeidExpressionAST *)
{
const Name *stdName = control()->identifier("std");
const Name *tiName = control()->identifier("type_info");
- const Name *q = control()->qualifiedNameId(control()->qualifiedNameId(/* :: */ 0, stdName), tiName);
+ const Name *q = control()->qualifiedNameId(control()->qualifiedNameId(/* :: */ nullptr, stdName), tiName);
FullySpecifiedType ty(control()->namedType(q));
addResult(ty, _scope);
@@ -443,7 +443,7 @@ bool ResolveExpression::visit(NumericLiteralAST *ast)
{
const Token &tk = tokenAt(ast->literal_token);
- Type *type = 0;
+ Type *type = nullptr;
bool isUnsigned = false;
if (tk.is(T_CHAR_LITERAL)) {
@@ -581,21 +581,17 @@ bool ResolveExpression::visit(UnaryExpressionAST *ast)
accept(ast->expression);
unsigned unaryOp = tokenKind(ast->unary_op_token);
if (unaryOp == T_AMPER) {
- QMutableListIterator<LookupItem > it(_results);
- while (it.hasNext()) {
- LookupItem p = it.next();
+ for (LookupItem &p : _results) {
FullySpecifiedType ty = p.type();
ty.setType(control()->pointerType(ty));
p.setType(ty);
- it.setValue(p);
}
} else if (unaryOp == T_STAR) {
- QMutableListIterator<LookupItem > it(_results);
- while (it.hasNext()) {
- LookupItem p = it.next();
+ for (int i = 0; i < _results.size(); ++i) {
+ LookupItem &p = _results[i];
FullySpecifiedType ty = p.type();
NamedType *namedTy = ty->asNamedType();
- if (namedTy != 0) {
+ if (namedTy != nullptr) {
const QList<LookupItem> types = _context.lookup(namedTy->name(), p.scope());
if (!types.empty())
ty = types.front().type();
@@ -603,9 +599,8 @@ bool ResolveExpression::visit(UnaryExpressionAST *ast)
bool added = false;
if (PointerType *ptrTy = ty->asPointerType()) {
p.setType(ptrTy->elementType());
- it.setValue(p);
added = true;
- } else if (namedTy != 0) {
+ } else if (namedTy != nullptr) {
const Name *starOp = control()->operatorNameId(OperatorNameId::StarOp);
if (ClassOrNamespace *b = _context.lookupType(namedTy->name(), p.scope(), p.binding())) {
foreach (const LookupItem &r, b->find(starOp)) {
@@ -616,7 +611,6 @@ bool ResolveExpression::visit(UnaryExpressionAST *ast)
FullySpecifiedType retTy = proto->returnType().simplified();
p.setType(retTy);
p.setScope(proto->enclosingScope());
- it.setValue(p);
added = true;
break;
}
@@ -626,7 +620,7 @@ bool ResolveExpression::visit(UnaryExpressionAST *ast)
}
}
if (!added)
- it.remove();
+ _results.removeAt(i--);
}
}
return false;
@@ -725,7 +719,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (!item.type()->isUndefinedType())
continue;
- if (item.declaration() == 0)
+ if (item.declaration() == nullptr)
continue;
if (item.type().isAuto()) {
@@ -738,7 +732,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
continue;
const StringLiteral *initializationString = decl->getInitializer();
- if (initializationString == 0)
+ if (initializationString == nullptr)
continue;
const QByteArray &initializer =
@@ -771,7 +765,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
Clone cloner(_context.bindings()->control().data());
for (int n = 0; n < typeItems.size(); ++ n) {
- FullySpecifiedType newType = cloner.type(typeItems[n].type(), 0);
+ FullySpecifiedType newType = cloner.type(typeItems[n].type(), nullptr);
if (n == 0) {
item.setType(newType);
item.setScope(typeItems[n].scope());
@@ -963,8 +957,8 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
QList<LookupItem> ResolveExpression::getMembers(ClassOrNamespace *binding, const Name *memberName) const
{
- Q_UNUSED(binding);
- Q_UNUSED(memberName);
+ Q_UNUSED(binding)
+ Q_UNUSED(memberName)
// ### port me
QList<LookupItem> members;
@@ -1023,7 +1017,7 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
// Evaluate the expression-id that follows the access operator.
- const Name *memberName = 0;
+ const Name *memberName = nullptr;
if (ast->member_name)
memberName = ast->member_name->name;
@@ -1040,7 +1034,7 @@ ClassOrNamespace *ResolveExpression::findClass(const FullySpecifiedType &origina
ClassOrNamespace *enclosingBinding) const
{
FullySpecifiedType ty = originalTy.simplified();
- ClassOrNamespace *binding = 0;
+ ClassOrNamespace *binding = nullptr;
if (Class *klass = ty->asClassType()) {
if (scope->isBlock())
@@ -1119,7 +1113,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
FullySpecifiedType overloadTy
= instantiate(binding->templateId(), overload);
Function *instantiatedFunction = overloadTy->asFunctionType();
- Q_ASSERT(instantiatedFunction != 0);
+ Q_ASSERT(instantiatedFunction != nullptr);
FullySpecifiedType retTy
= instantiatedFunction->returnType().simplified();
@@ -1168,7 +1162,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
return binding;
}
- ClassOrNamespace *enclosingBinding = 0;
+ ClassOrNamespace *enclosingBinding = nullptr;
if (ClassOrNamespace *binding = r.binding()) {
if (binding->instantiationOrigin())
enclosingBinding = binding;
@@ -1179,7 +1173,7 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
}
}
- return 0;
+ return nullptr;
}
ClassOrNamespace *ResolveExpression::findClassForTemplateParameterInExpressionScope(
@@ -1197,7 +1191,7 @@ ClassOrNamespace *ResolveExpression::findClassForTemplateParameterInExpressionSc
}
}
- return 0;
+ return nullptr;
}
FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol *candidate) const
@@ -1219,7 +1213,7 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
foreach (const LookupItem &result, receiverResults) {
FullySpecifiedType ty = result.type().simplified();
- ClassOrNamespace *binding = 0;
+ ClassOrNamespace *binding = nullptr;
if (ObjCClass *clazz = ty->asObjCClassType()) {
// static access, e.g.:
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index f53caf26aa..41f91c049f 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -49,13 +49,13 @@ public:
ClassOrNamespace *baseExpression(const QList<LookupItem> &baseResults,
int accessOp,
- bool *replacedDotOperator = 0) const;
+ bool *replacedDotOperator = nullptr) const;
const LookupContext &context() const;
protected:
ClassOrNamespace *findClass(const FullySpecifiedType &ty, Scope *scope,
- ClassOrNamespace *enclosingBinding = 0) const;
+ ClassOrNamespace *enclosingBinding = nullptr) const;
QList<LookupItem> expression(ExpressionAST *ast);
@@ -66,7 +66,7 @@ protected:
void thisObject();
- void addResult(const FullySpecifiedType &ty, Scope *scope, ClassOrNamespace *binding = 0);
+ void addResult(const FullySpecifiedType &ty, Scope *scope, ClassOrNamespace *binding = nullptr);
void addResults(const QList<Symbol *> &symbols);
void addResults(const QList<LookupItem> &items);
diff --git a/src/libs/cplusplus/SimpleLexer.cpp b/src/libs/cplusplus/SimpleLexer.cpp
index a01a2b9b67..57bad400de 100644
--- a/src/libs/cplusplus/SimpleLexer.cpp
+++ b/src/libs/cplusplus/SimpleLexer.cpp
@@ -110,7 +110,7 @@ Tokens SimpleLexer::operator()(const QString &text, int state)
return tokens;
}
-int SimpleLexer::tokenAt(const Tokens &tokens, unsigned utf16charsOffset)
+int SimpleLexer::tokenAt(const Tokens &tokens, int utf16charsOffset)
{
for (int index = tokens.size() - 1; index >= 0; --index) {
const Token &tk = tokens.at(index);
@@ -122,7 +122,7 @@ int SimpleLexer::tokenAt(const Tokens &tokens, unsigned utf16charsOffset)
}
Token SimpleLexer::tokenAt(const QString &text,
- unsigned utf16charsOffset,
+ int utf16charsOffset,
int state,
const LanguageFeatures &languageFeatures)
{
@@ -133,7 +133,7 @@ Token SimpleLexer::tokenAt(const QString &text,
return (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
}
-int SimpleLexer::tokenBefore(const Tokens &tokens, unsigned utf16charsOffset)
+int SimpleLexer::tokenBefore(const Tokens &tokens, int utf16charsOffset)
{
for (int index = tokens.size() - 1; index >= 0; --index) {
const Token &tk = tokens.at(index);
diff --git a/src/libs/cplusplus/SimpleLexer.h b/src/libs/cplusplus/SimpleLexer.h
index 2bd794933d..75138e830a 100644
--- a/src/libs/cplusplus/SimpleLexer.h
+++ b/src/libs/cplusplus/SimpleLexer.h
@@ -59,13 +59,13 @@ public:
int state() const
{ return _lastState; }
- static int tokenAt(const Tokens &tokens, unsigned utf16charsOffset);
+ static int tokenAt(const Tokens &tokens, int utf16charsOffset);
static Token tokenAt(const QString &text,
- unsigned utf16charsOffset,
+ int utf16charsOffset,
int state,
const LanguageFeatures &languageFeatures);
- static int tokenBefore(const Tokens &tokens, unsigned utf16charsOffset);
+ static int tokenBefore(const Tokens &tokens, int utf16charsOffset);
private:
int _lastState;
diff --git a/src/libs/cplusplus/SymbolNameVisitor.cpp b/src/libs/cplusplus/SymbolNameVisitor.cpp
index fe2b36f3d8..b34bf2f42a 100644
--- a/src/libs/cplusplus/SymbolNameVisitor.cpp
+++ b/src/libs/cplusplus/SymbolNameVisitor.cpp
@@ -31,7 +31,7 @@
using namespace CPlusPlus;
SymbolNameVisitor::SymbolNameVisitor()
- : _symbol(0)
+ : _symbol(nullptr)
{
}
diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp
index 1b3dda8b1c..02f838542c 100644
--- a/src/libs/cplusplus/TypeOfExpression.cpp
+++ b/src/libs/cplusplus/TypeOfExpression.cpp
@@ -38,8 +38,8 @@
using namespace CPlusPlus;
TypeOfExpression::TypeOfExpression():
- m_ast(0),
- m_scope(0),
+ m_ast(nullptr),
+ m_scope(nullptr),
m_expandTemplates(false)
{
}
@@ -50,8 +50,8 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
{
m_thisDocument = thisDocument;
m_snapshot = snapshot;
- m_ast = 0;
- m_scope = 0;
+ m_ast = nullptr;
+ m_scope = nullptr;
m_lookupContext = LookupContext();
Q_ASSERT(m_bindings.isNull());
@@ -178,7 +178,7 @@ QByteArray TypeOfExpression::preprocessedExpression(const QByteArray &utf8code)
m_environment = QSharedPointer<Environment>(env);
}
- Preprocessor preproc(0, m_environment.data());
+ Preprocessor preproc(nullptr, m_environment.data());
return preproc.run(QLatin1String("<expression>"), utf8code);
}
@@ -187,7 +187,7 @@ namespace CPlusPlus {
ExpressionAST *extractExpressionAST(Document::Ptr doc)
{
if (! doc->translationUnit()->ast())
- return 0;
+ return nullptr;
return doc->translationUnit()->ast()->asExpression();
}
diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp
index dabbcf0063..c46117dde7 100644
--- a/src/libs/cplusplus/TypePrettyPrinter.cpp
+++ b/src/libs/cplusplus/TypePrettyPrinter.cpp
@@ -169,7 +169,7 @@ void TypePrettyPrinter::visit(Template *type)
const Overview &oo = *overview();
if (oo.showTemplateParameters && ! _name.isEmpty()) {
_name += QLatin1Char('<');
- for (unsigned index = 0; index < type->templateParameterCount(); ++index) {
+ for (int index = 0; index < type->templateParameterCount(); ++index) {
if (index)
_name += QLatin1String(", ");
QString arg = oo.prettyName(type->templateParameterAt(index)->name());
@@ -410,7 +410,7 @@ void TypePrettyPrinter::visit(Function *type)
if (_overview->showEnclosingTemplate) {
if (Template *templ = type->enclosingTemplate()) {
QString templateScope = "template<";
- for (unsigned i = 0, total = templ->templateParameterCount(); i < total; ++i) {
+ for (int i = 0, total = templ->templateParameterCount(); i < total; ++i) {
if (Symbol *param = templ->templateParameterAt(i)) {
if (i > 0)
templateScope.append(", ");
@@ -437,7 +437,7 @@ void TypePrettyPrinter::visit(Function *type)
_text += QLatin1Char('(');
- for (unsigned index = 0, argc = type->argumentCount(); index < argc; ++index) {
+ for (int index = 0, argc = type->argumentCount(); index < argc; ++index) {
if (index != 0)
_text += QLatin1String(", ");
@@ -445,7 +445,7 @@ void TypePrettyPrinter::visit(Function *type)
if (index + 1 == _overview->markedArgument)
const_cast<Overview*>(_overview)->markedArgumentBegin = _text.length();
- const Name *name = 0;
+ const Name *name = nullptr;
if (_overview->showArgumentNames)
name = arg->name();
diff --git a/src/libs/cplusplus/cppmodelmanagerbase.cpp b/src/libs/cplusplus/cppmodelmanagerbase.cpp
index 19703e4fd9..3d8d43d709 100644
--- a/src/libs/cplusplus/cppmodelmanagerbase.cpp
+++ b/src/libs/cplusplus/cppmodelmanagerbase.cpp
@@ -27,7 +27,7 @@
namespace CPlusPlus {
-static CppModelManagerBase *g_instance = 0;
+static CppModelManagerBase *g_instance = nullptr;
CppModelManagerBase::CppModelManagerBase(QObject *parent)
: QObject(parent)
@@ -39,7 +39,7 @@ CppModelManagerBase::CppModelManagerBase(QObject *parent)
CppModelManagerBase::~CppModelManagerBase()
{
Q_ASSERT(g_instance == this);
- g_instance = 0;
+ g_instance = nullptr;
}
CppModelManagerBase *CppModelManagerBase::instance()
@@ -58,9 +58,9 @@ bool CppModelManagerBase::trySetExtraDiagnostics(const QString &fileName, const
bool CppModelManagerBase::setExtraDiagnostics(const QString &fileName, const QString &kind,
const QList<CPlusPlus::Document::DiagnosticMessage> &diagnostics)
{
- Q_UNUSED(fileName);
- Q_UNUSED(kind);
- Q_UNUSED(diagnostics);
+ Q_UNUSED(fileName)
+ Q_UNUSED(kind)
+ Q_UNUSED(diagnostics)
return false;
}
diff --git a/src/libs/cplusplus/cppmodelmanagerbase.h b/src/libs/cplusplus/cppmodelmanagerbase.h
index 680e7e2d06..52d9c9ace2 100644
--- a/src/libs/cplusplus/cppmodelmanagerbase.h
+++ b/src/libs/cplusplus/cppmodelmanagerbase.h
@@ -40,7 +40,7 @@ class CPLUSPLUS_EXPORT CppModelManagerBase : public QObject
{
Q_OBJECT
public:
- CppModelManagerBase(QObject *parent = 0);
+ CppModelManagerBase(QObject *parent = nullptr);
~CppModelManagerBase();
static CppModelManagerBase *instance();
diff --git a/src/libs/cplusplus/findcdbbreakpoint.cpp b/src/libs/cplusplus/findcdbbreakpoint.cpp
index 8943ad0001..54f618a50e 100644
--- a/src/libs/cplusplus/findcdbbreakpoint.cpp
+++ b/src/libs/cplusplus/findcdbbreakpoint.cpp
@@ -39,7 +39,7 @@ FindCdbBreakpoint::FindCdbBreakpoint(TranslationUnit *unit)
{
}
-unsigned FindCdbBreakpoint::searchFrom(unsigned line)
+int FindCdbBreakpoint::searchFrom(int line)
{
m_initialLine = line;
m_breakpointLine = NO_LINE_FOUND;
@@ -51,18 +51,18 @@ unsigned FindCdbBreakpoint::searchFrom(unsigned line)
void FindCdbBreakpoint::foundLine(unsigned tokenIndex)
{
- unsigned dummy = 0;
+ int dummy = 0;
getTokenStartPosition(tokenIndex, &m_breakpointLine, &dummy);
}
-unsigned FindCdbBreakpoint::endLine(unsigned tokenIndex) const
+int FindCdbBreakpoint::endLine(unsigned tokenIndex) const
{
- unsigned line = 0, column = 0;
+ int line = 0, column = 0;
getTokenEndPosition(tokenIndex, &line, &column);
return line;
}
-unsigned FindCdbBreakpoint::endLine(AST *ast) const
+int FindCdbBreakpoint::endLine(AST *ast) const
{
if (ast)
return endLine(ast->lastToken() - 1);
diff --git a/src/libs/cplusplus/findcdbbreakpoint.h b/src/libs/cplusplus/findcdbbreakpoint.h
index 6fb61030e7..0be6ae048d 100644
--- a/src/libs/cplusplus/findcdbbreakpoint.h
+++ b/src/libs/cplusplus/findcdbbreakpoint.h
@@ -33,13 +33,12 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT FindCdbBreakpoint: protected ASTVisitor
{
public:
- static const unsigned NO_LINE_FOUND = 0;
+ static const int NO_LINE_FOUND = 0;
public:
FindCdbBreakpoint(TranslationUnit *unit);
- unsigned operator()(unsigned line)
- { return searchFrom(line); }
+ int operator()(int line) { return searchFrom(line); }
/**
* Search for the next breakable line of code.
@@ -49,12 +48,12 @@ public:
* \return the next breakable code line (1-based), or \c NO_LINE_FOUND if
* no line could be found.
*/
- unsigned searchFrom(unsigned line);
+ int searchFrom(int line);
protected:
void foundLine(unsigned tokenIndex);
- unsigned endLine(unsigned tokenIndex) const;
- unsigned endLine(AST *ast) const;
+ int endLine(unsigned tokenIndex) const;
+ int endLine(AST *ast) const;
protected:
using ASTVisitor::visit;
@@ -86,9 +85,9 @@ protected:
bool visit(ObjCSynchronizedStatementAST *ast);
private:
- unsigned m_initialLine;
+ int m_initialLine;
- unsigned m_breakpointLine;
+ int m_breakpointLine;
};
} // namespace CPlusPlus
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index f8874101fe..d1f2d3eaf5 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -343,7 +343,7 @@ class ExpressionEvaluator
public:
ExpressionEvaluator(Client *client, Environment *env)
- : client(client), env(env), _lex(0)
+ : client(client), env(env), _lex(nullptr)
{ }
Value operator()(const Token *firstToken, const Token *lastToken,
@@ -422,7 +422,7 @@ protected:
(*_lex)->byteOffset,
(*_lex)->utf16charOffset,
(*_lex)->lineno, env, client)
- != 0);
+ != nullptr);
++(*_lex);
} else if ((*_lex)->is(T_LPAREN)) {
++(*_lex);
@@ -432,7 +432,7 @@ protected:
(*_lex)->utf16charOffset,
(*_lex)->lineno,
env, client)
- != 0);
+ != nullptr);
++(*_lex);
if ((*_lex)->is(T_RPAREN))
++(*_lex);
@@ -600,21 +600,21 @@ private:
} // end of anonymous namespace
Preprocessor::State::State()
- : m_lexer(0)
+ : m_lexer(nullptr)
, m_skipping(MAX_LEVEL)
, m_trueTest(MAX_LEVEL)
, m_ifLevel(0)
, m_tokenBufferDepth(0)
- , m_tokenBuffer(0)
+ , m_tokenBuffer(nullptr)
, m_inPreprocessorDirective(false)
, m_markExpandedTokens(true)
, m_noLines(false)
, m_inCondition(false)
, m_bytesOffsetRef(0)
, m_utf16charsOffsetRef(0)
- , m_result(0)
+ , m_result(nullptr)
, m_lineRef(1)
- , m_currentExpansion(0)
+ , m_currentExpansion(nullptr)
, m_includeGuardState(IncludeGuardState_BeforeIfndef)
{
m_skipping[m_ifLevel] = false;
@@ -848,7 +848,7 @@ void Preprocessor::handleDefined(PPToken *tk)
void Preprocessor::pushToken(Preprocessor::PPToken *tk)
{
const PPToken currentTokenBuffer[] = {*tk};
- m_state.pushTokenBuffer(currentTokenBuffer, currentTokenBuffer + 1, 0);
+ m_state.pushTokenBuffer(currentTokenBuffer, currentTokenBuffer + 1, nullptr);
}
void Preprocessor::lex(PPToken *tk)
@@ -1321,7 +1321,7 @@ void Preprocessor::trackExpansionCycles(PPToken *tk)
}
}
-static void adjustForCommentOrStringNewlines(unsigned *currentLine, const PPToken &tk)
+static void adjustForCommentOrStringNewlines(int *currentLine, const PPToken &tk)
{
if (tk.isComment() || tk.isStringLiteral())
(*currentLine) += tk.asByteArrayRef().count('\n');
@@ -1343,7 +1343,7 @@ void Preprocessor::synchronizeOutputLines(const PPToken &tk, bool forceLine)
generateOutputLineMarker(tk.lineno);
}
} else {
- for (unsigned i = m_env->currentLine; i < tk.lineno; ++i)
+ for (int i = m_env->currentLine; i < tk.lineno; ++i)
currentOutputBuffer().append('\n');
}
@@ -1419,7 +1419,7 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
ScopedSwap<QString> savedFileName(m_env->currentFile, fileName);
ScopedSwap<QByteArray> savedUtf8FileName(m_env->currentFileUtf8, fileName.toUtf8());
- ScopedSwap<unsigned> savedCurrentLine(m_env->currentLine, 1);
+ ScopedSwap<int> savedCurrentLine(m_env->currentLine, 1);
if (!m_state.m_noLines)
generateOutputLineMarker(1);
@@ -1774,7 +1774,7 @@ void Preprocessor::handleDefineDirective(PPToken *tk)
unsigned previousBytesOffset = 0;
unsigned previousUtf16charsOffset = 0;
unsigned previousLine = 0;
- Macro *macroReference = 0;
+ Macro *macroReference = nullptr;
while (isContinuationToken(*tk)) {
// Macro tokens are always marked as expanded. However, only for object-like macros
// we mark them as generated too. For function-like macros we postpone it until the
@@ -1791,7 +1791,7 @@ void Preprocessor::handleDefineDirective(PPToken *tk)
if (!macroReference->isFunctionLike()) {
m_client->notifyMacroReference(tk->byteOffset, tk->utf16charOffset,
tk->lineno, *macroReference);
- macroReference = 0;
+ macroReference = nullptr;
}
}
} else if (macroReference) {
@@ -1799,7 +1799,7 @@ void Preprocessor::handleDefineDirective(PPToken *tk)
m_client->notifyMacroReference(previousBytesOffset, previousUtf16charsOffset,
previousLine, *macroReference);
}
- macroReference = 0;
+ macroReference = nullptr;
}
previousBytesOffset = tk->byteOffset;
@@ -1870,7 +1870,7 @@ QByteArray Preprocessor::expand(PPToken *tk, PPToken *lastConditionToken)
// qDebug("*** Condition before: [%s]", condition.constData());
QByteArray result;
result.reserve(256);
- preprocess(m_state.m_currentFileName, condition, &result, 0, true, false, true,
+ preprocess(m_state.m_currentFileName, condition, &result, nullptr, true, false, true,
bytesBegin, utf16charsBegin, line);
result.squeeze();
// qDebug("*** Condition after: [%s]", result.constData());
diff --git a/src/libs/cplusplus/pp-engine.h b/src/libs/cplusplus/pp-engine.h
index fb9cdda2b2..8902cb7624 100644
--- a/src/libs/cplusplus/pp-engine.h
+++ b/src/libs/cplusplus/pp-engine.h
@@ -133,7 +133,7 @@ private:
unsigned m_bytesOffsetRef;
unsigned m_utf16charsOffsetRef;
QByteArray *m_result;
- unsigned m_lineRef;
+ int m_lineRef;
ExpansionStatus m_expansionStatus;
void setExpansionStatus(ExpansionStatus status)
@@ -181,7 +181,7 @@ private:
/// \param idToken the identifier token that ought to be in the input
/// after a #ifndef or a #define .
inline void updateIncludeGuardState(IncludeGuardStateHint hint,
- PPToken *idToken = 0)
+ PPToken *idToken = nullptr)
{
// some quick checks for the majority of the uninteresting cases:
if (m_includeGuardState == IncludeGuardState_NoGuard)
@@ -227,7 +227,7 @@ private:
void handlePreprocessorDirective(PPToken *tk);
void handleIncludeDirective(PPToken *tk, bool includeNext);
void handleDefineDirective(PPToken *tk);
- QByteArray expand(PPToken *tk, PPToken *lastConditionToken = 0);
+ QByteArray expand(PPToken *tk, PPToken *lastConditionToken = nullptr);
const Internal::PPToken evalExpression(PPToken *tk, Value &result);
void handleIfDirective(PPToken *tk);
void handleElifDirective(PPToken *tk, const PPToken &poundToken);
diff --git a/src/libs/extensionsystem/CMakeLists.txt b/src/libs/extensionsystem/CMakeLists.txt
index 864c57c1ae..53f928153c 100644
--- a/src/libs/extensionsystem/CMakeLists.txt
+++ b/src/libs/extensionsystem/CMakeLists.txt
@@ -1,6 +1,6 @@
add_qtc_library(ExtensionSystem
- DEPENDS Aggregation Utils Qt5::Core Qt5::Widgets
- PUBLIC_DEPENDS Qt5::Core
+ DEPENDS Aggregation Utils
+ PUBLIC_DEPENDS Qt5::Core Qt5::Widgets
SOURCES
extensionsystem_global.h
invoker.cpp invoker.h
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 2a020a384d..e5633e860b 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -48,6 +48,7 @@
#include <utils/algorithm.h>
#include <utils/benchmarker.h>
#include <utils/executeondestruction.h>
+#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
@@ -353,6 +354,15 @@ bool PluginManager::hasError()
});
}
+const QStringList PluginManager::allErrors()
+{
+ return Utils::transform<QStringList>(Utils::filtered(plugins(), [](const PluginSpec *spec) {
+ return spec->hasError() && spec->isEffectivelyEnabled();
+ }), [](const PluginSpec *spec) {
+ return spec->name().append(": ").append(spec->errorString());
+ });
+}
+
/*!
Returns all plugins that require \a spec to be loaded. Recurses into dependencies.
*/
@@ -380,9 +390,8 @@ QSet<PluginSpec *> PluginManager::pluginsRequiredByPlugin(PluginSpec *spec)
while (!queue.empty()) {
PluginSpec *checkSpec = queue.front();
queue.pop();
- QHashIterator<PluginDependency, PluginSpec *> depIt(checkSpec->dependencySpecs());
- while (depIt.hasNext()) {
- depIt.next();
+ const QHash<PluginDependency, PluginSpec *> deps = checkSpec->dependencySpecs();
+ for (auto depIt = deps.cbegin(), end = deps.cend(); depIt != end; ++depIt) {
if (depIt.key().type != PluginDependency::Required)
continue;
PluginSpec *depSpec = depIt.value();
@@ -412,10 +421,10 @@ static QString filled(const QString &s, int min)
QString PluginManager::systemInformation() const
{
QString result;
- const QString qtdiagBinary = HostOsInfo::withExecutableSuffix(
- QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qtdiag");
+ CommandLine qtDiag(HostOsInfo::withExecutableSuffix(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qtdiag"));
SynchronousProcess qtdiagProc;
- const SynchronousProcessResponse response = qtdiagProc.runBlocking(qtdiagBinary, QStringList());
+ const SynchronousProcessResponse response = qtdiagProc.runBlocking(qtDiag);
if (response.result == SynchronousProcessResponse::Finished)
result += response.allOutput() + "\n";
result += "Plugin information:\n\n";
@@ -923,7 +932,6 @@ void PluginManagerPrivate::deleteAll()
#ifdef WITH_TESTS
using TestPlan = QMap<QObject *, QStringList>; // Object -> selected test functions
-using TestPlanIterator = QMapIterator<QObject *, QStringList>;
static bool isTestFunction(const QMetaMethod &metaMethod)
{
@@ -1009,9 +1017,7 @@ static int executeTestPlan(const TestPlan &testPlan)
{
int failedTests = 0;
- TestPlanIterator it(testPlan);
- while (it.hasNext()) {
- it.next();
+ for (auto it = testPlan.cbegin(), end = testPlan.cend(); it != end; ++it) {
QObject *testObject = it.key();
QStringList functions = it.value();
@@ -1119,8 +1125,9 @@ static TestPlan generateCustomTestPlan(IPlugin *plugin,
void PluginManagerPrivate::startTests()
{
if (PluginManager::hasError()) {
- qWarning("Errors occurred while loading plugins, skipping test run. "
- "For details, start without \"-test\" option.");
+ qWarning("Errors occurred while loading plugins, skipping test run.");
+ for (const QString &pluginError : PluginManager::allErrors())
+ qWarning("%s", qPrintable(pluginError));
QTimer::singleShot(1, QCoreApplication::instance(), &QCoreApplication::quit);
return;
}
@@ -1315,9 +1322,8 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec,
}
// add dependencies
- QHashIterator<PluginDependency, PluginSpec *> it(spec->dependencySpecs());
- while (it.hasNext()) {
- it.next();
+ const QHash<PluginDependency, PluginSpec *> deps = spec->dependencySpecs();
+ for (auto it = deps.cbegin(), end = deps.cend(); it != end; ++it) {
// Skip test dependencies since they are not real dependencies but just force-loaded
// plugins when running tests
if (it.key().type == PluginDependency::Test)
@@ -1363,9 +1369,8 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt
break;
}
// check if dependencies have loaded without error
- QHashIterator<PluginDependency, PluginSpec *> it(spec->dependencySpecs());
- while (it.hasNext()) {
- it.next();
+ const QHash<PluginDependency, PluginSpec *> deps = spec->dependencySpecs();
+ for (auto it = deps.cbegin(), end = deps.cend(); it != end; ++it) {
if (it.key().type != PluginDependency::Required)
continue;
PluginSpec *depSpec = it.value();
diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h
index c926d07f4a..d65571bfb7 100644
--- a/src/libs/extensionsystem/pluginmanager.h
+++ b/src/libs/extensionsystem/pluginmanager.h
@@ -93,6 +93,7 @@ public:
static const QVector<PluginSpec *> plugins();
static QHash<QString, QVector<PluginSpec *>> pluginCollections();
static bool hasError();
+ static const QStringList allErrors();
static QSet<PluginSpec *> pluginsRequiringPlugin(PluginSpec *spec);
static QSet<PluginSpec *> pluginsRequiredByPlugin(PluginSpec *spec);
diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp
index b8d0643982..4f1c2683e9 100644
--- a/src/libs/extensionsystem/pluginspec.cpp
+++ b/src/libs/extensionsystem/pluginspec.cpp
@@ -929,9 +929,7 @@ QVector<PluginSpec *> PluginSpecPrivate::enableDependenciesIndirectly(bool enabl
if (!q->isEffectivelyEnabled()) // plugin not enabled, nothing to do
return {};
QVector<PluginSpec *> enabled;
- QHashIterator<PluginDependency, PluginSpec *> it(dependencySpecs);
- while (it.hasNext()) {
- it.next();
+ for (auto it = dependencySpecs.cbegin(), end = dependencySpecs.cend(); it != end; ++it) {
if (it.key().type != PluginDependency::Required
&& (!enableTestDependencies || it.key().type != PluginDependency::Test))
continue;
diff --git a/src/libs/glsl/glslast.cpp b/src/libs/glsl/glslast.cpp
index f85486a836..d3375bee43 100644
--- a/src/libs/glsl/glslast.cpp
+++ b/src/libs/glsl/glslast.cpp
@@ -325,7 +325,7 @@ void StructTypeAST::Field::setInnerType(TypeAST *innerType)
return;
TypeAST **parent = &type;
TypeAST *inner = type;
- while (inner != 0) {
+ while (inner != nullptr) {
ArrayTypeAST *array = inner->asArrayType();
if (!array)
break;
@@ -388,7 +388,7 @@ void VariableDeclarationAST::accept0(Visitor *visitor)
TypeAST *VariableDeclarationAST::declarationType(List<DeclarationAST *> *decls)
{
VariableDeclarationAST *var = decls->value->asVariableDeclaration();
- return var ? var->type : 0;
+ return var ? var->type : nullptr;
}
void TypeDeclarationAST::accept0(Visitor *visitor)
diff --git a/src/libs/glsl/glslastdump.cpp b/src/libs/glsl/glslastdump.cpp
index 9cd210dabe..9cc25c4f06 100644
--- a/src/libs/glsl/glslastdump.cpp
+++ b/src/libs/glsl/glslastdump.cpp
@@ -49,7 +49,7 @@ bool ASTDump::preVisit(AST *ast)
{
const char *id = typeid(*ast).name();
#ifdef Q_CC_GNU
- char *cppId = abi::__cxa_demangle(id, 0, 0, 0);
+ char *cppId = abi::__cxa_demangle(id, nullptr, nullptr, nullptr);
id = cppId;
#endif
out << QByteArray(_depth, ' ') << id << endl;
diff --git a/src/libs/glsl/glslengine.h b/src/libs/glsl/glslengine.h
index 7cf6e2d164..0942d5ef57 100644
--- a/src/libs/glsl/glslengine.h
+++ b/src/libs/glsl/glslengine.h
@@ -112,9 +112,9 @@ public:
// symbols
Namespace *newNamespace();
- Struct *newStruct(Scope *scope = 0);
- Block *newBlock(Scope *scope = 0);
- Function *newFunction(Scope *scope = 0);
+ Struct *newStruct(Scope *scope = nullptr);
+ Block *newBlock(Scope *scope = nullptr);
+ Function *newFunction(Scope *scope = nullptr);
Argument *newArgument(Function *function, const QString &name, const Type *type);
Variable *newVariable(Scope *scope, const QString &name, const Type *type, int qualifiers = 0);
diff --git a/src/libs/glsl/glsllexer.cpp b/src/libs/glsl/glsllexer.cpp
index 6042e3ddee..afaad6dc9d 100644
--- a/src/libs/glsl/glsllexer.cpp
+++ b/src/libs/glsl/glsllexer.cpp
@@ -60,9 +60,9 @@ void Lexer::yyinp()
int Lexer::yylex(Token *tk)
{
- const char *pos = 0;
+ const char *pos = nullptr;
int line = 0;
- _yyval.ptr = 0;
+ _yyval.ptr = nullptr;
const int kind = yylex_helper(&pos, &line);
tk->kind = kind;
tk->position = pos - _source;
diff --git a/src/libs/glsl/glsllexer.h b/src/libs/glsl/glsllexer.h
index 2b0ad83fed..3dcbe2168b 100644
--- a/src/libs/glsl/glsllexer.h
+++ b/src/libs/glsl/glsllexer.h
@@ -47,7 +47,7 @@ public:
};
Token()
- : kind(0), position(0), length(0), line(0), ptr(0) {}
+ : kind(0), position(0), length(0), line(0), ptr(nullptr) {}
bool is(int k) const { return k == kind; }
bool isNot(int k) const { return k != kind; }
diff --git a/src/libs/glsl/glslmemorypool.cpp b/src/libs/glsl/glslmemorypool.cpp
index dc681565df..7e4829a6e6 100644
--- a/src/libs/glsl/glslmemorypool.cpp
+++ b/src/libs/glsl/glslmemorypool.cpp
@@ -30,11 +30,11 @@
using namespace GLSL;
MemoryPool::MemoryPool()
- : _blocks(0),
+ : _blocks(nullptr),
_allocatedBlocks(0),
_blockCount(-1),
- _ptr(0),
- _end(0)
+ _ptr(nullptr),
+ _end(nullptr)
{ }
MemoryPool::~MemoryPool()
@@ -52,7 +52,7 @@ MemoryPool::~MemoryPool()
void MemoryPool::reset()
{
_blockCount = -1;
- _ptr = _end = 0;
+ _ptr = _end = nullptr;
}
void *MemoryPool::allocate_helper(size_t size)
@@ -68,7 +68,7 @@ void *MemoryPool::allocate_helper(size_t size)
_blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index)
- _blocks[index] = 0;
+ _blocks[index] = nullptr;
}
char *&block = _blocks[_blockCount];
diff --git a/src/libs/glsl/glslparser.cpp b/src/libs/glsl/glslparser.cpp
index f435032999..17dc26c61f 100644
--- a/src/libs/glsl/glslparser.cpp
+++ b/src/libs/glsl/glslparser.cpp
@@ -104,7 +104,7 @@ AST *Parser::parse(int startToken)
int action = 0;
yytoken = -1;
yyloc = -1;
- void *yyval = 0; // value of the current token.
+ void *yyval = nullptr; // value of the current token.
_recovered = false;
_tos = -1;
@@ -204,7 +204,7 @@ AST *Parser::parse(int startToken)
else if (*tptr == T_NUMBER || *tptr == T_TYPE_NAME)
yyval = (void *) _engine->identifier(QLatin1String("$0"));
else
- yyval = 0;
+ yyval = nullptr;
_symStack[_tos].ptr = yyval;
_locationStack[_tos] = yyloc;
@@ -224,7 +224,7 @@ AST *Parser::parse(int startToken)
} while (action);
- return 0;
+ return nullptr;
}
#line 643 "./glsl.g"
@@ -347,14 +347,14 @@ case 17: {
case 18: {
sym(1).function.id = sym(1).function_identifier;
- sym(1).function.arguments = 0;
+ sym(1).function.arguments = nullptr;
} break;
#line 788 "./glsl.g"
case 19: {
sym(1).function.id = sym(1).function_identifier;
- sym(1).function.arguments = 0;
+ sym(1).function.arguments = nullptr;
} break;
#line 796 "./glsl.g"
@@ -815,7 +815,7 @@ case 87: {
case 88: {
TypeAST *type = makeAstNode<QualifiedTypeAST>
- (sym(1).type_qualifier.qualifier, (TypeAST *)0,
+ (sym(1).type_qualifier.qualifier, (TypeAST *)nullptr,
sym(1).type_qualifier.layout_list);
ast(1) = makeAstNode<TypeDeclarationAST>(type);
} break;
@@ -878,7 +878,7 @@ case 97: {
ast(1) = makeAstNode<ParameterDeclarationAST>
(makeAstNode<QualifiedTypeAST>
(sym(1).qualifier, sym(3).param_declarator.type,
- (List<LayoutQualifierAST *> *)0),
+ (List<LayoutQualifierAST *> *)nullptr),
ParameterDeclarationAST::Qualifier(sym(2).qualifier),
sym(3).param_declarator.name);
} break;
@@ -897,9 +897,9 @@ case 98: {
case 99: {
ast(1) = makeAstNode<ParameterDeclarationAST>
(makeAstNode<QualifiedTypeAST>
- (sym(1).qualifier, type(3), (List<LayoutQualifierAST *> *)0),
+ (sym(1).qualifier, type(3), (List<LayoutQualifierAST *> *)nullptr),
ParameterDeclarationAST::Qualifier(sym(2).qualifier),
- (const QString *)0);
+ (const QString *)nullptr);
} break;
#line 1421 "./glsl.g"
@@ -907,7 +907,7 @@ case 99: {
case 100: {
ast(1) = makeAstNode<ParameterDeclarationAST>
(type(2), ParameterDeclarationAST::Qualifier(sym(1).qualifier),
- (const QString *)0);
+ (const QString *)nullptr);
} break;
#line 1430 "./glsl.g"
@@ -1065,7 +1065,7 @@ case 120: {
#line 1602 "./glsl.g"
case 121: {
- ast(1) = makeAstNode<QualifiedTypeAST>(0, type(1), (List<LayoutQualifierAST *> *)0);
+ ast(1) = makeAstNode<QualifiedTypeAST>(0, type(1), (List<LayoutQualifierAST *> *)nullptr);
} break;
#line 1609 "./glsl.g"
@@ -1121,7 +1121,7 @@ case 129: {
#line 1667 "./glsl.g"
case 130: {
- sym(1).layout = makeAstNode<LayoutQualifierAST>(string(1), (const QString *)0);
+ sym(1).layout = makeAstNode<LayoutQualifierAST>(string(1), (const QString *)nullptr);
} break;
#line 1674 "./glsl.g"
@@ -1140,7 +1140,7 @@ case 132: {
case 133: {
sym(1).type_qualifier.qualifier = sym(1).qualifier;
- sym(1).type_qualifier.layout_list = 0;
+ sym(1).type_qualifier.layout_list = nullptr;
} break;
#line 1696 "./glsl.g"
@@ -1161,35 +1161,35 @@ case 135: {
case 136: {
sym(1).type_qualifier.qualifier = sym(1).qualifier | sym(2).qualifier;
- sym(1).type_qualifier.layout_list = 0;
+ sym(1).type_qualifier.layout_list = nullptr;
} break;
#line 1720 "./glsl.g"
case 137: {
sym(1).type_qualifier.qualifier = sym(1).qualifier;
- sym(1).type_qualifier.layout_list = 0;
+ sym(1).type_qualifier.layout_list = nullptr;
} break;
#line 1728 "./glsl.g"
case 138: {
sym(1).type_qualifier.qualifier = sym(1).qualifier | sym(2).qualifier;
- sym(1).type_qualifier.layout_list = 0;
+ sym(1).type_qualifier.layout_list = nullptr;
} break;
#line 1736 "./glsl.g"
case 139: {
sym(1).type_qualifier.qualifier = sym(1).qualifier | sym(2).qualifier | sym(3).qualifier;
- sym(1).type_qualifier.layout_list = 0;
+ sym(1).type_qualifier.layout_list = nullptr;
} break;
#line 1744 "./glsl.g"
case 140: {
sym(1).type_qualifier.qualifier = QualifiedTypeAST::Invariant;
- sym(1).type_qualifier.layout_list = 0;
+ sym(1).type_qualifier.layout_list = nullptr;
} break;
#line 1752 "./glsl.g"
@@ -1905,14 +1905,14 @@ case 257: {
case 258: {
sym(1).field = makeAstNode<StructTypeAST::Field>
- (string(1), makeAstNode<ArrayTypeAST>((TypeAST *)0));
+ (string(1), makeAstNode<ArrayTypeAST>((TypeAST *)nullptr));
} break;
#line 2586 "./glsl.g"
case 259: {
sym(1).field = makeAstNode<StructTypeAST::Field>
- (string(1), makeAstNode<ArrayTypeAST>((TypeAST *)0, expression(3)));
+ (string(1), makeAstNode<ArrayTypeAST>((TypeAST *)nullptr, expression(3)));
} break;
#line 2594 "./glsl.g"
@@ -2070,7 +2070,7 @@ case 282: {
case 283: {
sym(1).ifstmt.thenClause = statement(1);
- sym(1).ifstmt.elseClause = 0;
+ sym(1).ifstmt.elseClause = nullptr;
} break;
#line 2776 "./glsl.g"
@@ -2162,7 +2162,7 @@ case 297: {
case 298: {
sym(1).forstmt.condition = expression(1);
- sym(1).forstmt.increment = 0;
+ sym(1).forstmt.increment = nullptr;
} break;
#line 2883 "./glsl.g"
@@ -2215,7 +2215,7 @@ case 306: {
sym(1).declaration_list = makeAstNode< List<DeclarationAST *> >
(sym(1).declaration);
} else {
- sym(1).declaration_list = 0;
+ sym(1).declaration_list = nullptr;
}
} break;
@@ -2230,7 +2230,7 @@ case 307: {
sym(1).declaration_list = makeAstNode< List<DeclarationAST *> >
(sym(2).declaration);
} else {
- sym(1).declaration_list = 0;
+ sym(1).declaration_list = nullptr;
}
}
} break;
@@ -2250,7 +2250,7 @@ case 309: {
#line 2976 "./glsl.g"
case 310: {
- ast(1) = 0;
+ ast(1) = nullptr;
} break;
#line 2983 "./glsl.g"
@@ -2262,7 +2262,7 @@ case 311: {
#line 2990 "./glsl.g"
case 312: {
- ast(1) = 0;
+ ast(1) = nullptr;
} break;
#line 2998 "./glsl.g"
diff --git a/src/libs/glsl/glslparser.h b/src/libs/glsl/glslparser.h
index 5e148c298b..65003e6974 100644
--- a/src/libs/glsl/glslparser.h
+++ b/src/libs/glsl/glslparser.h
@@ -91,13 +91,13 @@ public:
TranslationUnitAST *parse() {
if (AST *u = parse(T_FEED_GLSL))
return u->asTranslationUnit();
- return 0;
+ return nullptr;
}
ExpressionAST *parseExpression() {
if (AST *u = parse(T_FEED_EXPRESSION))
return u->asExpression();
- return 0;
+ return nullptr;
}
AST *parse(int startToken);
diff --git a/src/libs/glsl/glslsemantic.cpp b/src/libs/glsl/glslsemantic.cpp
index ae03ca148a..4db1c0e32c 100644
--- a/src/libs/glsl/glslsemantic.cpp
+++ b/src/libs/glsl/glslsemantic.cpp
@@ -33,9 +33,9 @@
using namespace GLSL;
Semantic::Semantic()
- : _engine(0)
- , _scope(0)
- , _type(0)
+ : _engine(nullptr)
+ , _scope(nullptr)
+ , _type(nullptr)
{
}
@@ -118,7 +118,7 @@ Semantic::ExprResult Semantic::functionIdentifier(FunctionIdentifierAST *ast)
if (ast) {
if (ast->name) {
if (Symbol *s = _scope->lookup(*ast->name)) {
- if (s->asOverloadSet() != 0 || s->asFunction() != 0)
+ if (s->asOverloadSet() != nullptr || s->asFunction() != nullptr)
result.type = s->type();
else
_engine->error(ast->lineno, QString::fromLatin1("`%1' cannot be used as a function").arg(*ast->name));
@@ -156,21 +156,21 @@ void Semantic::parameterDeclaration(ParameterDeclarationAST *ast, Function *fun)
bool Semantic::visit(TranslationUnitAST *ast)
{
- Q_UNUSED(ast);
+ Q_UNUSED(ast)
Q_ASSERT(!"unreachable");
return false;
}
bool Semantic::visit(FunctionIdentifierAST *ast)
{
- Q_UNUSED(ast);
+ Q_UNUSED(ast)
Q_ASSERT(!"unreachable");
return false;
}
bool Semantic::visit(StructTypeAST::Field *ast)
{
- Q_UNUSED(ast);
+ Q_UNUSED(ast)
Q_ASSERT(!"unreachable");
return false;
}
@@ -308,33 +308,33 @@ bool Semantic::implicitCast(const Type *type, const Type *target) const
return false;
} else if (type->isEqualTo(target)) {
return true;
- } else if (target->asUIntType() != 0) {
- return type->asIntType() != 0;
- } else if (target->asFloatType() != 0) {
- return type->asIntType() != 0 ||
- type->asUIntType() != 0;
- } else if (target->asDoubleType() != 0) {
- return type->asIntType() != 0 ||
- type->asUIntType() != 0 ||
- type->asFloatType() != 0;
+ } else if (target->asUIntType() != nullptr) {
+ return type->asIntType() != nullptr;
+ } else if (target->asFloatType() != nullptr) {
+ return type->asIntType() != nullptr ||
+ type->asUIntType() != nullptr;
+ } else if (target->asDoubleType() != nullptr) {
+ return type->asIntType() != nullptr ||
+ type->asUIntType() != nullptr ||
+ type->asFloatType() != nullptr;
} else if (const VectorType *targetVecTy = target->asVectorType()) {
if (const VectorType *vecTy = type->asVectorType()) {
if (targetVecTy->dimension() == vecTy->dimension()) {
const Type *targetElementType = targetVecTy->elementType();
const Type *elementType = vecTy->elementType();
- if (targetElementType->asUIntType() != 0) {
+ if (targetElementType->asUIntType() != nullptr) {
// uvec* -> ivec*
- return elementType->asIntType() != 0;
- } else if (targetElementType->asFloatType() != 0) {
+ return elementType->asIntType() != nullptr;
+ } else if (targetElementType->asFloatType() != nullptr) {
// vec* -> ivec* | uvec*
- return elementType->asIntType() != 0 ||
- elementType->asUIntType() != 0;
- } else if (targetElementType->asDoubleType() != 0) {
+ return elementType->asIntType() != nullptr ||
+ elementType->asUIntType() != nullptr;
+ } else if (targetElementType->asDoubleType() != nullptr) {
// dvec* -> ivec* | uvec* | fvec*
- return elementType->asIntType() != 0 ||
- elementType->asUIntType() != 0 ||
- elementType->asFloatType() != 0;
+ return elementType->asIntType() != nullptr ||
+ elementType->asUIntType() != nullptr ||
+ elementType->asFloatType() != nullptr;
}
}
}
@@ -345,9 +345,9 @@ bool Semantic::implicitCast(const Type *type, const Type *target) const
const Type *targetElementType = targetMatTy->elementType();
const Type *elementType = matTy->elementType();
- if (targetElementType->asDoubleType() != 0) {
+ if (targetElementType->asDoubleType() != nullptr) {
// dmat* -> mat*
- return elementType->asFloatType() != 0;
+ return elementType->asFloatType() != nullptr;
}
}
}
@@ -413,7 +413,7 @@ bool Semantic::visit(FunctionCallExpressionAST *ast)
bool Semantic::visit(DeclarationExpressionAST *ast)
{
const Type *ty = type(ast->type);
- Q_UNUSED(ty);
+ Q_UNUSED(ty)
// ast->name
ExprResult initializer = expression(ast->initializer);
return false;
@@ -473,7 +473,7 @@ bool Semantic::visit(ForStatementAST *ast)
bool Semantic::visit(JumpStatementAST *ast)
{
- Q_UNUSED(ast);
+ Q_UNUSED(ast)
return false;
}
@@ -750,7 +750,7 @@ bool Semantic::visit(NamedTypeAST *ast)
bool Semantic::visit(ArrayTypeAST *ast)
{
const Type *elementType = type(ast->elementType);
- Q_UNUSED(elementType);
+ Q_UNUSED(elementType)
ExprResult size = expression(ast->size);
_type = _engine->arrayType(elementType); // ### ignore the size for now
return false;
@@ -780,7 +780,7 @@ bool Semantic::visit(QualifiedTypeAST *ast)
LayoutQualifierAST *q = it->value;
// q->name;
// q->number;
- Q_UNUSED(q);
+ Q_UNUSED(q)
}
return false;
}
@@ -790,13 +790,13 @@ bool Semantic::visit(QualifiedTypeAST *ast)
bool Semantic::visit(PrecisionDeclarationAST *ast)
{
const Type *ty = type(ast->type);
- Q_UNUSED(ty);
+ Q_UNUSED(ty)
return false;
}
bool Semantic::visit(ParameterDeclarationAST *ast)
{
- Q_UNUSED(ast);
+ Q_UNUSED(ast)
Q_ASSERT(!"unreachable");
return false;
}
@@ -822,7 +822,7 @@ bool Semantic::visit(VariableDeclarationAST *ast)
bool Semantic::visit(TypeDeclarationAST *ast)
{
const Type *ty = type(ast->type);
- Q_UNUSED(ty);
+ Q_UNUSED(ty)
return false;
}
@@ -835,7 +835,7 @@ bool Semantic::visit(TypeAndVariableDeclarationAST *ast)
bool Semantic::visit(InvariantDeclarationAST *ast)
{
- Q_UNUSED(ast);
+ Q_UNUSED(ast)
return false;
}
diff --git a/src/libs/glsl/glslsemantic.h b/src/libs/glsl/glslsemantic.h
index 05d1c664a4..78eec83843 100644
--- a/src/libs/glsl/glslsemantic.h
+++ b/src/libs/glsl/glslsemantic.h
@@ -37,7 +37,7 @@ public:
~Semantic() override;
struct ExprResult {
- ExprResult(const Type *type = 0, bool isConstant = false)
+ ExprResult(const Type *type = nullptr, bool isConstant = false)
: type(type), isConstant(isConstant) {}
~ExprResult() { }
@@ -45,7 +45,7 @@ public:
bool isValid() const {
if (! type)
return false;
- else if (type->asUndefinedType() != 0)
+ else if (type->asUndefinedType() != nullptr)
return false;
return true;
}
diff --git a/src/libs/glsl/glslsymbol.cpp b/src/libs/glsl/glslsymbol.cpp
index 80f310ecad..30808f4e63 100644
--- a/src/libs/glsl/glslsymbol.cpp
+++ b/src/libs/glsl/glslsymbol.cpp
@@ -69,7 +69,7 @@ Symbol *Scope::lookup(const QString &name) const
else if (Scope *s = scope())
return s->lookup(name);
else
- return 0;
+ return nullptr;
}
QList<Symbol *> Scope::members() const
diff --git a/src/libs/glsl/glslsymbol.h b/src/libs/glsl/glslsymbol.h
index 51bb070e5a..4d965fce1e 100644
--- a/src/libs/glsl/glslsymbol.h
+++ b/src/libs/glsl/glslsymbol.h
@@ -36,7 +36,7 @@ class Scope;
class GLSL_EXPORT Symbol
{
public:
- Symbol(Scope *scope = 0);
+ Symbol(Scope *scope = nullptr);
virtual ~Symbol();
Scope *scope() const;
@@ -45,14 +45,14 @@ public:
QString name() const;
void setName(const QString &name);
- virtual Scope *asScope() { return 0; }
- virtual Struct *asStruct() { return 0; }
- virtual Function *asFunction() { return 0; }
- virtual Argument *asArgument() { return 0; }
- virtual Block *asBlock() { return 0; }
- virtual Variable *asVariable() { return 0; }
- virtual OverloadSet *asOverloadSet() { return 0; }
- virtual Namespace *asNamespace() { return 0; }
+ virtual Scope *asScope() { return nullptr; }
+ virtual Struct *asStruct() { return nullptr; }
+ virtual Function *asFunction() { return nullptr; }
+ virtual Argument *asArgument() { return nullptr; }
+ virtual Block *asBlock() { return nullptr; }
+ virtual Variable *asVariable() { return nullptr; }
+ virtual OverloadSet *asOverloadSet() { return nullptr; }
+ virtual Namespace *asNamespace() { return nullptr; }
virtual const Type *type() const = 0;
@@ -64,7 +64,7 @@ private:
class GLSL_EXPORT Scope: public Symbol
{
public:
- Scope(Scope *sscope = 0);
+ Scope(Scope *sscope = nullptr);
Symbol *lookup(const QString &name) const;
diff --git a/src/libs/glsl/glslsymbols.cpp b/src/libs/glsl/glslsymbols.cpp
index 20d7084c2d..6dc5ec60e2 100644
--- a/src/libs/glsl/glslsymbols.cpp
+++ b/src/libs/glsl/glslsymbols.cpp
@@ -31,7 +31,7 @@ using namespace GLSL;
Argument::Argument(Function *scope)
: Symbol(scope)
- , _type(0)
+ , _type(nullptr)
{
}
@@ -63,7 +63,7 @@ void Block::add(Symbol *symbol)
const Type *Block::type() const
{
// ### assert?
- return 0;
+ return nullptr;
}
Symbol *Block::find(const QString &name) const
@@ -73,7 +73,7 @@ Symbol *Block::find(const QString &name) const
Variable::Variable(Scope *scope)
: Symbol(scope)
- , _type(0)
+ , _type(nullptr)
, _qualifiers(0)
{
}
@@ -127,7 +127,7 @@ void Namespace::add(Symbol *symbol)
const Type *Namespace::type() const
{
- return 0;
+ return nullptr;
}
Symbol *Namespace::find(const QString &name) const
diff --git a/src/libs/glsl/glslsymbols.h b/src/libs/glsl/glslsymbols.h
index 60cce39db8..84983aba4e 100644
--- a/src/libs/glsl/glslsymbols.h
+++ b/src/libs/glsl/glslsymbols.h
@@ -68,7 +68,7 @@ private:
class GLSL_EXPORT Block: public Scope
{
public:
- Block(Scope *enclosingScope = 0);
+ Block(Scope *enclosingScope = nullptr);
QList<Symbol *> members() const override;
void add(Symbol *symbol) override;
diff --git a/src/libs/glsl/glsltype.h b/src/libs/glsl/glsltype.h
index 94aa422937..4035cc8cdb 100644
--- a/src/libs/glsl/glsltype.h
+++ b/src/libs/glsl/glsltype.h
@@ -36,23 +36,23 @@ public:
virtual QString toString() const = 0;
- virtual const UndefinedType *asUndefinedType() const { return 0; }
- virtual const VoidType *asVoidType() const { return 0; }
- virtual const BoolType *asBoolType() const { return 0; }
- virtual const IntType *asIntType() const { return 0; }
- virtual const UIntType *asUIntType() const { return 0; }
- virtual const FloatType *asFloatType() const { return 0; }
- virtual const DoubleType *asDoubleType() const { return 0; }
- virtual const ScalarType *asScalarType() const { return 0; }
- virtual const IndexType *asIndexType() const { return 0; }
- virtual const VectorType *asVectorType() const { return 0; }
- virtual const MatrixType *asMatrixType() const { return 0; }
- virtual const ArrayType *asArrayType() const { return 0; }
- virtual const SamplerType *asSamplerType() const { return 0; }
- virtual const OverloadSet *asOverloadSetType() const { return 0; }
-
- virtual const Struct *asStructType() const { return 0; }
- virtual const Function *asFunctionType() const { return 0; }
+ virtual const UndefinedType *asUndefinedType() const { return nullptr; }
+ virtual const VoidType *asVoidType() const { return nullptr; }
+ virtual const BoolType *asBoolType() const { return nullptr; }
+ virtual const IntType *asIntType() const { return nullptr; }
+ virtual const UIntType *asUIntType() const { return nullptr; }
+ virtual const FloatType *asFloatType() const { return nullptr; }
+ virtual const DoubleType *asDoubleType() const { return nullptr; }
+ virtual const ScalarType *asScalarType() const { return nullptr; }
+ virtual const IndexType *asIndexType() const { return nullptr; }
+ virtual const VectorType *asVectorType() const { return nullptr; }
+ virtual const MatrixType *asMatrixType() const { return nullptr; }
+ virtual const ArrayType *asArrayType() const { return nullptr; }
+ virtual const SamplerType *asSamplerType() const { return nullptr; }
+ virtual const OverloadSet *asOverloadSetType() const { return nullptr; }
+
+ virtual const Struct *asStructType() const { return nullptr; }
+ virtual const Function *asFunctionType() const { return nullptr; }
virtual bool isEqualTo(const Type *other) const = 0;
virtual bool isLessThan(const Type *other) const = 0;
diff --git a/src/libs/glsl/glsltypes.cpp b/src/libs/glsl/glsltypes.cpp
index 6bd4cd4552..f05bfb6784 100644
--- a/src/libs/glsl/glsltypes.cpp
+++ b/src/libs/glsl/glsltypes.cpp
@@ -32,119 +32,119 @@ using namespace GLSL;
bool UndefinedType::isEqualTo(const Type *other) const
{
- if (other && other->asUndefinedType() != 0)
+ if (other && other->asUndefinedType() != nullptr)
return true;
return false;
}
bool UndefinedType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asUndefinedType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asUndefinedType() != nullptr);
return false;
}
bool VoidType::isEqualTo(const Type *other) const
{
- if (other && other->asVoidType() != 0)
+ if (other && other->asVoidType() != nullptr)
return true;
return false;
}
bool VoidType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asVoidType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asVoidType() != nullptr);
return false;
}
bool BoolType::isEqualTo(const Type *other) const
{
- if (other && other->asBoolType() != 0)
+ if (other && other->asBoolType() != nullptr)
return true;
return false;
}
bool BoolType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asBoolType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asBoolType() != nullptr);
return false;
}
bool IntType::isEqualTo(const Type *other) const
{
- if (other && other->asIntType() != 0)
+ if (other && other->asIntType() != nullptr)
return true;
return false;
}
bool IntType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asIntType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asIntType() != nullptr);
return false;
}
bool UIntType::isEqualTo(const Type *other) const
{
- if (other && other->asUIntType() != 0)
+ if (other && other->asUIntType() != nullptr)
return true;
return false;
}
bool UIntType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asUIntType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asUIntType() != nullptr);
return false;
}
bool FloatType::isEqualTo(const Type *other) const
{
- if (other && other->asFloatType() != 0)
+ if (other && other->asFloatType() != nullptr)
return true;
return false;
}
bool FloatType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asFloatType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asFloatType() != nullptr);
return false;
}
bool DoubleType::isEqualTo(const Type *other) const
{
- if (other && other->asDoubleType() != 0)
+ if (other && other->asDoubleType() != nullptr)
return true;
return false;
}
bool DoubleType::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
- Q_ASSERT(other != 0);
- Q_ASSERT(other->asDoubleType() != 0);
+ Q_UNUSED(other)
+ Q_ASSERT(other != nullptr);
+ Q_ASSERT(other->asDoubleType() != nullptr);
return false;
}
QString VectorType::toString() const
{
const char *prefix = "";
- if (elementType()->asBoolType() != 0)
+ if (elementType()->asBoolType() != nullptr)
prefix = "b";
- else if (elementType()->asIntType() != 0)
+ else if (elementType()->asIntType() != nullptr)
prefix = "i'";
- else if (elementType()->asUIntType() != 0)
+ else if (elementType()->asUIntType() != nullptr)
prefix = "u";
- else if (elementType()->asDoubleType() != 0)
+ else if (elementType()->asDoubleType() != nullptr)
prefix = "d";
return QString::fromLatin1("%1vec%2").arg(QLatin1String(prefix)).arg(_dimension);
}
@@ -249,9 +249,9 @@ bool VectorType::isEqualTo(const Type *other) const
bool VectorType::isLessThan(const Type *other) const
{
- Q_ASSERT(other != 0);
+ Q_ASSERT(other != nullptr);
const VectorType *vec = other->asVectorType();
- Q_ASSERT(vec != 0);
+ Q_ASSERT(vec != nullptr);
if (_dimension < vec->dimension())
return true;
else if (_dimension == vec->dimension() && elementType() < vec->elementType())
@@ -262,13 +262,13 @@ bool VectorType::isLessThan(const Type *other) const
QString MatrixType::toString() const
{
const char *prefix = "";
- if (elementType()->asBoolType() != 0)
+ if (elementType()->asBoolType() != nullptr)
prefix = "b";
- else if (elementType()->asIntType() != 0)
+ else if (elementType()->asIntType() != nullptr)
prefix = "i";
- else if (elementType()->asUIntType() != 0)
+ else if (elementType()->asUIntType() != nullptr)
prefix = "u";
- else if (elementType()->asDoubleType() != 0)
+ else if (elementType()->asDoubleType() != nullptr)
prefix = "d";
return QString::fromLatin1("%1mat%2x%3").arg(QLatin1String(prefix)).arg(_columns).arg(_rows);
}
@@ -291,9 +291,9 @@ bool MatrixType::isEqualTo(const Type *other) const
bool MatrixType::isLessThan(const Type *other) const
{
- Q_ASSERT(other != 0);
+ Q_ASSERT(other != nullptr);
const MatrixType *mat = other->asMatrixType();
- Q_ASSERT(mat != 0);
+ Q_ASSERT(mat != nullptr);
if (_columns < mat->columns()) {
return true;
} else if (_columns == mat->columns()) {
@@ -321,9 +321,9 @@ bool ArrayType::isEqualTo(const Type *other) const
bool ArrayType::isLessThan(const Type *other) const
{
- Q_ASSERT(other != 0);
+ Q_ASSERT(other != nullptr);
const ArrayType *array = other->asArrayType();
- Q_ASSERT(array != 0);
+ Q_ASSERT(array != nullptr);
return elementType() < array->elementType();
}
@@ -348,18 +348,18 @@ Symbol *Struct::find(const QString &name) const
if (s->name() == name)
return s;
}
- return 0;
+ return nullptr;
}
bool Struct::isEqualTo(const Type *other) const
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
bool Struct::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
@@ -420,13 +420,13 @@ Argument *Function::argumentAt(int index) const
bool Function::isEqualTo(const Type *other) const
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
bool Function::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
@@ -446,7 +446,7 @@ Symbol *Function::find(const QString &name) const
if (arg->name() == name)
return arg;
}
- return 0;
+ return nullptr;
}
QString SamplerType::toString() const
@@ -465,9 +465,9 @@ bool SamplerType::isEqualTo(const Type *other) const
bool SamplerType::isLessThan(const Type *other) const
{
- Q_ASSERT(other != 0);
+ Q_ASSERT(other != nullptr);
const SamplerType *samp = other->asSamplerType();
- Q_ASSERT(samp != 0);
+ Q_ASSERT(samp != nullptr);
return _kind < samp->kind();
}
@@ -493,7 +493,7 @@ const Type *OverloadSet::type() const
Symbol *OverloadSet::find(const QString &) const
{
- return 0;
+ return nullptr;
}
void OverloadSet::add(Symbol *symbol)
@@ -506,12 +506,12 @@ void OverloadSet::add(Symbol *symbol)
bool OverloadSet::isEqualTo(const Type *other) const
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
bool OverloadSet::isLessThan(const Type *other) const
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
diff --git a/src/libs/glsl/glsltypes.h b/src/libs/glsl/glsltypes.h
index 93acb91e8e..d55d91fa16 100644
--- a/src/libs/glsl/glsltypes.h
+++ b/src/libs/glsl/glsltypes.h
@@ -186,7 +186,7 @@ public:
class GLSL_EXPORT Struct: public Type, public Scope
{
public:
- Struct(Scope *scope = 0)
+ Struct(Scope *scope = nullptr)
: Scope(scope) {}
QList<Symbol *> members() const override;
@@ -210,7 +210,7 @@ private:
class GLSL_EXPORT Function: public Type, public Scope
{
public:
- Function(Scope *scope = 0)
+ Function(Scope *scope = nullptr)
: Scope(scope) {}
const Type *returnType() const;
@@ -267,7 +267,7 @@ private:
class GLSL_EXPORT OverloadSet: public Type, public Scope
{
public:
- OverloadSet(Scope *enclosingScope = 0);
+ OverloadSet(Scope *enclosingScope = nullptr);
QVector<Function *> functions() const;
void addFunction(Function *function);
diff --git a/src/libs/languageserverprotocol/clientcapabilities.cpp b/src/libs/languageserverprotocol/clientcapabilities.cpp
index f73c4ee04c..1f79ffae0d 100644
--- a/src/libs/languageserverprotocol/clientcapabilities.cpp
+++ b/src/libs/languageserverprotocol/clientcapabilities.cpp
@@ -76,23 +76,24 @@ bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStrin
bool TextDocumentClientCapabilities::isValid(QStringList *error) const
{
return checkOptional<SynchronizationCapabilities>(error, synchronizationKey)
- && checkOptional<CompletionCapabilities>(error, completionKey)
- && checkOptional<HoverCapabilities>(error, hoverKey)
- && checkOptional<SignatureHelpCapabilities>(error, signatureHelpKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, referencesKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, documentHighlightKey)
- && checkOptional<SymbolCapabilities>(error, documentSymbolKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, formattingKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, rangeFormattingKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, onTypeFormattingKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, definitionKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, typeDefinitionKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, implementationKey)
- && checkOptional<CodeActionCapabilities>(error, codeActionKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, codeLensKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, documentLinkKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, colorProviderKey)
- && checkOptional<DynamicRegistrationCapabilities>(error, renameKey);
+ && checkOptional<CompletionCapabilities>(error, completionKey)
+ && checkOptional<HoverCapabilities>(error, hoverKey)
+ && checkOptional<SignatureHelpCapabilities>(error, signatureHelpKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, referencesKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, documentHighlightKey)
+ && checkOptional<SymbolCapabilities>(error, documentSymbolKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, formattingKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, rangeFormattingKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, onTypeFormattingKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, definitionKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, typeDefinitionKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, implementationKey)
+ && checkOptional<CodeActionCapabilities>(error, codeActionKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, codeLensKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, documentLinkKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, colorProviderKey)
+ && checkOptional<DynamicRegistrationCapabilities>(error, renameKey)
+ && checkOptional<SemanticHighlightingCapabilities>(error, semanticHighlightingCapabilitiesKey);
}
bool SymbolCapabilities::isValid(QStringList *error) const
diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h
index 3664007dd1..ec1bdd25b5 100644
--- a/src/libs/languageserverprotocol/clientcapabilities.h
+++ b/src/libs/languageserverprotocol/clientcapabilities.h
@@ -120,6 +120,26 @@ public:
{ insert(synchronizationKey, synchronization); }
void clearSynchronization() { remove(synchronizationKey); }
+ class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingCapabilities : public JsonObject
+ {
+ public:
+ using JsonObject::JsonObject;
+
+ bool semanticHighlighting() const { return typedValue<bool>(semanticHighlightingKey); }
+ void setSemanticHighlighting(bool semanticHighlighting)
+ { insert(semanticHighlightingKey, semanticHighlighting); }
+
+ bool isValid(QStringList *error) const override
+ { return check<bool>(error, semanticHighlightingKey); }
+ };
+
+ Utils::optional<SemanticHighlightingCapabilities> semanticHighlightingCapabilities() const
+ { return optionalValue<SemanticHighlightingCapabilities>(semanticHighlightingCapabilitiesKey); }
+ void setSemanticHighlightingCapabilities(
+ const SemanticHighlightingCapabilities &semanticHighlightingCapabilities)
+ { insert(semanticHighlightingCapabilitiesKey, semanticHighlightingCapabilities); }
+ void clearSemanticHighlightingCapabilities() { remove(semanticHighlightingCapabilitiesKey); }
+
class LANGUAGESERVERPROTOCOL_EXPORT CompletionCapabilities : public DynamicRegistrationCapabilities
{
public:
diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h
index 7e1ea3720b..cccf0789b9 100644
--- a/src/libs/languageserverprotocol/jsonkeys.h
+++ b/src/libs/languageserverprotocol/jsonkeys.h
@@ -130,6 +130,7 @@ constexpr char labelKey[] = "label";
constexpr char languageIdKey[] = "languageId";
constexpr char languageKey[] = "language";
constexpr char lineKey[] = "line";
+constexpr char linesKey[] = "lines";
constexpr char locationKey[] = "location";
constexpr char messageKey[] = "message";
constexpr char methodKey[] = "method";
@@ -167,8 +168,11 @@ constexpr char rootUriKey[] = "rootUri";
constexpr char saveKey[] = "save";
constexpr char schemeKey[] = "scheme";
constexpr char scopeUriKey[] = "scopeUri";
+constexpr char scopesKey[] = "scopes";
constexpr char sectionKey[] = "section";
constexpr char selectionRangeKey[] = "selectionRange";
+constexpr char semanticHighlightingKey[] = "semanticHighlighting";
+constexpr char semanticHighlightingCapabilitiesKey[] = "semanticHighlightingCapabilities";
constexpr char settingsKey[] = "settings";
constexpr char severityKey[] = "severity";
constexpr char signatureHelpKey[] = "signatureHelp";
@@ -191,6 +195,7 @@ constexpr char textDocumentSyncKey[] = "textDocumentSync";
constexpr char textEditKey[] = "textEdit";
constexpr char textKey[] = "text";
constexpr char titleKey[] = "title";
+constexpr char tokensKey[] = "tokens";
constexpr char traceKey[] = "trace";
constexpr char triggerCharacterKey[] = "triggerCharacter";
constexpr char triggerCharactersKey[] = "triggerCharacters";
diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp
index cfb4cc6fab..f66b6b7e16 100644
--- a/src/libs/languageserverprotocol/languagefeatures.cpp
+++ b/src/libs/languageserverprotocol/languagefeatures.cpp
@@ -48,6 +48,7 @@ constexpr const char DocumentRangeFormattingRequest::methodName[];
constexpr const char DocumentOnTypeFormattingRequest::methodName[];
constexpr const char RenameRequest::methodName[];
constexpr const char SignatureHelpRequest::methodName[];
+constexpr const char SemanticHighlightNotification::methodName[];
HoverContent LanguageServerProtocol::Hover::content() const
{
@@ -441,4 +442,59 @@ bool CodeAction::isValid(QStringList *error) const
&& checkOptional<Command>(error, commandKey);
}
+Utils::optional<QList<SemanticHighlightToken>> SemanticHighlightingInformation::tokens() const
+{
+ QList<SemanticHighlightToken> resultTokens;
+
+ const QByteArray tokensByteArray = QByteArray::fromBase64(
+ typedValue<QString>(tokensKey).toLocal8Bit());
+ constexpr int tokensByteSize = 8;
+ int index = 0;
+ while (index + tokensByteSize <= tokensByteArray.size()) {
+ resultTokens << SemanticHighlightToken(tokensByteArray.mid(index, tokensByteSize));
+ index += tokensByteSize;
+ }
+ return Utils::make_optional(resultTokens);
+}
+
+void SemanticHighlightingInformation::setTokens(const QList<SemanticHighlightToken> &tokens)
+{
+ QByteArray byteArray;
+ byteArray.reserve(8 * tokens.size());
+ for (const SemanticHighlightToken &token : tokens)
+ token.appendToByteArray(byteArray);
+ insert(tokensKey, QString::fromLocal8Bit(byteArray.toBase64()));
+}
+
+SemanticHighlightToken::SemanticHighlightToken(const QByteArray &token)
+{
+ QTC_ASSERT(token.size() == 8, return );
+ character = ( quint32(token.at(0)) << 24
+ | quint32(token.at(1)) << 16
+ | quint32(token.at(2)) << 8
+ | quint32(token.at(3)));
+
+ length = quint16(token.at(4) << 8 | token.at(5));
+
+ scope = quint16(token.at(6) << 8 | token.at(7));
+}
+
+void SemanticHighlightToken::appendToByteArray(QByteArray &byteArray) const
+{
+ byteArray.append(char((character & 0xff000000) >> 24));
+ byteArray.append(char((character & 0x00ff0000) >> 16));
+ byteArray.append(char((character & 0x0000ff00) >> 8));
+ byteArray.append(char((character & 0x000000ff)));
+ byteArray.append(char((length & 0xff00) >> 8));
+ byteArray.append(char((length & 0x00ff)));
+ byteArray.append(char((scope & 0xff00) >> 8));
+ byteArray.append(char((scope & 0x00ff)));
+}
+
+bool SemanticHighlightingParams::isValid(QStringList *error) const
+{
+ return check<VersionedTextDocumentIdentifier>(error, textDocumentKey)
+ && checkArray<SemanticHighlightingInformation>(error, linesKey);
+}
+
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h
index ddd732718a..bb98d7f8bd 100644
--- a/src/libs/languageserverprotocol/languagefeatures.h
+++ b/src/libs/languageserverprotocol/languagefeatures.h
@@ -806,4 +806,60 @@ public:
constexpr static const char methodName[] = "textDocument/rename";
};
+class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightToken
+{
+public:
+ // Just accepts token with 8 bytes
+ SemanticHighlightToken(const QByteArray &token);
+ SemanticHighlightToken() = default;
+
+ void appendToByteArray(QByteArray &byteArray) const;
+
+ quint32 character = 0;
+ quint16 length = 0;
+ quint16 scope = 0;
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingInformation : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+
+ int line() const { return typedValue<int>(lineKey); }
+ void setLine(int line) { insert(lineKey, line); }
+
+ Utils::optional<QList<SemanticHighlightToken>> tokens() const;
+ void setTokens(const QList<SemanticHighlightToken> &tokens);
+ void clearTokens() { remove(tokensKey); }
+
+ bool isValid(QStringList *error) const override
+ { return check<int>(error, lineKey) && checkOptional<QString>(error, tokensKey); }
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingParams : public JsonObject
+{
+public:
+ using JsonObject::JsonObject;
+
+ VersionedTextDocumentIdentifier textDocument() const
+ { return typedValue<VersionedTextDocumentIdentifier>(textDocumentKey); }
+ void setTextDocument(const VersionedTextDocumentIdentifier &textDocument)
+ { insert(textDocumentKey, textDocument); }
+
+ QList<SemanticHighlightingInformation> lines() const
+ { return array<SemanticHighlightingInformation>(linesKey); }
+ void setLines(const QList<SemanticHighlightingInformation> &lines)
+ { insertArray(linesKey, lines); }
+
+ bool isValid(QStringList *error) const override;
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification
+ : public Notification<SemanticHighlightingParams>
+{
+public:
+ using Notification::Notification;
+ constexpr static const char methodName[] = "textDocument/semanticHighlighting";
+};
+
} // namespace LanguageClient
diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp
index 8aa1ecf81c..6b8bc0f749 100644
--- a/src/libs/languageserverprotocol/lsptypes.cpp
+++ b/src/libs/languageserverprotocol/lsptypes.cpp
@@ -96,7 +96,7 @@ void WorkspaceEdit::setChanges(const Changes &changes)
QJsonArray edits;
for (const TextEdit &edit : it.value())
edits.append(QJsonValue(edit));
- changesObject.insert(it.key().toFileName().toString(), edits);
+ changesObject.insert(it.key().toFilePath().toString(), edits);
}
insert(changesKey, changesObject);
}
@@ -410,7 +410,7 @@ DocumentUri::DocumentUri(const Utils::FilePath &other)
: QUrl(QUrl::fromLocalFile(other.toString()))
{ }
-Utils::FilePath DocumentUri::toFileName() const
+Utils::FilePath DocumentUri::toFilePath() const
{
return isLocalFile() ? Utils::FilePath::fromUserInput(QUrl(*this).toLocalFile())
: Utils::FilePath();
diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h
index ade3ac7ccf..fca410636d 100644
--- a/src/libs/languageserverprotocol/lsptypes.h
+++ b/src/libs/languageserverprotocol/lsptypes.h
@@ -45,10 +45,10 @@ class LANGUAGESERVERPROTOCOL_EXPORT DocumentUri : public QUrl
{
public:
DocumentUri() = default;
- Utils::FilePath toFileName() const;
+ Utils::FilePath toFilePath() const;
static DocumentUri fromProtocol(const QString &uri) { return DocumentUri(uri); }
- static DocumentUri fromFileName(const Utils::FilePath &file) { return DocumentUri(file); }
+ static DocumentUri fromFilePath(const Utils::FilePath &file) { return DocumentUri(file); }
operator QJsonValue() const { return QJsonValue(toString()); }
diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp
index 1b2c0bd9cc..a8e932ad50 100644
--- a/src/libs/languageserverprotocol/servercapabilities.cpp
+++ b/src/libs/languageserverprotocol/servercapabilities.cpp
@@ -170,7 +170,8 @@ bool ServerCapabilities::isValid(QStringList *error) const
&& checkOptional<DocumentLinkOptions>(error, documentLinkProviderKey)
&& checkOptional<bool, JsonObject>(error, colorProviderKey)
&& checkOptional<ExecuteCommandOptions>(error, executeCommandProviderKey)
- && checkOptional<WorkspaceServerCapabilities>(error, workspaceKey);
+ && checkOptional<WorkspaceServerCapabilities>(error, workspaceKey)
+ && checkOptional<SemanticHighlightingServerCapabilities>(error, semanticHighlightingKey);
}
Utils::optional<Utils::variant<QString, bool> >
@@ -219,4 +220,44 @@ bool TextDocumentSyncOptions::isValid(QStringList *error) const
&& checkOptional<SaveOptions>(error, saveKey);
}
+Utils::optional<QList<QList<QString>>> ServerCapabilities::SemanticHighlightingServerCapabilities::scopes() const
+{
+ QList<QList<QString>> scopes;
+ if (!contains(scopesKey))
+ return Utils::nullopt;
+ for (const QJsonValue jsonScopeValue : value(scopesKey).toArray()) {
+ if (!jsonScopeValue.isArray())
+ return {};
+ QList<QString> scope;
+ for (const QJsonValue value : jsonScopeValue.toArray()) {
+ if (!value.isString())
+ return {};
+ scope.append(value.toString());
+ }
+ scopes.append(scope);
+ }
+ return Utils::make_optional(scopes);
+}
+
+void ServerCapabilities::SemanticHighlightingServerCapabilities::setScopes(
+ const QList<QList<QString>> &scopes)
+{
+ QJsonArray jsonScopes;
+ for (const QList<QString> &scope : scopes) {
+ QJsonArray jsonScope;
+ for (const QString &value : scope)
+ jsonScope.append(value);
+ jsonScopes.append(jsonScope);
+ }
+ insert(scopesKey, jsonScopes);
+}
+
+bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(QStringList *) const
+{
+ return contains(scopesKey) && value(scopesKey).isArray()
+ && Utils::allOf(value(scopesKey).toArray(), [](const QJsonValue &array) {
+ return array.isArray() && Utils::allOf(array.toArray(), &QJsonValue::isString);
+ });
+}
+
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h
index 4c8011378f..7365449b0f 100644
--- a/src/libs/languageserverprotocol/servercapabilities.h
+++ b/src/libs/languageserverprotocol/servercapabilities.h
@@ -223,6 +223,17 @@ public:
void clearId() { remove(idKey); }
};
+ class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightingServerCapabilities : public JsonObject
+ {
+ public:
+ using JsonObject::JsonObject;
+
+ Utils::optional<QList<QList<QString>>> scopes() const;
+ void setScopes(const QList<QList<QString>> &scopes);
+
+ bool isValid(QStringList *) const override;
+ };
+
// Defines how text documents are synced. Is either a detailed structure defining each
// notification or for backwards compatibility the TextDocumentSyncKind number.
using TextDocumentSync = Utils::variant<TextDocumentSyncOptions, int>;
@@ -423,6 +434,12 @@ public:
void setExperimental(const JsonObject &experimental) { insert(experimentalKey, experimental); }
void clearExperimental() { remove(experimentalKey); }
+ Utils::optional<SemanticHighlightingServerCapabilities> semanticHighlighting() const
+ { return optionalValue<SemanticHighlightingServerCapabilities>(semanticHighlightingKey); }
+ void setSemanticHighlighting(const SemanticHighlightingServerCapabilities &semanticHighlighting)
+ { insert(semanticHighlightingKey, semanticHighlighting); }
+ void clearSemanticHighlighting() { remove(semanticHighlightingKey); }
+
bool isValid(QStringList *error) const override;
};
diff --git a/src/libs/libs.pro b/src/libs/libs.pro
index cbd788ced0..550a6b0b97 100644
--- a/src/libs/libs.pro
+++ b/src/libs/libs.pro
@@ -33,6 +33,9 @@ for(l, SUBDIRS) {
SUBDIRS += \
utils/process_stub.pro
+include(../shared/yaml-cpp/yaml-cpp_installation.pri)
+isEmpty(EXTERNAL_YAML_CPP_FOUND): SUBDIRS += 3rdparty/yaml-cpp
+
isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR): KSYNTAXHIGHLIGHTING_LIB_DIR=$$(KSYNTAXHIGHLIGHTING_LIB_DIR)
!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
# enable short information message
diff --git a/src/libs/libs.qbs b/src/libs/libs.qbs
index 1c4275f6f1..84fc626501 100644
--- a/src/libs/libs.qbs
+++ b/src/libs/libs.qbs
@@ -22,5 +22,6 @@ Project {
"utils/process_ctrlc_stub.qbs",
"utils/utils.qbs",
"3rdparty/syntax-highlighting/syntax-highlighting.qbs",
+ "3rdparty/yaml-cpp/yaml-cpp.qbs",
].concat(project.additionalLibs)
}
diff --git a/src/libs/modelinglib/qmt/config/textscanner.cpp b/src/libs/modelinglib/qmt/config/textscanner.cpp
index d9652e346c..23173789c5 100644
--- a/src/libs/modelinglib/qmt/config/textscanner.cpp
+++ b/src/libs/modelinglib/qmt/config/textscanner.cpp
@@ -296,7 +296,7 @@ Token TextScanner::scanOperator(const SourceChar &firstChar)
unreadChar(extraChars.pop());
}
QMT_CHECK(haveOperator);
- Q_UNUSED(haveOperator); // avoid warning in release mode
+ Q_UNUSED(haveOperator) // avoid warning in release mode
return Token(Token::TokenOperator, subtype, op, firstChar.pos);
}
text += sourceChar.ch;
diff --git a/src/libs/modelinglib/qmt/controller/undocommand.cpp b/src/libs/modelinglib/qmt/controller/undocommand.cpp
index 40348d3f86..130f201e03 100644
--- a/src/libs/modelinglib/qmt/controller/undocommand.cpp
+++ b/src/libs/modelinglib/qmt/controller/undocommand.cpp
@@ -58,7 +58,7 @@ bool UndoCommand::mergeWith(const QUndoCommand *other)
bool UndoCommand::mergeWith(const UndoCommand *other)
{
- Q_UNUSED(other);
+ Q_UNUSED(other)
return false;
}
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
index d882c81eef..805e96eafd 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dclonevisitor.cpp
@@ -50,7 +50,7 @@ DCloneVisitor::DCloneVisitor()
void DCloneVisitor::visitDElement(const DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(m_cloned);
}
@@ -158,7 +158,7 @@ DCloneDeepVisitor::DCloneDeepVisitor()
void DCloneDeepVisitor::visitDElement(const DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(m_cloned);
}
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp b/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
index e87fb8ce5e..1d6a770b77 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dfactory.cpp
@@ -59,7 +59,7 @@ DFactory::DFactory()
void DFactory::visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(m_product);
}
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp
index 20531bb85c..baf7adea65 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dflatassignmentvisitor.cpp
@@ -54,7 +54,7 @@ DFlatAssignmentVisitor::DFlatAssignmentVisitor(DElement *target)
void DFlatAssignmentVisitor::visitDElement(const DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void DFlatAssignmentVisitor::visitDObject(const DObject *object)
diff --git a/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp b/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp
index aa8ad153b1..f7d7e702e5 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/diagramcontroller.cpp
@@ -576,8 +576,8 @@ void DiagramController::onEndResetModel()
void DiagramController::onBeginUpdateObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
// nothing to do
}
@@ -608,8 +608,8 @@ void DiagramController::onEndUpdateObject(int row, const MObject *parent)
void DiagramController::onBeginInsertObject(int row, const MObject *owner)
{
- Q_UNUSED(row);
- Q_UNUSED(owner);
+ Q_UNUSED(row)
+ Q_UNUSED(owner)
}
void DiagramController::onEndInsertObject(int row, const MObject *owner)
@@ -634,14 +634,14 @@ void DiagramController::onBeginRemoveObject(int row, const MObject *parent)
void DiagramController::onEndRemoveObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void DiagramController::onBeginMoveObject(int formerRow, const MObject *formerOwner)
{
- Q_UNUSED(formerRow);
- Q_UNUSED(formerOwner);
+ Q_UNUSED(formerRow)
+ Q_UNUSED(formerOwner)
}
void DiagramController::onEndMoveObject(int row, const MObject *owner)
@@ -663,8 +663,8 @@ void DiagramController::onEndMoveObject(int row, const MObject *owner)
void DiagramController::onBeginUpdateRelation(int row, const MObject *owner)
{
- Q_UNUSED(row);
- Q_UNUSED(owner);
+ Q_UNUSED(row)
+ Q_UNUSED(owner)
// nothing to do
}
@@ -691,14 +691,14 @@ void DiagramController::onBeginRemoveRelation(int row, const MObject *owner)
void DiagramController::onEndRemoveRelation(int row, const MObject *owner)
{
- Q_UNUSED(row);
- Q_UNUSED(owner);
+ Q_UNUSED(row)
+ Q_UNUSED(owner)
}
void DiagramController::onBeginMoveRelation(int formerRow, const MObject *formerOwner)
{
- Q_UNUSED(formerRow);
- Q_UNUSED(formerOwner);
+ Q_UNUSED(formerRow)
+ Q_UNUSED(formerOwner)
// nothing to do
}
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
index 6b3695f1ba..cc1ffa681a 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dupdatevisitor.cpp
@@ -65,7 +65,7 @@ void DUpdateVisitor::setCheckNeedsUpdate(bool checkNeedsUpdate)
void DUpdateVisitor::visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(m_target);
}
diff --git a/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp b/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
index 56fdfe2cb4..f182eb993d 100644
--- a/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
+++ b/src/libs/modelinglib/qmt/diagram_controller/dvoidvisitor.cpp
@@ -49,7 +49,7 @@ DVoidVisitor::DVoidVisitor()
void DVoidVisitor::visitDElement(DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void DVoidVisitor::visitDObject(DObject *object)
@@ -128,7 +128,7 @@ DConstVoidVisitor::DConstVoidVisitor()
void DConstVoidVisitor::visitDElement(const DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void DConstVoidVisitor::visitDObject(const DObject *object)
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp
index 36c8ae07d4..82fba740a1 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodel.cpp
@@ -85,8 +85,8 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
QPen pen(QBrush(Qt::gray), 1.0, Qt::DotLine);
painter->setPen(pen);
@@ -539,7 +539,7 @@ void DiagramSceneModel::selectItem(QGraphicsItem *item, bool multiSelect)
void DiagramSceneModel::moveSelectedItems(QGraphicsItem *grabbedItem, const QPointF &delta)
{
- Q_UNUSED(grabbedItem);
+ Q_UNUSED(grabbedItem)
if (delta != QPointF(0.0, 0.0)) {
foreach (QGraphicsItem *item, m_selectedItems) {
@@ -754,8 +754,8 @@ void DiagramSceneModel::onEndResetDiagram(const MDiagram *diagram)
void DiagramSceneModel::onBeginUpdateElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
QMT_CHECK(m_busyState == NotBusy);
m_busyState = UpdateElement;
@@ -775,8 +775,8 @@ void DiagramSceneModel::onEndUpdateElement(int row, const MDiagram *diagram)
void DiagramSceneModel::onBeginInsertElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
QMT_CHECK(m_busyState == NotBusy);
m_busyState = InsertElement;
}
@@ -825,8 +825,8 @@ void DiagramSceneModel::onBeginRemoveElement(int row, const MDiagram *diagram)
void DiagramSceneModel::onEndRemoveElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
QMT_CHECK(m_busyState == RemoveElement);
// update elements from store (see above)
for (const Uid &end_uid : m_relationEndsUid) {
diff --git a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp
index 2a0a557190..91633b18bb 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/diagramscenemodelitemvisitors.cpp
@@ -63,13 +63,13 @@ DiagramSceneModel::CreationVisitor::CreationVisitor(DiagramSceneModel *diagramSc
void DiagramSceneModel::CreationVisitor::visitDElement(DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(false);
}
void DiagramSceneModel::CreationVisitor::visitDObject(DObject *object)
{
- Q_UNUSED(object);
+ Q_UNUSED(object)
QMT_CHECK(false);
}
@@ -159,7 +159,7 @@ DiagramSceneModel::UpdateVisitor::UpdateVisitor(QGraphicsItem *item, DiagramScen
void DiagramSceneModel::UpdateVisitor::visitDElement(DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(false);
}
@@ -284,7 +284,7 @@ void DiagramSceneModel::UpdateVisitor::visitDConnection(DConnection *connection)
void DiagramSceneModel::UpdateVisitor::visitDAnnotation(DAnnotation *annotation)
{
- Q_UNUSED(annotation); // avoid warning in release mode
+ Q_UNUSED(annotation) // avoid warning in release mode
QMT_ASSERT(m_graphicsItem, return);
AnnotationItem *annotationItem = qgraphicsitem_cast<AnnotationItem *>(m_graphicsItem);
@@ -295,7 +295,7 @@ void DiagramSceneModel::UpdateVisitor::visitDAnnotation(DAnnotation *annotation)
void DiagramSceneModel::UpdateVisitor::visitDBoundary(DBoundary *boundary)
{
- Q_UNUSED(boundary); // avoid warning in release mode
+ Q_UNUSED(boundary) // avoid warning in release mode
QMT_ASSERT(m_graphicsItem, return);
BoundaryItem *boundaryItem = qgraphicsitem_cast<BoundaryItem *>(m_graphicsItem);
@@ -306,7 +306,7 @@ void DiagramSceneModel::UpdateVisitor::visitDBoundary(DBoundary *boundary)
void DiagramSceneModel::UpdateVisitor::visitDSwimlane(DSwimlane *swimlane)
{
- Q_UNUSED(swimlane); // avoid warning in release mode
+ Q_UNUSED(swimlane) // avoid warning in release mode
QMT_ASSERT(m_graphicsItem, return);
SwimlaneItem *swimlaneItem = qgraphicsitem_cast<SwimlaneItem *>(m_graphicsItem);
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp
index 6169f4cad8..6759378b3c 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/annotationitem.cpp
@@ -87,9 +87,9 @@ QRectF AnnotationItem::boundingRect() const
void AnnotationItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
void AnnotationItem::update()
@@ -161,10 +161,10 @@ void AnnotationItem::setPosAndRect(const QPointF &originalPos, const QRectF &ori
void AnnotationItem::alignItemSizeToRaster(Side adjustHorizontalSide, Side adjustVerticalSide,
double rasterWidth, double rasterHeight)
{
- Q_UNUSED(adjustHorizontalSide);
- Q_UNUSED(adjustVerticalSide);
- Q_UNUSED(rasterWidth);
- Q_UNUSED(rasterHeight);
+ Q_UNUSED(adjustHorizontalSide)
+ Q_UNUSED(adjustVerticalSide)
+ Q_UNUSED(rasterWidth)
+ Q_UNUSED(rasterHeight)
}
void AnnotationItem::moveDelta(const QPointF &delta)
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp
index 1aee12d465..109819a569 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/associationitem.cpp
@@ -75,7 +75,7 @@ void AssociationItem::updateEndLabels(const DAssociationEnd &end, const DAssocia
QGraphicsSimpleTextItem **endName, QGraphicsSimpleTextItem **endCardinality,
const Style *style)
{
- Q_UNUSED(end);
+ Q_UNUSED(end)
if (!otherEnd.name().isEmpty()) {
if (!*endName)
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp
index e437f4c3ec..cb5aab1a6a 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/boundaryitem.cpp
@@ -89,9 +89,9 @@ QRectF BoundaryItem::boundingRect() const
void BoundaryItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
void BoundaryItem::update()
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp
index d8e3a37df5..e59865d1ba 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/connectionitem.cpp
@@ -75,7 +75,7 @@ void ConnectionItem::updateEndLabels(const DConnectionEnd &end, const DConnectio
QGraphicsSimpleTextItem **endName, QGraphicsSimpleTextItem **endCardinality,
const Style *style)
{
- Q_UNUSED(end);
+ Q_UNUSED(end)
if (!otherEnd.name().isEmpty()) {
if (!*endName)
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp
index a2e3a54df7..e3b50bab1b 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/itemitem.cpp
@@ -69,7 +69,7 @@ void ItemItem::update()
updateStereotypeIconDisplay();
auto diagramItem = dynamic_cast<DItem *>(object());
- Q_UNUSED(diagramItem); // avoid warning about unsed variable
+ Q_UNUSED(diagramItem) // avoid warning about unsed variable
QMT_ASSERT(diagramItem, return);
const Style *style = adaptedStyle(shapeIconId());
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp
index f00ed98b96..b68ed9a4f7 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/objectitem.cpp
@@ -83,9 +83,9 @@ QRectF ObjectItem::boundingRect() const
void ObjectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
QPointF ObjectItem::pos() const
@@ -273,7 +273,7 @@ ILatchable::Action ObjectItem::verticalLatchAction() const
QList<ILatchable::Latch> ObjectItem::horizontalLatches(ILatchable::Action action, bool grabbedItem) const
{
- Q_UNUSED(grabbedItem);
+ Q_UNUSED(grabbedItem)
QRectF rect = mapRectToScene(this->rect());
QList<ILatchable::Latch> result;
@@ -301,7 +301,7 @@ QList<ILatchable::Latch> ObjectItem::horizontalLatches(ILatchable::Action action
QList<ILatchable::Latch> ObjectItem::verticalLatches(ILatchable::Action action, bool grabbedItem) const
{
- Q_UNUSED(grabbedItem);
+ Q_UNUSED(grabbedItem)
QRectF rect = mapRectToScene(this->rect());
QList<ILatchable::Latch> result;
@@ -394,7 +394,7 @@ void ObjectItem::relationDrawn(const QString &id, ObjectItem *targetItem, const
void ObjectItem::align(IAlignable::AlignType alignType, const QString &identifier)
{
- Q_UNUSED(identifier); // avoid warning in release mode
+ Q_UNUSED(identifier) // avoid warning in release mode
// subclasses may support other identifiers than the standard ones.
// but this implementation does not. So assert the names.
@@ -541,7 +541,7 @@ void ObjectItem::updateStereotypes(const QString &stereotypeIconId, StereotypeIc
QSizeF ObjectItem::stereotypeIconMinimumSize(const StereotypeIcon &stereotypeIcon,
qreal minimumWidth, qreal minimumHeight) const
{
- Q_UNUSED(minimumWidth);
+ Q_UNUSED(minimumWidth)
qreal width = 0.0;
qreal height = 0.0;
@@ -946,14 +946,14 @@ bool ObjectItem::showContext() const
bool ObjectItem::extendContextMenu(QMenu *menu)
{
- Q_UNUSED(menu);
+ Q_UNUSED(menu)
return false;
}
bool ObjectItem::handleSelectedContextMenuAction(const QString &id)
{
- Q_UNUSED(id);
+ Q_UNUSED(id)
return false;
}
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp
index c383a21a32..b778441a70 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/relationitem.cpp
@@ -238,9 +238,9 @@ QRectF RelationItem::boundingRect() const
void RelationItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
#ifdef DEBUG_PAINT_SHAPE
painter->save();
@@ -518,12 +518,12 @@ void RelationItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
void RelationItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
}
void RelationItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
}
const Style *RelationItem::adaptedStyle()
diff --git a/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp
index 6d38cc71ef..bdc68476b3 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/items/swimlaneitem.cpp
@@ -68,9 +68,9 @@ QRectF SwimlaneItem::boundingRect() const
void SwimlaneItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
void SwimlaneItem::update()
@@ -81,7 +81,7 @@ void SwimlaneItem::update()
prepareGeometryChange();
const Style *style = adaptedStyle();
- Q_UNUSED(style);
+ Q_UNUSED(style)
// swimline line
if (!m_lineItem)
@@ -137,7 +137,7 @@ bool SwimlaneItem::isFocusSelected() const
void SwimlaneItem::setFocusSelected(bool focusSelected)
{
- Q_UNUSED(focusSelected);
+ Q_UNUSED(focusSelected)
}
QRectF SwimlaneItem::getSecondarySelectionBoundary()
diff --git a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp
index 0209fdf2a2..ff0da88abb 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/latchcontroller.cpp
@@ -75,7 +75,7 @@ void LatchController::addToGraphicsScene(QGraphicsScene *graphicsScene)
void LatchController::removeFromGraphicsScene(QGraphicsScene *graphicsScene)
{
- Q_UNUSED(graphicsScene); // avoid warning in release mode
+ Q_UNUSED(graphicsScene) // avoid warning in release mode
if (m_verticalAlignLine->scene()) {
QMT_CHECK(graphicsScene == m_verticalAlignLine->scene());
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp
index 6a68f5fdc7..d675db9ef6 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/alignbuttonsitem.cpp
@@ -54,8 +54,8 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
painter->save();
painter->setPen(pen());
@@ -66,7 +66,7 @@ public:
void mousePressEvent(QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
@@ -107,9 +107,9 @@ QRectF AlignButtonsItem::boundingRect() const
void AlignButtonsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
void AlignButtonsItem::clear()
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.cpp
index 998f23b079..835e959fa6 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/alignlineitem.cpp
@@ -77,9 +77,9 @@ QRectF AlignLineItem::boundingRect() const
void AlignLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp
index 93a4a10f19..6782723ce4 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/arrowitem.cpp
@@ -79,9 +79,9 @@ public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
#ifdef DEBUG_PAINT_SHAPE
painter->setPen(QPen(Qt::blue));
@@ -323,9 +323,9 @@ QRectF ArrowItem::boundingRect() const
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
#ifdef DEBUG_PAINT_SHAPE
painter->setPen(QPen(Qt::blue));
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.cpp
index 9f8c429cd5..374f1e786a 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/customiconitem.cpp
@@ -96,8 +96,8 @@ QRectF CustomIconItem::boundingRect() const
void CustomIconItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
painter->save();
painter->setBrush(m_brush);
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp
index 78fa4fff80..4b613c0465 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/pathselectionitem.cpp
@@ -157,9 +157,9 @@ QRectF PathSelectionItem::boundingRect() const
void PathSelectionItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
#ifdef DEBUG_PAINT_SHAPE
painter->save();
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp
index 64936fb773..6478e41f1e 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/rectangularselectionitem.cpp
@@ -111,9 +111,9 @@ QRectF RectangularSelectionItem::boundingRect() const
void RectangularSelectionItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(painter)
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
}
void RectangularSelectionItem::setRect(const QRectF &rectangle)
@@ -226,7 +226,7 @@ void RectangularSelectionItem::update()
void RectangularSelectionItem::moveHandle(Handle handle, const QPointF &deltaMove, HandleStatus handleStatus, HandleQualifier handleQualifier)
{
- Q_UNUSED(handleQualifier);
+ Q_UNUSED(handleQualifier)
switch (handleStatus) {
case Press:
diff --git a/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp b/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp
index 705f673ac5..ab07d7f2b3 100644
--- a/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp
+++ b/src/libs/modelinglib/qmt/diagram_scene/parts/relationstarter.cpp
@@ -59,8 +59,8 @@ QRectF RelationStarter::boundingRect() const
void RelationStarter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
painter->save();
painter->setPen(pen());
@@ -153,7 +153,7 @@ void RelationStarter::keyPressEvent(QKeyEvent *event)
void RelationStarter::focusOutEvent(QFocusEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
if (m_currentPreviewArrow) {
m_currentPreviewArrow->scene()->removeItem(m_currentPreviewArrow);
delete m_currentPreviewArrow;
diff --git a/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp b/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp
index 7592bc57db..62253e626c 100644
--- a/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp
+++ b/src/libs/modelinglib/qmt/diagram_widgets_ui/stackeddiagramsview.cpp
@@ -102,7 +102,7 @@ void StackedDiagramsView::onCurrentChanged(int tabIndex)
void StackedDiagramsView::onDiagramRenamed(const MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
// nothing to do!
}
diff --git a/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp b/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp
index 9968fbf0b8..5a42bf1f33 100644
--- a/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp
+++ b/src/libs/modelinglib/qmt/infrastructure/geometryutilities.cpp
@@ -58,7 +58,11 @@ bool GeometryUtilities::intersect(const QPolygonF &polygon, const QLineF &line,
{
for (int i = 0; i <= polygon.size() - 2; ++i) {
QLineF polygonLine(polygon.at(i), polygon.at(i+1));
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QLineF::IntersectType intersectionType = polygonLine.intersect(line, intersectionPoint);
+#else
+ QLineF::IntersectType intersectionType = polygonLine.intersects(line, intersectionPoint);
+#endif
if (intersectionType == QLineF::BoundedIntersection) {
if (intersectionLine)
*intersectionLine = polygonLine;
diff --git a/src/libs/modelinglib/qmt/model/melement.cpp b/src/libs/modelinglib/qmt/model/melement.cpp
index f73a56ad94..8ffb57d4a5 100644
--- a/src/libs/modelinglib/qmt/model/melement.cpp
+++ b/src/libs/modelinglib/qmt/model/melement.cpp
@@ -39,7 +39,7 @@ void MExpansion::assign(MElement *lhs, const MElement &rhs)
void MExpansion::destroy(MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
delete this;
}
diff --git a/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp
index f8ed8800f0..4542a5a3af 100644
--- a/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mchildrenvisitor.cpp
@@ -40,7 +40,7 @@ namespace qmt {
void MChildrenVisitor::visitMElement(MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void MChildrenVisitor::visitMObject(MObject *object)
diff --git a/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp
index a8d431a87e..a2a6e3392f 100644
--- a/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mclonevisitor.cpp
@@ -50,7 +50,7 @@ MCloneVisitor::MCloneVisitor()
void MCloneVisitor::visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(m_cloned);
}
@@ -149,7 +149,7 @@ MCloneDeepVisitor::MCloneDeepVisitor()
void MCloneDeepVisitor::visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(m_cloned);
}
diff --git a/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp b/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp
index 4e475ce3dd..329f6ed0c7 100644
--- a/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp
+++ b/src/libs/modelinglib/qmt/model_controller/mvoidvisitor.cpp
@@ -45,7 +45,7 @@ namespace qmt {
void MVoidVisitor::visitMElement(MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void MVoidVisitor::visitMObject(MObject *object)
@@ -110,7 +110,7 @@ void MVoidVisitor::visitMConnection(MConnection *connection)
void MVoidConstVisitor::visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void MVoidConstVisitor::visitMObject(const MObject *object)
diff --git a/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.cpp b/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.cpp
index 56a7524b66..6f47b26938 100644
--- a/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.cpp
+++ b/src/libs/modelinglib/qmt/model_ui/sortedtreemodel.cpp
@@ -79,9 +79,9 @@ bool SortedTreeModel::lessThan(const QModelIndex &left, const QModelIndex &right
void SortedTreeModel::onTreeModelRowsInserted(const QModelIndex &parent, int start, int end)
{
- Q_UNUSED(parent);
- Q_UNUSED(start);
- Q_UNUSED(end);
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
startDelayedSortTimer();
}
diff --git a/src/libs/modelinglib/qmt/model_ui/treemodel.cpp b/src/libs/modelinglib/qmt/model_ui/treemodel.cpp
index 18d1cb2c23..ce7bb0504e 100644
--- a/src/libs/modelinglib/qmt/model_ui/treemodel.cpp
+++ b/src/libs/modelinglib/qmt/model_ui/treemodel.cpp
@@ -80,13 +80,13 @@ public:
void visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(false);
}
void visitMObject(const MObject *object)
{
- Q_UNUSED(object);
+ Q_UNUSED(object)
QMT_ASSERT(m_item, return);
m_item->setEditable(false);
}
@@ -156,7 +156,7 @@ public:
void visitMRelation(const MRelation *relation)
{
- Q_UNUSED(relation);
+ Q_UNUSED(relation)
QMT_ASSERT(m_item, return);
m_item->setEditable(false);
m_item->setData(TreeModel::Relation, TreeModel::RoleItemType);
@@ -216,7 +216,7 @@ public:
void visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(false);
}
@@ -502,8 +502,8 @@ void TreeModel::onEndResetModel()
void TreeModel::onBeginUpdateObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
QMT_CHECK(m_busyState == NotBusy);
m_busyState = UpdateElement;
}
@@ -536,8 +536,8 @@ void TreeModel::onEndUpdateObject(int row, const MObject *parent)
void TreeModel::onBeginInsertObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
QMT_CHECK(m_busyState == NotBusy);
m_busyState = InsertElement;
}
@@ -569,8 +569,8 @@ void TreeModel::onBeginRemoveObject(int row, const MObject *parent)
void TreeModel::onEndRemoveObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
QMT_CHECK(m_busyState == RemoveElement);
m_busyState = NotBusy;
}
@@ -602,8 +602,8 @@ void TreeModel::onEndMoveObject(int row, const MObject *owner)
void TreeModel::onBeginUpdateRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
QMT_CHECK(m_busyState == NotBusy);
m_busyState = UpdateRelation;
}
@@ -637,8 +637,8 @@ void TreeModel::onEndUpdateRelation(int row, const MObject *parent)
void TreeModel::onBeginInsertRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
QMT_CHECK(m_busyState == NotBusy);
m_busyState = InsertRelation;
}
@@ -668,8 +668,8 @@ void TreeModel::onBeginRemoveRelation(int row, const MObject *parent)
void TreeModel::onEndRemoveRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
QMT_CHECK(m_busyState == RemoveRelation);
m_busyState = NotBusy;
}
@@ -699,7 +699,7 @@ void TreeModel::onEndMoveRelation(int row, const MObject *owner)
void TreeModel::onRelationEndChanged(MRelation *relation, MObject *endObject)
{
- Q_UNUSED(endObject);
+ Q_UNUSED(endObject)
QMT_CHECK(m_busyState == NotBusy);
MObject *parent = relation->owner();
@@ -725,8 +725,8 @@ void TreeModel::onRelationEndChanged(MRelation *relation, MObject *endObject)
void TreeModel::onModelDataChanged(const QModelIndex &topleft, const QModelIndex &bottomright)
{
- Q_UNUSED(topleft);
- Q_UNUSED(bottomright);
+ Q_UNUSED(topleft)
+ Q_UNUSED(bottomright)
// TODO fix editing object name in model tree
// item->text() no longer returns a simple object name
// classes contains namespace label
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
index 3bcc0727fb..b3cfc13a0b 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
@@ -108,7 +108,7 @@ void ModelTreeView::selectFromSourceModelIndex(const QModelIndex &index)
void ModelTreeView::startDrag(Qt::DropActions supportedActions)
{
- Q_UNUSED(supportedActions);
+ Q_UNUSED(supportedActions)
TreeModel *treeModel = m_sortedTreeModel->treeModel();
QMT_ASSERT(treeModel, return);
@@ -231,7 +231,7 @@ void ModelTreeView::dropEvent(QDropEvent *event)
void ModelTreeView::focusInEvent(QFocusEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
emit treeViewActivated();
}
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp
index 2f5f8d8487..109427b7c2 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/palettebox.cpp
@@ -92,7 +92,7 @@ void PaletteBox::setCurrentIndex(int index)
void PaletteBox::paintEvent(QPaintEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
QPainter painter(this);
qreal w = static_cast<qreal>(width()) / static_cast<qreal>(m_brushes.size());
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp
index 350803d168..a63a409494 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesview.cpp
@@ -209,8 +209,8 @@ void PropertiesView::onEndResetModel()
void PropertiesView::onBeginUpdateObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onEndUpdateObject(int row, const MObject *parent)
@@ -222,14 +222,14 @@ void PropertiesView::onEndUpdateObject(int row, const MObject *parent)
void PropertiesView::onBeginInsertObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onEndInsertObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onBeginRemoveObject(int row, const MObject *parent)
@@ -241,14 +241,14 @@ void PropertiesView::onBeginRemoveObject(int row, const MObject *parent)
void PropertiesView::onEndRemoveObject(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onBeginMoveObject(int formerRow, const MObject *formerOwner)
{
- Q_UNUSED(formerRow);
- Q_UNUSED(formerOwner);
+ Q_UNUSED(formerRow)
+ Q_UNUSED(formerOwner)
}
void PropertiesView::onEndMoveObject(int row, const MObject *owner)
@@ -260,8 +260,8 @@ void PropertiesView::onEndMoveObject(int row, const MObject *owner)
void PropertiesView::onBeginUpdateRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onEndUpdateRelation(int row, const MObject *parent)
@@ -273,14 +273,14 @@ void PropertiesView::onEndUpdateRelation(int row, const MObject *parent)
void PropertiesView::onBeginInsertRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onEndInsertRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onBeginRemoveRelation(int row, const MObject *parent)
@@ -292,14 +292,14 @@ void PropertiesView::onBeginRemoveRelation(int row, const MObject *parent)
void PropertiesView::onEndRemoveRelation(int row, const MObject *parent)
{
- Q_UNUSED(row);
- Q_UNUSED(parent);
+ Q_UNUSED(row)
+ Q_UNUSED(parent)
}
void PropertiesView::onBeginMoveRelation(int formerRow, const MObject *formerOwner)
{
- Q_UNUSED(formerRow);
- Q_UNUSED(formerOwner);
+ Q_UNUSED(formerRow)
+ Q_UNUSED(formerOwner)
}
void PropertiesView::onEndMoveRelation(int row, const MObject *owner)
@@ -311,7 +311,7 @@ void PropertiesView::onEndMoveRelation(int row, const MObject *owner)
void PropertiesView::onRelationEndChanged(MRelation *relation, MObject *endObject)
{
- Q_UNUSED(endObject);
+ Q_UNUSED(endObject)
if (relation && m_selectedModelElements.contains(relation))
m_mview->update(m_selectedModelElements);
}
@@ -327,7 +327,7 @@ void PropertiesView::onEndResetAllDiagrams()
void PropertiesView::onBeginResetDiagram(const MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
}
void PropertiesView::onEndResetDiagram(const MDiagram *diagram)
@@ -338,8 +338,8 @@ void PropertiesView::onEndResetDiagram(const MDiagram *diagram)
void PropertiesView::onBeginUpdateElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
}
void PropertiesView::onEndUpdateElement(int row, const MDiagram *diagram)
@@ -353,14 +353,14 @@ void PropertiesView::onEndUpdateElement(int row, const MDiagram *diagram)
void PropertiesView::onBeginInsertElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
}
void PropertiesView::onEndInsertElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
}
void PropertiesView::onBeginRemoveElement(int row, const MDiagram *diagram)
@@ -374,8 +374,8 @@ void PropertiesView::onBeginRemoveElement(int row, const MDiagram *diagram)
void PropertiesView::onEndRemoveElement(int row, const MDiagram *diagram)
{
- Q_UNUSED(row);
- Q_UNUSED(diagram);
+ Q_UNUSED(row)
+ Q_UNUSED(diagram)
}
void PropertiesView::beginUpdate(MElement *modelElement)
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
index c8b11d44e1..31c764c5ad 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
@@ -341,7 +341,7 @@ void PropertiesView::MView::edit()
void PropertiesView::MView::visitMElement(const MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
prepare();
if (!m_stereotypeComboBox) {
@@ -352,8 +352,13 @@ void PropertiesView::MView::visitMElement(const MElement *element)
m_stereotypeComboBox->addItems(m_propertiesView->stereotypeController()->knownStereotypes(m_stereotypeElement));
connect(m_stereotypeComboBox->lineEdit(), &QLineEdit::textEdited,
this, &PropertiesView::MView::onStereotypesChanged);
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
connect(m_stereotypeComboBox, QOverload<const QString &>::of(&QComboBox::activated),
this, &PropertiesView::MView::onStereotypesChanged);
+#else
+ connect(m_stereotypeComboBox, &QComboBox::textActivated,
+ this, &PropertiesView::MView::onStereotypesChanged);
+#endif
}
if (!m_stereotypeComboBox->hasFocus()) {
QList<QString> stereotypeList;
@@ -848,7 +853,7 @@ void PropertiesView::MView::visitMConnection(const MConnection *connection)
void PropertiesView::MView::visitDElement(const DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
if (m_modelElements.size() > 0 && m_modelElements.at(0)) {
m_propertiesTitle.clear();
diff --git a/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp b/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
index 1f1eaab643..f2da9a9292 100644
--- a/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
+++ b/src/libs/modelinglib/qmt/style/defaultstyleengine.cpp
@@ -144,15 +144,15 @@ class BoundaryStyleKey
uint qHash(const BoundaryStyleKey &styleKey)
{
- Q_UNUSED(styleKey);
+ Q_UNUSED(styleKey)
return 1;
}
bool operator==(const BoundaryStyleKey &lhs, const BoundaryStyleKey &rhs)
{
- Q_UNUSED(lhs);
- Q_UNUSED(rhs);
+ Q_UNUSED(lhs)
+ Q_UNUSED(rhs)
return true;
}
@@ -164,15 +164,15 @@ class SwimlaneStyleKey
uint qHash(const SwimlaneStyleKey &styleKey)
{
- Q_UNUSED(styleKey);
+ Q_UNUSED(styleKey)
return 1;
}
bool operator==(const SwimlaneStyleKey &lhs, const SwimlaneStyleKey &rhs)
{
- Q_UNUSED(lhs);
- Q_UNUSED(rhs);
+ Q_UNUSED(lhs)
+ Q_UNUSED(rhs)
return true;
}
@@ -344,7 +344,7 @@ const Style *DefaultStyleEngine::applyObjectStyle(const Style *baseStyle, const
const Style *DefaultStyleEngine::applyRelationStyle(const Style *baseStyle, const StyledRelation &styledRelation,
const Parameters *parameters)
{
- Q_UNUSED(parameters);
+ Q_UNUSED(parameters)
ElementType elementType = objectType(styledRelation.endA());
RelationStyleKey key(elementType, styledRelation.endA() ? styledRelation.endA()->visualPrimaryRole() : DObject::PrimaryRoleNormal);
@@ -391,14 +391,14 @@ const Style *DefaultStyleEngine::applyAnnotationStyle(const Style *baseStyle, co
const Style *DefaultStyleEngine::applyBoundaryStyle(const Style *baseStyle, const DBoundary *boundary,
const Parameters *parameters)
{
- Q_UNUSED(boundary);
+ Q_UNUSED(boundary)
return applyBoundaryStyle(baseStyle, parameters);
}
const Style *DefaultStyleEngine::applySwimlaneStyle(const Style *baseStyle, const DSwimlane *swimlane, const StyleEngine::Parameters *parameters)
{
- Q_UNUSED(swimlane);
+ Q_UNUSED(swimlane)
return applySwimlaneStyle(baseStyle, parameters);
}
@@ -406,7 +406,7 @@ const Style *DefaultStyleEngine::applySwimlaneStyle(const Style *baseStyle, cons
const Style *DefaultStyleEngine::applyAnnotationStyle(const Style *baseStyle, DAnnotation::VisualRole visualRole,
const StyleEngine::Parameters *parameters)
{
- Q_UNUSED(parameters);
+ Q_UNUSED(parameters)
AnnotationStyleKey key(visualRole);
const Style *derivedStyle = m_annotationStyleMap.value(key);
@@ -447,7 +447,7 @@ const Style *DefaultStyleEngine::applyAnnotationStyle(const Style *baseStyle, DA
const Style *DefaultStyleEngine::applyBoundaryStyle(const Style *baseStyle, const StyleEngine::Parameters *parameters)
{
- Q_UNUSED(parameters);
+ Q_UNUSED(parameters)
BoundaryStyleKey key;
const Style *derivedStyle = m_boundaryStyleMap.value(key);
@@ -463,7 +463,7 @@ const Style *DefaultStyleEngine::applyBoundaryStyle(const Style *baseStyle, cons
const Style *DefaultStyleEngine::applySwimlaneStyle(const Style *baseStyle, const StyleEngine::Parameters *parameters)
{
- Q_UNUSED(parameters);
+ Q_UNUSED(parameters)
SwimlaneStyleKey key;
const Style *derivedStyle = m_swimlaneStyleMap.value(key);
@@ -614,7 +614,7 @@ QColor DefaultStyleEngine::fillColor(ElementType elementType, const ObjectVisual
QColor DefaultStyleEngine::textColor(const DObject *object, int depth)
{
- Q_UNUSED(depth);
+ Q_UNUSED(depth)
QColor textColor;
DObject::VisualPrimaryRole visualRole = object ? object->visualPrimaryRole() : DObject::PrimaryRoleNormal;
@@ -627,7 +627,7 @@ QColor DefaultStyleEngine::textColor(const DObject *object, int depth)
QColor DefaultStyleEngine::textColor(ElementType elementType, const ObjectVisuals &objectVisuals)
{
- Q_UNUSED(elementType);
+ Q_UNUSED(elementType)
QColor textColor;
if (objectVisuals.visualSecondaryRole() == DObject::SecondaryRoleSoften)
diff --git a/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp b/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp
index e896f08462..f36060cbed 100644
--- a/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp
+++ b/src/libs/modelinglib/qmt/tasks/alignonrastervisitor.cpp
@@ -73,7 +73,7 @@ void AlignOnRasterVisitor::setDiagram(MDiagram *diagram)
void AlignOnRasterVisitor::visitDElement(DElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
QMT_CHECK(false);
}
@@ -116,7 +116,7 @@ void AlignOnRasterVisitor::visitDItem(DItem *item)
void AlignOnRasterVisitor::visitDRelation(DRelation *relation)
{
- Q_UNUSED(relation);
+ Q_UNUSED(relation)
}
void AlignOnRasterVisitor::visitDInheritance(DInheritance *inheritance)
diff --git a/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp b/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp
index 6cdc299472..ec15b0f7d8 100644
--- a/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp
+++ b/src/libs/modelinglib/qmt/tasks/diagramscenecontroller.cpp
@@ -90,7 +90,7 @@ public:
void visitMObject(const MObject *object) override
{
- Q_UNUSED(object);
+ Q_UNUSED(object)
if (auto connection = dynamic_cast<const MConnection *>(m_relation)) {
CustomRelation customRelation = m_stereotypeController->findCustomRelation(connection->customRelationId());
if (!customRelation.isNull()) {
@@ -594,7 +594,7 @@ QRectF alignObjectHeight(DObject *object, const QSizeF &size)
QRectF alignObjectSize(DObject *object, const QSizeF &size)
{
- Q_UNUSED(object);
+ Q_UNUSED(object)
QRectF rect;
rect.setX(-size.width() / 2.0);
diff --git a/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h b/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h
index e9b2f0699a..a706bbc66d 100644
--- a/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h
+++ b/src/libs/modelinglib/qtserialization/inc/qark/typeregistry.h
@@ -246,7 +246,7 @@ QString typeUid()
template<class T>
QString typeUid(const T &t)
{
- Q_UNUSED(t); // avoid warning in some compilers
+ Q_UNUSED(t) // avoid warning in some compilers
#if !defined(QT_NO_DEBUG) // avoid warning about unused function ::hasNameToUidMap in Qt >= 5.5
QMT_CHECK_X((registry::TypeNameRegistry<T>::hasNameToUidMap()),
"typeUid<T>()", "type maps are not correctly initialized");
@@ -260,7 +260,7 @@ QString typeUid(const T &t)
template<class Archive, class T>
typename registry::TypeRegistry<Archive, T>::TypeInfo typeInfo(const T &t)
{
- Q_UNUSED(t); // avoid warning in some compilers
+ Q_UNUSED(t) // avoid warning in some compilers
#if !defined(QT_NO_DEBUG) // avoid warning about unused function ::hasNameToUidMap in Qt >= 5.5
QMT_CHECK_X((registry::TypeRegistry<Archive,T>::hasMap()),
qPrintable(QString(QLatin1String("TypeRegistry<Archive, %1>::typeInfo(const T&)")).arg(typeUid<T>())),
diff --git a/src/libs/qmldebug/qmldebugcommandlinearguments.h b/src/libs/qmldebug/qmldebugcommandlinearguments.h
index 0c9979647a..f3a6017493 100644
--- a/src/libs/qmldebug/qmldebugcommandlinearguments.h
+++ b/src/libs/qmldebug/qmldebugcommandlinearguments.h
@@ -25,7 +25,9 @@
#pragma once
-#include <utils/port.h>
+#include <coreplugin/id.h>
+#include <projectexplorer/projectexplorerconstants.h>
+
#include <QString>
#include <QUrl>
@@ -69,9 +71,10 @@ inline QString qmlDebugCommandLineArguments(QmlDebugServicesPreset services,
}
inline QString qmlDebugTcpArguments(QmlDebugServicesPreset services,
- Utils::Port port, bool block = true)
+ const QUrl &server, bool block = true)
{
- return qmlDebugCommandLineArguments(services, QString("port:%1").arg(port.number()), block);
+ // TODO: Also generate host:<host> if applicable.
+ return qmlDebugCommandLineArguments(services, QString("port:%1").arg(server.port()), block);
}
inline QString qmlDebugNativeArguments(QmlDebugServicesPreset services, bool block = true)
@@ -85,4 +88,24 @@ inline QString qmlDebugLocalArguments(QmlDebugServicesPreset services, const QSt
return qmlDebugCommandLineArguments(services, QLatin1String("file:") + socket, block);
}
+inline Core::Id runnerIdForRunMode(Core::Id runMode)
+{
+ if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
+ return ProjectExplorer::Constants::QML_PROFILER_RUNNER;
+ if (runMode == ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE)
+ return ProjectExplorer::Constants::QML_PREVIEW_RUNNER;
+ return {};
+}
+
+inline QmlDebugServicesPreset servicesForRunMode(Core::Id runMode)
+{
+ if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
+ return QmlDebug::QmlProfilerServices;
+ if (runMode == ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE)
+ return QmlDebug::QmlPreviewServices;
+ if (runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE)
+ return QmlDebug::QmlDebuggerServices;
+ return {};
+}
+
} // namespace QmlDebug
diff --git a/src/libs/qmldebug/qmldebugconnection.cpp b/src/libs/qmldebug/qmldebugconnection.cpp
index 629360a8bc..b06a88f947 100644
--- a/src/libs/qmldebug/qmldebugconnection.cpp
+++ b/src/libs/qmldebug/qmldebugconnection.cpp
@@ -250,7 +250,7 @@ QmlDebugConnection::QmlDebugConnection(QObject *parent)
qRegisterMetaType<QAbstractSocket::SocketError>(),
qRegisterMetaType<QLocalSocket::LocalSocketError>()
};
- Q_UNUSED(metaTypes);
+ Q_UNUSED(metaTypes)
}
QmlDebugConnection::~QmlDebugConnection()
diff --git a/src/libs/qmldebug/qmldebugconnectionmanager.cpp b/src/libs/qmldebug/qmldebugconnectionmanager.cpp
index 217260d8d2..173bbb2d97 100644
--- a/src/libs/qmldebug/qmldebugconnectionmanager.cpp
+++ b/src/libs/qmldebug/qmldebugconnectionmanager.cpp
@@ -158,7 +158,7 @@ void QmlDebugConnectionManager::retryConnect()
void QmlDebugConnectionManager::logState(const QString &message)
{
- Q_UNUSED(message);
+ Q_UNUSED(message)
}
QmlDebugConnection *QmlDebugConnectionManager::connection() const
diff --git a/src/libs/qmldebug/qmldebugconnectionmanager.h b/src/libs/qmldebug/qmldebugconnectionmanager.h
index ccda63f38f..82c4a8bbe4 100644
--- a/src/libs/qmldebug/qmldebugconnectionmanager.h
+++ b/src/libs/qmldebug/qmldebugconnectionmanager.h
@@ -38,7 +38,7 @@ class QMLDEBUG_EXPORT QmlDebugConnectionManager : public QObject
{
Q_OBJECT
public:
- explicit QmlDebugConnectionManager(QObject *parent = 0);
+ explicit QmlDebugConnectionManager(QObject *parent = nullptr);
~QmlDebugConnectionManager() override;
void connectToServer(const QUrl &server);
diff --git a/src/libs/qmldebug/qmloutputparser.h b/src/libs/qmldebug/qmloutputparser.h
index 60db2e4d52..cf07d9c798 100644
--- a/src/libs/qmldebug/qmloutputparser.h
+++ b/src/libs/qmldebug/qmloutputparser.h
@@ -36,7 +36,7 @@ class QMLDEBUG_EXPORT QmlOutputParser : public QObject
{
Q_OBJECT
public:
- QmlOutputParser(QObject *parent = 0);
+ QmlOutputParser(QObject *parent = nullptr);
void setNoOutputText(const QString &text);
void processOutput(const QString &output);
diff --git a/src/libs/qmldebug/qpacketprotocol.cpp b/src/libs/qmldebug/qpacketprotocol.cpp
index dbe4088ed2..3bbabc1cf7 100644
--- a/src/libs/qmldebug/qpacketprotocol.cpp
+++ b/src/libs/qmldebug/qpacketprotocol.cpp
@@ -164,7 +164,7 @@ public:
qint32 inProgressSizeLE;
const qint64 read = dev->read((char *)&inProgressSizeLE, sizeof(qint32));
Q_ASSERT(read == sizeof(qint32));
- Q_UNUSED(read);
+ Q_UNUSED(read)
inProgressSize = qFromLittleEndian(inProgressSizeLE);
// Check sizing constraints
diff --git a/src/libs/qmldebug/qpacketprotocol.h b/src/libs/qmldebug/qpacketprotocol.h
index 6931c05ec1..f77ef0e93d 100644
--- a/src/libs/qmldebug/qpacketprotocol.h
+++ b/src/libs/qmldebug/qpacketprotocol.h
@@ -43,7 +43,7 @@ class QMLDEBUG_EXPORT QPacketProtocol : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QPacketProtocol)
public:
- explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0);
+ explicit QPacketProtocol(QIODevice *dev, QObject *parent = nullptr);
void send(const QByteArray &data);
qint64 packetsAvailable() const;
diff --git a/src/libs/qmleditorwidgets/colorbox.h b/src/libs/qmleditorwidgets/colorbox.h
index dd576f61f2..52dfdf6585 100644
--- a/src/libs/qmleditorwidgets/colorbox.h
+++ b/src/libs/qmleditorwidgets/colorbox.h
@@ -42,7 +42,7 @@ class QMLEDITORWIDGETS_EXPORT ColorBox : public QWidget
Q_PROPERTY(int alpha READ alpha WRITE setAlpha NOTIFY alphaChanged)
public:
- ColorBox(QWidget *parent = 0) : QWidget(parent), m_color(Qt::white), m_saturatedColor(Qt::white), m_mousePressed(false), m_lastHue(0)
+ ColorBox(QWidget *parent = nullptr) : QWidget(parent), m_color(Qt::white), m_saturatedColor(Qt::white), m_mousePressed(false), m_lastHue(0)
{
setFixedWidth(130);
setFixedHeight(130);
diff --git a/src/libs/qmleditorwidgets/colorbutton.h b/src/libs/qmleditorwidgets/colorbutton.h
index 8928f65da3..a7ad15cc7e 100644
--- a/src/libs/qmleditorwidgets/colorbutton.h
+++ b/src/libs/qmleditorwidgets/colorbutton.h
@@ -40,7 +40,7 @@ Q_PROPERTY(bool noColor READ noColor WRITE setNoColor)
Q_PROPERTY(bool showArrow READ showArrow WRITE setShowArrow)
public:
- ColorButton(QWidget *parent = 0) :
+ ColorButton(QWidget *parent = nullptr) :
QToolButton (parent),
m_colorString(QLatin1String("#ffffff")),
m_noColor(false),
diff --git a/src/libs/qmleditorwidgets/contextpanetextwidget.h b/src/libs/qmleditorwidgets/contextpanetextwidget.h
index 6249fe4e85..ab706dc0c3 100644
--- a/src/libs/qmleditorwidgets/contextpanetextwidget.h
+++ b/src/libs/qmleditorwidgets/contextpanetextwidget.h
@@ -44,7 +44,7 @@ class QMLEDITORWIDGETS_EXPORT ContextPaneTextWidget : public QWidget
Q_OBJECT
public:
- explicit ContextPaneTextWidget(QWidget *parent = 0);
+ explicit ContextPaneTextWidget(QWidget *parent = nullptr);
~ContextPaneTextWidget();
void setProperties(QmlJS::PropertyReader *propertyReader);
void setVerticalAlignmentVisible(bool);
diff --git a/src/libs/qmleditorwidgets/contextpanewidget.cpp b/src/libs/qmleditorwidgets/contextpanewidget.cpp
index d09902be1b..db8b69a47f 100644
--- a/src/libs/qmleditorwidgets/contextpanewidget.cpp
+++ b/src/libs/qmleditorwidgets/contextpanewidget.cpp
@@ -155,10 +155,9 @@ void DragWidget::enterEvent(QEvent *)
setCursor(Qt::ArrowCursor);
}
-ContextPaneWidget::ContextPaneWidget(QWidget *parent) : DragWidget(parent), m_currentWidget(0)
+ContextPaneWidget::ContextPaneWidget(QWidget *parent) : DragWidget(parent), m_currentWidget(nullptr)
{
QGridLayout *layout = new QGridLayout(this);
- layout->setMargin(0);
layout->setContentsMargins(1, 1, 1, 1);
layout->setSpacing(0);
m_toolButton = new QToolButton(this);
@@ -207,7 +206,7 @@ ContextPaneWidget::~ContextPaneWidget()
//if the pane was never activated the widget is not in a widget tree
if (!m_bauhausColorDialog.isNull()) {
delete m_bauhausColorDialog.data();
- m_bauhausColorDialog = 0;
+ m_bauhausColorDialog = nullptr;
}
}
diff --git a/src/libs/qmleditorwidgets/contextpanewidget.h b/src/libs/qmleditorwidgets/contextpanewidget.h
index 84ebf85b24..deb5d45752 100644
--- a/src/libs/qmleditorwidgets/contextpanewidget.h
+++ b/src/libs/qmleditorwidgets/contextpanewidget.h
@@ -51,7 +51,7 @@ class QMLEDITORWIDGETS_EXPORT DragWidget : public QFrame
Q_OBJECT
public:
- explicit DragWidget(QWidget *parent = 0);
+ explicit DragWidget(QWidget *parent = nullptr);
void setSecondaryTarget(QWidget* w)
{ m_secondaryTarget = w; }
@@ -76,7 +76,7 @@ class QMLEDITORWIDGETS_EXPORT ContextPaneWidget : public DragWidget
Q_OBJECT
public:
- explicit ContextPaneWidget(QWidget *parent = 0);
+ explicit ContextPaneWidget(QWidget *parent = nullptr);
~ContextPaneWidget() override;
void activate(const QPoint &pos, const QPoint &alternative, const QPoint &alternative2, bool pinned);
void rePosition(const QPoint &pos, const QPoint &alternative , const QPoint &alternative3, bool pinned);
diff --git a/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp b/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp
index dcc3e9ecc6..b2912ceb42 100644
--- a/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp
+++ b/src/libs/qmleditorwidgets/contextpanewidgetimage.cpp
@@ -884,7 +884,6 @@ PreviewDialog::PreviewDialog(QWidget *parent) : DragWidget(parent)
QVBoxLayout *layout = new QVBoxLayout(this);
QHBoxLayout *horizontalLayout = new QHBoxLayout();
QHBoxLayout *horizontalLayout2 = new QHBoxLayout();
- layout->setMargin(0);
layout->setContentsMargins(2, 2, 2, 16);
layout->setSpacing(4);
QToolButton *toolButton = new QToolButton(this);
@@ -942,7 +941,7 @@ void PreviewDialog::setPixmap(const QPixmap &p, int zoom)
void PreviewDialog::wheelEvent(QWheelEvent* event)
{
- int delta = event->delta();
+ const auto delta = event->angleDelta().y();
event->accept();
if (delta > 0) {
if (m_zoom == 1)
diff --git a/src/libs/qmleditorwidgets/contextpanewidgetimage.h b/src/libs/qmleditorwidgets/contextpanewidgetimage.h
index a031447eec..89c7413e77 100644
--- a/src/libs/qmleditorwidgets/contextpanewidgetimage.h
+++ b/src/libs/qmleditorwidgets/contextpanewidgetimage.h
@@ -52,7 +52,7 @@ class PreviewLabel : public QLabel
Q_OBJECT
public:
- PreviewLabel(QWidget *parent = 0);
+ PreviewLabel(QWidget *parent = nullptr);
void setZoom(int);
void setIsBorderImage(bool b);
void setMargins(int left, int top, int right, int bottom);
@@ -91,7 +91,7 @@ class PreviewDialog : public DragWidget
Q_OBJECT
public:
- PreviewDialog(QWidget *parent = 0);
+ PreviewDialog(QWidget *parent = nullptr);
void setPixmap(const QPixmap &p, int zoom = 1);
void setZoom(int z);
void setIsBorderImage(bool b);
@@ -118,7 +118,7 @@ class QMLEDITORWIDGETS_EXPORT ContextPaneWidgetImage : public QWidget
Q_OBJECT
public:
- explicit ContextPaneWidgetImage(QWidget *parent = 0, bool borderImage = false);
+ explicit ContextPaneWidgetImage(QWidget *parent = nullptr, bool borderImage = false);
~ContextPaneWidgetImage();
void setProperties(QmlJS::PropertyReader *propertyReader);
void setPath(const QString& path);
@@ -161,7 +161,7 @@ class LabelFilter: public QObject {
Q_OBJECT
public:
- LabelFilter(QObject* parent =0) : QObject(parent) {}
+ LabelFilter(QObject* parent =nullptr) : QObject(parent) {}
signals:
void doubleClicked();
protected:
@@ -172,7 +172,7 @@ class WheelFilter: public QObject {
Q_OBJECT
public:
- WheelFilter(QObject* parent =0) : QObject(parent) {}
+ WheelFilter(QObject* parent =nullptr) : QObject(parent) {}
void setTarget(QObject *target) { m_target = target; }
protected:
bool eventFilter(QObject *obj, QEvent *event);
diff --git a/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h b/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h
index b1f259ae04..1ae75cc982 100644
--- a/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h
+++ b/src/libs/qmleditorwidgets/contextpanewidgetrectangle.h
@@ -41,7 +41,7 @@ class QMLEDITORWIDGETS_EXPORT ContextPaneWidgetRectangle : public QWidget
Q_OBJECT
public:
- explicit ContextPaneWidgetRectangle(QWidget *parent = 0);
+ explicit ContextPaneWidgetRectangle(QWidget *parent = nullptr);
~ContextPaneWidgetRectangle();
void setProperties(QmlJS::PropertyReader *propertyReader);
void enabableGradientEditing(bool);
diff --git a/src/libs/qmleditorwidgets/customcolordialog.cpp b/src/libs/qmleditorwidgets/customcolordialog.cpp
index de603e0ea9..3792785ad2 100644
--- a/src/libs/qmleditorwidgets/customcolordialog.cpp
+++ b/src/libs/qmleditorwidgets/customcolordialog.cpp
@@ -62,8 +62,7 @@ CustomColorDialog::CustomColorDialog(QWidget *parent) : QFrame(parent )
QVBoxLayout* vBox = new QVBoxLayout(colorFrameWidget);
colorFrameWidget->setLayout(vBox);
vBox->setSpacing(0);
- vBox->setMargin(0);
- vBox->setContentsMargins(0,5,0,28);
+ vBox->setContentsMargins(0, 5, 0, 28);
m_beforeColorWidget = new QFrame(colorFrameWidget);
m_beforeColorWidget->setFixedSize(30, 18);
@@ -85,7 +84,7 @@ CustomColorDialog::CustomColorDialog(QWidget *parent) : QFrame(parent )
QGridLayout *gridLayout = new QGridLayout(this);
gridLayout->setSpacing(4);
gridLayout->setVerticalSpacing(4);
- gridLayout->setMargin(4);
+ gridLayout->setContentsMargins(4, 4, 4, 4);
setLayout(gridLayout);
gridLayout->addWidget(m_colorBox, 0, 0, 4, 1);
@@ -141,7 +140,7 @@ CustomColorDialog::CustomColorDialog(QWidget *parent) : QFrame(parent )
void CustomColorDialog::setupColor(const QColor &color)
{
QPalette pal;
- pal.setColor(QPalette::Background, color);
+ pal.setColor(QPalette::Window, color);
m_beforeColorWidget->setPalette(pal);
setColor(color);
}
@@ -176,7 +175,7 @@ void CustomColorDialog::setupWidgets()
m_bSpinBox->setValue(m_color.blueF());
m_colorBox->setColor(m_color);
QPalette pal;
- pal.setColor(QPalette::Background, m_color);
+ pal.setColor(QPalette::Window, m_color);
m_currentColorWidget->setPalette(pal);
m_blockUpdate = false;
}
diff --git a/src/libs/qmleditorwidgets/customcolordialog.h b/src/libs/qmleditorwidgets/customcolordialog.h
index a6df6e692d..88564c8142 100644
--- a/src/libs/qmleditorwidgets/customcolordialog.h
+++ b/src/libs/qmleditorwidgets/customcolordialog.h
@@ -43,7 +43,7 @@ class QMLEDITORWIDGETS_EXPORT CustomColorDialog : public QFrame {
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
- CustomColorDialog(QWidget *parent = 0);
+ CustomColorDialog(QWidget *parent = nullptr);
QColor color() const { return m_color; }
void setupColor(const QColor &color);
void setColor(const QColor &color)
diff --git a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp
index d43b458881..a794b337a0 100644
--- a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp
+++ b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp
@@ -48,12 +48,12 @@ class EasingSimulation : public QObject
Q_OBJECT
public:
QGraphicsView *m_g;
- EasingSimulation(QObject *parent=0, QGraphicsView *v=0):QObject(parent) {
+ EasingSimulation(QObject *parent=nullptr, QGraphicsView *v=nullptr):QObject(parent) {
m_qtLogo = new PixmapItem(QPixmap(":/qmleditorwidgets/qt_logo.png"));
m_scene.addItem(m_qtLogo);
m_scene.setSceneRect(0,0,v->viewport()->width(),m_qtLogo->boundingRect().height());
m_qtLogo->hide();
- m_sequential = 0;
+ m_sequential = nullptr;
m_g = v;
m_g->setScene(&m_scene);
}
diff --git a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.h b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.h
index 480860f0c5..3cab9523b5 100644
--- a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.h
+++ b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.h
@@ -45,7 +45,7 @@ class EasingContextPane : public QWidget
enum GraphDisplayMode { GraphMode, SimulationMode };
public:
- explicit EasingContextPane(QWidget *parent = 0);
+ explicit EasingContextPane(QWidget *parent = nullptr);
~EasingContextPane() override;
void setProperties(QmlJS::PropertyReader *propertyReader);
diff --git a/src/libs/qmleditorwidgets/easingpane/easinggraph.h b/src/libs/qmleditorwidgets/easingpane/easinggraph.h
index a4bfabf0db..517ee7dc1e 100644
--- a/src/libs/qmleditorwidgets/easingpane/easinggraph.h
+++ b/src/libs/qmleditorwidgets/easingpane/easinggraph.h
@@ -49,7 +49,7 @@ class EasingGraph: public QWidget
Q_PROPERTY (QColor zeroColor READ zeroColor WRITE setZeroColor NOTIFY zeroColorChanged)
public:
- EasingGraph(QWidget *parent=0);
+ EasingGraph(QWidget *parent=nullptr);
~EasingGraph() override;
QEasingCurve::Type easingType() const;
diff --git a/src/libs/qmleditorwidgets/filewidget.h b/src/libs/qmleditorwidgets/filewidget.h
index da5c3c305d..320002a635 100644
--- a/src/libs/qmleditorwidgets/filewidget.h
+++ b/src/libs/qmleditorwidgets/filewidget.h
@@ -52,7 +52,7 @@ class QMLEDITORWIDGETS_EXPORT FileWidget : public QWidget
public:
- FileWidget(QWidget *parent = 0);
+ FileWidget(QWidget *parent = nullptr);
~FileWidget() override;
QString fileName() const
diff --git a/src/libs/qmleditorwidgets/fontsizespinbox.cpp b/src/libs/qmleditorwidgets/fontsizespinbox.cpp
index 4a8ee48427..f127b5a677 100644
--- a/src/libs/qmleditorwidgets/fontsizespinbox.cpp
+++ b/src/libs/qmleditorwidgets/fontsizespinbox.cpp
@@ -92,7 +92,7 @@ void FontSizeSpinBox::onEditingFinished()
QValidator::State FontSizeSpinBox::validate (QString &input, int &p) const
{
QRegExp rx(QLatin1String("\\d+\\s*(px|pt)"));
- QRegExpValidator v(rx, 0);
+ QRegExpValidator v(rx, nullptr);
return v.validate(input, p);
}
diff --git a/src/libs/qmleditorwidgets/fontsizespinbox.h b/src/libs/qmleditorwidgets/fontsizespinbox.h
index d9ee85092c..c74e33b2fd 100644
--- a/src/libs/qmleditorwidgets/fontsizespinbox.h
+++ b/src/libs/qmleditorwidgets/fontsizespinbox.h
@@ -39,7 +39,7 @@ class QMLEDITORWIDGETS_EXPORT FontSizeSpinBox : public QAbstractSpinBox
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
public:
- explicit FontSizeSpinBox(QWidget *parent = 0);
+ explicit FontSizeSpinBox(QWidget *parent = nullptr);
bool isPixelSize() { return !m_isPointSize; }
bool isPointSize() { return m_isPointSize; }
diff --git a/src/libs/qmleditorwidgets/gradientline.h b/src/libs/qmleditorwidgets/gradientline.h
index 0d5cff8a7f..d6f5e132f7 100644
--- a/src/libs/qmleditorwidgets/gradientline.h
+++ b/src/libs/qmleditorwidgets/gradientline.h
@@ -39,7 +39,7 @@ class QMLEDITORWIDGETS_EXPORT GradientLine : public QWidget {
Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
public:
- GradientLine(QWidget *parent = 0);
+ GradientLine(QWidget *parent = nullptr);
QString gradientName() const { return m_gradientName; }
void setGradientName(const QString &newName);
diff --git a/src/libs/qmleditorwidgets/huecontrol.h b/src/libs/qmleditorwidgets/huecontrol.h
index f9db8790ed..902b3ceaa8 100644
--- a/src/libs/qmleditorwidgets/huecontrol.h
+++ b/src/libs/qmleditorwidgets/huecontrol.h
@@ -36,7 +36,7 @@ class QMLEDITORWIDGETS_EXPORT HueControl : public QWidget
Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged)
public:
- HueControl(QWidget *parent = 0) : QWidget(parent), m_color(Qt::white), m_mousePressed(false)
+ HueControl(QWidget *parent = nullptr) : QWidget(parent), m_color(Qt::white), m_mousePressed(false)
{
setFixedWidth(28);
setFixedHeight(130);
diff --git a/src/libs/qmljs/jsoncheck.cpp b/src/libs/qmljs/jsoncheck.cpp
index 3940f46099..15d0edb1a7 100644
--- a/src/libs/qmljs/jsoncheck.cpp
+++ b/src/libs/qmljs/jsoncheck.cpp
@@ -41,7 +41,7 @@ using namespace Utils;
JsonCheck::JsonCheck(Document::Ptr doc)
: m_doc(doc)
- , m_schema(0)
+ , m_schema(nullptr)
{
QTC_CHECK(m_doc->ast());
}
diff --git a/src/libs/qmljs/parser/qmljsengine_p.h b/src/libs/qmljs/parser/qmljsengine_p.h
index 093f68bac5..2321c5aa8f 100644
--- a/src/libs/qmljs/parser/qmljsengine_p.h
+++ b/src/libs/qmljs/parser/qmljsengine_p.h
@@ -61,19 +61,19 @@ public:
virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
{
- Q_UNUSED(jsfile);
- Q_UNUSED(module);
- Q_UNUSED(line);
- Q_UNUSED(column);
+ Q_UNUSED(jsfile)
+ Q_UNUSED(module)
+ Q_UNUSED(line)
+ Q_UNUSED(column)
}
virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
{
- Q_UNUSED(uri);
- Q_UNUSED(version);
- Q_UNUSED(module);
- Q_UNUSED(line);
- Q_UNUSED(column);
+ Q_UNUSED(uri)
+ Q_UNUSED(version)
+ Q_UNUSED(module)
+ Q_UNUSED(line)
+ Q_UNUSED(column)
}
};
diff --git a/src/libs/qmljs/persistenttrie.cpp b/src/libs/qmljs/persistenttrie.cpp
index 08c17dd164..1d6c9bf5ba 100644
--- a/src/libs/qmljs/persistenttrie.cpp
+++ b/src/libs/qmljs/persistenttrie.cpp
@@ -286,12 +286,9 @@ public:
ReplaceInTrie() { }
void operator()(QString s)
{
- QHashIterator<QString, QString> i(replacements);
QString res = s;
- while (i.hasNext()) {
- i.next();
+ for (auto i = replacements.cbegin(), end = replacements.cend(); i != end; ++i)
res.replace(i.key(), i.value());
- }
trie = TrieNode::insertF(trie,res);
}
};
@@ -312,7 +309,7 @@ std::pair<TrieNode::Ptr,int> TrieNode::intersectF(
typedef TrieNode::Ptr P;
typedef QMap<QString,int>::const_iterator MapIterator;
if (v1.isNull() || v2.isNull())
- return std::make_pair(P(0), ((v1.isNull()) ? 1 : 0) | ((v2.isNull()) ? 2 : 0));
+ return std::make_pair(P(nullptr), ((v1.isNull()) ? 1 : 0) | ((v2.isNull()) ? 2 : 0));
QString::const_iterator i = v1->prefix.constBegin()+index1, iEnd = v1->prefix.constEnd();
QString::const_iterator j = v2->prefix.constBegin(), jEnd = v2->prefix.constEnd();
while (i != iEnd && j != jEnd) {
@@ -348,7 +345,7 @@ std::pair<TrieNode::Ptr,int> TrieNode::intersectF(
foreach (P t2, v2->postfixes)
if (t2->prefix.isEmpty())
return std::make_pair(v1,1);
- return std::make_pair(P(0), 0);
+ return std::make_pair(P(nullptr), 0);
}
QMap<QString,int> p1, p2;
QList<P> p3;
@@ -430,7 +427,7 @@ std::pair<TrieNode::Ptr,int> TrieNode::intersectF(
switch (sameV1V2) {
case 0:
if (p3.isEmpty())
- return std::make_pair(P(0),0);
+ return std::make_pair(P(nullptr),0);
else
return std::make_pair(TrieNode::create(v1->prefix,p3),0);
case 2:
@@ -454,7 +451,7 @@ std::pair<TrieNode::Ptr,int> TrieNode::intersectF(
v1->prefix.left(index1).append(res.first->prefix),
res.first->postfixes), 0);
}
- return std::make_pair(P(0), 0);
+ return std::make_pair(P(nullptr), 0);
} else {
// i != iEnd && j == jEnd
foreach (P t2, v2->postfixes)
@@ -462,7 +459,7 @@ std::pair<TrieNode::Ptr,int> TrieNode::intersectF(
std::pair<P,int> res = intersectF(v1,t2,i-v1->prefix.constBegin());
return std::make_pair(res.first, (res.second & 1));
}
- return std::make_pair(P(0), 0);
+ return std::make_pair(P(nullptr), 0);
}
}
diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp
index 6b904da040..70912cdf21 100644
--- a/src/libs/qmljs/qmljsbind.cpp
+++ b/src/libs/qmljs/qmljsbind.cpp
@@ -53,9 +53,9 @@ using namespace QmlJS::AST;
Bind::Bind(Document *doc, QList<DiagnosticMessage> *messages, bool isJsLibrary, const QList<ImportInfo> &jsImports)
: _doc(doc),
- _currentObjectValue(0),
- _idEnvironment(0),
- _rootObjectValue(0),
+ _currentObjectValue(nullptr),
+ _idEnvironment(nullptr),
+ _rootObjectValue(nullptr),
_isJsLibrary(isJsLibrary),
_imports(jsImports),
_diagnosticMessages(messages)
@@ -134,7 +134,7 @@ ObjectValue *Bind::switchObjectValue(ObjectValue *newObjectValue)
ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitializer *initializer)
{
- ObjectValue *parentObjectValue = 0;
+ ObjectValue *parentObjectValue = nullptr;
// normal component instance
ASTObjectValue *objectValue = new ASTObjectValue(qualifiedTypeNameId, initializer, _doc, &_valueOwner);
@@ -169,13 +169,13 @@ void Bind::accept(Node *node)
bool Bind::visit(AST::UiProgram *)
{
- _idEnvironment = _valueOwner.newObject(/*prototype =*/ 0);
+ _idEnvironment = _valueOwner.newObject(/*prototype =*/ nullptr);
return true;
}
bool Bind::visit(AST::Program *)
{
- _currentObjectValue = _valueOwner.newObject(/*prototype =*/ 0);
+ _currentObjectValue = _valueOwner.newObject(/*prototype =*/ nullptr);
_rootObjectValue = _currentObjectValue;
return true;
}
@@ -236,7 +236,7 @@ bool Bind::visit(UiPublicMember *ast)
const Block *block = AST::cast<const Block*>(ast->statement);
if (block) {
// build block scope
- ObjectValue *blockScope = _valueOwner.newObject(/*prototype=*/0);
+ ObjectValue *blockScope = _valueOwner.newObject(/*prototype=*/nullptr);
_attachedJSScopes.insert(ast, blockScope); // associated with the UiPublicMember, not with the block
ObjectValue *parent = switchObjectValue(blockScope);
accept(ast->statement);
@@ -259,7 +259,7 @@ bool Bind::visit(UiObjectDefinition *ast)
_qmlObjects.insert(ast, value);
} else {
_groupedPropertyBindings.insert(ast);
- ObjectValue *oldObjectValue = switchObjectValue(0);
+ ObjectValue *oldObjectValue = switchObjectValue(nullptr);
accept(ast->initializer);
switchObjectValue(oldObjectValue);
}
@@ -289,7 +289,7 @@ bool Bind::visit(UiScriptBinding *ast)
const Block *block = AST::cast<const Block*>(ast->statement);
if (block) {
// build block scope
- ObjectValue *blockScope = _valueOwner.newObject(/*prototype=*/0);
+ ObjectValue *blockScope = _valueOwner.newObject(/*prototype=*/nullptr);
_attachedJSScopes.insert(ast, blockScope); // associated with the UiScriptBinding, not with the block
ObjectValue *parent = switchObjectValue(blockScope);
accept(ast->statement);
@@ -328,7 +328,7 @@ bool Bind::visit(FunctionExpression *ast)
_currentObjectValue->setMember(ast->name.toString(), function);
// build function scope
- ObjectValue *functionScope = _valueOwner.newObject(/*prototype=*/0);
+ ObjectValue *functionScope = _valueOwner.newObject(/*prototype=*/nullptr);
_attachedJSScopes.insert(ast, functionScope);
ObjectValue *parent = switchObjectValue(functionScope);
@@ -345,7 +345,7 @@ bool Bind::visit(FunctionExpression *ast)
// ### TODO, currently covered by the accept(body)
// 3. Arguments object
- ObjectValue *arguments = _valueOwner.newObject(/*prototype=*/0);
+ ObjectValue *arguments = _valueOwner.newObject(/*prototype=*/nullptr);
arguments->setMember(QLatin1String("callee"), function);
arguments->setMember(QLatin1String("length"), _valueOwner.numberValue());
functionScope->setMember(QLatin1String("arguments"), arguments);
diff --git a/src/libs/qmljs/qmljsbundle.cpp b/src/libs/qmljs/qmljsbundle.cpp
index 9789d37492..6c7ee6029b 100644
--- a/src/libs/qmljs/qmljsbundle.cpp
+++ b/src/libs/qmljs/qmljsbundle.cpp
@@ -219,11 +219,11 @@ QStringList QmlBundle::maybeReadTrie(Trie &trie, Utils::JsonObjectValue *config,
return res;
}
Utils::JsonValue *imp0 = config->member(propertyName);
- Utils::JsonArrayValue *imp = ((imp0 != 0) ? imp0->toArray() : 0);
- if (imp != 0) {
+ Utils::JsonArrayValue *imp = ((imp0 != nullptr) ? imp0->toArray() : nullptr);
+ if (imp != nullptr) {
foreach (Utils::JsonValue *v, imp->elements()) {
- Utils::JsonStringValue *impStr = ((v != 0) ? v->toString() : 0);
- if (impStr != 0) {
+ Utils::JsonStringValue *impStr = ((v != nullptr) ? v->toString() : nullptr);
+ if (impStr != nullptr) {
trie.insert(impStr->value());
} else {
res.append(QString::fromLatin1("Expected all elements of array in property \"%1\" "
@@ -251,7 +251,7 @@ bool QmlBundle::readFrom(QString path, QStringList *errors)
return false;
}
JsonObjectValue *config = JsonValue::create(QString::fromUtf8(f.readAll()), &pool)->toObject();
- if (config == 0) {
+ if (config == nullptr) {
if (errors)
(*errors) << QString::fromLatin1("Could not parse json object in file at %1 .").arg(path);
return false;
@@ -259,8 +259,8 @@ bool QmlBundle::readFrom(QString path, QStringList *errors)
QStringList errs;
if (config->hasMember(QLatin1String("name"))) {
JsonValue *n0 = config->member(QLatin1String("name"));
- JsonStringValue *n = ((n0 != 0) ? n0->toString() : 0);
- if (n != 0)
+ JsonStringValue *n = ((n0 != nullptr) ? n0->toString() : nullptr);
+ if (n != nullptr)
m_name = n->value();
else
errs.append(QString::fromLatin1("Property \"name\" in QmlBundle at %1 is expected "
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 6b961df84a..e3fe353b95 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -388,7 +388,7 @@ protected:
QTC_ASSERT(_block == 0, _block = 0);
}
- void postVisit(Node *ast)
+ void postVisit(Node *ast) override
{
if (!_seenNonDeclarationStatement && ast->statementCast()
&& !cast<VariableStatement *>(ast)) {
@@ -396,7 +396,7 @@ protected:
}
}
- bool visit(IdentifierExpression *ast)
+ bool visit(IdentifierExpression *ast) override
{
if (ast->name.isEmpty())
return false;
@@ -409,14 +409,14 @@ protected:
return false;
}
- bool visit(VariableStatement *ast)
+ bool visit(VariableStatement *ast) override
{
if (_seenNonDeclarationStatement)
addMessage(HintDeclarationsShouldBeAtStartOfFunction, ast->declarationKindToken);
return true;
}
- bool visit(PatternElement *ast)
+ bool visit(PatternElement *ast) override
{
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
return true;
@@ -433,12 +433,13 @@ protected:
if (_declaredVariables.contains(name)) {
addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
} else {
- for (auto k : _declaredBlockVariables.keys()) {
- if (k.first == name) {
- addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
- break;
- }
- }
+ const auto found = std::find_if(_declaredBlockVariables.keyBegin(),
+ _declaredBlockVariables.keyEnd(),
+ [name](const auto &key) {
+ return key.first == name;
+ });
+ if (found != _declaredBlockVariables.keyEnd())
+ addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
}
}
@@ -456,7 +457,7 @@ protected:
return true;
}
- bool visit(FunctionDeclaration *ast)
+ bool visit(FunctionDeclaration *ast) override
{
if (_seenNonDeclarationStatement)
addMessage(HintDeclarationsShouldBeAtStartOfFunction, ast->functionToken);
@@ -464,7 +465,7 @@ protected:
return visit(static_cast<FunctionExpression *>(ast));
}
- bool visit(FunctionExpression *ast)
+ bool visit(FunctionExpression *ast) override
{
if (ast->name.isEmpty())
return false;
@@ -875,7 +876,7 @@ static bool checkTopLevelBindingForParentReference(ExpressionStatement *expStmt,
return false;
SourceLocation location = locationFromRange(expStmt->firstSourceLocation(), expStmt->lastSourceLocation());
- QString stmtSource = source.mid(location.begin(), location.length);
+ QString stmtSource = source.mid(int(location.begin()), int(location.length));
if (stmtSource.contains(QRegExp("(^|\\W)parent\\.")))
return true;
@@ -1241,8 +1242,8 @@ bool Check::visit(BinaryExpression *ast)
// check spacing
SourceLocation op = ast->operatorToken;
- if ((op.begin() > 0 && !source.at(op.begin() - 1).isSpace())
- || (int(op.end()) < source.size() && !source.at(op.end()).isSpace())) {
+ if ((op.begin() > 0 && !source.at(int(op.begin()) - 1).isSpace())
+ || (int(op.end()) < source.size() && !source.at(int(op.end())).isSpace())) {
addMessage(HintBinaryOperatorSpacing, op);
}
@@ -1277,15 +1278,13 @@ bool Check::visit(BinaryExpression *ast)
}
if (int(op.end()) + 1 < source.size()) {
- const QChar next = source.at(op.end());
- if (next.isSpace() && next != newline
- && source.at(op.end() + 1) == match)
- addMessage(msg, SourceLocation(op.begin(), 3, op.startLine, op.startColumn));
+ const QChar next = source.at(int(op.end()));
+ if (next.isSpace() && next != newline && source.at(int(op.end()) + 1) == match)
+ addMessage(msg, SourceLocation((op.begin()), 3, op.startLine, op.startColumn));
}
if (op.begin() >= 2) {
- const QChar prev = source.at(op.begin() - 1);
- if (prev.isSpace() && prev != newline
- && source.at(op.begin() - 2) == match)
+ const QChar prev = source.at(int(op.begin()) - 1);
+ if (prev.isSpace() && prev != newline && source.at(int(op.begin()) - 2) == match)
addMessage(msg, SourceLocation(op.begin() - 2, 3, op.startLine, op.startColumn - 2));
}
}
@@ -1375,6 +1374,7 @@ bool Check::visit(ExpressionStatement *ast)
case QSOperator::InplaceURightShift:
case QSOperator::InplaceXor:
ok = true;
+ break;
default: break;
}
}
@@ -1507,8 +1507,9 @@ static bool hasOnlySpaces(const QString &s)
void Check::addMessage(const Message &message)
{
if (message.isValid() && _enabledMessages.contains(message.type)) {
- if (m_disabledMessageTypesByLine.contains(message.location.startLine)) {
- QList<MessageTypeAndSuppression> &disabledMessages = m_disabledMessageTypesByLine[message.location.startLine];
+ if (m_disabledMessageTypesByLine.contains(int(message.location.startLine))) {
+ QList<MessageTypeAndSuppression> &disabledMessages
+ = m_disabledMessageTypesByLine[int(message.location.startLine)];
for (int i = 0; i < disabledMessages.size(); ++i) {
if (disabledMessages[i].type == message.type) {
disabledMessages[i].wasSuppressed = true;
@@ -1532,7 +1533,7 @@ void Check::scanCommentsForAnnotations()
QRegExp disableCommentPattern(Message::suppressionPattern());
foreach (const SourceLocation &commentLoc, _doc->engine()->comments()) {
- const QString &comment = _doc->source().mid(commentLoc.begin(), commentLoc.length);
+ const QString &comment = _doc->source().mid(int(commentLoc.begin()), int(commentLoc.length));
// enable all checks annotation
if (comment.contains("@enable-all-checks"))
@@ -1548,34 +1549,34 @@ void Check::scanCommentsForAnnotations()
MessageTypeAndSuppression entry;
entry.type = static_cast<StaticAnalysis::Type>(disableCommentPattern.cap(1).toInt());
entry.wasSuppressed = false;
- entry.suppressionSource = SourceLocation(commentLoc.offset + lastOffset,
- disableCommentPattern.matchedLength(),
+ entry.suppressionSource = SourceLocation(commentLoc.offset + quint32(lastOffset),
+ quint32(disableCommentPattern.matchedLength()),
commentLoc.startLine,
- commentLoc.startColumn + lastOffset);
+ commentLoc.startColumn + quint32(lastOffset));
disabledMessageTypes += entry;
}
if (!disabledMessageTypes.isEmpty()) {
- int appliesToLine = commentLoc.startLine;
+ quint32 appliesToLine = commentLoc.startLine;
// if the comment is preceded by spaces only, it applies to the next line
// note: startColumn is 1-based and *after* the starting // or /*
if (commentLoc.startColumn >= 3) {
- const QString &beforeComment = _doc->source().mid(commentLoc.begin() - commentLoc.startColumn + 1,
- commentLoc.startColumn - 3);
+ const QString &beforeComment = _doc->source().mid(int(commentLoc.begin()
+ - commentLoc.startColumn + 1),
+ int(commentLoc.startColumn) - 3);
if (hasOnlySpaces(beforeComment))
++appliesToLine;
}
- m_disabledMessageTypesByLine[appliesToLine] += disabledMessageTypes;
+ m_disabledMessageTypesByLine[int(appliesToLine)] += disabledMessageTypes;
}
}
}
void Check::warnAboutUnnecessarySuppressions()
{
- QHashIterator< int, QList<MessageTypeAndSuppression> > it(m_disabledMessageTypesByLine);
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_disabledMessageTypesByLine.cbegin(), end = m_disabledMessageTypesByLine.cend();
+ it != end; ++it) {
foreach (const MessageTypeAndSuppression &entry, it.value()) {
if (!entry.wasSuppressed)
addMessage(WarnUnnecessaryMessageSuppression, entry.suppressionSource);
@@ -1856,7 +1857,8 @@ void Check::checkCaseFallthrough(StatementList *statements, SourceLocation error
|| comment.end() > nextLoc.begin())
continue;
- const QString &commentText = _doc->source().mid(comment.begin(), comment.length);
+ const QString &commentText = _doc->source().mid(int(comment.begin()),
+ int(comment.length));
if (commentText.contains("fall through")
|| commentText.contains("fall-through")
|| commentText.contains("fallthrough")) {
diff --git a/src/libs/qmljs/qmljscontext.cpp b/src/libs/qmljs/qmljscontext.cpp
index d8d0f31bbe..3e90a40db8 100644
--- a/src/libs/qmljs/qmljscontext.cpp
+++ b/src/libs/qmljs/qmljscontext.cpp
@@ -97,7 +97,7 @@ ViewerContext Context::viewerContext() const
const Imports *Context::imports(const QmlJS::Document *doc) const
{
if (!doc)
- return 0;
+ return nullptr;
return _imports.value(doc).data();
}
@@ -106,16 +106,16 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, UiQualifiedId
{
const Imports *importsObj = imports(doc);
if (!importsObj)
- return 0;
+ return nullptr;
const ObjectValue *objectValue = importsObj->typeScope();
if (!objectValue)
- return 0;
+ return nullptr;
for (UiQualifiedId *iter = qmlTypeName; objectValue && iter && iter != qmlTypeNameEnd;
iter = iter->next) {
- const Value *value = objectValue->lookupMember(iter->name.toString(), this, 0, false);
+ const Value *value = objectValue->lookupMember(iter->name.toString(), this, nullptr, false);
if (!value)
- return 0;
+ return nullptr;
objectValue = value->asObjectValue();
}
@@ -127,18 +127,18 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, const QString
{
const Imports *importsObj = imports(doc);
if (!importsObj)
- return 0;
+ return nullptr;
const ObjectValue *objectValue = importsObj->typeScope();
if (!objectValue)
- return 0;
+ return nullptr;
foreach (const QString &name, qmlTypeName) {
if (!objectValue)
- return 0;
+ return nullptr;
const Value *value = objectValue->lookupMember(name, this);
if (!value)
- return 0;
+ return nullptr;
objectValue = value->asObjectValue();
}
diff --git a/src/libs/qmljs/qmljscontext.h b/src/libs/qmljs/qmljscontext.h
index cafee3e970..0da21e8861 100644
--- a/src/libs/qmljs/qmljscontext.h
+++ b/src/libs/qmljs/qmljscontext.h
@@ -60,7 +60,7 @@ public:
const Imports *imports(const Document *doc) const;
const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName,
- AST::UiQualifiedId *qmlTypeNameEnd = 0) const;
+ AST::UiQualifiedId *qmlTypeNameEnd = nullptr) const;
const ObjectValue *lookupType(const Document *doc, const QStringList &qmlTypeName) const;
const Value *lookupReference(const Value *value) const;
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index 6ebe5b0b2f..c848a78c53 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -39,6 +39,8 @@
#include <algorithm>
+static constexpr int sizeofQChar = int(sizeof(QChar));
+
using namespace QmlJS;
using namespace QmlJS::AST;
@@ -86,9 +88,9 @@ using namespace QmlJS::AST;
*/
Document::Document(const QString &fileName, Dialect language)
- : _engine(0)
- , _ast(0)
- , _bind(0)
+ : _engine(nullptr)
+ , _ast(nullptr)
+ , _bind(nullptr)
, _fileName(QDir::cleanPath(fileName))
, _editorRevision(0)
, _language(language)
@@ -170,7 +172,7 @@ AST::ExpressionNode *Document::expression() const
if (_ast)
return _ast->expressionCast();
- return 0;
+ return nullptr;
}
AST::Node *Document::ast() const
@@ -248,12 +250,6 @@ public:
{}
- void pragmaLibrary(int line, int column)
- {
- isLibrary = true;
- addLocation(line, column);
- }
-
void importFile(const QString &jsfile, const QString &module,
int line, int column) override
{
@@ -306,12 +302,13 @@ bool Document::parse_helper(int startToken)
_parsedCorrectly = parser.parse();
break;
case QmlJSGrammar::T_FEED_JS_SCRIPT:
- case QmlJSGrammar::T_FEED_JS_MODULE:
+ case QmlJSGrammar::T_FEED_JS_MODULE: {
_parsedCorrectly = parser.parseProgram();
- for (const auto &d: directives.locations()) {
+ const QList<SourceLocation> locations = directives.locations();
+ for (const auto &d : locations) {
_jsdirectives << d;
}
- break;
+ } break;
case QmlJSGrammar::T_FEED_JS_EXPRESSION:
_parsedCorrectly = parser.parseExpression();
@@ -383,10 +380,6 @@ LibraryInfo::LibraryInfo(const QmlDirParser &parser, const QByteArray &fingerpri
updateFingerprint();
}
-LibraryInfo::~LibraryInfo()
-{
-}
-
QByteArray LibraryInfo::calculateFingerprint() const
{
QCryptographicHash hash(QCryptographicHash::Sha1);
@@ -396,12 +389,14 @@ QByteArray LibraryInfo::calculateFingerprint() const
foreach (const QmlDirParser::Component &component, _components) {
len = component.fileName.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(component.fileName.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(component.fileName.constData()),
+ len * sizeofQChar);
hash.addData(reinterpret_cast<const char *>(&component.majorVersion), sizeof(component.majorVersion));
hash.addData(reinterpret_cast<const char *>(&component.minorVersion), sizeof(component.minorVersion));
len = component.typeName.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(component.typeName.constData()), component.typeName.size() * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(component.typeName.constData()),
+ component.typeName.size() * sizeofQChar);
int flags = (component.singleton ? (1 << 0) : 0) + (component.internal ? (1 << 1) : 0);
hash.addData(reinterpret_cast<const char *>(&flags), sizeof(flags));
}
@@ -410,17 +405,18 @@ QByteArray LibraryInfo::calculateFingerprint() const
foreach (const QmlDirParser::Plugin &plugin, _plugins) {
len = plugin.path.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(plugin.path.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(plugin.path.constData()), len * sizeofQChar);
len = plugin.name.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(plugin.name.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(plugin.name.constData()), len * sizeofQChar);
}
len = _typeinfos.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
foreach (const QmlDirParser::TypeInfo &typeinfo, _typeinfos) {
len = typeinfo.fileName.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(typeinfo.fileName.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(typeinfo.fileName.constData()),
+ len * sizeofQChar);
}
len = _metaObjects.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
@@ -433,7 +429,7 @@ QByteArray LibraryInfo::calculateFingerprint() const
hash.addData(reinterpret_cast<const char *>(&_dumpStatus), sizeof(_dumpStatus));
len = _dumpError.size(); // localization dependent (avoid?)
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(_dumpError.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(_dumpError.constData()), len * sizeofQChar);
len = _moduleApis.size();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
@@ -623,9 +619,9 @@ void ModuleApiInfo::addToHash(QCryptographicHash &hash) const
{
int len = uri.length();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(uri.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(uri.constData()), len * sizeofQChar);
version.addToHash(hash);
len = cppName.length();
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- hash.addData(reinterpret_cast<const char *>(cppName.constData()), len * sizeof(QChar));
+ hash.addData(reinterpret_cast<const char *>(cppName.constData()), len * sizeofQChar);
}
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 82df720776..5e80e7612b 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -167,7 +167,8 @@ public:
LibraryInfo();
explicit LibraryInfo(Status status);
explicit LibraryInfo(const QmlDirParser &parser, const QByteArray &fingerprint = QByteArray());
- ~LibraryInfo();
+ ~LibraryInfo() = default;
+ LibraryInfo(const LibraryInfo &other) = default;
QByteArray calculateFingerprint() const;
void updateFingerprint();
diff --git a/src/libs/qmljs/qmljsevaluate.cpp b/src/libs/qmljs/qmljsevaluate.cpp
index 754113d199..4a408dac93 100644
--- a/src/libs/qmljs/qmljsevaluate.cpp
+++ b/src/libs/qmljs/qmljsevaluate.cpp
@@ -61,7 +61,7 @@ Evaluate::Evaluate(const ScopeChain *scopeChain, ReferenceContext *referenceCont
_context(scopeChain->context()),
_referenceContext(referenceContext),
_scopeChain(scopeChain),
- _result(0)
+ _result(nullptr)
{
}
@@ -95,7 +95,7 @@ const Value *Evaluate::value(AST::Node *ast)
const Value *Evaluate::reference(AST::Node *ast)
{
// save the result
- const Value *previousResult = switchResult(0);
+ const Value *previousResult = switchResult(nullptr);
// process the expression
accept(ast);
@@ -426,8 +426,8 @@ bool Evaluate::visit(AST::NotExpression *)
bool Evaluate::visit(AST::BinaryExpression *ast)
{
- const Value *lhs = 0;
- const Value *rhs = 0;
+ const Value *lhs = nullptr;
+ const Value *rhs = nullptr;
switch (ast->op) {
case QSOperator::Add:
case QSOperator::InplaceAdd:
diff --git a/src/libs/qmljs/qmljsevaluate.h b/src/libs/qmljs/qmljsevaluate.h
index 7e3a218415..45ffc2ece8 100644
--- a/src/libs/qmljs/qmljsevaluate.h
+++ b/src/libs/qmljs/qmljsevaluate.h
@@ -41,7 +41,7 @@ class FunctionValue;
class QMLJS_EXPORT Evaluate: protected AST::Visitor
{
public:
- Evaluate(const ScopeChain *scopeChain, ReferenceContext *referenceContext = 0);
+ Evaluate(const ScopeChain *scopeChain, ReferenceContext *referenceContext = nullptr);
~Evaluate();
// same as value()
diff --git a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
index 6bf17505d6..7ba890e17a 100644
--- a/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
+++ b/src/libs/qmljs/qmljsfindexportedcpptypes.cpp
@@ -57,7 +57,7 @@ class ContextProperty {
public:
QString name;
QString expression;
- unsigned line, column;
+ int line, column;
};
class FindExportsVisitor : protected ASTVisitor
@@ -87,13 +87,15 @@ public:
QmlRegisterSingletonTypeUrl,
// template<typename T> int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
// or template<typename T, int metaObjectRevision> int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
- QmlRegisterUncreatableType
+ QmlRegisterUncreatableType,
+ // int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject, const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString &reason)
+ QmlRegisterUncreatableMetaObject
};
FindExportsVisitor(CPlusPlus::Document::Ptr doc)
: ASTVisitor(doc->translationUnit())
, _doc(doc)
- , _compound(0)
+ , _compound(nullptr)
{}
void operator()()
@@ -142,7 +144,7 @@ protected:
if (!idExp || !idExp->name)
return false;
RegistrationFunction registrationFunction = InvalidRegistrationFunction;
- TypeIdAST *typeId = 0;
+ TypeIdAST *typeId = nullptr;
if (TemplateIdAST *templateId = idExp->name->asTemplateId()) {
if (!templateId->identifier_token)
return false;
@@ -189,6 +191,8 @@ protected:
registrationFunction = QmlRegisterType5;
else if (fName == "qmlRegisterSingletonType")
registrationFunction = QmlRegisterSingletonTypeCallback2;
+ else if (fName == "qmlRegisterUncreatableMetaObject")
+ registrationFunction = QmlRegisterUncreatableMetaObject;
else
return false;
} else {
@@ -215,11 +219,17 @@ protected:
|| !ast->expression_list->next->next->next->next->value
|| ast->expression_list->next->next->next->next->next)
return false;
+ break;
+ case QmlRegisterUncreatableMetaObject:
+ if (!ast->expression_list->next->next->next->next->next
+ || !ast->expression_list->next->next->next->next->next->value
+ || ast->expression_list->next->next->next->next->next->next)
+ return false;
}
- ExpressionAST *uriExp = 0;
- ExpressionAST *majorVersionExp = 0;
- ExpressionAST *minorVersionExp = 0;
- ExpressionAST *nameExp = 0;
+ ExpressionAST *uriExp = nullptr;
+ ExpressionAST *majorVersionExp = nullptr;
+ ExpressionAST *minorVersionExp = nullptr;
+ ExpressionAST *nameExp = nullptr;
if (registrationFunction == QmlRegisterType5) {
uriExp = ast->expression_list->next->value;
majorVersionExp = ast->expression_list->next->next->value;
@@ -235,17 +245,22 @@ protected:
majorVersionExp = ast->expression_list->next->next->value;
minorVersionExp = ast->expression_list->next->next->next->value;
nameExp = ast->expression_list->next->next->next->next->value;
+ } else if (registrationFunction == QmlRegisterUncreatableMetaObject) {
+ uriExp = ast->expression_list->next->value;
+ majorVersionExp = ast->expression_list->next->next->value;
+ minorVersionExp = ast->expression_list->next->next->next->value;
+ nameExp = ast->expression_list->next->next->next->next->value;
} else {
uriExp = ast->expression_list->value;
majorVersionExp = ast->expression_list->next->value;
minorVersionExp = ast->expression_list->next->next->value;
nameExp = ast->expression_list->next->next->next->value;
}
- const StringLiteral *nameLit = 0;
+ const StringLiteral *nameLit = nullptr;
if (StringLiteralAST *nameAst = skipStringCall(nameExp)->asStringLiteral())
nameLit = translationUnit()->stringLiteral(nameAst->literal_token);
if (!nameLit) {
- unsigned line, column;
+ int line, column;
translationUnit()->getTokenStartPosition(nameExp->firstToken(), &line, &column);
_messages += Document::DiagnosticMessage(
Document::DiagnosticMessage::Warning,
@@ -290,7 +305,7 @@ protected:
const Token end = _doc->translationUnit()->tokenAt(ast->firstToken());
// go through comments backwards to find the annotation closest to the call
- for (unsigned i = _doc->translationUnit()->commentCount(); i-- > 0; ) {
+ for (int i = _doc->translationUnit()->commentCount(); i-- > 0; ) {
const Token commentToken = _doc->translationUnit()->commentAt(i);
if (commentToken.utf16charsBegin() >= end.utf16charsBegin()
|| commentToken.utf16charsEnd() <= begin.utf16charsBegin()) {
@@ -305,7 +320,7 @@ protected:
}
if (packageName.isEmpty()) {
packageName = QmlJS::CppQmlTypes::defaultPackage;
- unsigned line, column;
+ int line, column;
translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
_messages += Document::DiagnosticMessage(
Document::DiagnosticMessage::Warning,
@@ -318,8 +333,8 @@ protected:
}
// version arguments must be integer literals
- const NumericLiteral *majorLit = 0;
- const NumericLiteral *minorLit = 0;
+ const NumericLiteral *majorLit = nullptr;
+ const NumericLiteral *minorLit = nullptr;
if (NumericLiteralAST *majorAst = majorVersionExp->asNumericLiteral())
majorLit = translationUnit()->numericLiteral(majorAst->literal_token);
if (NumericLiteralAST *minorAst = minorVersionExp->asNumericLiteral())
@@ -331,7 +346,8 @@ protected:
|| registrationFunction == QmlRegisterSingletonTypeCallback2
|| registrationFunction == QmlRegisterSingletonTypeUrl;
exportedType.isCreatable = !exportedType.isSingleton
- && registrationFunction != QmlRegisterUncreatableType;
+ && registrationFunction != QmlRegisterUncreatableType
+ && registrationFunction != QmlRegisterUncreatableMetaObject;
exportedType.typeName = QString::fromUtf8(nameLit->chars(), nameLit->size());
exportedType.packageName = packageName;
if (majorLit && minorLit && majorLit->isInt() && minorLit->isInt()) {
@@ -341,7 +357,7 @@ protected:
}
// we want to do lookup later, so also store the surrounding scope
- unsigned line, column;
+ int line, column;
translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
exportedType.scope = _doc->scopeAt(line, column);
@@ -363,6 +379,8 @@ protected:
exportedType.url = QString::fromUtf8(urlLit->chars(), urlLit->size());
}
}
+ } else if (registrationFunction == QmlRegisterUncreatableMetaObject) {
+ // Anything to do here?
} else {
qCWarning(QmlJS::qmljsLog()) << "missing template type for registrationFunction " << registrationFunction;
}
@@ -377,7 +395,7 @@ protected:
return idExp->name;
if (MemberAccessAST *memberExp = exp->asMemberAccess())
return memberExp->member_name;
- return 0;
+ return nullptr;
}
static ExpressionAST *skipQVariant(ExpressionAST *ast, TranslationUnit *translationUnit)
@@ -479,11 +497,11 @@ protected:
return false;
// first argument must be a string literal
- const StringLiteral *nameLit = 0;
+ const StringLiteral *nameLit = nullptr;
if (StringLiteralAST *nameAst = skipStringCall(ast->expression_list->value)->asStringLiteral())
nameLit = translationUnit()->stringLiteral(nameAst->literal_token);
if (!nameLit) {
- unsigned line, column;
+ int line, column;
translationUnit()->getTokenStartPosition(ast->expression_list->value->firstToken(), &line, &column);
_messages += Document::DiagnosticMessage(
Document::DiagnosticMessage::Warning,
@@ -634,7 +652,7 @@ static QString toQmlType(const FullySpecifiedType &type)
static Class *lookupClass(const QString &expression, Scope *scope, TypeOfExpression &typeOf)
{
QList<LookupItem> results = typeOf(expression.toUtf8(), scope);
- Class *klass = 0;
+ Class *klass = nullptr;
foreach (const LookupItem &item, results) {
if (item.declaration()) {
klass = item.declaration()->asClass();
@@ -642,7 +660,7 @@ static Class *lookupClass(const QString &expression, Scope *scope, TypeOfExpress
return klass;
}
}
- return 0;
+ return nullptr;
}
static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject(
@@ -666,7 +684,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject(
// add the no-package export, so the cpp name can be used in properties
fmo->addExport(fmo->className(), QmlJS::CppQmlTypes::cppPackage, ComponentVersion());
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (!member->name())
continue;
@@ -678,7 +696,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject(
method.setMethodType(FakeMetaMethod::Signal);
else
method.setMethodType(FakeMetaMethod::Slot);
- for (unsigned a = 0, argc = func->argumentCount(); a < argc; ++a) {
+ for (int a = 0, argc = func->argumentCount(); a < argc; ++a) {
Symbol *arg = func->argumentAt(a);
QString name;
if (arg->name())
@@ -702,7 +720,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject(
}
if (QtEnum *qtEnum = member->asQtEnum()) {
// find the matching enum
- Enum *e = 0;
+ Enum *e = nullptr;
QList<LookupItem> result = typeOf(namePrinter.prettyName(qtEnum->name()).toUtf8(), klass);
foreach (const LookupItem &item, result) {
if (item.declaration()) {
@@ -715,7 +733,7 @@ static LanguageUtils::FakeMetaObject::Ptr buildFakeMetaObject(
continue;
FakeMetaEnum metaEnum(namePrinter.prettyName(e->name()));
- for (unsigned j = 0; j < e->memberCount(); ++j) {
+ for (int j = 0; j < e->memberCount(); ++j) {
Symbol *enumMember = e->memberAt(j);
if (!enumMember->name())
continue;
@@ -754,7 +772,7 @@ static void buildExportedQmlObjects(
return;
foreach (const ExportedQmlType &exportedType, cppExports) {
- Class *klass = 0;
+ Class *klass = nullptr;
if (!exportedType.typeExpression.isEmpty())
klass = lookupClass(exportedType.typeExpression, exportedType.scope, typeOf);
// TODO: something smarter with exportedType.url
@@ -900,6 +918,7 @@ bool FindExportedCppTypes::maybeExportsTypes(const CPlusPlus::Document::Ptr &doc
const QByteArray qmlRegisterSingletonTypeToken("qmlRegisterType");
const QByteArray qmlRegisterTypeToken("qmlRegisterSingletonType");
const QByteArray qmlRegisterUncreatableTypeToken("qmlRegisterUncreatableType");
+ const QByteArray qmlRegisterUncreatableMetaObjectToken("qmlRegisterUncreatableMetaObject");
const QByteArray setContextPropertyToken("setContextProperty");
if (document->control()->findIdentifier(
qmlRegisterTypeToken.constData(), qmlRegisterTypeToken.size())) {
@@ -917,6 +936,10 @@ bool FindExportedCppTypes::maybeExportsTypes(const CPlusPlus::Document::Ptr &doc
setContextPropertyToken.constData(), setContextPropertyToken.size())) {
return true;
}
+ if (document->control()->findIdentifier(
+ qmlRegisterUncreatableMetaObjectToken.constData(), qmlRegisterUncreatableMetaObjectToken.size())) {
+ return true;
+ }
return false;
}
diff --git a/src/libs/qmljs/qmljsicons.cpp b/src/libs/qmljs/qmljsicons.cpp
index 71ab381108..5f3c8ab43c 100644
--- a/src/libs/qmljs/qmljsicons.cpp
+++ b/src/libs/qmljs/qmljsicons.cpp
@@ -44,7 +44,7 @@ static Q_LOGGING_CATEGORY(iconsLog, "qtc.qmljs.icons", QtWarningMsg)
namespace QmlJS {
-Icons *Icons::m_instance = 0;
+Icons *Icons::m_instance = nullptr;
class IconsPrivate
{
@@ -62,7 +62,7 @@ Icons::Icons()
Icons::~Icons()
{
- m_instance = 0;
+ m_instance = nullptr;
delete d;
}
diff --git a/src/libs/qmljs/qmljsicontextpane.h b/src/libs/qmljs/qmljsicontextpane.h
index 3a36a104ef..cc2a981040 100644
--- a/src/libs/qmljs/qmljsicontextpane.h
+++ b/src/libs/qmljs/qmljsicontextpane.h
@@ -43,7 +43,7 @@ class QMLJS_EXPORT IContextPane : public QObject
Q_OBJECT
public:
- IContextPane(QObject *parent = 0) : QObject(parent) {}
+ IContextPane(QObject *parent = nullptr) : QObject(parent) {}
virtual ~IContextPane() {}
virtual void apply(TextEditor::TextEditorWidget *editorWidget, Document::Ptr document, const ScopeChain *scopeChain, AST::Node *node, bool update, bool force = false) = 0;
virtual void setEnabled(bool) = 0;
diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp
index 3f17846dab..e5d0161665 100644
--- a/src/libs/qmljs/qmljsimportdependencies.cpp
+++ b/src/libs/qmljs/qmljsimportdependencies.cpp
@@ -584,10 +584,8 @@ void ImportDependencies::filter(const ViewerContext &vContext)
{
QMap<QString, CoreImport> newCoreImports;
QMap<ImportKey, QStringList> newImportCache;
- QMapIterator<QString, CoreImport> j(m_coreImports);
bool hasChanges = false;
- while (j.hasNext()) {
- j.next();
+ for (auto j = m_coreImports.cbegin(), end = m_coreImports.cend(); j != end; ++j) {
const CoreImport &cImport = j.value();
if (vContext.languageIsCompatible(cImport.language)) {
QList<Export> newExports;
@@ -717,8 +715,8 @@ ImportDependencies::ImportElements ImportDependencies::candidateImports(
QList<DependencyInfo::ConstPtr> ImportDependencies::createDependencyInfos(
const ImportKey &mainDoc, const ViewerContext &vContext) const
{
- Q_UNUSED(mainDoc);
- Q_UNUSED(vContext);
+ Q_UNUSED(mainDoc)
+ Q_UNUSED(vContext)
QList<DependencyInfo::ConstPtr> res;
QTC_CHECK(false);
return res;
@@ -897,8 +895,8 @@ public:
const Export &e,
const CoreImport &cI) const
{
- Q_UNUSED(m);
- Q_UNUSED(cI);
+ Q_UNUSED(m)
+ Q_UNUSED(cI)
imports.insert(e.exportName.flatKey());
return true;
}
@@ -923,30 +921,24 @@ QSet<ImportKey> ImportDependencies::subdirImports(
void ImportDependencies::checkConsistency() const
{
- QMapIterator<ImportKey, QStringList> j(m_importCache);
- while (j.hasNext()) {
- j.next();
- foreach (const QString &s, j.value()) {
+ for (auto j = m_importCache.cbegin(), end = m_importCache.cend(); j != end; ++j) {
+ for (const QString &s : j.value()) {
bool found = false;
foreach (const Export &e, m_coreImports.value(s).possibleExports)
if (e.exportName == j.key())
found = true;
- Q_ASSERT(found); Q_UNUSED(found);
+ Q_ASSERT(found); Q_UNUSED(found)
}
}
- QMapIterator<QString,CoreImport> i(m_coreImports);
- while (i.hasNext()) {
- i.next();
+ for (auto i = m_coreImports.cbegin(), end = m_coreImports.cend(); i != end; ++i) {
foreach (const Export &e, i.value().possibleExports) {
if (!m_importCache.value(e.exportName).contains(i.key())) {
qCWarning(importsLog) << e.exportName.toString();
qCWarning(importsLog) << i.key();
- QMapIterator<ImportKey, QStringList> j(m_importCache);
- while (j.hasNext()) {
- j.next();
+ for (auto j = m_importCache.cbegin(), end = m_importCache.cend(); j != end; ++j)
qCWarning(importsLog) << j.key().toString() << j.value();
- }
+
qCWarning(importsLog) << m_importCache.contains(e.exportName);
qCWarning(importsLog) << m_importCache.value(e.exportName);
}
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 91f195f8fc..825ead9109 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -99,7 +99,7 @@ class LookupMember: public MemberProcessor
public:
LookupMember(const QString &name)
- : m_name(name), m_value(0) {}
+ : m_name(name), m_value(nullptr) {}
const Value *value() const { return m_value; }
@@ -290,7 +290,7 @@ void CppComponentValue::processMembers(MemberProcessor *processor) const
signatures->reserve(m_metaObject->methodCount());
for (int index = 0; index < m_metaObject->methodCount(); ++index)
signatures->append(new MetaFunction(m_metaObject->method(index), valueOwner()));
- if (!m_metaSignatures.testAndSetOrdered(0, signatures)) {
+ if (!m_metaSignatures.testAndSetOrdered(nullptr, signatures)) {
delete signatures;
signatures = m_metaSignatures.load();
}
@@ -500,7 +500,7 @@ FakeMetaEnum CppComponentValue::getEnum(const QString &typeName, const CppCompon
}
}
if (foundInScope)
- *foundInScope = 0;
+ *foundInScope = nullptr;
return FakeMetaEnum();
}
@@ -514,8 +514,8 @@ const QmlEnumValue *CppComponentValue::getEnumValue(const QString &typeName, con
}
}
if (foundInScope)
- *foundInScope = 0;
- return 0;
+ *foundInScope = nullptr;
+ return nullptr;
}
const ObjectValue *CppComponentValue::signalScope(const QString &signalName) const
@@ -534,7 +534,7 @@ const ObjectValue *CppComponentValue::signalScope(const QString &signalName) con
const QStringList &parameterTypes = method.parameterTypes();
QTC_ASSERT(parameterNames.size() == parameterTypes.size(), continue);
- ObjectValue *scope = valueOwner()->newObject(/*prototype=*/0);
+ ObjectValue *scope = valueOwner()->newObject(/*prototype=*/nullptr);
for (int i = 0; i < parameterNames.size(); ++i) {
const QString &name = parameterNames.at(i);
const QString &type = parameterTypes.at(i);
@@ -544,7 +544,7 @@ const ObjectValue *CppComponentValue::signalScope(const QString &signalName) con
}
scopes->insert(generatedSlotName(method.methodName()), scope);
}
- if (!m_signalScopes.testAndSetOrdered(0, scopes)) {
+ if (!m_signalScopes.testAndSetOrdered(nullptr, scopes)) {
delete scopes;
scopes = m_signalScopes.load();
}
@@ -708,137 +708,137 @@ bool Value::getSourceLocation(QString *, int *, int *) const
const NullValue *Value::asNullValue() const
{
- return 0;
+ return nullptr;
}
const UndefinedValue *Value::asUndefinedValue() const
{
- return 0;
+ return nullptr;
}
const UnknownValue *Value::asUnknownValue() const
{
- return 0;
+ return nullptr;
}
const NumberValue *Value::asNumberValue() const
{
- return 0;
+ return nullptr;
}
const IntValue *Value::asIntValue() const
{
- return 0;
+ return nullptr;
}
const RealValue *Value::asRealValue() const
{
- return 0;
+ return nullptr;
}
const BooleanValue *Value::asBooleanValue() const
{
- return 0;
+ return nullptr;
}
const StringValue *Value::asStringValue() const
{
- return 0;
+ return nullptr;
}
const UrlValue *Value::asUrlValue() const
{
- return 0;
+ return nullptr;
}
const ObjectValue *Value::asObjectValue() const
{
- return 0;
+ return nullptr;
}
const FunctionValue *Value::asFunctionValue() const
{
- return 0;
+ return nullptr;
}
const Reference *Value::asReference() const
{
- return 0;
+ return nullptr;
}
const ColorValue *Value::asColorValue() const
{
- return 0;
+ return nullptr;
}
const AnchorLineValue *Value::asAnchorLineValue() const
{
- return 0;
+ return nullptr;
}
const CppComponentValue *Value::asCppComponentValue() const
{
- return 0;
+ return nullptr;
}
const ASTObjectValue *Value::asAstObjectValue() const
{
- return 0;
+ return nullptr;
}
const QmlEnumValue *Value::asQmlEnumValue() const
{
- return 0;
+ return nullptr;
}
const QmlPrototypeReference *Value::asQmlPrototypeReference() const
{
- return 0;
+ return nullptr;
}
const ASTPropertyReference *Value::asAstPropertyReference() const
{
- return 0;
+ return nullptr;
}
const ASTVariableReference *Value::asAstVariableReference() const
{
- return 0;
+ return nullptr;
}
const Internal::QtObjectPrototypeReference *Value::asQtObjectPrototypeReference() const
{
- return 0;
+ return nullptr;
}
const ASTSignal *Value::asAstSignal() const
{
- return 0;
+ return nullptr;
}
const ASTFunctionValue *Value::asAstFunctionValue() const
{
- return 0;
+ return nullptr;
}
const Function *Value::asFunction() const
{
- return 0;
+ return nullptr;
}
const MetaFunction *Value::asMetaFunction() const
{
- return 0;
+ return nullptr;
}
const JSImportScope *Value::asJSImportScope() const
{
- return 0;
+ return nullptr;
}
const TypeScope *Value::asTypeScope() const
{
- return 0;
+ return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1003,7 +1003,7 @@ bool MemberProcessor::processGeneratedSlot(const QString &, const Value *)
ObjectValue::ObjectValue(ValueOwner *valueOwner, const QString &originId)
: m_valueOwner(valueOwner), m_originId(originId),
- _prototype(0)
+ _prototype(nullptr)
{
valueOwner->registerValue(this);
}
@@ -1098,11 +1098,7 @@ bool ObjectValue::checkPrototype(const ObjectValue *, QSet<const ObjectValue *>
void ObjectValue::processMembers(MemberProcessor *processor) const
{
- QHashIterator<QString, PropertyData> it(m_members);
-
- while (it.hasNext()) {
- it.next();
-
+ for (auto it = m_members.cbegin(), end = m_members.cend(); it != end; ++it) {
if (! processor->processProperty(it.key(), it.value().value, it.value().propertyInfo))
break;
}
@@ -1126,7 +1122,7 @@ const Value *ObjectValue::lookupMember(const QString &name, const Context *conte
}
}
- const ObjectValue *prototypeObject = 0;
+ const ObjectValue *prototypeObject = nullptr;
if (examinePrototypes && context) {
PrototypeIterator iter(this, context);
@@ -1139,13 +1135,13 @@ const Value *ObjectValue::lookupMember(const QString &name, const Context *conte
}
if (foundInObject)
- *foundInObject = 0;
+ *foundInObject = nullptr;
- return 0;
+ return nullptr;
}
PrototypeIterator::PrototypeIterator(const ObjectValue *start, const Context *context)
- : m_current(0)
+ : m_current(nullptr)
, m_next(start)
, m_context(context)
, m_error(NoError)
@@ -1155,7 +1151,7 @@ PrototypeIterator::PrototypeIterator(const ObjectValue *start, const Context *co
}
PrototypeIterator::PrototypeIterator(const ObjectValue *start, const ContextPtr &context)
- : m_current(0)
+ : m_current(nullptr)
, m_next(start)
, m_context(context.data())
, m_error(NoError)
@@ -1183,7 +1179,7 @@ bool PrototypeIterator::hasNext()
}
if (m_prototypes.contains(m_next)) {
m_error = CycleError;
- m_next = 0;
+ m_next = nullptr;
return false;
}
return true;
@@ -1194,17 +1190,17 @@ const ObjectValue *PrototypeIterator::next()
if (hasNext()) {
m_current = m_next;
m_prototypes += m_next;
- m_next = 0;
+ m_next = nullptr;
return m_current;
}
- return 0;
+ return nullptr;
}
const ObjectValue *PrototypeIterator::peekNext()
{
if (hasNext())
return m_next;
- return 0;
+ return nullptr;
}
PrototypeIterator::Error PrototypeIterator::error() const
@@ -1273,7 +1269,7 @@ void FunctionValue::accept(ValueVisitor *visitor) const
Function::Function(ValueOwner *valueOwner)
: FunctionValue(valueOwner)
- , m_returnValue(0)
+ , m_returnValue(nullptr)
, m_optionalNamedArgumentCount(0)
, m_isVariadic(false)
{
@@ -1368,7 +1364,7 @@ CppQmlTypesLoader::BuiltinObjects CppQmlTypesLoader::loadQmlTypes(const QFileInf
file.close();
- parseQmlTypeDescriptions(contents, &newObjects, 0, &newDependencies, &error, &warning,
+ parseQmlTypeDescriptions(contents, &newObjects, nullptr, &newDependencies, &error, &warning,
qmlTypeFile.absoluteFilePath());
} else {
error = file.errorString();
@@ -1421,7 +1417,7 @@ void CppQmlTypesLoader::parseQmlTypeDescriptions(const QByteArray &contents,
}
CppQmlTypes::CppQmlTypes(ValueOwner *valueOwner)
- : m_cppContextProperties(0)
+ : m_cppContextProperties(nullptr)
, m_valueOwner(valueOwner)
{
@@ -1607,13 +1603,13 @@ const ObjectValue *CppQmlTypes::cppContextProperties() const
ConvertToNumber::ConvertToNumber(ValueOwner *valueOwner)
- : m_valueOwner(valueOwner), m_result(0)
+ : m_valueOwner(valueOwner), m_result(nullptr)
{
}
const Value *ConvertToNumber::operator()(const Value *value)
{
- const Value *previousValue = switchResult(0);
+ const Value *previousValue = switchResult(nullptr);
if (value)
value->accept(this);
@@ -1670,13 +1666,13 @@ void ConvertToNumber::visit(const FunctionValue *object)
}
ConvertToString::ConvertToString(ValueOwner *valueOwner)
- : m_valueOwner(valueOwner), m_result(0)
+ : m_valueOwner(valueOwner), m_result(nullptr)
{
}
const Value *ConvertToString::operator()(const Value *value)
{
- const Value *previousValue = switchResult(0);
+ const Value *previousValue = switchResult(nullptr);
if (value)
value->accept(this);
@@ -1733,13 +1729,13 @@ void ConvertToString::visit(const FunctionValue *object)
}
ConvertToObject::ConvertToObject(ValueOwner *valueOwner)
- : m_valueOwner(valueOwner), m_result(0)
+ : m_valueOwner(valueOwner), m_result(nullptr)
{
}
const Value *ConvertToObject::operator()(const Value *value)
{
- const Value *previousValue = switchResult(0);
+ const Value *previousValue = switchResult(nullptr);
if (value)
value->accept(this);
@@ -1855,7 +1851,7 @@ ASTObjectValue::ASTObjectValue(UiQualifiedId *typeName,
const Document *doc,
ValueOwner *valueOwner)
: ObjectValue(valueOwner, doc->importId()),
- m_typeName(typeName), m_initializer(initializer), m_doc(doc), m_defaultPropertyRef(0)
+ m_typeName(typeName), m_initializer(initializer), m_doc(doc), m_defaultPropertyRef(nullptr)
{
if (m_initializer) {
for (UiObjectMemberList *it = m_initializer->members; it; it = it->next) {
@@ -2166,7 +2162,7 @@ ASTSignal::ASTSignal(UiPublicMember *ast, const Document *doc, ValueOwner *value
const QString &signalName = ast->name.toString();
m_slotName = generatedSlotName(signalName);
- ObjectValue *v = valueOwner->newObject(/*prototype=*/0);
+ ObjectValue *v = valueOwner->newObject(/*prototype=*/nullptr);
for (UiParameterList *it = ast->parameters; it; it = it->next) {
if (!it->name.isEmpty())
v->setMember(it->name.toString(), valueOwner->defaultValueForBuiltinType(it->type->name.toString()));
@@ -2222,7 +2218,7 @@ bool ASTSignal::getSourceLocation(QString *fileName, int *line, int *column) con
ImportInfo::ImportInfo()
: m_type(ImportType::Invalid)
- , m_ast(0)
+ , m_ast(nullptr)
{
}
@@ -2332,7 +2328,7 @@ UiImport *ImportInfo::ast() const
}
Import::Import()
- : object(0), valid(false), used(false)
+ : object(nullptr), valid(false), used(false)
{}
Import::Import(const Import &other)
@@ -2359,10 +2355,9 @@ TypeScope::TypeScope(const Imports *imports, ValueOwner *valueOwner)
const Value *TypeScope::lookupMember(const QString &name, const Context *context,
const ObjectValue **foundInObject, bool) const
{
- QListIterator<Import> it(m_imports->all());
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ const QList<Import> &imports = m_imports->all();
+ for (int pos = imports.size(); --pos >= 0; ) {
+ const Import &i = imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
@@ -2374,7 +2369,7 @@ const Value *TypeScope::lookupMember(const QString &name, const Context *context
if (info.as() == name) {
if (foundInObject)
*foundInObject = this;
- i.used = true;
+ i.used = true; // FIXME: This evilly modifies a 'const' object
return import;
}
continue;
@@ -2386,16 +2381,15 @@ const Value *TypeScope::lookupMember(const QString &name, const Context *context
}
}
if (foundInObject)
- *foundInObject = 0;
- return 0;
+ *foundInObject = nullptr;
+ return nullptr;
}
void TypeScope::processMembers(MemberProcessor *processor) const
{
- QListIterator<Import> it(m_imports->all());
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ const QList<Import> &imports = m_imports->all();
+ for (int pos = imports.size(); --pos >= 0; ) {
+ const Import &i = imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
@@ -2424,10 +2418,9 @@ JSImportScope::JSImportScope(const Imports *imports, ValueOwner *valueOwner)
const Value *JSImportScope::lookupMember(const QString &name, const Context *,
const ObjectValue **foundInObject, bool) const
{
- QListIterator<Import> it(m_imports->all());
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ const QList<Import> &imports = m_imports->all();
+ for (int pos = imports.size(); --pos >= 0; ) {
+ const Import &i = imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
@@ -2443,16 +2436,15 @@ const Value *JSImportScope::lookupMember(const QString &name, const Context *,
}
}
if (foundInObject)
- *foundInObject = 0;
- return 0;
+ *foundInObject = nullptr;
+ return nullptr;
}
void JSImportScope::processMembers(MemberProcessor *processor) const
{
- QListIterator<Import> it(m_imports->all());
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ const QList<Import> &imports = m_imports->all();
+ for (int pos = imports.size(); --pos >= 0; ) {
+ const Import &i = imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
@@ -2505,10 +2497,8 @@ ImportInfo Imports::info(const QString &name, const Context *context) const
if (dotIdx != -1)
firstId = firstId.left(dotIdx);
- QListIterator<Import> it(m_imports);
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ for (int pos = m_imports.size(); --pos >= 0; ) {
+ const Import &i = m_imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
@@ -2531,10 +2521,8 @@ ImportInfo Imports::info(const QString &name, const Context *context) const
QString Imports::nameForImportedObject(const ObjectValue *value, const Context *context) const
{
- QListIterator<Import> it(m_imports);
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ for (int pos = m_imports.size(); --pos >= 0; ) {
+ const Import &i = m_imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
@@ -2617,10 +2605,8 @@ public:
void Imports::dump() const
{
qCDebug(qmljsLog) << "Imports contents, in search order:";
- QListIterator<Import> it(m_imports);
- it.toBack();
- while (it.hasPrevious()) {
- const Import &i = it.previous();
+ for (int pos = m_imports.size(); --pos >= 0; ) {
+ const Import &i = m_imports.at(pos);
const ObjectValue *import = i.object;
const ImportInfo &info = i.info;
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index f2e953180c..a726b3bff1 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -163,163 +163,163 @@ template <typename RetTy> const RetTy *value_cast(const Value *)
template <> Q_INLINE_TEMPLATE const NullValue *value_cast(const Value *v)
{
if (v) return v->asNullValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const UndefinedValue *value_cast(const Value *v)
{
if (v) return v->asUndefinedValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const UnknownValue *value_cast(const Value *v)
{
if (v) return v->asUnknownValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const NumberValue *value_cast(const Value *v)
{
if (v) return v->asNumberValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const IntValue *value_cast(const Value *v)
{
if (v) return v->asIntValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const RealValue *value_cast(const Value *v)
{
if (v) return v->asRealValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const BooleanValue *value_cast(const Value *v)
{
if (v) return v->asBooleanValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const StringValue *value_cast(const Value *v)
{
if (v) return v->asStringValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const UrlValue *value_cast(const Value *v)
{
if (v) return v->asUrlValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ObjectValue *value_cast(const Value *v)
{
if (v) return v->asObjectValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ASTFunctionValue *value_cast(const Value *v)
{
if (v) return v->asAstFunctionValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const FunctionValue *value_cast(const Value *v)
{
if (v) return v->asFunctionValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const Reference *value_cast(const Value *v)
{
if (v) return v->asReference();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ColorValue *value_cast(const Value *v)
{
if (v) return v->asColorValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const AnchorLineValue *value_cast(const Value *v)
{
if (v) return v->asAnchorLineValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const CppComponentValue *value_cast(const Value *v)
{
if (v) return v->asCppComponentValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ASTObjectValue *value_cast(const Value *v)
{
if (v) return v->asAstObjectValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const QmlEnumValue *value_cast(const Value *v)
{
if (v) return v->asQmlEnumValue();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const QmlPrototypeReference *value_cast(const Value *v)
{
if (v) return v->asQmlPrototypeReference();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ASTPropertyReference *value_cast(const Value *v)
{
if (v) return v->asAstPropertyReference();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const Internal::QtObjectPrototypeReference *value_cast(const Value *v)
{
if (v) return v->asQtObjectPrototypeReference();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ASTVariableReference *value_cast(const Value *v)
{
if (v) return v->asAstVariableReference();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const Function *value_cast(const Value *v)
{
if (v) return v->asFunction();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const MetaFunction *value_cast(const Value *v)
{
if (v) return v->asMetaFunction();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const JSImportScope *value_cast(const Value *v)
{
if (v) return v->asJSImportScope();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const TypeScope *value_cast(const Value *v)
{
if (v) return v->asTypeScope();
- else return 0;
+ else return nullptr;
}
template <> Q_INLINE_TEMPLATE const ASTSignal *value_cast(const Value *v)
{
if (v) return v->asAstSignal();
- else return 0;
+ else return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
@@ -480,7 +480,7 @@ class QMLJS_EXPORT PropertyData {
public:
const Value *value;
PropertyInfo propertyInfo;
- PropertyData(const Value *value = 0,
+ PropertyData(const Value *value = nullptr,
PropertyInfo propertyInfo = PropertyInfo(PropertyInfo::Default))
: value(value), propertyInfo(propertyInfo)
{ }
@@ -513,10 +513,10 @@ public:
virtual void removeMember(const QString &name);
virtual const Value *lookupMember(const QString &name, const Context *context,
- const ObjectValue **foundInObject = 0,
+ const ObjectValue **foundInObject = nullptr,
bool examinePrototypes = true) const;
virtual const Value *lookupMember(const QString &name, const ContextPtr &context,
- const ObjectValue **foundInObject = 0,
+ const ObjectValue **foundInObject = nullptr,
bool examinePrototypes = true) const
{ return lookupMember(name, context.data(), foundInObject, examinePrototypes); }
@@ -620,8 +620,8 @@ public:
bool hasLocalProperty(const QString &typeName) const;
bool hasProperty(const QString &typeName) const;
- LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const CppComponentValue **foundInScope = 0) const;
- const QmlEnumValue *getEnumValue(const QString &typeName, const CppComponentValue **foundInScope = 0) const;
+ LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const CppComponentValue **foundInScope = nullptr) const;
+ const QmlEnumValue *getEnumValue(const QString &typeName, const CppComponentValue **foundInScope = nullptr) const;
const ObjectValue *signalScope(const QString &signalName) const;
protected:
@@ -1000,11 +1000,11 @@ public:
ImportInfo();
static ImportInfo moduleImport(QString uri, LanguageUtils::ComponentVersion version,
- const QString &as, AST::UiImport *ast = 0);
+ const QString &as, AST::UiImport *ast = nullptr);
static ImportInfo pathImport(const QString &docPath, const QString &path,
LanguageUtils::ComponentVersion version,
- const QString &as, AST::UiImport *ast = 0);
- static ImportInfo invalidImport(AST::UiImport *ast = 0);
+ const QString &as, AST::UiImport *ast = nullptr);
+ static ImportInfo invalidImport(AST::UiImport *ast = nullptr);
static ImportInfo implicitDirectoryImport(const QString &directory);
static ImportInfo qrcDirectoryImport(const QString &directory);
@@ -1059,7 +1059,7 @@ public:
TypeScope(const Imports *imports, ValueOwner *valueOwner);
virtual const Value *lookupMember(const QString &name, const Context *context,
- const ObjectValue **foundInObject = 0,
+ const ObjectValue **foundInObject = nullptr,
bool examinePrototypes = true) const override;
void processMembers(MemberProcessor *processor) const override;
const TypeScope *asTypeScope() const override;
@@ -1073,7 +1073,7 @@ public:
JSImportScope(const Imports *imports, ValueOwner *valueOwner);
virtual const Value *lookupMember(const QString &name, const Context *context,
- const ObjectValue **foundInObject = 0,
+ const ObjectValue **foundInObject = nullptr,
bool examinePrototypes = true) const override;
void processMembers(MemberProcessor *processor) const override;
const JSImportScope *asJSImportScope() const override;
diff --git a/src/libs/qmljs/qmljslineinfo.cpp b/src/libs/qmljs/qmljslineinfo.cpp
index e3a83e1244..9a7ab32e25 100644
--- a/src/libs/qmljs/qmljslineinfo.cpp
+++ b/src/libs/qmljs/qmljslineinfo.cpp
@@ -89,9 +89,9 @@ LineInfo::LineInfo()
*/
// shorthands
- yyLine = 0;
- yyBraceDepth = 0;
- yyLeftBraceFollows = 0;
+ yyLine = nullptr;
+ yyBraceDepth = nullptr;
+ yyLeftBraceFollows = nullptr;
}
LineInfo::~LineInfo()
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 1acdb68ed9..396e69b8e5 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -138,29 +138,24 @@ Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const Librar
d->builtins = builtins;
d->vContext = vContext;
- d->diagnosticMessages = 0;
- d->allDiagnosticMessages = 0;
+ d->diagnosticMessages = nullptr;
+ d->allDiagnosticMessages = nullptr;
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
if (modelManager) {
- ModelManagerInterface::CppDataHash cppDataHash = modelManager->cppData();
+ const ModelManagerInterface::CppDataHash cppDataHash = modelManager->cppData();
{
// populate engine with types from C++
- ModelManagerInterface::CppDataHashIterator cppDataHashIterator(cppDataHash);
- while (cppDataHashIterator.hasNext()) {
- cppDataHashIterator.next();
- d->valueOwner->cppQmlTypes().load(cppDataHashIterator.key(),
- cppDataHashIterator.value().exportedTypes);
- }
+ for (auto it = cppDataHash.cbegin(), end = cppDataHash.cend(); it != end; ++it)
+ d->valueOwner->cppQmlTypes().load(it.key(), it.value().exportedTypes);
}
// build an object with the context properties from C++
- ObjectValue *cppContextProperties = d->valueOwner->newObject(/* prototype = */ 0);
- foreach (const ModelManagerInterface::CppData &cppData, cppDataHash) {
- QHashIterator<QString, QString> it(cppData.contextProperties);
- while (it.hasNext()) {
- it.next();
- const Value *value = 0;
+ ObjectValue *cppContextProperties = d->valueOwner->newObject(/* prototype = */ nullptr);
+ for (const ModelManagerInterface::CppData &cppData : cppDataHash) {
+ for (auto it = cppData.contextProperties.cbegin(), end = cppData.contextProperties.cend();
+ it != end; ++it) {
+ const Value *value = nullptr;
const QString cppTypeName = it.value();
if (!cppTypeName.isEmpty())
value = d->valueOwner->cppQmlTypes().objectByCppName(cppTypeName);
@@ -294,7 +289,7 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
{
Import import;
import.info = importInfo;
- import.object = 0;
+ import.object = nullptr;
import.valid = true;
QString path = importInfo.path();
@@ -319,7 +314,7 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
} else if (importInfo.type() == ImportType::QrcFile) {
QLocale locale;
QStringList filePaths = ModelManagerInterface::instance()
- ->filesAtQrcPath(path, &locale, 0, ModelManagerInterface::ActiveQrcResources);
+ ->filesAtQrcPath(path, &locale, nullptr, ModelManagerInterface::ActiveQrcResources);
if (filePaths.isEmpty())
filePaths = ModelManagerInterface::instance()->filesAtQrcPath(path);
if (!filePaths.isEmpty()) {
@@ -332,10 +327,8 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
importLibrary(doc, path, &import);
- QMapIterator<QString,QStringList> iter(ModelManagerInterface::instance()
- ->filesInQrcPath(path));
- while (iter.hasNext()) {
- iter.next();
+ const QMap<QString, QStringList> paths = ModelManagerInterface::instance()->filesInQrcPath(path);
+ for (auto iter = paths.cbegin(), end = paths.cend(); iter != end; ++iter) {
if (ModelManagerInterface::guessLanguageOfFile(iter.key()).isQmlLikeLanguage()) {
Document::Ptr importedDoc = snapshot.document(iter.value().at(0));
if (importedDoc && importedDoc->bind()->rootObjectValue()) {
diff --git a/src/libs/qmljs/qmljslink.h b/src/libs/qmljs/qmljslink.h
index 59e5e3f85a..e4357061b3 100644
--- a/src/libs/qmljs/qmljslink.h
+++ b/src/libs/qmljs/qmljslink.h
@@ -46,7 +46,7 @@ public:
Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins);
// Link all documents in snapshot, collecting all diagnostic messages (if messages != 0)
- ContextPtr operator()(QHash<QString, QList<DiagnosticMessage> > *messages = 0);
+ ContextPtr operator()(QHash<QString, QList<DiagnosticMessage> > *messages = nullptr);
// Link all documents in snapshot, appending the diagnostic messages
// for 'doc' in 'messages'
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 6bb1bc8ff9..4453172e8a 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -175,15 +175,10 @@ Dialect ModelManagerInterface::guessLanguageOfFile(const QString &fileName)
QStringList ModelManagerInterface::globPatternsForLanguages(const QList<Dialect> languages)
{
- QHash<QString, Dialect> lMapping;
- if (instance())
- lMapping = instance()->languageForSuffix();
- else
- lMapping = defaultLanguageMapping();
QStringList patterns;
- QHashIterator<QString,Dialect> i(lMapping);
- while (i.hasNext()) {
- i.next();
+ const QHash<QString, Dialect> lMapping =
+ instance() ? instance()->languageForSuffix() : defaultLanguageMapping();
+ for (auto i = lMapping.cbegin(), end = lMapping.cend(); i != end; ++i) {
if (languages.contains(i.value()))
patterns << QLatin1String("*.") + i.key();
}
@@ -237,7 +232,7 @@ ModelManagerInterface::WorkingCopy ModelManagerInterface::workingCopyInternal()
void ModelManagerInterface::addTaskInternal(QFuture<void> result, const QString &msg,
const char *taskId) const
{
- Q_UNUSED(result);
+ Q_UNUSED(result)
qCDebug(qmljsLog) << "started " << taskId << " " << msg;
}
@@ -725,9 +720,8 @@ static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapsho
*importedFiles += importPath;
}
} else if (import.type() == ImportType::QrcDirectory) {
- QMapIterator<QString,QStringList> dirContents(ModelManagerInterface::instance()->filesInQrcPath(importName));
- while (dirContents.hasNext()) {
- dirContents.next();
+ const QMap<QString, QStringList> files = ModelManagerInterface::instance()->filesInQrcPath(importName);
+ for (auto dirContents = files.cbegin(), end = files.cend(); dirContents != end; ++dirContents) {
if (ModelManagerInterface::guessLanguageOfFile(dirContents.key()).isQmlLikeOrJsLanguage()) {
foreach (const QString &filePath, dirContents.value()) {
if (! snapshot.document(filePath))
@@ -1091,10 +1085,7 @@ void ModelManagerInterface::updateImportPaths()
PathsAndLanguages allImportPaths;
QmlLanguageBundles activeBundles;
QmlLanguageBundles extendedBundles;
- QMapIterator<ProjectExplorer::Project *, ProjectInfo> pInfoIter(m_projects);
- QHashIterator<Dialect, QmlJS::ViewerContext> vCtxsIter = m_defaultVContexts;
- while (pInfoIter.hasNext()) {
- pInfoIter.next();
+ for (auto pInfoIter = m_projects.cbegin(), end = m_projects.cend(); pInfoIter != end; ++pInfoIter) {
const PathsAndLanguages &iPaths = pInfoIter.value().importPaths;
for (int i = 0; i < iPaths.size(); ++i) {
PathAndLanguage pAndL = iPaths.at(i);
@@ -1104,14 +1095,12 @@ void ModelManagerInterface::updateImportPaths()
pAndL.language());
}
}
- while (vCtxsIter.hasNext()) {
- vCtxsIter.next();
+ for (auto vCtxsIter = m_defaultVContexts.cbegin(), end = m_defaultVContexts.cend();
+ vCtxsIter != end; ++ vCtxsIter) {
foreach (const QString &path, vCtxsIter.value().paths)
allImportPaths.maybeInsert(Utils::FilePath::fromString(path), vCtxsIter.value().language);
}
- pInfoIter.toFront();
- while (pInfoIter.hasNext()) {
- pInfoIter.next();
+ for (auto pInfoIter = m_projects.cbegin(), end = m_projects.cend(); pInfoIter != end; ++pInfoIter) {
activeBundles.mergeLanguageBundles(pInfoIter.value().activeBundle);
foreach (Dialect l, pInfoIter.value().activeBundle.languages()) {
foreach (const QString &path, pInfoIter.value().activeBundle.bundleForLanguage(l)
@@ -1122,9 +1111,7 @@ void ModelManagerInterface::updateImportPaths()
}
}
}
- pInfoIter.toFront();
- while (pInfoIter.hasNext()) {
- pInfoIter.next();
+ for (auto pInfoIter = m_projects.cbegin(), end = m_projects.cend(); pInfoIter != end; ++pInfoIter) {
QString pathAtt = pInfoIter.value().qtQmlPath;
if (!pathAtt.isEmpty())
allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h
index cd36cbca2f..b9bfe67db4 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.h
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h
@@ -132,7 +132,6 @@ public:
};
typedef QHash<QString, CppData> CppDataHash;
- typedef QHashIterator<QString, CppData> CppDataHashIterator;
public:
ModelManagerInterface(QObject *parent = nullptr);
diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp
index 2c6afb61c0..e4f51e64c2 100644
--- a/src/libs/qmljs/qmljsplugindumper.cpp
+++ b/src/libs/qmljs/qmljsplugindumper.cpp
@@ -44,7 +44,7 @@ using namespace QmlJS;
PluginDumper::PluginDumper(ModelManagerInterface *modelManager)
: QObject(modelManager)
, m_modelManager(modelManager)
- , m_pluginWatcher(0)
+ , m_pluginWatcher(nullptr)
{
qRegisterMetaType<QmlJS::ModelManagerInterface::ProjectInfo>("QmlJS::ModelManagerInterface::ProjectInfo");
}
@@ -436,7 +436,7 @@ void PluginDumper::loadDependencies(const QStringList &dependencies,
visitedPtr->insert(name);
}
QStringList newDependencies;
- loadQmlTypeDescription(dependenciesPaths, errors, warnings, objects, 0, &newDependencies);
+ loadQmlTypeDescription(dependenciesPaths, errors, warnings, objects, nullptr, &newDependencies);
newDependencies = Utils::toList(Utils::toSet(newDependencies) - *visitedPtr);
if (!newDependencies.isEmpty())
loadDependencies(newDependencies, errors, warnings, objects, visitedPtr.take());
diff --git a/src/libs/qmljs/qmljsrewriter.cpp b/src/libs/qmljs/qmljsrewriter.cpp
index b672f8df86..25cad3d2db 100644
--- a/src/libs/qmljs/qmljsrewriter.cpp
+++ b/src/libs/qmljs/qmljsrewriter.cpp
@@ -67,7 +67,7 @@ Rewriter::Range Rewriter::addBinding(AST::UiObjectInitializer *ast,
SourceLocation endOfPreviousMember;
SourceLocation startOfNextMember;
- if (insertAfter == 0 || insertAfter->member == 0) {
+ if (insertAfter == nullptr || insertAfter->member == nullptr) {
// insert as first member
endOfPreviousMember = ast->lbraceToken;
@@ -88,7 +88,7 @@ Rewriter::Range Rewriter::addBinding(AST::UiObjectInitializer *ast,
bool needsTrailingSemicolon = false;
if (isOneLiner) {
- if (insertAfter == 0) { // we're inserting after an lbrace
+ if (insertAfter == nullptr) { // we're inserting after an lbrace
if (ast->members) { // we're inserting before a member (and not the rbrace)
needsTrailingSemicolon = bindingType == ScriptBinding;
}
@@ -142,8 +142,8 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb
{
const int objectDefinitionInsertionPoint = propertyOrder.indexOf(QString());
- UiObjectMemberList *lastObjectDef = 0;
- UiObjectMemberList *lastNonObjectDef = 0;
+ UiObjectMemberList *lastObjectDef = nullptr;
+ UiObjectMemberList *lastNonObjectDef = nullptr;
for (UiObjectMemberList *iter = members; iter; iter = iter->next) {
UiObjectMember *member = iter->member;
@@ -175,8 +175,8 @@ UiArrayMemberList *Rewriter::searchMemberToInsertAfter(UiArrayMemberList *member
{
const int objectDefinitionInsertionPoint = propertyOrder.indexOf(QString());
- UiArrayMemberList *lastObjectDef = 0;
- UiArrayMemberList *lastNonObjectDef = 0;
+ UiArrayMemberList *lastObjectDef = nullptr;
+ UiArrayMemberList *lastNonObjectDef = nullptr;
for (UiArrayMemberList *iter = members; iter; iter = iter->next) {
UiObjectMember *member = iter->member;
@@ -208,7 +208,7 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb
const QStringList &propertyOrder)
{
if (!members)
- return 0; // empty members
+ return nullptr; // empty members
QHash<QString, UiObjectMemberList *> orderedMembers;
@@ -236,11 +236,11 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb
for (; idx > 0; --idx) {
const QString prop = propertyOrder.at(idx - 1);
UiObjectMemberList *candidate = orderedMembers.value(prop, 0);
- if (candidate != 0)
+ if (candidate != nullptr)
return candidate;
}
- return 0;
+ return nullptr;
}
void Rewriter::changeBinding(UiObjectInitializer *ast,
@@ -356,7 +356,7 @@ void Rewriter::insertIntoArray(UiArrayBinding *ast, const QString &newValue)
if (!ast)
return;
- UiObjectMember *lastMember = 0;
+ UiObjectMember *lastMember = nullptr;
for (UiArrayMemberList *iter = ast->members; iter; iter = iter->next) {
lastMember = iter->member;
}
@@ -400,7 +400,7 @@ void Rewriter::removeGroupedProperty(UiObjectDefinition *ast,
const QString propName = propertyName.mid(dotIdx + 1);
- UiObjectMember *wanted = 0;
+ UiObjectMember *wanted = nullptr;
unsigned memberCount = 0;
for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) {
++memberCount;
@@ -590,7 +590,7 @@ UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(UiObjectMemberList *m
void Rewriter::appendToArrayBinding(UiArrayBinding *arrayBinding,
const QString &content)
{
- UiObjectMember *lastMember = 0;
+ UiObjectMember *lastMember = nullptr;
for (UiArrayMemberList *iter = arrayBinding->members; iter; iter = iter->next)
if (iter->member)
lastMember = iter->member;
@@ -671,7 +671,7 @@ void Rewriter::extendToLeadingOrTrailingComma(UiArrayBinding *parentArray,
int &start,
int &end) const
{
- UiArrayMemberList *currentMember = 0;
+ UiArrayMemberList *currentMember = nullptr;
for (UiArrayMemberList *it = parentArray->members; it; it = it->next) {
if (it->member == member) {
currentMember = it;
diff --git a/src/libs/qmljs/qmljsscopebuilder.cpp b/src/libs/qmljs/qmljsscopebuilder.cpp
index 7b071662b9..ca59e74dca 100644
--- a/src/libs/qmljs/qmljsscopebuilder.cpp
+++ b/src/libs/qmljs/qmljsscopebuilder.cpp
@@ -67,8 +67,8 @@ void ScopeBuilder::push(AST::Node *node)
if (!_scopeChain->qmlScopeObjects().isEmpty()
&& name.startsWith(QLatin1String("on"))
&& !script->qualifiedId->next) {
- const ObjectValue *owner = 0;
- const Value *value = 0;
+ const ObjectValue *owner = nullptr;
+ const Value *value = nullptr;
// try to find the name on the scope objects
foreach (const ObjectValue *scope, _scopeChain->qmlScopeObjects()) {
value = scope->lookupMember(name, _scopeChain->context(), &owner);
@@ -217,19 +217,19 @@ void ScopeBuilder::setQmlScopeObject(Node *node)
const Value *ScopeBuilder::scopeObjectLookup(AST::UiQualifiedId *id)
{
// do a name lookup on the scope objects
- const Value *result = 0;
+ const Value *result = nullptr;
foreach (const ObjectValue *scopeObject, _scopeChain->qmlScopeObjects()) {
const ObjectValue *object = scopeObject;
for (UiQualifiedId *it = id; it; it = it->next) {
if (it->name.isEmpty())
- return 0;
+ return nullptr;
result = object->lookupMember(it->name.toString(), _scopeChain->context());
if (!result)
break;
if (it->next) {
object = result->asObjectValue();
if (!object) {
- result = 0;
+ result = nullptr;
break;
}
}
@@ -255,5 +255,5 @@ const ObjectValue *ScopeBuilder::isPropertyChangesObject(const ContextPtr &conte
return prototype;
}
}
- return 0;
+ return nullptr;
}
diff --git a/src/libs/qmljs/qmljsscopechain.cpp b/src/libs/qmljs/qmljsscopechain.cpp
index cda0b0c656..c9fadb91e9 100644
--- a/src/libs/qmljs/qmljsscopechain.cpp
+++ b/src/libs/qmljs/qmljsscopechain.cpp
@@ -77,14 +77,14 @@ QList<const QmlComponentChain *> QmlComponentChain::instantiatingComponents() co
const ObjectValue *QmlComponentChain::idScope() const
{
if (!m_document)
- return 0;
+ return nullptr;
return m_document->bind()->idEnvironment();
}
const ObjectValue *QmlComponentChain::rootObjectScope() const
{
if (!m_document)
- return 0;
+ return nullptr;
return m_document->bind()->rootObjectValue();
}
@@ -97,10 +97,10 @@ void QmlComponentChain::addInstantiatingComponent(const QmlComponentChain *compo
ScopeChain::ScopeChain(const Document::Ptr &document, const ContextPtr &context)
: m_document(document)
, m_context(context)
- , m_globalScope(0)
- , m_cppContextProperties(0)
- , m_qmlTypes(0)
- , m_jsImports(0)
+ , m_globalScope(nullptr)
+ , m_cppContextProperties(nullptr)
+ , m_qmlTypes(nullptr)
+ , m_jsImports(nullptr)
, m_modified(false)
{
initializeRootScope();
@@ -130,7 +130,7 @@ const Value * ScopeChain::lookup(const QString &name, const ObjectValue **foundI
}
if (foundInScope)
- *foundInScope = 0;
+ *foundInScope = nullptr;
// we're confident to implement global lookup correctly, so return 'undefined'
return m_context->valueOwner()->undefinedValue();
@@ -264,8 +264,8 @@ void ScopeChain::update() const
}
}
- ObjectValue *root = 0;
- ObjectValue *ids = 0;
+ ObjectValue *root = nullptr;
+ ObjectValue *ids = nullptr;
if (m_qmlComponentScope && m_qmlComponentScope->document()) {
const Bind *bind = m_qmlComponentScope->document()->bind();
root = bind->rootObjectValue();
diff --git a/src/libs/qmljs/qmljsscopechain.h b/src/libs/qmljs/qmljsscopechain.h
index a08d686248..829ff1230f 100644
--- a/src/libs/qmljs/qmljsscopechain.h
+++ b/src/libs/qmljs/qmljsscopechain.h
@@ -72,7 +72,7 @@ public:
Document::Ptr document() const;
const ContextPtr &context() const;
- const Value *lookup(const QString &name, const ObjectValue **foundInScope = 0) const;
+ const Value *lookup(const QString &name, const ObjectValue **foundInScope = nullptr) const;
const Value *evaluate(AST::Node *node) const;
const ObjectValue *globalScope() const;
diff --git a/src/libs/qmljs/qmljstypedescriptionreader.cpp b/src/libs/qmljs/qmljstypedescriptionreader.cpp
index 80ec498d8f..895922a1eb 100644
--- a/src/libs/qmljs/qmljstypedescriptionreader.cpp
+++ b/src/libs/qmljs/qmljstypedescriptionreader.cpp
@@ -42,7 +42,7 @@ using namespace QmlJS::AST;
using namespace LanguageUtils;
TypeDescriptionReader::TypeDescriptionReader(const QString &fileName, const QString &data)
- : _fileName (fileName), _source(data), _objects(0)
+ : _fileName (fileName), _source(data), _objects(nullptr)
{
}
diff --git a/src/libs/qmljs/qmljsutils.cpp b/src/libs/qmljs/qmljsutils.cpp
index d212e8fdcd..4872a0bae7 100644
--- a/src/libs/qmljs/qmljsutils.cpp
+++ b/src/libs/qmljs/qmljsutils.cpp
@@ -140,7 +140,7 @@ SourceLocation QmlJS::fullLocationForQualifiedId(AST::UiQualifiedId *qualifiedId
QString QmlJS::idOfObject(Node *object, UiScriptBinding **idBinding)
{
if (idBinding)
- *idBinding = 0;
+ *idBinding = nullptr;
UiObjectInitializer *initializer = initializerOfObject(object);
if (!initializer) {
@@ -179,7 +179,7 @@ UiObjectInitializer *QmlJS::initializerOfObject(Node *object)
return definition->initializer;
if (UiObjectBinding *binding = cast<UiObjectBinding *>(object))
return binding->initializer;
- return 0;
+ return nullptr;
}
UiQualifiedId *QmlJS::qualifiedTypeNameId(Node *node)
@@ -188,7 +188,7 @@ UiQualifiedId *QmlJS::qualifiedTypeNameId(Node *node)
return binding->qualifiedTypeNameId;
else if (UiObjectDefinition *binding = AST::cast<UiObjectDefinition *>(node))
return binding->qualifiedTypeNameId;
- return 0;
+ return nullptr;
}
DiagnosticMessage QmlJS::errorMessage(const AST::SourceLocation &loc, const QString &message)
diff --git a/src/libs/qmljs/qmljsutils.h b/src/libs/qmljs/qmljsutils.h
index a9da56ed2d..103548ade3 100644
--- a/src/libs/qmljs/qmljsutils.h
+++ b/src/libs/qmljs/qmljsutils.h
@@ -43,7 +43,7 @@ QMLJS_EXPORT AST::SourceLocation locationFromRange(const AST::SourceLocation &st
QMLJS_EXPORT AST::SourceLocation fullLocationForQualifiedId(AST::UiQualifiedId *);
-QMLJS_EXPORT QString idOfObject(AST::Node *object, AST::UiScriptBinding **idBinding = 0);
+QMLJS_EXPORT QString idOfObject(AST::Node *object, AST::UiScriptBinding **idBinding = nullptr);
QMLJS_EXPORT AST::UiObjectInitializer *initializerOfObject(AST::Node *object);
diff --git a/src/libs/qmljs/qmljsvalueowner.cpp b/src/libs/qmljs/qmljsvalueowner.cpp
index bc58f61490..573ccb2aa1 100644
--- a/src/libs/qmljs/qmljsvalueowner.cpp
+++ b/src/libs/qmljs/qmljsvalueowner.cpp
@@ -130,7 +130,7 @@ SharedValueOwner *ValueOwner::sharedValueOwner(QString kind)
SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
: ValueOwner(this) // need to avoid recursing in ValueOwner ctor
{
- _objectPrototype = newObject(/*prototype = */ 0);
+ _objectPrototype = newObject(/*prototype = */ nullptr);
_functionPrototype = newObject(_objectPrototype);
_numberPrototype = newObject(_objectPrototype);
_booleanPrototype = newObject(_objectPrototype);
@@ -409,7 +409,7 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
_globalObject->setMember(QLatin1String("Date"), dateCtor());
_globalObject->setMember(QLatin1String("RegExp"), regexpCtor());
- Function *f = 0;
+ Function *f = nullptr;
// XMLHttpRequest
ObjectValue *xmlHttpRequest = newObject();
@@ -477,7 +477,7 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
_globalObject->setMember(QLatin1String("JSON"), json);
// QML objects
- _qmlFontObject = newObject(/*prototype =*/ 0);
+ _qmlFontObject = newObject(/*prototype =*/ nullptr);
_qmlFontObject->setClassName(QLatin1String("font"));
_qmlFontObject->setMember(QLatin1String("family"), stringValue());
_qmlFontObject->setMember(QLatin1String("styleName"), stringValue());
@@ -496,24 +496,24 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
_qmlFontObject->setMember(QLatin1String("kerning"), booleanValue());
_qmlFontObject->setMember(QLatin1String("preferShaping"), booleanValue());
- _qmlPointObject = newObject(/*prototype =*/ 0);
+ _qmlPointObject = newObject(/*prototype =*/ nullptr);
_qmlPointObject->setClassName(QLatin1String("Point"));
_qmlPointObject->setMember(QLatin1String("x"), numberValue());
_qmlPointObject->setMember(QLatin1String("y"), numberValue());
- _qmlSizeObject = newObject(/*prototype =*/ 0);
+ _qmlSizeObject = newObject(/*prototype =*/ nullptr);
_qmlSizeObject->setClassName(QLatin1String("Size"));
_qmlSizeObject->setMember(QLatin1String("width"), numberValue());
_qmlSizeObject->setMember(QLatin1String("height"), numberValue());
- _qmlRectObject = newObject(/*prototype =*/ 0);
+ _qmlRectObject = newObject(/*prototype =*/ nullptr);
_qmlRectObject->setClassName(QLatin1String("Rect"));
_qmlRectObject->setMember(QLatin1String("x"), numberValue());
_qmlRectObject->setMember(QLatin1String("y"), numberValue());
_qmlRectObject->setMember(QLatin1String("width"), numberValue());
_qmlRectObject->setMember(QLatin1String("height"), numberValue());
- _qmlVector2DObject = newObject(/*prototype =*/ 0);
+ _qmlVector2DObject = newObject(/*prototype =*/ nullptr);
_qmlVector2DObject->setClassName(QLatin1String("Vector2D"));
_qmlVector2DObject->setMember(QLatin1String("x"), realValue());
_qmlVector2DObject->setMember(QLatin1String("y"), realValue());
@@ -527,7 +527,7 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
addFunction(_qmlVector2DObject, QLatin1String("toVector4d"), _qmlVector4DObject, 0);
addFunction(_qmlVector2DObject, QLatin1String("fuzzyEquals"), booleanValue(), 1, 1);
- _qmlVector3DObject = newObject(/*prototype =*/ 0);
+ _qmlVector3DObject = newObject(/*prototype =*/ nullptr);
_qmlVector3DObject->setClassName(QLatin1String("Vector3D"));
_qmlVector3DObject->setMember(QLatin1String("x"), realValue());
_qmlVector3DObject->setMember(QLatin1String("y"), realValue());
@@ -542,7 +542,7 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
addFunction(_qmlVector3DObject, QLatin1String("toVector4d"), _qmlVector4DObject, 0);
addFunction(_qmlVector3DObject, QLatin1String("fuzzyEquals"), booleanValue(), 1, 1);
- _qmlVector4DObject = newObject(/*prototype =*/ 0);
+ _qmlVector4DObject = newObject(/*prototype =*/ nullptr);
_qmlVector4DObject->setClassName(QLatin1String("Vector4D"));
_qmlVector4DObject->setMember(QLatin1String("x"), realValue());
_qmlVector4DObject->setMember(QLatin1String("y"), realValue());
@@ -558,14 +558,14 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
addFunction(_qmlVector4DObject, QLatin1String("toVector3d"), _qmlVector3DObject, 0);
addFunction(_qmlVector4DObject, QLatin1String("fuzzyEquals"), booleanValue(), 1, 1);
- _qmlQuaternionObject = newObject(/*prototype =*/ 0);
+ _qmlQuaternionObject = newObject(/*prototype =*/ nullptr);
_qmlQuaternionObject->setClassName(QLatin1String("Quaternion"));
_qmlQuaternionObject->setMember(QLatin1String("scalar"), realValue());
_qmlQuaternionObject->setMember(QLatin1String("x"), realValue());
_qmlQuaternionObject->setMember(QLatin1String("y"), realValue());
_qmlQuaternionObject->setMember(QLatin1String("z"), realValue());
- _qmlMatrix4x4Object = newObject(/*prototype =*/ 0);
+ _qmlMatrix4x4Object = newObject(/*prototype =*/ nullptr);
_qmlMatrix4x4Object->setClassName(QLatin1String("Matrix4x4"));
for (int i = 1; i < 5; ++i)
for (int j = 1; j < 5; ++j)
@@ -634,7 +634,7 @@ SharedValueOwner::SharedValueOwner(SharedValueOwnerKind kind)
_globalObject->setMember(QLatin1String("Qt"), _qtObject);
// firebug/webkit compat
- ObjectValue *consoleObject = newObject(/*prototype */ 0);
+ ObjectValue *consoleObject = newObject(/*prototype */ nullptr);
addFunction(consoleObject, QLatin1String("log"), 1, 0, true);
addFunction(consoleObject, QLatin1String("debug"), 1, 0, true);
if (kind == Qt5Kind) {
diff --git a/src/libs/qmljs/qmljsvalueowner.h b/src/libs/qmljs/qmljsvalueowner.h
index 90c3f923e2..9c5adfe53d 100644
--- a/src/libs/qmljs/qmljsvalueowner.h
+++ b/src/libs/qmljs/qmljsvalueowner.h
@@ -62,7 +62,7 @@ class QMLJS_EXPORT ValueOwner
public:
static SharedValueOwner *sharedValueOwner(QString kind = QString());
- ValueOwner(const SharedValueOwner *shared = 0);
+ ValueOwner(const SharedValueOwner *shared = nullptr);
virtual ~ValueOwner();
const NullValue *nullValue() const;
diff --git a/src/libs/sqlite/CMakeLists.txt b/src/libs/sqlite/CMakeLists.txt
index 48eda5cf92..62c8609a7a 100644
--- a/src/libs/sqlite/CMakeLists.txt
+++ b/src/libs/sqlite/CMakeLists.txt
@@ -3,7 +3,7 @@ add_qtc_library(Sqlite
SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS
SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA
BUILD_SQLITE_LIBRARY
- DEPENDS Qt5::Core
+ DEPENDS Qt5::Core Threads::Threads ${CMAKE_DL_LIBS}
PUBLIC_INCLUDES ../3rdparty/sqlite
SOURCES
../3rdparty/sqlite/sqlite3.c
diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp
index 2f60677e59..4d5b350801 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.cpp
+++ b/src/libs/sqlite/sqlitedatabasebackend.cpp
@@ -99,7 +99,7 @@ void DatabaseBackend::open(Utils::SmallStringView databaseFilePath, OpenMode mod
int resultCode = sqlite3_open_v2(databaseFilePath.data(),
&m_databaseHandle,
openMode(mode),
- NULL);
+ nullptr);
checkDatabaseCouldBeOpened(resultCode);
diff --git a/src/libs/ssh/sftpfilesystemmodel.cpp b/src/libs/ssh/sftpfilesystemmodel.cpp
index 0e9eb48e5e..73860bacae 100644
--- a/src/libs/ssh/sftpfilesystemmodel.cpp
+++ b/src/libs/ssh/sftpfilesystemmodel.cpp
@@ -46,7 +46,7 @@ class SftpDirNode;
class SftpFileNode
{
public:
- SftpFileNode() : parent(0) { }
+ SftpFileNode() : parent(nullptr) { }
virtual ~SftpFileNode() { }
QString path;
@@ -98,9 +98,9 @@ using namespace Internal;
SftpFileSystemModel::SftpFileSystemModel(QObject *parent)
: QAbstractItemModel(parent), d(new SftpFileSystemModelPrivate)
{
- d->sshConnection = 0;
+ d->sshConnection = nullptr;
d->rootDirectory = QLatin1Char('/');
- d->rootNode = 0;
+ d->rootNode = nullptr;
d->statJobId = SftpInvalidJob;
}
@@ -131,7 +131,7 @@ void SftpFileSystemModel::setRootDirectory(const QString &path)
beginResetModel();
d->rootDirectory = path;
delete d->rootNode;
- d->rootNode = 0;
+ d->rootNode = nullptr;
d->lsOps.clear();
d->statJobId = SftpInvalidJob;
endResetModel();
@@ -157,7 +157,7 @@ SftpJobId SftpFileSystemModel::downloadFile(const QModelIndex &index, const QStr
int SftpFileSystemModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 2; // type + name
}
@@ -262,17 +262,17 @@ void SftpFileSystemModel::statRootDirectory()
void SftpFileSystemModel::shutDown()
{
if (d->sftpSession) {
- disconnect(d->sftpSession.get(), 0, this, 0);
+ disconnect(d->sftpSession.get(), nullptr, this, nullptr);
d->sftpSession->quit();
d->sftpSession.release()->deleteLater();
}
if (d->sshConnection) {
- disconnect(d->sshConnection, 0, this, 0);
+ disconnect(d->sshConnection, nullptr, this, nullptr);
QSsh::releaseConnection(d->sshConnection);
- d->sshConnection = 0;
+ d->sshConnection = nullptr;
}
delete d->rootNode;
- d->rootNode = 0;
+ d->rootNode = nullptr;
}
void SftpFileSystemModel::handleSshConnectionFailure()
diff --git a/src/libs/ssh/sftpfilesystemmodel.h b/src/libs/ssh/sftpfilesystemmodel.h
index 091dfabb4c..96ba2a2a54 100644
--- a/src/libs/ssh/sftpfilesystemmodel.h
+++ b/src/libs/ssh/sftpfilesystemmodel.h
@@ -41,7 +41,7 @@ class QSSH_EXPORT SftpFileSystemModel : public QAbstractItemModel
{
Q_OBJECT
public:
- explicit SftpFileSystemModel(QObject *parent = 0);
+ explicit SftpFileSystemModel(QObject *parent = nullptr);
~SftpFileSystemModel();
/*
diff --git a/src/libs/ssh/sshconnection.h b/src/libs/ssh/sshconnection.h
index 89af4d71d9..9f6ece99fd 100644
--- a/src/libs/ssh/sshconnection.h
+++ b/src/libs/ssh/sshconnection.h
@@ -99,7 +99,7 @@ class QSSH_EXPORT SshConnection : public QObject
public:
enum State { Unconnected, Connecting, Connected, Disconnecting };
- explicit SshConnection(const SshConnectionParameters &serverInfo, QObject *parent = 0);
+ explicit SshConnection(const SshConnectionParameters &serverInfo, QObject *parent = nullptr);
void connectToHost();
void disconnectFromHost();
diff --git a/src/libs/ssh/sshconnectionmanager.cpp b/src/libs/ssh/sshconnectionmanager.cpp
index c3bb1821ee..68533728f2 100644
--- a/src/libs/ssh/sshconnectionmanager.cpp
+++ b/src/libs/ssh/sshconnectionmanager.cpp
@@ -70,7 +70,7 @@ public:
~SshConnectionManager()
{
foreach (const UnaquiredConnection &connection, m_unacquiredConnections) {
- disconnect(connection.connection, 0, this, 0);
+ disconnect(connection.connection, nullptr, this, nullptr);
delete connection.connection;
}
@@ -162,7 +162,7 @@ public:
}
if (doDelete) {
- disconnect(connection, 0, this, 0);
+ disconnect(connection, nullptr, this, nullptr);
m_deprecatedConnections.removeAll(connection);
connection->deleteLater();
}
@@ -175,7 +175,7 @@ public:
for (int i = 0; i < m_unacquiredConnections.count(); ++i) {
SshConnection * const connection = m_unacquiredConnections.at(i).connection;
if (connection->connectionParameters() == sshParams) {
- disconnect(connection, 0, this, 0);
+ disconnect(connection, nullptr, this, nullptr);
delete connection;
m_unacquiredConnections.removeAt(i);
break;
@@ -205,7 +205,7 @@ private:
return;
if (m_unacquiredConnections.removeOne(UnaquiredConnection(currentConnection))) {
- disconnect(currentConnection, 0, this, 0);
+ disconnect(currentConnection, nullptr, this, nullptr);
currentConnection->deleteLater();
}
}
@@ -216,7 +216,7 @@ private:
for (int i = m_unacquiredConnections.count() - 1; i >= 0; --i) {
UnaquiredConnection &c = m_unacquiredConnections[i];
if (c.scheduledForRemoval) {
- disconnect(c.connection, 0, this, 0);
+ disconnect(c.connection, nullptr, this, nullptr);
c.connection->deleteLater();
m_unacquiredConnections.removeAt(i);
} else {
diff --git a/src/libs/ssh/sshkeycreationdialog.h b/src/libs/ssh/sshkeycreationdialog.h
index a73fb3b3c2..dca0bdef82 100644
--- a/src/libs/ssh/sshkeycreationdialog.h
+++ b/src/libs/ssh/sshkeycreationdialog.h
@@ -37,7 +37,7 @@ class QSSH_EXPORT SshKeyCreationDialog : public QDialog
{
Q_OBJECT
public:
- SshKeyCreationDialog(QWidget *parent = 0);
+ SshKeyCreationDialog(QWidget *parent = nullptr);
~SshKeyCreationDialog();
QString privateKeyFilePath() const;
diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp
index 635f23e150..3d1ef6a81e 100644
--- a/src/libs/ssh/sshremoteprocess.cpp
+++ b/src/libs/ssh/sshremoteprocess.cpp
@@ -83,15 +83,14 @@ SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &co
void SshRemoteProcess::doStart()
{
QTC_ASSERT(!isRunning(), return);
- const QStringList args = fullLocalCommandLine();
+ const Utils::CommandLine cmd = fullLocalCommandLine();
if (!d->displayName.isEmpty()) {
QProcessEnvironment env = processEnvironment();
env.insert("DISPLAY", d->displayName);
setProcessEnvironment(env);
}
- qCDebug(sshLog) << "starting remote process:" << QDir::toNativeSeparators(args.first())
- << args;
- QProcess::start(args.first(), args.mid(1));
+ qCDebug(sshLog) << "starting remote process:" << cmd.toUserOutput();
+ QProcess::start(cmd.executable().toString(), cmd.splitArguments());
}
SshRemoteProcess::~SshRemoteProcess()
@@ -119,17 +118,22 @@ bool SshRemoteProcess::isRunning() const
return state() == QProcess::Running;
}
-QStringList SshRemoteProcess::fullLocalCommandLine() const
+Utils::CommandLine SshRemoteProcess::fullLocalCommandLine() const
{
- QStringList args = QStringList("-q") << d->connectionArgs;
- if (d->useTerminal)
- args.prepend("-tt");
+ Utils::CommandLine cmd{SshSettings::sshFilePath()};
+
if (!d->displayName.isEmpty())
- args.prepend("-X");
+ cmd.addArg("-X");
+ if (d->useTerminal)
+ cmd.addArg("-tt");
+
+ cmd.addArg("-q");
+ cmd.addArgs(d->connectionArgs);
+
if (!d->remoteCommand.isEmpty())
- args << d->remoteCommand;
- args.prepend(SshSettings::sshFilePath().toString());
- return args;
+ cmd.addArg(d->remoteCommand);
+
+ return cmd;
}
} // namespace QSsh
diff --git a/src/libs/ssh/sshremoteprocess.h b/src/libs/ssh/sshremoteprocess.h
index 02ab3546fd..d1d62d76fa 100644
--- a/src/libs/ssh/sshremoteprocess.h
+++ b/src/libs/ssh/sshremoteprocess.h
@@ -28,7 +28,7 @@
#include "ssh_global.h"
#include "sshprocess.h"
-#include <QStringList>
+#include <utils/fileutils.h>
namespace QSsh {
class SshConnection;
@@ -46,7 +46,7 @@ public:
void start();
bool isRunning() const;
- QStringList fullLocalCommandLine() const;
+ Utils::CommandLine fullLocalCommandLine() const;
signals:
void done(const QString &error);
diff --git a/src/libs/ssh/sshremoteprocessrunner.cpp b/src/libs/ssh/sshremoteprocessrunner.cpp
index 7a062e6ab8..0a4419a0d6 100644
--- a/src/libs/ssh/sshremoteprocessrunner.cpp
+++ b/src/libs/ssh/sshremoteprocessrunner.cpp
@@ -189,9 +189,9 @@ void SshRemoteProcessRunner::setState(int newState)
d->m_process.release()->deleteLater();
}
if (d->m_connection) {
- disconnect(d->m_connection, 0, this, 0);
+ disconnect(d->m_connection, nullptr, this, nullptr);
QSsh::releaseConnection(d->m_connection);
- d->m_connection = 0;
+ d->m_connection = nullptr;
}
}
}
diff --git a/src/libs/ssh/sshremoteprocessrunner.h b/src/libs/ssh/sshremoteprocessrunner.h
index 082f30ed57..5b3f1b05b4 100644
--- a/src/libs/ssh/sshremoteprocessrunner.h
+++ b/src/libs/ssh/sshremoteprocessrunner.h
@@ -36,7 +36,7 @@ class QSSH_EXPORT SshRemoteProcessRunner : public QObject
Q_OBJECT
public:
- SshRemoteProcessRunner(QObject *parent = 0);
+ SshRemoteProcessRunner(QObject *parent = nullptr);
~SshRemoteProcessRunner();
void run(const QString &command, const SshConnectionParameters &sshParams);
diff --git a/src/libs/tracing/CMakeLists.txt b/src/libs/tracing/CMakeLists.txt
index 41a42bbac5..9cc68ec149 100644
--- a/src/libs/tracing/CMakeLists.txt
+++ b/src/libs/tracing/CMakeLists.txt
@@ -6,6 +6,7 @@ endif()
add_qtc_library(Tracing
DEPENDS Utils Qt5::Qml Qt5::Quick
+ PUBLIC_DEPENDS Qt5::Widgets
SOURCES ${TEST_SOURCES}
flamegraph.cpp flamegraph.h
flamegraphattached.h
diff --git a/src/libs/tracing/flamegraph.cpp b/src/libs/tracing/flamegraph.cpp
index 67329209ac..b7afef4551 100644
--- a/src/libs/tracing/flamegraph.cpp
+++ b/src/libs/tracing/flamegraph.cpp
@@ -198,18 +198,18 @@ void FlameGraph::rebuild()
void FlameGraph::mousePressEvent(QMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
}
void FlameGraph::mouseReleaseEvent(QMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
setSelectedTypeId(-1);
}
void FlameGraph::mouseDoubleClickEvent(QMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
setSelectedTypeId(-1);
resetRoot();
}
diff --git a/src/libs/tracing/qml/ButtonsBar.qml b/src/libs/tracing/qml/ButtonsBar.qml
index a151eb9f91..32111daa57 100644
--- a/src/libs/tracing/qml/ButtonsBar.qml
+++ b/src/libs/tracing/qml/ButtonsBar.qml
@@ -24,9 +24,8 @@
****************************************************************************/
import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtQuick.Layouts 1.0
-import QtQuick.Controls.Styles 1.2
+import QtQuick.Controls 2.0
+import QtQuick.Layouts 1.3
import TimelineTheme 1.0
@@ -55,19 +54,12 @@ ToolBar {
return rangeButton.checked
}
- style: ToolBarStyle {
- padding {
- left: 0
- right: 0
- top: 0
- bottom: 0
- }
- background: Rectangle {
- anchors.fill: parent
- color: Theme.color(Theme.PanelStatusBarBackgroundColor)
- }
+ background: Rectangle {
+ anchors.fill: parent
+ color: Theme.color(Theme.PanelStatusBarBackgroundColor)
}
+
RowLayout {
spacing: 0
anchors.fill: parent
@@ -77,7 +69,7 @@ ToolBar {
Layout.fillHeight: true
imageSource: "image://icons/prev"
- tooltip: qsTr("Jump to previous event.")
+ ToolTip.text: qsTr("Jump to previous event.")
onClicked: buttons.jumpToPrev()
}
@@ -86,7 +78,7 @@ ToolBar {
Layout.fillHeight: true
imageSource: "image://icons/next"
- tooltip: qsTr("Jump to next event.")
+ ToolTip.text: qsTr("Jump to next event.")
onClicked: buttons.jumpToNext()
}
@@ -95,7 +87,7 @@ ToolBar {
Layout.fillHeight: true
imageSource: "image://icons/zoom"
- tooltip: qsTr("Show zoom slider.")
+ ToolTip.text: qsTr("Show zoom slider.")
checkable: true
checked: false
onCheckedChanged: buttons.zoomControlChanged()
@@ -106,7 +98,7 @@ ToolBar {
Layout.fillHeight: true
imageSource: "image://icons/" + (checked ? "rangeselected" : "rangeselection");
- tooltip: qsTr("Select range.")
+ ToolTip.text: qsTr("Select range.")
checkable: true
checked: false
onCheckedChanged: buttons.rangeSelectChanged()
@@ -117,7 +109,7 @@ ToolBar {
Layout.fillHeight: true
imageSource: "image://icons/selectionmode"
- tooltip: qsTr("View event information on mouseover.")
+ ToolTip.text: qsTr("View event information on mouseover.")
checkable: true
checked: false
onCheckedChanged: buttons.lockChanged()
diff --git a/src/libs/tracing/qml/CategoryLabel.qml b/src/libs/tracing/qml/CategoryLabel.qml
index 5945b0f6df..171c92400e 100644
--- a/src/libs/tracing/qml/CategoryLabel.qml
+++ b/src/libs/tracing/qml/CategoryLabel.qml
@@ -24,8 +24,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
+import QtQuick.Controls 2.2
import TimelineTheme 1.0
@@ -62,6 +61,12 @@ Item {
drag.minimumY: dragging ? 0 : -dragOffset // Account for parent change below
drag.maximumY: draggerParent.height - (dragging ? 0 : dragOffset)
drag.axis: Drag.YAxis
+ hoverEnabled: true
+ ToolTip {
+ text: model.tooltip || labelContainer.text
+ visible: enabled && parent.containsMouse
+ delay: 1000
+ }
}
DropArea {
@@ -116,6 +121,8 @@ Item {
sourceComponent: RowLabel {
label: labels[index];
onSelectBySelectionId: {
+ if (labelContainer.model.hasMixedTypesInExpandedState)
+ return;
if (labelContainer.reverseSelect) {
labelContainer.selectPrevBySelectionId(label.id);
} else {
@@ -161,7 +168,7 @@ Item {
visible: eventIds.length > 0
imageSource: "image://icons/note"
- tooltip: texts.join("\n");
+ ToolTip.text: texts.join("\n");
onClicked: {
if (++currentNote >= eventIds.length)
currentNote = 0;
@@ -176,7 +183,7 @@ Item {
implicitHeight: txt.height - 1
enabled: expanded || (model && !model.empty)
imageSource: expanded ? "image://icons/close_split" : "image://icons/split"
- tooltip: expanded ? qsTr("Collapse category") : qsTr("Expand category")
+ ToolTip.text: expanded ? qsTr("Collapse category") : qsTr("Expand category")
onClicked: model.expanded = !expanded
}
diff --git a/src/libs/tracing/qml/FlameGraphView.qml b/src/libs/tracing/qml/FlameGraphView.qml
index 9712b91cd5..f98bcb3134 100644
--- a/src/libs/tracing/qml/FlameGraphView.qml
+++ b/src/libs/tracing/qml/FlameGraphView.qml
@@ -28,7 +28,7 @@ import TimelineTheme 1.0
import QtQml 2.2
import QtQuick 2.9
-import QtQuick.Controls 1.3
+import QtQuick.Controls 2.3
ScrollView {
id: root
@@ -45,7 +45,7 @@ ScrollView {
function resetRoot() { flamegraph.resetRoot(); }
property bool zoomed: flamegraph.zoomed
- property int sizeRole: -1
+ property var sizeRole: modes[Math.max(0, modesMenu.currentIndex)]
property var model: null
property int typeIdRole: -1
@@ -56,7 +56,7 @@ ScrollView {
property int summaryRole: -1
property int noteRole: -1
- property var trRoleNames: []
+ property var trRoleNames: ({})
property var modes: []
@@ -314,27 +314,11 @@ ScrollView {
}
}
- Button {
+ ComboBox {
+ id: modesMenu
x: flickable.width - width
y: flickable.contentY
-
- // It won't listen to anchors.margins and by default it doesn't add any margin. Great.
- width: implicitWidth + 20
-
- text: qsTr("Visualize %1").arg(trRoleNames[root.sizeRole])
-
- menu: Menu {
- id: modesMenu
- Instantiator {
- model: root.modes
- MenuItem {
- text: root.trRoleNames[modelData]
- onTriggered: root.sizeRole = modelData
- }
- onObjectAdded: modesMenu.insertItem(index, object)
- onObjectRemoved: modesMenu.removeItem(object)
- }
- }
+ model: root.modes.map(function(role) { return root.trRoleNames[role] });
}
}
}
diff --git a/src/libs/tracing/qml/ImageToolButton.qml b/src/libs/tracing/qml/ImageToolButton.qml
index 353e38f122..686fd2db88 100644
--- a/src/libs/tracing/qml/ImageToolButton.qml
+++ b/src/libs/tracing/qml/ImageToolButton.qml
@@ -24,8 +24,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtQuick.Controls.Styles 1.2
+import QtQuick.Controls 2.0
import TimelineTheme 1.0
@@ -34,6 +33,9 @@ ToolButton {
property string imageSource
+ ToolTip.visible: enabled && hovered
+ ToolTip.delay: 1000
+
Image {
source: parent.enabled ? parent.imageSource : parent.imageSource + "/disabled"
width: 16
@@ -42,13 +44,11 @@ ToolButton {
smooth: false
}
- style: ButtonStyle {
- background: Rectangle {
- color: (control.checked || control.pressed)
- ? Theme.color(Theme.FancyToolButtonSelectedColor)
- : control.hovered
- ? Theme.color(Theme.FancyToolButtonHoverColor)
- : "#00000000"
- }
+ background: Rectangle {
+ color: (parent.checked || parent.pressed)
+ ? Theme.color(Theme.FancyToolButtonSelectedColor)
+ : parent.hovered
+ ? Theme.color(Theme.FancyToolButtonHoverColor)
+ : "#00000000"
}
}
diff --git a/src/libs/tracing/qml/MainView.qml b/src/libs/tracing/qml/MainView.qml
index 2e1f97a3ba..f544721f9a 100644
--- a/src/libs/tracing/qml/MainView.qml
+++ b/src/libs/tracing/qml/MainView.qml
@@ -24,8 +24,7 @@
****************************************************************************/
import QtQuick 2.1
-import QtQuick.Controls 1.0
-import QtQuick.Controls.Styles 1.0
+import QtQuick.Controls 2.0
import TimelineTheme 1.0
@@ -73,7 +72,7 @@ Rectangle {
rangeDetails.hide();
selectionRangeMode = false;
zoomSlider.externalUpdate = true;
- zoomSlider.value = zoomSlider.minimumValue;
+ zoomSlider.value = zoomSlider.from;
}
// This is called from outside to synchronize the timeline to other views
@@ -192,6 +191,7 @@ Rectangle {
TimelineContent {
id: content
+
anchors.left: buttonsBar.right
anchors.top: buttonsBar.bottom
anchors.bottom: overview.top
@@ -255,13 +255,13 @@ Rectangle {
onReleased: {
if (selectionRange.creationState === selectionRange.creationSecondLimit) {
- content.stayInteractive = true;
+ content.interactive = true;
selectionRange.creationState = selectionRange.creationFinished;
}
}
onPressed: {
if (selectionRange.creationState === selectionRange.creationFirstLimit) {
- content.stayInteractive = false;
+ content.interactive = false;
selectionRange.setPos(selectionRangeControl.mouseX + content.contentX);
selectionRange.creationState = selectionRange.creationSecondLimit;
}
@@ -281,12 +281,12 @@ Rectangle {
flickableDirection: Flickable.HorizontalFlick
clip: true
interactive: false
- x: content.x + content.flickableItem.x
- y: content.y + content.flickableItem.y
+ x: content.x
+ y: content.y
height: (selectionRangeMode &&
selectionRange.creationState !== selectionRange.creationInactive) ?
- content.flickableItem.height : 0
- width: content.flickableItem.width
+ content.height : 0
+ width: content.width
contentX: content.contentX
contentWidth: content.contentWidth
@@ -320,11 +320,11 @@ Rectangle {
}
TimelineRulers {
- contentX: buttonsBar.width - content.x - content.flickableItem.x + content.contentX
+ contentX: buttonsBar.width + content.contentX
anchors.left: buttonsBar.right
anchors.right: parent.right
anchors.top: parent.top
- height: content.flickableItem.height + buttonsBar.height
+ height: content.height + buttonsBar.height
windowStart: zoomControl.windowStart
viewTimePerPixel: selectionRange.viewTimePerPixel
scaleHeight: buttonsBar.height
@@ -404,17 +404,9 @@ Rectangle {
function showInfo() {
var timelineModel = timelineModelAggregator.models[selectedModel];
- var eventData = timelineModel.details(selectedItem)
- var content = [];
- for (var k in eventData) {
- if (k === "displayName") {
- dialogTitle = eventData[k];
- } else {
- content.push(k);
- content.push(eventData[k]);
- }
- }
- rangeDetails.model = content;
+ var eventData = timelineModel.orderedDetails(selectedItem)
+ dialogTitle = eventData["title"] || "";
+ rangeDetails.model = eventData["content"] || [];
var location = timelineModel.location(selectedItem)
if (location.hasOwnProperty("file")) { // not empty
@@ -458,8 +450,8 @@ Rectangle {
Slider {
id: zoomSlider
anchors.fill: parent
- minimumValue: 1
- maximumValue: 10000
+ from: 1
+ to: 10000
stepSize: 100
property int exponent: 3
@@ -478,7 +470,7 @@ Rectangle {
}
var windowLength = Math.max(
- Math.pow(value / maximumValue, exponent) * zoomControl.windowDuration,
+ Math.pow(value / to, exponent) * zoomControl.windowDuration,
minWindowLength);
var startTime = Math.max(zoomControl.windowStart, fixedPoint - windowLength / 2)
diff --git a/src/libs/tracing/qml/RangeDetails.qml b/src/libs/tracing/qml/RangeDetails.qml
index ccb86a5c3c..cb99479ca4 100644
--- a/src/libs/tracing/qml/RangeDetails.qml
+++ b/src/libs/tracing/qml/RangeDetails.qml
@@ -24,6 +24,8 @@
****************************************************************************/
import QtQuick 2.9
+import QtQuick.Controls 2.0
+
import TimelineTheme 1.0
Item {
@@ -108,6 +110,7 @@ Item {
implicitHeight: typeTitle.height
visible: !rangeDetails.noteReadonly
onClicked: noteEdit.focus = true
+ ToolTip.text: qsTr("Edit note")
}
ImageToolButton {
@@ -117,6 +120,7 @@ Item {
anchors.right: closeIcon.left
implicitHeight: typeTitle.height
onClicked: locked = !locked
+ ToolTip.text: qsTr("View event information on mouseover.")
}
ImageToolButton {
@@ -126,6 +130,7 @@ Item {
implicitHeight: typeTitle.height
imageSource: "image://icons/close_window"
onClicked: rangeDetails.clearSelection()
+ ToolTip.text: qsTr("Close")
}
}
diff --git a/src/libs/tracing/qml/RowLabel.qml b/src/libs/tracing/qml/RowLabel.qml
index be394b5e7e..e73d51b291 100644
--- a/src/libs/tracing/qml/RowLabel.qml
+++ b/src/libs/tracing/qml/RowLabel.qml
@@ -24,8 +24,7 @@
****************************************************************************/
import QtQuick 2.0
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.2
+import QtQuick.Controls 2.2
import TimelineTheme 1.0
Button {
@@ -38,25 +37,26 @@ Button {
signal setRowHeight(int newHeight)
property string labelText: label.description ? label.description : qsTr("[unknown]")
- action: Action {
- onTriggered: button.selectBySelectionId();
- tooltip: button.labelText + (label.displayName ? (" (" + label.displayName + ")") : "")
+
+ onPressed: selectBySelectionId();
+ ToolTip.text: labelText + (label.displayName ? (" (" + label.displayName + ")") : "")
+ ToolTip.visible: hovered
+ ToolTip.delay: 1000
+
+ background: Rectangle {
+ border.width: 1
+ border.color: Theme.color(Theme.Timeline_DividerColor)
+ color: Theme.color(Theme.PanelStatusBarBackgroundColor)
}
- style: ButtonStyle {
- background: Rectangle {
- border.width: 1
- border.color: Theme.color(Theme.Timeline_DividerColor)
- color: Theme.color(Theme.PanelStatusBarBackgroundColor)
- }
- label: TimelineText {
- text: button.labelText
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignLeft
- elide: Text.ElideRight
- color: Theme.color(Theme.PanelTextColorLight)
- }
+ contentItem: TimelineText {
+ text: button.labelText
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignLeft
+ elide: Text.ElideRight
+ color: Theme.color(Theme.PanelTextColorLight)
}
+
MouseArea {
hoverEnabled: true
property bool resizing: false
diff --git a/src/libs/tracing/qml/SelectionRangeDetails.qml b/src/libs/tracing/qml/SelectionRangeDetails.qml
index 458e5cf7ad..288ac7693c 100644
--- a/src/libs/tracing/qml/SelectionRangeDetails.qml
+++ b/src/libs/tracing/qml/SelectionRangeDetails.qml
@@ -24,6 +24,8 @@
****************************************************************************/
import QtQuick 2.1
+import QtQuick.Controls 2.0
+
import TimelineTheme 1.0
import TimelineTimeFormatter 1.0
@@ -133,5 +135,6 @@ Item {
anchors.top: selectionRangeDetails.top
implicitHeight: typeTitle.height
onClicked: selectionRangeDetails.close()
+ ToolTip.text: qsTr("Close")
}
}
diff --git a/src/libs/tracing/qml/TimelineContent.qml b/src/libs/tracing/qml/TimelineContent.qml
index 636d707356..5eb667822f 100644
--- a/src/libs/tracing/qml/TimelineContent.qml
+++ b/src/libs/tracing/qml/TimelineContent.qml
@@ -24,20 +24,26 @@
****************************************************************************/
import QtQuick 2.0
-import QtQuick.Controls 1.2
+import QtQuick.Controls 2.2
import TimelineRenderer 1.0
import QtQml.Models 2.1
-ScrollView {
- id: scroller
+Flickable {
+ id: flick
+ clip: true
+ contentHeight: timelineView.height + height
+ flickableDirection: Flickable.HorizontalAndVerticalFlick
+ boundsBehavior: Flickable.StopAtBounds
+ pixelAligned: true
+
+ ScrollBar.horizontal: ScrollBar {}
+ ScrollBar.vertical: ScrollBar {}
+
+ property bool recursionGuard: false
property QtObject zoomer
property QtObject modelProxy
- property int contentX: flick.contentX
- property int contentY: flick.contentY
- property int contentWidth: flick.contentWidth
- property int contentHeight: flick.contentHeight
property bool selectionLocked
property int typeId
@@ -58,146 +64,122 @@ ScrollView {
timelineModel.items.move(sourceIndex, targetIndex)
}
- function scroll()
- {
- flick.scroll();
+
+ function guarded(operation) {
+ if (recursionGuard)
+ return;
+ recursionGuard = true;
+ operation();
+ recursionGuard = false;
}
- // ScrollView will try to deinteractivate it. We don't want that
- // as the horizontal flickable is interactive, too. We do occasionally
- // switch to non-interactive ourselves, though.
- property bool stayInteractive: true
- onStayInteractiveChanged: flick.interactive = stayInteractive
-
- Flickable {
- id: flick
- contentHeight: timelineView.height + height
- flickableDirection: Flickable.HorizontalAndVerticalFlick
- boundsBehavior: Flickable.StopAtBounds
- pixelAligned: true
-
- onInteractiveChanged: interactive = stayInteractive
-
- property bool recursionGuard: false
-
- function guarded(operation) {
- if (recursionGuard)
- return;
- recursionGuard = true;
- operation();
- recursionGuard = false;
+ // Logically we should bind to flick.width above as we use flick.width in scroll().
+ // However, this width changes before flick.width when the window is resized and if we
+ // don't explicitly set contentX here, for some reason an automatic change in contentX is
+ // triggered after this width has changed, but before flick.width changes. This would be
+ // indistinguishabe from a manual flick by the user and thus changes the range position. We
+ // don't want to change the range position on resizing the window. Therefore we bind to this
+ // width.
+ onWidthChanged: scroll()
+
+ // Update the zoom control on scrolling.
+ onContentXChanged: guarded(function() {
+ var newStartTime = contentX * zoomer.rangeDuration / width + zoomer.windowStart;
+ if (isFinite(newStartTime) && Math.abs(newStartTime - zoomer.rangeStart) >= 1) {
+ var newEndTime = (contentX + width) * zoomer.rangeDuration / width + zoomer.windowStart;
+ if (isFinite(newEndTime))
+ zoomer.setRange(newStartTime, newEndTime);
}
-
- // Logically we should bind to scroller.width above as we use scroller.width in scroll().
- // However, this width changes before scroller.width when the window is resized and if we
- // don't explicitly set contentX here, for some reason an automatic change in contentX is
- // triggered after this width has changed, but before scroller.width changes. This would be
- // indistinguishabe from a manual flick by the user and thus changes the range position. We
- // don't want to change the range position on resizing the window. Therefore we bind to this
- // width.
- onWidthChanged: scroll()
-
- // Update the zoom control on scrolling.
- onContentXChanged: guarded(function() {
- var newStartTime = contentX * zoomer.rangeDuration / scroller.width
- + zoomer.windowStart;
- if (isFinite(newStartTime) && Math.abs(newStartTime - zoomer.rangeStart) >= 1) {
- var newEndTime = (contentX + scroller.width) * zoomer.rangeDuration / scroller.width
- + zoomer.windowStart;
- if (isFinite(newEndTime))
- zoomer.setRange(newStartTime, newEndTime);
+ });
+
+ // Scroll when the zoom control is updated
+ function scroll() {
+ guarded(function() {
+ if (zoomer.rangeDuration <= 0) {
+ contentWidth = 0;
+ contentX = 0;
+ } else {
+ var newWidth = zoomer.windowDuration * width / zoomer.rangeDuration;
+ if (isFinite(newWidth) && Math.abs(newWidth - contentWidth) >= 1)
+ contentWidth = newWidth;
+ var newStartX = (zoomer.rangeStart - zoomer.windowStart) * width /
+ zoomer.rangeDuration;
+ if (isFinite(newStartX) && Math.abs(newStartX - contentX) >= 1)
+ contentX = newStartX;
}
});
+ }
- // Scroll when the zoom control is updated
- function scroll() {
- guarded(function() {
- if (zoomer.rangeDuration <= 0) {
- contentWidth = 0;
- contentX = 0;
- } else {
- var newWidth = zoomer.windowDuration * scroller.width / zoomer.rangeDuration;
- if (isFinite(newWidth) && Math.abs(newWidth - contentWidth) >= 1)
- contentWidth = newWidth;
- var newStartX = (zoomer.rangeStart - zoomer.windowStart) * scroller.width /
- zoomer.rangeDuration;
- if (isFinite(newStartX) && Math.abs(newStartX - contentX) >= 1)
- contentX = newStartX;
- }
- });
- }
-
- Column {
- id: timelineView
-
- signal clearChildren
- signal select(int modelIndex, int eventIndex)
-
- DelegateModel {
- id: timelineModel
- model: modelProxy.models
- delegate: TimelineRenderer {
- id: renderer
- model: modelData
- notes: modelProxy.notes
- zoomer: scroller.zoomer
- selectionLocked: scroller.selectionLocked
- x: 0
- height: modelData.height
- property int visualIndex: DelegateModel.itemsIndex
-
- // paint "under" the vertical scrollbar, so that it always matches with the
- // timemarks
- width: flick.contentWidth
-
- Connections {
- target: timelineView
- onClearChildren: renderer.clearData()
- onSelect: {
- if (modelIndex === index || modelIndex === -1) {
- renderer.selectedItem = eventIndex;
- if (eventIndex !== -1)
- renderer.recenter();
- }
+ Column {
+ id: timelineView
+
+ signal clearChildren
+ signal select(int modelIndex, int eventIndex)
+
+ DelegateModel {
+ id: timelineModel
+ model: modelProxy.models
+ delegate: TimelineRenderer {
+ id: renderer
+ model: modelData
+ notes: modelProxy.notes
+ zoomer: flick.zoomer
+ selectionLocked: flick.selectionLocked
+ x: 0
+ height: modelData.height
+ property int visualIndex: DelegateModel.itemsIndex
+
+ // paint "under" the vertical scrollbar, so that it always matches with the
+ // timemarks
+ width: flick.contentWidth
+
+ Connections {
+ target: timelineView
+ onClearChildren: renderer.clearData()
+ onSelect: {
+ if (modelIndex === index || modelIndex === -1) {
+ renderer.selectedItem = eventIndex;
+ if (eventIndex !== -1)
+ renderer.recenter();
}
}
+ }
- function recenter() {
- if (modelData.endTime(selectedItem) < zoomer.rangeStart ||
- modelData.startTime(selectedItem) > zoomer.rangeEnd) {
-
- var newStart = Math.max((modelData.startTime(selectedItem) +
- modelData.endTime(selectedItem) -
- zoomer.rangeDuration) / 2, zoomer.traceStart);
- zoomer.setRange(newStart,
- Math.min(newStart + zoomer.rangeDuration, zoomer.traceEnd));
- }
+ function recenter() {
+ if (modelData.endTime(selectedItem) < zoomer.rangeStart ||
+ modelData.startTime(selectedItem) > zoomer.rangeEnd) {
- var row = modelData.row(selectedItem);
- var rowStart = modelData.rowOffset(row) + y;
- var rowEnd = rowStart + modelData.rowHeight(row);
- if (rowStart < flick.contentY || rowEnd - scroller.height > flick.contentY)
- flick.contentY = (rowStart + rowEnd - scroller.height) / 2;
+ var newStart = Math.max((modelData.startTime(selectedItem) +
+ modelData.endTime(selectedItem) -
+ zoomer.rangeDuration) / 2, zoomer.traceStart);
+ zoomer.setRange(newStart,
+ Math.min(newStart + zoomer.rangeDuration, zoomer.traceEnd));
}
- onSelectedItemChanged: scroller.propagateSelection(index, selectedItem);
+ var row = modelData.row(selectedItem);
+ var rowStart = modelData.rowOffset(row) + y;
+ var rowEnd = rowStart + modelData.rowHeight(row);
+ if (rowStart < flick.contentY || rowEnd - flick.height > flick.contentY)
+ flick.contentY = (rowStart + rowEnd - flick.height) / 2;
+ }
+
+ onSelectedItemChanged: flick.propagateSelection(index, selectedItem);
- Connections {
- target: model
- onDetailsChanged: {
- if (selectedItem != -1) {
- scroller.propagateSelection(-1, -1);
- scroller.propagateSelection(index, selectedItem);
- }
+ Connections {
+ target: model
+ onDetailsChanged: {
+ if (selectedItem != -1) {
+ flick.propagateSelection(-1, -1);
+ flick.propagateSelection(index, selectedItem);
}
}
}
}
+ }
- Repeater {
- id: repeater
- model: timelineModel
- }
+ Repeater {
+ id: repeater
+ model: timelineModel
}
}
}
diff --git a/src/libs/tracing/qml/TimelineLabels.qml b/src/libs/tracing/qml/TimelineLabels.qml
index 71434822f4..ac5fd2123d 100644
--- a/src/libs/tracing/qml/TimelineLabels.qml
+++ b/src/libs/tracing/qml/TimelineLabels.qml
@@ -86,6 +86,12 @@ Flickable {
height: loader.height
width: loader.width
+ Rectangle {
+ height: loader.height
+ width: 3
+ color: modelData.categoryColor
+ }
+
CategoryLabel {
id: label
model: modelData
diff --git a/src/libs/tracing/timelineabstractrenderer.cpp b/src/libs/tracing/timelineabstractrenderer.cpp
index c2e8886ee1..8242b70aad 100644
--- a/src/libs/tracing/timelineabstractrenderer.cpp
+++ b/src/libs/tracing/timelineabstractrenderer.cpp
@@ -28,7 +28,7 @@
namespace Timeline {
TimelineAbstractRenderer::TimelineAbstractRendererPrivate::TimelineAbstractRendererPrivate() :
- selectedItem(-1), selectionLocked(true), model(0), notes(0), zoomer(0), modelDirty(false),
+ selectedItem(-1), selectionLocked(true), model(nullptr), notes(nullptr), zoomer(nullptr), modelDirty(false),
rowHeightsDirty(false), notesDirty(false)
{
}
diff --git a/src/libs/tracing/timelineformattime.cpp b/src/libs/tracing/timelineformattime.cpp
index 54f12d90dd..314a68f236 100644
--- a/src/libs/tracing/timelineformattime.cpp
+++ b/src/libs/tracing/timelineformattime.cpp
@@ -30,7 +30,7 @@ namespace Timeline {
QString formatTime(qint64 timestamp, qint64 reference)
{
- static const char *decimalUnits[] = {"ns", "\xb5s", "ms", "s"};
+ static const char *decimalUnits[] = {" ns", " \xb5s", " ms", " s"};
static const double second = 1e9;
static const double minute = 60;
static const double hour = 60;
@@ -63,7 +63,7 @@ QString formatTime(qint64 timestamp, qint64 reference)
double seconds = timestamp / second;
if (seconds < minute) {
- return QString::number(seconds, 'g', qMax(round, 3)) + "s";
+ return QString::number(seconds, 'g', qMax(round, 3)) + " s";
} else {
int minutes = seconds / minute;
seconds -= minutes * minute;
@@ -88,8 +88,8 @@ QString formatTime(qint64 timestamp, qint64 reference)
static QObject *createFormatter(QQmlEngine *engine, QJSEngine *scriptEngine)
{
- Q_UNUSED(engine);
- Q_UNUSED(scriptEngine);
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
return new TimeFormatter;
}
@@ -97,7 +97,7 @@ void TimeFormatter::setupTimeFormatter()
{
static const int typeIndex = qmlRegisterSingletonType<TimeFormatter>(
"TimelineTimeFormatter", 1, 0, "TimeFormatter", createFormatter);
- Q_UNUSED(typeIndex);
+ Q_UNUSED(typeIndex)
}
}
diff --git a/src/libs/tracing/timelineitemsrenderpass.cpp b/src/libs/tracing/timelineitemsrenderpass.cpp
index a4f89dc64d..2a4727f056 100644
--- a/src/libs/tracing/timelineitemsrenderpass.cpp
+++ b/src/libs/tracing/timelineitemsrenderpass.cpp
@@ -269,11 +269,11 @@ OpaqueColoredPoint2DWithSize *OpaqueColoredPoint2DWithSize::fromVertexData(QSGGe
Q_ASSERT(attributes[3].position == 3);
Q_ASSERT(attributes[3].tupleSize == 4);
Q_ASSERT(attributes[3].type == GL_UNSIGNED_BYTE);
- Q_UNUSED(attributes);
+ Q_UNUSED(attributes)
return static_cast<OpaqueColoredPoint2DWithSize *>(geometry->vertexData());
}
-TimelineItemsGeometry::TimelineItemsGeometry() : usedVertices(0), node(0)
+TimelineItemsGeometry::TimelineItemsGeometry() : usedVertices(0), node(nullptr)
{
initNodes();
}
@@ -383,7 +383,7 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstrac
int indexTo, bool stateChanged,
float spacing) const
{
- Q_UNUSED(stateChanged);
+ Q_UNUSED(stateChanged)
const TimelineModel *model = renderer->model();
if (!model || indexFrom < 0 || indexTo > model->count() || indexFrom >= indexTo)
return oldState;
@@ -392,7 +392,7 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstrac
QColor(Qt::blue)).lighter(130);
TimelineItemsRenderPassState *state;
- if (oldState == 0)
+ if (oldState == nullptr)
state = new TimelineItemsRenderPassState(model);
else
state = static_cast<TimelineItemsRenderPassState *>(oldState);
@@ -472,7 +472,7 @@ void TimelineItemsMaterialShader::updateState(const RenderState &state, QSGMater
char const *const *TimelineItemsMaterialShader::attributeNames() const
{
- static const char *const attr[] = {"vertexCoord", "rectSize", "selectionId", "vertexColor", 0};
+ static const char *const attr[] = {"vertexCoord", "rectSize", "selectionId", "vertexColor", nullptr};
return attr;
}
diff --git a/src/libs/tracing/timelinemodel.cpp b/src/libs/tracing/timelinemodel.cpp
index c7b7c98904..b045c15817 100644
--- a/src/libs/tracing/timelinemodel.cpp
+++ b/src/libs/tracing/timelinemodel.cpp
@@ -135,8 +135,8 @@ int TimelineModel::row(int index) const
}
TimelineModel::TimelineModelPrivate::TimelineModelPrivate(int modelId) :
- modelId(modelId), expanded(false), hidden(false),
- expandedRowCount(1), collapsedRowCount(1)
+ modelId(modelId), categoryColor(Qt::transparent), hasMixedTypesInExpandedState(false),
+ expanded(false), hidden(false), expandedRowCount(1), collapsedRowCount(1)
{
}
@@ -170,7 +170,7 @@ int TimelineModel::modelId() const
int TimelineModel::collapsedRowHeight(int rowNumber) const
{
- Q_UNUSED(rowNumber);
+ Q_UNUSED(rowNumber)
return TimelineModelPrivate::DefaultRowHeight;
}
@@ -367,7 +367,7 @@ int TimelineModel::parentIndex(int index) const
QVariantMap TimelineModel::location(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
QVariantMap map;
return map;
}
@@ -379,25 +379,25 @@ QVariantMap TimelineModel::location(int index) const
*/
bool TimelineModel::handlesTypeId(int typeIndex) const
{
- Q_UNUSED(typeIndex);
+ Q_UNUSED(typeIndex)
return false;
}
float TimelineModel::relativeHeight(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return 1.0f;
}
qint64 TimelineModel::rowMinValue(int rowNumber) const
{
- Q_UNUSED(rowNumber);
+ Q_UNUSED(rowNumber)
return 0;
}
qint64 TimelineModel::rowMaxValue(int rowNumber) const
{
- Q_UNUSED(rowNumber);
+ Q_UNUSED(rowNumber)
return 0;
}
@@ -514,9 +514,42 @@ int TimelineModel::rowCount() const
return d->expanded ? d->expandedRowCount : d->collapsedRowCount;
}
+QString TimelineModel::tooltip() const
+{
+ return d->tooltip;
+}
+
+void TimelineModel::setTooltip(const QString &text)
+{
+ d->tooltip = text;
+ emit tooltipChanged();
+}
+
+QColor TimelineModel::categoryColor() const
+{
+ return d->categoryColor;
+}
+
+void TimelineModel::setCategoryColor(const QColor &color)
+{
+ d->categoryColor = color;
+ emit categoryColorChanged();
+}
+
+bool TimelineModel::hasMixedTypesInExpandedState() const
+{
+ return d->hasMixedTypesInExpandedState;
+}
+
+void TimelineModel::setHasMixedTypesInExpandedState(bool value)
+{
+ d->hasMixedTypesInExpandedState = value;
+ emit hasMixedTypesInExpandedStateChanged();
+}
+
QRgb TimelineModel::color(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return QRgb();
}
@@ -527,19 +560,45 @@ QVariantList TimelineModel::labels() const
QVariantMap TimelineModel::details(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return QVariantMap();
}
+/**
+ * @brief TimelineModel::orderedDetails returns the title and content for the details popup
+ * @param index of the selected item
+ * @return QVariantMap containing the fields 'title' (QString) and 'content' (QVariantList
+ * with alternating keys and values as QStrings)
+ */
+QVariantMap TimelineModel::orderedDetails(int index) const
+{
+ QVariantMap info = details(index);
+ QVariantMap data;
+ QVariantList content;
+ auto it = info.constBegin();
+ auto end = info.constEnd();
+ while (it != end) {
+ if (it.key() == "displayName") {
+ data.insert("title", it.value());
+ } else {
+ content.append(it.key());
+ content.append(it.value());
+ }
+ ++it;
+ }
+ data.insert("content", content);
+ return data;
+}
+
int TimelineModel::expandedRow(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return 0;
}
int TimelineModel::collapsedRow(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return 0;
}
diff --git a/src/libs/tracing/timelinemodel.h b/src/libs/tracing/timelinemodel.h
index 65d4784e07..53b8835017 100644
--- a/src/libs/tracing/timelinemodel.h
+++ b/src/libs/tracing/timelinemodel.h
@@ -40,6 +40,9 @@ class TRACING_EXPORT TimelineModel : public QObject
Q_OBJECT
Q_PROPERTY(int modelId READ modelId CONSTANT)
Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged)
+ Q_PROPERTY(QString tooltip READ tooltip NOTIFY tooltipChanged)
+ Q_PROPERTY(QColor categoryColor READ categoryColor NOTIFY categoryColorChanged)
+ Q_PROPERTY(bool hasMixedTypesInExpandedState READ hasMixedTypesInExpandedState NOTIFY hasMixedTypesInExpandedStateChanged)
Q_PROPERTY(bool empty READ isEmpty NOTIFY contentChanged)
Q_PROPERTY(bool hidden READ hidden WRITE setHidden NOTIFY hiddenChanged)
Q_PROPERTY(bool expanded READ expanded WRITE setExpanded NOTIFY expandedChanged)
@@ -92,10 +95,21 @@ public:
int collapsedRowCount() const;
int rowCount() const;
+ QString tooltip() const;
+ void setTooltip(const QString &text);
+
+ QColor categoryColor() const;
+ void setCategoryColor(const QColor &color);
+
+ // if this is disabled, a click on the row label will select the single type it contains
+ bool hasMixedTypesInExpandedState() const;
+ void setHasMixedTypesInExpandedState(bool value);
+
// Methods which can optionally be implemented by child models.
Q_INVOKABLE virtual QRgb color(int index) const;
virtual QVariantList labels() const;
Q_INVOKABLE virtual QVariantMap details(int index) const;
+ Q_INVOKABLE virtual QVariantMap orderedDetails(int index) const;
Q_INVOKABLE virtual int expandedRow(int index) const;
Q_INVOKABLE virtual int collapsedRow(int index) const;
Q_INVOKABLE int row(int index) const;
@@ -124,6 +138,9 @@ signals:
void heightChanged();
void rowCountChanged();
void displayNameChanged();
+ void tooltipChanged();
+ void categoryColorChanged();
+ void hasMixedTypesInExpandedStateChanged();
void labelsChanged();
void detailsChanged();
diff --git a/src/libs/tracing/timelinemodel_p.h b/src/libs/tracing/timelinemodel_p.h
index bc2ac76850..98e7af20fe 100644
--- a/src/libs/tracing/timelinemodel_p.h
+++ b/src/libs/tracing/timelinemodel_p.h
@@ -138,6 +138,9 @@ public:
QVector<int> rowOffsets;
const int modelId;
QString displayName;
+ QString tooltip;
+ QColor categoryColor;
+ bool hasMixedTypesInExpandedState;
bool expanded;
bool hidden;
diff --git a/src/libs/tracing/timelinenotesrenderpass.cpp b/src/libs/tracing/timelinenotesrenderpass.cpp
index 0aa36a1762..bfc3273eed 100644
--- a/src/libs/tracing/timelinenotesrenderpass.cpp
+++ b/src/libs/tracing/timelinenotesrenderpass.cpp
@@ -106,9 +106,9 @@ TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstrac
int lastIndex, bool stateChanged,
float spacing) const
{
- Q_UNUSED(firstIndex);
- Q_UNUSED(lastIndex);
- Q_UNUSED(spacing);
+ Q_UNUSED(firstIndex)
+ Q_UNUSED(lastIndex)
+ Q_UNUSED(spacing)
const TimelineNotesModel *notes = renderer->notes();
const TimelineModel *model = renderer->model();
@@ -117,7 +117,7 @@ TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstrac
return oldState;
TimelineNotesRenderPassState *state;
- if (oldState == 0) {
+ if (oldState == nullptr) {
state = new TimelineNotesRenderPassState(model->expandedRowCount());
} else {
if (!stateChanged && !renderer->notesDirty())
@@ -253,7 +253,7 @@ void NotesMaterialShader::updateState(const RenderState &state, QSGMaterial *, Q
char const *const *NotesMaterialShader::attributeNames() const
{
- static const char *const attr[] = {"vertexCoord", "distanceFromTop", 0};
+ static const char *const attr[] = {"vertexCoord", "distanceFromTop", nullptr};
return attr;
}
diff --git a/src/libs/tracing/timelineoverviewrenderer.cpp b/src/libs/tracing/timelineoverviewrenderer.cpp
index 8b78c54a1f..9cd824186e 100644
--- a/src/libs/tracing/timelineoverviewrenderer.cpp
+++ b/src/libs/tracing/timelineoverviewrenderer.cpp
@@ -34,7 +34,7 @@ TimelineOverviewRenderer::TimelineOverviewRenderer(QQuickItem *parent) :
}
TimelineOverviewRenderer::TimelineOverviewRendererPrivate::TimelineOverviewRendererPrivate() :
- renderState(0)
+ renderState(nullptr)
{
}
@@ -50,15 +50,15 @@ QSGNode *TimelineOverviewRenderer::updatePaintNode(QSGNode *oldNode,
if (!d->model || d->model->isEmpty() || !d->zoomer || d->zoomer->traceDuration() <= 0) {
delete oldNode;
- return 0;
+ return nullptr;
}
if (d->modelDirty) {
delete d->renderState;
- d->renderState = 0;
+ d->renderState = nullptr;
}
- if (d->renderState == 0) {
+ if (d->renderState == nullptr) {
d->renderState = new TimelineRenderState(d->zoomer->traceStart(), d->zoomer->traceEnd(),
1.0, d->renderPasses.size());
}
@@ -77,7 +77,7 @@ QSGNode *TimelineOverviewRenderer::updatePaintNode(QSGNode *oldNode,
if (d->renderState->isEmpty())
d->renderState->assembleNodeTree(d->model, d->model->height(), 0);
- TimelineAbstractRenderer::updatePaintNode(0, updatePaintNodeData);
+ TimelineAbstractRenderer::updatePaintNode(nullptr, updatePaintNodeData);
QMatrix4x4 matrix;
matrix.scale(xSpacing, ySpacing, 1);
diff --git a/src/libs/tracing/timelinerenderer.cpp b/src/libs/tracing/timelinerenderer.cpp
index 182a7aadd6..2abd234e01 100644
--- a/src/libs/tracing/timelinerenderer.cpp
+++ b/src/libs/tracing/timelinerenderer.cpp
@@ -43,7 +43,7 @@
namespace Timeline {
-TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate() : lastState(0)
+TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate() : lastState(nullptr)
{
resetCurrentSelection();
}
@@ -58,7 +58,7 @@ void TimelineRenderer::TimelineRendererPrivate::clear()
for (auto i = renderStates.begin(); i != renderStates.end(); ++i)
qDeleteAll(*i);
renderStates.clear();
- lastState = 0;
+ lastState = nullptr;
}
TimelineRenderer::TimelineRenderer(QQuickItem *parent) :
@@ -102,7 +102,7 @@ TimelineRenderState *TimelineRenderer::TimelineRendererPrivate::findRenderState(
if (renderStates.length() <= level)
renderStates.resize(level + 1);
TimelineRenderState *state = renderStates[level][offset];
- if (state == 0) {
+ if (state == nullptr) {
state = new TimelineRenderState(start, end, 1.0 / static_cast<qreal>(SafeFloatMax),
renderPasses.size());
renderStates[level][offset] = state;
@@ -117,7 +117,7 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u
if (!d->model || d->model->hidden() || d->model->isEmpty() || !d->zoomer ||
d->zoomer->windowDuration() <= 0) {
delete node;
- return 0;
+ return nullptr;
}
float spacing = static_cast<float>(width() / d->zoomer->windowDuration());
@@ -146,7 +146,7 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u
TimelineModel::defaultRowHeight());
}
- TimelineAbstractRenderer::updatePaintNode(0, updatePaintNodeData);
+ TimelineAbstractRenderer::updatePaintNode(nullptr, updatePaintNodeData);
d->lastState = state;
QMatrix4x4 matrix;
@@ -158,7 +158,7 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u
void TimelineRenderer::mousePressEvent(QMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
}
int TimelineRenderer::TimelineRendererPrivate::rowFromPosition(int y) const
@@ -209,8 +209,13 @@ void TimelineRenderer::wheelEvent(QWheelEvent *event)
int degrees = (event->angleDelta().x() + event->angleDelta().y()) / 8;
const qint64 circle = 360;
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
qint64 mouseTime = event->pos().x() * zoom->windowDuration() / width() +
zoom->windowStart();
+#else
+ qint64 mouseTime = event->position().toPoint().x() * zoom->windowDuration() / width() +
+ zoom->windowStart();
+#endif
qint64 beforeMouse = (mouseTime - zoom->rangeStart()) * (circle - degrees) / circle;
qint64 afterMouse = (zoom->rangeEnd() - mouseTime) * (circle - degrees) / circle;
diff --git a/src/libs/tracing/timelinerenderpass.cpp b/src/libs/tracing/timelinerenderpass.cpp
index 7c87f239c6..f4644cd502 100644
--- a/src/libs/tracing/timelinerenderpass.cpp
+++ b/src/libs/tracing/timelinerenderpass.cpp
@@ -41,12 +41,12 @@ const QVector<QSGNode *> &TimelineRenderPass::State::collapsedRows() const
QSGNode *TimelineRenderPass::State::expandedOverlay() const
{
- return 0;
+ return nullptr;
}
QSGNode *TimelineRenderPass::State::collapsedOverlay() const
{
- return 0;
+ return nullptr;
}
TimelineRenderPass::State::~State()
diff --git a/src/libs/tracing/timelinerenderstate.cpp b/src/libs/tracing/timelinerenderstate.cpp
index f897496c56..d8eeb0527f 100644
--- a/src/libs/tracing/timelinerenderstate.cpp
+++ b/src/libs/tracing/timelinerenderstate.cpp
@@ -195,7 +195,7 @@ void TimelineRenderState::updateExpandedRowHeights(const TimelineModel *model, i
Q_D(TimelineRenderState);
int row = 0;
qreal offset = 0;
- for (QSGNode *rowNode = d->expandedRowRoot->firstChild(); rowNode != 0;
+ for (QSGNode *rowNode = d->expandedRowRoot->firstChild(); rowNode != nullptr;
rowNode = rowNode->nextSibling()) {
qreal rowHeight = model->expandedRowHeight(row++);
QMatrix4x4 matrix;
diff --git a/src/libs/tracing/timelineselectionrenderpass.cpp b/src/libs/tracing/timelineselectionrenderpass.cpp
index b8d6c2991a..52be3eda58 100644
--- a/src/libs/tracing/timelineselectionrenderpass.cpp
+++ b/src/libs/tracing/timelineselectionrenderpass.cpp
@@ -66,7 +66,7 @@ TimelineRenderPass::State *TimelineSelectionRenderPass::update(
const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState,
State *oldState, int firstIndex, int lastIndex, bool stateChanged, float spacing) const
{
- Q_UNUSED(stateChanged);
+ Q_UNUSED(stateChanged)
const TimelineModel *model = renderer->model();
if (!model || model->isEmpty())
@@ -74,7 +74,7 @@ TimelineRenderPass::State *TimelineSelectionRenderPass::update(
TimelineSelectionRenderPassState *state;
- if (oldState == 0)
+ if (oldState == nullptr)
state = new TimelineSelectionRenderPassState;
else
state = static_cast<TimelineSelectionRenderPassState *>(oldState);
@@ -153,7 +153,7 @@ TimelineSelectionRenderPass::TimelineSelectionRenderPass()
}
TimelineSelectionRenderPassState::TimelineSelectionRenderPassState() :
- m_expandedOverlay(0), m_collapsedOverlay(0)
+ m_expandedOverlay(nullptr), m_collapsedOverlay(nullptr)
{
m_expandedOverlay = createSelectionNode(&m_material);
m_collapsedOverlay = createSelectionNode(&m_material);
diff --git a/src/libs/tracing/timelinetheme.cpp b/src/libs/tracing/timelinetheme.cpp
index 22d8697b78..a8a7c874e1 100644
--- a/src/libs/tracing/timelinetheme.cpp
+++ b/src/libs/tracing/timelinetheme.cpp
@@ -105,8 +105,8 @@ public:
static QObject *singletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
- Q_UNUSED(engine);
- Q_UNUSED(scriptEngine);
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
return Utils::proxyTheme();
}
@@ -114,7 +114,7 @@ void TimelineTheme::setupTheme(QQmlEngine *engine)
{
static const int typeIndex = qmlRegisterSingletonType<Utils::Theme>("TimelineTheme", 1, 0,
"Theme", singletonProvider);
- Q_UNUSED(typeIndex);
+ Q_UNUSED(typeIndex)
engine->addImageProvider(QLatin1String("icons"), new TimelineImageIconProvider);
}
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
index 5863c35d1f..6d2cdce97a 100644
--- a/src/libs/utils/CMakeLists.txt
+++ b/src/libs/utils/CMakeLists.txt
@@ -1,6 +1,9 @@
if (IDE_LIBEXEC_PATH AND IDE_BIN_PATH)
- file(RELATIVE_PATH RELATIVE_TOOLS_PATH
- "${CMAKE_INSTALL_PREFIX}/${IDE_BIN_PATH}" "${CMAKE_INSTALL_PREFIX}/${IDE_LIBEXEC_PATH}")
+ get_filename_component(bin_path
+ "${CMAKE_INSTALL_PREFIX}/${IDE_BIN_PATH}" ABSOLUTE "${CMAKE_BINARY_DIR}")
+ get_filename_component(libexec_path
+ "${CMAKE_INSTALL_PREFIX}/${IDE_LIBEXEC_PATH}" ABSOLUTE "${CMAKE_BINARY_DIR}")
+ file(RELATIVE_PATH RELATIVE_TOOLS_PATH "${bin_path}" "${libexec_path}")
else()
message(WARNING "IDE_LIBEXEC_PATH or IDE_BIN_PATH undefined when calculating tools path")
set(RELATIVE_TOOLS_PATH "")
@@ -21,6 +24,7 @@ add_qtc_library(Utils
basetreeview.cpp basetreeview.h
benchmarker.cpp benchmarker.h
buildablehelperlibrary.cpp buildablehelperlibrary.h
+ camelcasecursor.cpp camelcasecursor.h
categorysortfiltermodel.cpp categorysortfiltermodel.h
changeset.cpp changeset.h
checkablemessagebox.cpp checkablemessagebox.h
@@ -28,7 +32,7 @@ add_qtc_library(Utils
codegeneration.cpp codegeneration.h
completinglineedit.cpp completinglineedit.h
completingtextedit.cpp completingtextedit.h
- consoleprocess.cpp consoleprocess.h consoleprocess_p.h
+ consoleprocess.cpp consoleprocess.h
cpplanguage_details.h
crumblepath.cpp crumblepath.h
delegates.cpp delegates.h
@@ -36,12 +40,19 @@ add_qtc_library(Utils
detailsbutton.cpp detailsbutton.h
detailswidget.cpp detailswidget.h
differ.cpp differ.h
+ displayname.cpp displayname.h
dropsupport.cpp dropsupport.h
elfreader.cpp elfreader.h
elidinglabel.cpp elidinglabel.h
environment.cpp environment.h
+ environmentfwd.h
environmentdialog.cpp environmentdialog.h
environmentmodel.cpp environmentmodel.h
+ namevaluedictionary.cpp namevaluedictionary.h
+ namevalueitem.cpp namevalueitem.h
+ namevaluemodel.cpp namevaluemodel.h
+ namevaluesdialog.cpp namevaluesdialog.h
+ namevaluevalidator.cpp namevaluevalidator.h
execmenu.cpp execmenu.h
executeondestruction.h
fadingindicator.cpp fadingindicator.h
@@ -84,6 +95,11 @@ add_qtc_library(Utils
mimetypes/mimeprovider.cpp mimetypes/mimeprovider_p.h
mimetypes/mimetype.cpp mimetypes/mimetype.h mimetypes/mimetype_p.h
mimetypes/mimetypeparser.cpp mimetypes/mimetypeparser_p.h
+ namevaluedictionary.cpp namevaluedictionary.h
+ namevalueitem.cpp namevalueitem.h
+ namevaluemodel.cpp namevaluemodel.h
+ namevaluesdialog.cpp namevaluesdialog.h
+ namevaluevalidator.cpp namevaluevalidator.h
navigationtreeview.cpp navigationtreeview.h
networkaccessmanager.cpp networkaccessmanager.h
newclasswidget.cpp newclasswidget.h newclasswidget.ui
@@ -163,7 +179,6 @@ add_qtc_library(Utils
extend_qtc_target(Utils CONDITION WIN32
SOURCES
- consoleprocess_win.cpp
process_ctrlc_stub.cpp
touchbar/touchbar.cpp
DEPENDS
@@ -176,7 +191,6 @@ extend_qtc_target(Utils CONDITION WIN32
extend_qtc_target(Utils CONDITION APPLE
SOURCES
- consoleprocess_unix.cpp
fileutils_mac.mm fileutils_mac.h
processhandle_mac.mm
theme/theme_mac.mm theme/theme_mac.h
@@ -188,7 +202,6 @@ extend_qtc_target(Utils CONDITION APPLE
extend_qtc_target(Utils CONDITION UNIX AND NOT APPLE
SOURCES
- consoleprocess_unix.cpp
touchbar/touchbar.cpp
)
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index 237863c573..c337d93bb9 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -407,6 +407,20 @@ bool allOf(const T &container, F predicate)
return std::all_of(std::begin(container), std::end(container), predicate);
}
+// allOf taking a member function pointer
+template<typename T, typename R, typename S>
+bool allOf(const T &container, R (S::*predicate)() const)
+{
+ return std::all_of(std::begin(container), std::end(container), std::mem_fn(predicate));
+}
+
+// allOf taking a member pointer
+template<typename T, typename R, typename S>
+bool allOf(const T &container, R S::*member)
+{
+ return std::all_of(std::begin(container), std::end(container), std::mem_fn(member));
+}
+
//////////////////
// erase
/////////////////
@@ -885,6 +899,8 @@ std::tuple<C, C> partition(const C &container, F predicate)
{
C hit;
C miss;
+ reserve(hit, container.size());
+ reserve(miss, container.size());
auto hitIns = inserter(hit);
auto missIns = inserter(miss);
for (auto i : container) {
@@ -1256,7 +1272,21 @@ QSet<T> toSet(const QList<T> &list)
#endif
}
-template <class T>
+template<class T>
+QSet<T> toSet(const QVector<T> &vec)
+{
+#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
+ QSet<T> result;
+ for (const T &p : vec) {
+ result.insert(p);
+ }
+ return result;
+#else
+ return QSet<T>(vec.begin(), vec.end());
+#endif
+}
+
+template<class T>
QList<T> toList(const QSet<T> &set)
{
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp
index 352b17bb4b..00b73002f8 100644
--- a/src/libs/utils/basetreeview.cpp
+++ b/src/libs/utils/basetreeview.cpp
@@ -345,7 +345,7 @@ public:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override
{
- Q_UNUSED(option);
+ Q_UNUSED(option)
QLabel *label = new QLabel(parent);
label->setAutoFillBackground(true);
label->setTextInteractionFlags(Qt::TextSelectableByMouse
diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp
index 33ba624dc4..80ddeafa1a 100644
--- a/src/libs/utils/buildablehelperlibrary.cpp
+++ b/src/libs/utils/buildablehelperlibrary.cpp
@@ -46,7 +46,7 @@ QString BuildableHelperLibrary::qtChooserToQmakePath(const QString &path)
const QString toolDir = QLatin1String("QTTOOLDIR=\"");
SynchronousProcess proc;
proc.setTimeoutS(1);
- SynchronousProcessResponse response = proc.runBlocking(path, QStringList(QLatin1String("-print-env")));
+ SynchronousProcessResponse response = proc.runBlocking({path, {"-print-env"}});
if (response.result != SynchronousProcessResponse::Finished)
return QString();
const QString output = response.stdOut();
@@ -130,7 +130,7 @@ QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath)
SynchronousProcess qmake;
qmake.setTimeoutS(5);
- SynchronousProcessResponse response = qmake.runBlocking(qmakePath, QStringList(QLatin1String("--version")));
+ SynchronousProcessResponse response = qmake.runBlocking({qmakePath, {"--version"}});
if (response.result != SynchronousProcessResponse::Finished) {
qWarning() << response.exitMessage(qmakePath, 5);
return QString();
diff --git a/src/libs/utils/camelcasecursor.cpp b/src/libs/utils/camelcasecursor.cpp
new file mode 100644
index 0000000000..65e69bd70b
--- /dev/null
+++ b/src/libs/utils/camelcasecursor.cpp
@@ -0,0 +1,341 @@
+/**************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Andre Hartmann <aha_1980@gmx.de>
+** 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 "camelcasecursor.h"
+
+#include <QLineEdit>
+#include <QPlainTextEdit>
+
+template<typename C, typename E>
+bool moveCursor(C *cursor, E *edit, QTextCursor::MoveOperation direction, QTextCursor::MoveMode mode);
+
+template<>
+bool moveCursor(QTextCursor *cursor, QPlainTextEdit *, QTextCursor::MoveOperation direction,
+ QTextCursor::MoveMode mode)
+{
+ return cursor->movePosition(direction, mode);
+}
+
+template<typename C>
+bool moveCursor(C *, QLineEdit *edit, QTextCursor::MoveOperation direction, QTextCursor::MoveMode mode)
+{
+ bool mark = (mode == QTextCursor::KeepAnchor);
+ switch (direction) {
+ case QTextCursor::Left:
+ edit->cursorBackward(mark);
+ break;
+ case QTextCursor::WordLeft:
+ edit->cursorWordBackward(mark);
+ break;
+ case QTextCursor::Right:
+ edit->cursorForward(mark);
+ break;
+ case QTextCursor::WordRight:
+ edit->cursorWordForward(mark);
+ break;
+ default:
+ return false;
+ }
+ return edit->cursorPosition() > 0 && edit->cursorPosition() < edit->text().size();
+}
+
+template<typename C, typename E>
+QChar charUnderCursor(C *cursor, E *edit);
+
+template<>
+QChar charUnderCursor(QTextCursor *cursor, QPlainTextEdit *edit)
+{
+ return edit->document()->characterAt(cursor->position());
+}
+
+template<typename C>
+QChar charUnderCursor(C *, QLineEdit *edit)
+{
+ const int pos = edit->cursorPosition();
+ if (pos < 0 || pos >= edit->text().length())
+ return QChar::Null;
+
+ return edit->text().at(pos);
+};
+
+template<typename C, typename E>
+int position(C *cursor, E *edit);
+
+template<>
+int position(QTextCursor *cursor, QPlainTextEdit *)
+{
+ return cursor->position();
+}
+
+template<typename C>
+int position(C *, QLineEdit *edit)
+{
+ return edit->cursorPosition();
+}
+
+enum class Input {
+ Upper,
+ Lower,
+ Underscore,
+ Space,
+ Other
+};
+
+template<typename C, typename E>
+bool camelCaseLeft(C *cursor, E *edit, QTextCursor::MoveMode mode)
+{
+ int state = 0;
+
+ if (!moveCursor(cursor, edit, QTextCursor::Left, mode))
+ return false;
+
+ for (;;) {
+ QChar c = charUnderCursor(cursor, edit);
+ Input input = Input::Other;
+ if (c.isUpper())
+ input = Input::Upper;
+ else if (c.isLower() || c.isDigit())
+ input = Input::Lower;
+ else if (c == '_')
+ input = Input::Underscore;
+ else if (c.isSpace() && c != QChar::ParagraphSeparator)
+ input = Input::Space;
+ else
+ input = Input::Other;
+
+ switch (state) {
+ case 0:
+ switch (input) {
+ case Input::Upper:
+ state = 1;
+ break;
+ case Input::Lower:
+ state = 2;
+ break;
+ case Input::Underscore:
+ state = 3;
+ break;
+ case Input::Space:
+ state = 4;
+ break;
+ default:
+ moveCursor(cursor, edit, QTextCursor::Right, mode);
+ return moveCursor(cursor, edit, QTextCursor::WordLeft, mode);
+ }
+ break;
+ case 1:
+ switch (input) {
+ case Input::Upper:
+ break;
+ default:
+ return moveCursor(cursor, edit, QTextCursor::Right, mode);
+ return true;
+ }
+ break;
+ case 2:
+ switch (input) {
+ case Input::Upper:
+ return true;
+ case Input::Lower:
+ break;
+ default:
+ return moveCursor(cursor, edit, QTextCursor::Right, mode);
+ return true;
+ }
+ break;
+ case 3:
+ switch (input) {
+ case Input::Underscore:
+ break;
+ case Input::Upper:
+ state = 1;
+ break;
+ case Input::Lower:
+ state = 2;
+ break;
+ default:
+ moveCursor(cursor, edit, QTextCursor::Right, mode);
+ return true;
+ }
+ break;
+ case 4:
+ switch (input) {
+ case Input::Space:
+ break;
+ case Input::Upper:
+ state = 1;
+ break;
+ case Input::Lower:
+ state = 2;
+ break;
+ case Input::Underscore:
+ state = 3;
+ break;
+ default:
+ return moveCursor(cursor, edit, QTextCursor::Right, mode);
+ if (position(cursor, edit) == 0)
+ return true;
+ return moveCursor(cursor, edit, QTextCursor::WordLeft, mode);
+ }
+ }
+
+ if (!moveCursor(cursor, edit, QTextCursor::Left, mode))
+ return true;
+ }
+}
+
+template<typename C, typename E>
+bool camelCaseRight(C *cursor, E *edit, QTextCursor::MoveMode mark)
+{
+ int state = 0;
+
+ for (;;) {
+ QChar c = charUnderCursor(cursor, edit);
+ Input input = Input::Other;
+ if (c.isUpper())
+ input = Input::Upper;
+ else if (c.isLower() || c.isDigit())
+ input = Input::Lower;
+ else if (c == '_')
+ input = Input::Underscore;
+ else if (c.isSpace() && c != QChar::ParagraphSeparator)
+ input = Input::Space;
+ else
+ input = Input::Other;
+
+ switch (state) {
+ case 0:
+ switch (input) {
+ case Input::Upper:
+ state = 4;
+ break;
+ case Input::Lower:
+ state = 1;
+ break;
+ case Input::Underscore:
+ state = 6;
+ break;
+ default:
+ return moveCursor(cursor, edit, QTextCursor::WordRight, mark);
+ }
+ break;
+ case 1:
+ switch (input) {
+ case Input::Upper:
+ return true;
+ case Input::Lower:
+ break;
+ case Input::Underscore:
+ state = 6;
+ break;
+ case Input::Space:
+ state = 7;
+ break;
+ default:
+ return true;
+ }
+ break;
+ case 2:
+ switch (input) {
+ case Input::Upper:
+ break;
+ case Input::Lower:
+ moveCursor(cursor, edit, QTextCursor::Left, mark);
+ return true;
+ case Input::Underscore:
+ state = 6;
+ break;
+ case Input::Space:
+ state = 7;
+ break;
+ default:
+ return true;
+ }
+ break;
+ case 4:
+ switch (input) {
+ case Input::Upper:
+ state = 2;
+ break;
+ case Input::Lower:
+ state = 1;
+ break;
+ case Input::Underscore:
+ state = 6;
+ break;
+ case Input::Space:
+ state = 7;
+ break;
+ default:
+ return true;
+ }
+ break;
+ case 6:
+ switch (input) {
+ case Input::Underscore:
+ break;
+ case Input::Space:
+ state = 7;
+ break;
+ default:
+ return true;
+ }
+ break;
+ case 7:
+ switch (input) {
+ case Input::Space:
+ break;
+ default:
+ return true;
+ }
+ break;
+ }
+ if (!moveCursor(cursor, edit, QTextCursor::Right, mark))
+ return false;
+ }
+}
+
+bool CamelCaseCursor::left(QTextCursor *cursor, QPlainTextEdit *edit, QTextCursor::MoveMode mode)
+{
+ return camelCaseLeft(cursor, edit, mode);
+}
+
+bool CamelCaseCursor::left(QLineEdit *edit, QTextCursor::MoveMode mode)
+{
+ QTextCursor temp;
+ return camelCaseLeft(&temp, edit, mode);
+}
+
+bool CamelCaseCursor::right(QTextCursor *cursor, QPlainTextEdit *edit, QTextCursor::MoveMode mode)
+{
+ return camelCaseRight(cursor, edit, mode);
+}
+
+bool CamelCaseCursor::right(QLineEdit *edit, QTextCursor::MoveMode mode)
+{
+ QTextCursor temp;
+ return camelCaseRight(&temp, edit, mode);
+}
diff --git a/src/libs/utils/camelcasecursor.h b/src/libs/utils/camelcasecursor.h
new file mode 100644
index 0000000000..5967545737
--- /dev/null
+++ b/src/libs/utils/camelcasecursor.h
@@ -0,0 +1,45 @@
+/**************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Andre Hartmann <aha_1980@gmx.de>
+** 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 "utils_global.h"
+
+#include <QTextCursor>
+
+QT_BEGIN_NAMESPACE
+class QLineEdit;
+class QPlainTextEdit;
+QT_END_NAMESPACE
+
+class QTCREATOR_UTILS_EXPORT CamelCaseCursor
+{
+public:
+ static bool left(QTextCursor *cursor, QPlainTextEdit *edit, QTextCursor::MoveMode mode);
+ static bool left(QLineEdit *edit, QTextCursor::MoveMode mode);
+ static bool right(QTextCursor *cursor, QPlainTextEdit *edit, QTextCursor::MoveMode mode);
+ static bool right(QLineEdit *edit, QTextCursor::MoveMode mode);
+};
diff --git a/src/libs/utils/changeset.cpp b/src/libs/utils/changeset.cpp
index 7ee4339182..a7b27dcacd 100644
--- a/src/libs/utils/changeset.cpp
+++ b/src/libs/utils/changeset.cpp
@@ -53,11 +53,9 @@ static bool overlaps(int posA, int lengthA, int posB, int lengthB) {
}
}
-bool ChangeSet::hasOverlap(int pos, int length)
+bool ChangeSet::hasOverlap(int pos, int length) const
{
- QListIterator<EditOp> i(m_operationList);
- while (i.hasNext()) {
- const EditOp &cmd = i.next();
+ for (const EditOp &cmd : m_operationList) {
switch (cmd.type) {
case EditOp::Replace:
@@ -251,9 +249,7 @@ void ChangeSet::doReplace(const EditOp &op, QList<EditOp> *replaceList)
Q_ASSERT(op.type == EditOp::Replace);
{
- QMutableListIterator<EditOp> i(*replaceList);
- while (i.hasNext()) {
- EditOp &c = i.next();
+ for (EditOp &c : *replaceList) {
if (op.pos1 <= c.pos1)
c.pos1 += op.text.size();
if (op.pos1 < c.pos1)
diff --git a/src/libs/utils/changeset.h b/src/libs/utils/changeset.h
index 4b63cfb727..5cb484c9b6 100644
--- a/src/libs/utils/changeset.h
+++ b/src/libs/utils/changeset.h
@@ -105,7 +105,7 @@ private:
bool flip_helper(int pos1, int length1, int pos2, int length2);
bool copy_helper(int pos, int length, int to);
- bool hasOverlap(int pos, int length);
+ bool hasOverlap(int pos, int length) const;
QString textAt(int pos, int length);
void doReplace(const EditOp &replace, QList<EditOp> *replaceList);
diff --git a/src/libs/utils/consoleprocess.cpp b/src/libs/utils/consoleprocess.cpp
index 335f9084c7..1e51550def 100644
--- a/src/libs/utils/consoleprocess.cpp
+++ b/src/libs/utils/consoleprocess.cpp
@@ -23,10 +23,47 @@
**
****************************************************************************/
-#include "consoleprocess_p.h"
+#include "consoleprocess.h"
+
+#include <utils/algorithm.h>
+#include <utils/environment.h>
+#include <utils/hostosinfo.h>
+#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+#include <utils/winutils.h>
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QCoreApplication>
+#include <QDir>
+#include <QFileInfo>
+#include <QLocalServer>
+#include <QLocalSocket>
+#include <QSettings>
+#include <QTemporaryFile>
+#include <QTimer>
+#include <QWinEventNotifier>
+
+#ifdef Q_OS_WIN
+
+# include <windows.h>
+# include <stdlib.h>
+# include <cstring>
+
+#else
+
+# include <sys/stat.h>
+# include <sys/types.h>
+# include <errno.h>
+# include <string.h>
+# include <unistd.h>
+
+#endif
namespace Utils {
+// TerminalCommand
+
TerminalCommand::TerminalCommand(const QString &command, const QString &openArgs, const QString &executeArgs)
: command(command)
, openArgs(openArgs)
@@ -34,12 +71,811 @@ TerminalCommand::TerminalCommand(const QString &command, const QString &openArgs
{
}
+// ConsoleProcessPrivate
+
+class ConsoleProcessPrivate
+{
+public:
+ ConsoleProcessPrivate() = default;
+
+ static QString m_defaultConsoleProcess;
+ ConsoleProcess::Mode m_mode = ConsoleProcess::Run;
+ QString m_workingDir;
+ Environment m_environment;
+ qint64 m_appPid = 0;
+ int m_appCode;
+ CommandLine m_commandLine;
+ QProcess::ExitStatus m_appStatus;
+ QLocalServer m_stubServer;
+ QLocalSocket *m_stubSocket = nullptr;
+ QTemporaryFile *m_tempFile = nullptr;
+ QProcess::ProcessError m_error = QProcess::UnknownError;
+ QString m_errorString;
+ bool m_abortOnMetaChars = true;
+ QSettings *m_settings = nullptr;
+
+ // Used on Unix only
+ QProcess m_process;
+ bool m_stubConnected = false;
+ QTimer *m_stubConnectTimer = nullptr;
+ QByteArray m_stubServerDir;
+ qint64 m_stubPid = 0;
+
+ // Used on Windows only
+ qint64 m_appMainThreadId = 0;
+
+#ifdef Q_OS_WIN
+ PROCESS_INFORMATION *m_pid = nullptr;
+ HANDLE m_hInferior = NULL;
+ QWinEventNotifier *inferiorFinishedNotifier = nullptr;
+ QWinEventNotifier *processFinishedNotifier = nullptr;
+#endif
+};
+
+
+// ConsoleProcess
+
+ConsoleProcess::ConsoleProcess(QObject *parent) :
+ QObject(parent), d(new ConsoleProcessPrivate)
+{
+ connect(&d->m_stubServer, &QLocalServer::newConnection,
+ this, &ConsoleProcess::stubConnectionAvailable);
+
+ d->m_process.setProcessChannelMode(QProcess::ForwardedChannels);
+}
+
ConsoleProcess::~ConsoleProcess()
{
stop();
delete d;
}
+void ConsoleProcess::setCommand(const CommandLine &command)
+{
+ d->m_commandLine = command;
+}
+
+void ConsoleProcess::setSettings(QSettings *settings)
+{
+ d->m_settings = settings;
+}
+
+Q_GLOBAL_STATIC_WITH_ARGS(const QVector<TerminalCommand>, knownTerminals, (
+{
+ {"x-terminal-emulator", "", "-e"},
+ {"xterm", "", "-e"},
+ {"aterm", "", "-e"},
+ {"Eterm", "", "-e"},
+ {"rxvt", "", "-e"},
+ {"urxvt", "", "-e"},
+ {"xfce4-terminal", "", "-x"},
+ {"konsole", "--separate", "-e"},
+ {"gnome-terminal", "", "--"}
+}));
+
+TerminalCommand ConsoleProcess::defaultTerminalEmulator()
+{
+ static TerminalCommand defaultTerm;
+
+ if (defaultTerm.command.isEmpty()) {
+
+ if (HostOsInfo::isMacHost()) {
+ const QString termCmd = QCoreApplication::applicationDirPath()
+ + "/../Resources/scripts/openTerminal.py";
+ if (QFileInfo::exists(termCmd))
+ defaultTerm = {termCmd, "", ""};
+ else
+ defaultTerm = {"/usr/X11/bin/xterm", "", "-e"};
+
+ } else if (HostOsInfo::isAnyUnixHost()) {
+ defaultTerm = {"xterm", "", "-e"};
+ const Environment env = Environment::systemEnvironment();
+ for (const TerminalCommand &term : *knownTerminals) {
+ const QString result = env.searchInPath(term.command).toString();
+ if (!result.isEmpty()) {
+ defaultTerm = {result, term.openArgs, term.executeArgs};
+ break;
+ }
+ }
+ }
+ }
+
+ return defaultTerm;
+}
+
+QVector<TerminalCommand> ConsoleProcess::availableTerminalEmulators()
+{
+ QVector<TerminalCommand> result;
+
+ if (HostOsInfo::isAnyUnixHost()) {
+ const Environment env = Environment::systemEnvironment();
+ for (const TerminalCommand &term : *knownTerminals) {
+ const QString command = env.searchInPath(term.command).toString();
+ if (!command.isEmpty())
+ result.push_back({command, term.openArgs, term.executeArgs});
+ }
+ // sort and put default terminal on top
+ const TerminalCommand defaultTerm = defaultTerminalEmulator();
+ result.removeAll(defaultTerm);
+ sort(result);
+ result.prepend(defaultTerm);
+ }
+
+ return result;
+}
+
+const char kTerminalVersion[] = "4.8";
+const char kTerminalVersionKey[] = "General/Terminal/SettingsVersion";
+const char kTerminalCommandKey[] = "General/Terminal/Command";
+const char kTerminalOpenOptionsKey[] = "General/Terminal/OpenOptions";
+const char kTerminalExecuteOptionsKey[] = "General/Terminal/ExecuteOptions";
+
+TerminalCommand ConsoleProcess::terminalEmulator(const QSettings *settings)
+{
+ if (settings && HostOsInfo::isAnyUnixHost()) {
+ if (settings->value(kTerminalVersionKey).toString() == kTerminalVersion) {
+ if (settings->contains(kTerminalCommandKey))
+ return {settings->value(kTerminalCommandKey).toString(),
+ settings->value(kTerminalOpenOptionsKey).toString(),
+ settings->value(kTerminalExecuteOptionsKey).toString()};
+ } else {
+ // TODO remove reading of old settings some time after 4.8
+ const QString value = settings->value("General/TerminalEmulator").toString().trimmed();
+ if (!value.isEmpty()) {
+ // split off command and options
+ const QStringList splitCommand = QtcProcess::splitArgs(value);
+ if (QTC_GUARD(!splitCommand.isEmpty())) {
+ const QString command = splitCommand.first();
+ const QStringList quotedArgs = Utils::transform(splitCommand.mid(1),
+ &QtcProcess::quoteArgUnix);
+ const QString options = quotedArgs.join(' ');
+ return {command, "", options};
+ }
+ }
+ }
+ }
+
+ return defaultTerminalEmulator();
+}
+
+void ConsoleProcess::setTerminalEmulator(QSettings *settings, const TerminalCommand &term)
+{
+ if (HostOsInfo::isAnyUnixHost()) {
+ settings->setValue(kTerminalVersionKey, kTerminalVersion);
+ if (term == defaultTerminalEmulator()) {
+ settings->remove(kTerminalCommandKey);
+ settings->remove(kTerminalOpenOptionsKey);
+ settings->remove(kTerminalExecuteOptionsKey);
+ } else {
+ settings->setValue(kTerminalCommandKey, term.command);
+ settings->setValue(kTerminalOpenOptionsKey, term.openArgs);
+ settings->setValue(kTerminalExecuteOptionsKey, term.executeArgs);
+ }
+ }
+}
+
+static QString quoteWinCommand(const QString &program)
+{
+ const QChar doubleQuote = QLatin1Char('"');
+
+ // add the program as the first arg ... it works better
+ QString programName = program;
+ programName.replace(QLatin1Char('/'), QLatin1Char('\\'));
+ if (!programName.startsWith(doubleQuote) && !programName.endsWith(doubleQuote)
+ && programName.contains(QLatin1Char(' '))) {
+ programName.prepend(doubleQuote);
+ programName.append(doubleQuote);
+ }
+ return programName;
+}
+
+static QString quoteWinArgument(const QString &arg)
+{
+ if (!arg.length())
+ return QString::fromLatin1("\"\"");
+
+ QString ret(arg);
+ // Quotes are escaped and their preceding backslashes are doubled.
+ ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
+ if (ret.contains(QRegExp(QLatin1String("\\s")))) {
+ // The argument must not end with a \ since this would be interpreted
+ // as escaping the quote -- rather put the \ behind the quote: e.g.
+ // rather use "foo"\ than "foo\"
+ int i = ret.length();
+ while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
+ --i;
+ ret.insert(i, QLatin1Char('"'));
+ ret.prepend(QLatin1Char('"'));
+ }
+ return ret;
+}
+
+// Quote a Windows command line correctly for the "CreateProcess" API
+QString createWinCommandline(const QString &program, const QStringList &args)
+{
+ QString programName = quoteWinCommand(program);
+ foreach (const QString &arg, args) {
+ programName += QLatin1Char(' ');
+ programName += quoteWinArgument(arg);
+ }
+ return programName;
+}
+
+QString createWinCommandline(const QString &program, const QString &args)
+{
+ QString programName = quoteWinCommand(program);
+ if (!args.isEmpty()) {
+ programName += QLatin1Char(' ');
+ programName += args;
+ }
+ return programName;
+}
+
+
+bool ConsoleProcess::startTerminalEmulator(QSettings *settings, const QString &workingDir,
+ const Environment &env)
+{
+#ifdef Q_OS_WIN
+ Q_UNUSED(settings)
+
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ PROCESS_INFORMATION pinfo;
+ ZeroMemory(&pinfo, sizeof(pinfo));
+
+ QString cmdLine = createWinCommandline(
+ QString::fromLocal8Bit(qgetenv("COMSPEC")), QString());
+ // cmdLine is assumed to be detached -
+ // https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083
+
+ QString totalEnvironment = env.toStringList().join(QChar(QChar::Null)) + QChar(QChar::Null);
+ LPVOID envPtr = (env != Environment::systemEnvironment())
+ ? (WCHAR *)(totalEnvironment.utf16()) : nullptr;
+
+ bool success = CreateProcessW(0, (WCHAR *)cmdLine.utf16(),
+ 0, 0, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
+ envPtr, workingDir.isEmpty() ? 0 : (WCHAR *)workingDir.utf16(),
+ &si, &pinfo);
+
+ if (success) {
+ CloseHandle(pinfo.hThread);
+ CloseHandle(pinfo.hProcess);
+ }
+
+ return success;
+#else
+ const TerminalCommand term = terminalEmulator(settings);
+ QProcess process;
+ process.setProgram(term.command);
+ process.setArguments(QtcProcess::splitArgs(term.openArgs));
+ process.setProcessEnvironment(env.toProcessEnvironment());
+ process.setWorkingDirectory(workingDir);
+
+ return process.startDetached();
+#endif
+}
+
+void ConsoleProcess::setAbortOnMetaChars(bool abort)
+{
+ d->m_abortOnMetaChars = abort;
+}
+
+qint64 ConsoleProcess::applicationMainThreadID() const
+{
+ if (HostOsInfo::isWindowsHost())
+ return d->m_appMainThreadId;
+ return -1;
+}
+
+bool ConsoleProcess::start()
+{
+ if (isRunning())
+ return false;
+
+ d->m_errorString.clear();
+ d->m_error = QProcess::UnknownError;
+
+#ifdef Q_OS_WIN
+
+ QString pcmd;
+ QString pargs;
+ if (d->m_mode != Run) { // The debugger engines already pre-process the arguments.
+ pcmd = d->m_commandLine.executable().toString();
+ pargs = d->m_commandLine.arguments();
+ } else {
+ QtcProcess::Arguments outArgs;
+ QtcProcess::prepareCommand(d->m_commandLine.executable().toString(),
+ d->m_commandLine.arguments(),
+ &pcmd, &outArgs, OsTypeWindows,
+ &d->m_environment, &d->m_workingDir);
+ pargs = outArgs.toWindowsArgs();
+ }
+
+ const QString err = stubServerListen();
+ if (!err.isEmpty()) {
+ emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
+ return false;
+ }
+
+ QStringList env = d->m_environment.toStringList();
+ if (!env.isEmpty()) {
+ d->m_tempFile = new QTemporaryFile();
+ if (!d->m_tempFile->open()) {
+ stubServerShutdown();
+ emitError(QProcess::FailedToStart, msgCannotCreateTempFile(d->m_tempFile->errorString()));
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ return false;
+ }
+ QTextStream out(d->m_tempFile);
+ out.setCodec("UTF-16LE");
+ out.setGenerateByteOrderMark(false);
+
+ // Add PATH and SystemRoot environment variables in case they are missing
+ const QStringList fixedEnvironment = [env] {
+ QStringList envStrings = env;
+ // add PATH if necessary (for DLL loading)
+ if (envStrings.filter(QRegExp(QLatin1String("^PATH="),Qt::CaseInsensitive)).isEmpty()) {
+ QByteArray path = qgetenv("PATH");
+ if (!path.isEmpty())
+ envStrings.prepend(QString::fromLatin1("PATH=%1").arg(QString::fromLocal8Bit(path)));
+ }
+ // add systemroot if needed
+ if (envStrings.filter(QRegExp(QLatin1String("^SystemRoot="),Qt::CaseInsensitive)).isEmpty()) {
+ QByteArray systemRoot = qgetenv("SystemRoot");
+ if (!systemRoot.isEmpty())
+ envStrings.prepend(QString::fromLatin1("SystemRoot=%1").arg(QString::fromLocal8Bit(systemRoot)));
+ }
+ return envStrings;
+ }();
+
+ for (const QString &var : fixedEnvironment)
+ out << var << QChar(0);
+ out << QChar(0);
+ out.flush();
+ if (out.status() != QTextStream::Ok) {
+ stubServerShutdown();
+ emitError(QProcess::FailedToStart, msgCannotWriteTempFile());
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ return false;
+ }
+ }
+
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ d->m_pid = new PROCESS_INFORMATION;
+ ZeroMemory(d->m_pid, sizeof(PROCESS_INFORMATION));
+
+ QString workDir = QDir::toNativeSeparators(workingDirectory());
+ if (!workDir.isEmpty() && !workDir.endsWith(QLatin1Char('\\')))
+ workDir.append(QLatin1Char('\\'));
+
+ QStringList stubArgs;
+ stubArgs << modeOption(d->m_mode)
+ << d->m_stubServer.fullServerName()
+ << workDir
+ << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
+ << createWinCommandline(pcmd, pargs)
+ << msgPromptToClose();
+
+ const QString cmdLine = createWinCommandline(
+ QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_process_stub.exe"), stubArgs);
+
+ bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
+ 0, 0, FALSE, CREATE_NEW_CONSOLE,
+ 0, 0,
+ &si, d->m_pid);
+
+ if (!success) {
+ delete d->m_pid;
+ d->m_pid = nullptr;
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ stubServerShutdown();
+ emitError(QProcess::FailedToStart, tr("The process \"%1\" could not be started: %2").arg(cmdLine, winErrorMessage(GetLastError())));
+ return false;
+ }
+
+ d->processFinishedNotifier = new QWinEventNotifier(d->m_pid->hProcess, this);
+ connect(d->processFinishedNotifier, &QWinEventNotifier::activated,
+ this, &ConsoleProcess::stubExited);
+
+#else
+
+ QtcProcess::SplitError perr;
+ QtcProcess::Arguments pargs = QtcProcess::prepareArgs(d->m_commandLine.arguments(),
+ &perr,
+ HostOsInfo::hostOs(),
+ &d->m_environment,
+ &d->m_workingDir,
+ d->m_abortOnMetaChars);
+
+ QString pcmd;
+ if (perr == QtcProcess::SplitOk) {
+ pcmd = d->m_commandLine.executable().toString();
+ } else {
+ if (perr != QtcProcess::FoundMeta) {
+ emitError(QProcess::FailedToStart, tr("Quoting error in command."));
+ return false;
+ }
+ if (d->m_mode == Debug) {
+ // FIXME: QTCREATORBUG-2809
+ emitError(QProcess::FailedToStart, tr("Debugging complex shell commands in a terminal"
+ " is currently not supported."));
+ return false;
+ }
+ pcmd = QLatin1String("/bin/sh");
+ pargs = QtcProcess::Arguments::createUnixArgs(
+ {"-c", (QtcProcess::quoteArg(d->m_commandLine.executable().toString())
+ + ' ' + d->m_commandLine.arguments())});
+ }
+
+ QtcProcess::SplitError qerr;
+ const TerminalCommand terminal = terminalEmulator(d->m_settings);
+ const QtcProcess::Arguments terminalArgs = QtcProcess::prepareArgs(terminal.executeArgs,
+ &qerr,
+ HostOsInfo::hostOs(),
+ &d->m_environment,
+ &d->m_workingDir);
+ if (qerr != QtcProcess::SplitOk) {
+ emitError(QProcess::FailedToStart, qerr == QtcProcess::BadQuoting
+ ? tr("Quoting error in terminal command.")
+ : tr("Terminal command may not be a shell command."));
+ return false;
+ }
+
+ const QString err = stubServerListen();
+ if (!err.isEmpty()) {
+ emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
+ return false;
+ }
+
+ d->m_environment.unset(QLatin1String("TERM"));
+ const QStringList env = d->m_environment.toStringList();
+ if (!env.isEmpty()) {
+ d->m_tempFile = new QTemporaryFile();
+ if (!d->m_tempFile->open()) {
+ stubServerShutdown();
+ emitError(QProcess::FailedToStart, msgCannotCreateTempFile(d->m_tempFile->errorString()));
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ return false;
+ }
+ QByteArray contents;
+ for (const QString &var : env) {
+ QByteArray l8b = var.toLocal8Bit();
+ contents.append(l8b.constData(), l8b.size() + 1);
+ }
+ if (d->m_tempFile->write(contents) != contents.size() || !d->m_tempFile->flush()) {
+ stubServerShutdown();
+ emitError(QProcess::FailedToStart, msgCannotWriteTempFile());
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ return false;
+ }
+ }
+
+ const QString stubPath = QCoreApplication::applicationDirPath()
+ + QLatin1String("/" QTC_REL_TOOLS_PATH "/qtcreator_process_stub");
+ const QStringList allArgs = terminalArgs.toUnixArgs()
+ << stubPath
+ << modeOption(d->m_mode)
+ << d->m_stubServer.fullServerName()
+ << msgPromptToClose()
+ << workingDirectory()
+ << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
+ << QString::number(getpid())
+ << pcmd
+ << pargs.toUnixArgs();
+
+ d->m_process.start(terminal.command, allArgs);
+ if (!d->m_process.waitForStarted()) {
+ stubServerShutdown();
+ emitError(QProcess::UnknownError, tr("Cannot start the terminal emulator \"%1\", change the setting in the "
+ "Environment options.").arg(terminal.command));
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ return false;
+ }
+ d->m_stubConnectTimer = new QTimer(this);
+ connect(d->m_stubConnectTimer, &QTimer::timeout, this, &ConsoleProcess::stop);
+ d->m_stubConnectTimer->setSingleShot(true);
+ d->m_stubConnectTimer->start(10000);
+
+#endif
+
+ return true;
+}
+
+void ConsoleProcess::killProcess()
+{
+#ifdef Q_OS_WIN
+ if (d->m_hInferior != NULL) {
+ TerminateProcess(d->m_hInferior, (unsigned)-1);
+ cleanupInferior();
+ }
+#else
+ if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
+ d->m_stubSocket->write("k", 1);
+ d->m_stubSocket->flush();
+ }
+ d->m_appPid = 0;
+#endif
+}
+
+void ConsoleProcess::killStub()
+{
+#ifdef Q_OS_WIN
+ if (d->m_pid) {
+ TerminateProcess(d->m_pid->hProcess, (unsigned)-1);
+ WaitForSingleObject(d->m_pid->hProcess, INFINITE);
+ cleanupStub();
+ }
+#else
+ if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
+ d->m_stubSocket->write("s", 1);
+ d->m_stubSocket->flush();
+ }
+ stubServerShutdown();
+ d->m_stubPid = 0;
+#endif
+}
+
+void ConsoleProcess::stop()
+{
+ killProcess();
+ killStub();
+ if (isRunning() && HostOsInfo::isAnyUnixHost()) {
+ d->m_process.terminate();
+ if (!d->m_process.waitForFinished(1000) && d->m_process.state() == QProcess::Running) {
+ d->m_process.kill();
+ d->m_process.waitForFinished();
+ }
+ }
+}
+
+bool ConsoleProcess::isRunning() const
+{
+#ifdef Q_OS_WIN
+ return d->m_pid != nullptr;
+#else
+ return d->m_process.state() != QProcess::NotRunning
+ || (d->m_stubSocket && d->m_stubSocket->isOpen());
+#endif
+}
+
+QString ConsoleProcess::stubServerListen()
+{
+#ifdef Q_OS_WIN
+ if (d->m_stubServer.listen(QString::fromLatin1("creator-%1-%2")
+ .arg(QCoreApplication::applicationPid())
+ .arg(rand())))
+ return QString();
+ return d->m_stubServer.errorString();
+#else
+ // We need to put the socket in a private directory, as some systems simply do not
+ // check the file permissions of sockets.
+ QString stubFifoDir;
+ while (true) {
+ {
+ QTemporaryFile tf;
+ if (!tf.open())
+ return msgCannotCreateTempFile(tf.errorString());
+ stubFifoDir = tf.fileName();
+ }
+ // By now the temp file was deleted again
+ d->m_stubServerDir = QFile::encodeName(stubFifoDir);
+ if (!::mkdir(d->m_stubServerDir.constData(), 0700))
+ break;
+ if (errno != EEXIST)
+ return msgCannotCreateTempDir(stubFifoDir, QString::fromLocal8Bit(strerror(errno)));
+ }
+ const QString stubServer = stubFifoDir + QLatin1String("/stub-socket");
+ if (!d->m_stubServer.listen(stubServer)) {
+ ::rmdir(d->m_stubServerDir.constData());
+ return tr("Cannot create socket \"%1\": %2").arg(stubServer, d->m_stubServer.errorString());
+ }
+ return QString();
+#endif
+}
+
+void ConsoleProcess::stubServerShutdown()
+{
+#ifdef Q_OS_WIN
+ delete d->m_stubSocket;
+ d->m_stubSocket = nullptr;
+ if (d->m_stubServer.isListening())
+ d->m_stubServer.close();
+#else
+ if (d->m_stubSocket) {
+ readStubOutput(); // we could get the shutdown signal before emptying the buffer
+ d->m_stubSocket->disconnect(); // avoid getting queued readyRead signals
+ d->m_stubSocket->deleteLater(); // we might be called from the disconnected signal of m_stubSocket
+ }
+ d->m_stubSocket = nullptr;
+ if (d->m_stubServer.isListening()) {
+ d->m_stubServer.close();
+ ::rmdir(d->m_stubServerDir.constData());
+ }
+#endif
+}
+
+void ConsoleProcess::stubConnectionAvailable()
+{
+ d->m_stubConnected = true;
+ emit stubStarted();
+
+ if (d->m_stubConnectTimer) {
+ delete d->m_stubConnectTimer;
+ d->m_stubConnectTimer = nullptr;
+ }
+
+ d->m_stubSocket = d->m_stubServer.nextPendingConnection();
+ connect(d->m_stubSocket, &QIODevice::readyRead, this, &ConsoleProcess::readStubOutput);
+
+ if (HostOsInfo::isAnyUnixHost())
+ connect(d->m_stubSocket, &QLocalSocket::disconnected, this, &ConsoleProcess::stubExited);
+}
+
+static QString errorMsg(int code)
+{
+ return QString::fromLocal8Bit(strerror(code));
+}
+
+void ConsoleProcess::readStubOutput()
+{
+ while (d->m_stubSocket->canReadLine()) {
+ QByteArray out = d->m_stubSocket->readLine();
+#ifdef Q_OS_WIN
+ out.chop(2); // \r\n
+ if (out.startsWith("err:chdir ")) {
+ emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(workingDirectory(), winErrorMessage(out.mid(10).toInt())));
+ } else if (out.startsWith("err:exec ")) {
+ emitError(QProcess::FailedToStart, msgCannotExecute(d->m_commandLine.executable().toUserOutput(), winErrorMessage(out.mid(9).toInt())));
+ } else if (out.startsWith("thread ")) { // Windows only
+ d->m_appMainThreadId = out.mid(7).toLongLong();
+ } else if (out.startsWith("pid ")) {
+ // Will not need it any more
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ d->m_appPid = out.mid(4).toLongLong();
+
+ d->m_hInferior = OpenProcess(
+ SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE,
+ FALSE, d->m_appPid);
+ if (d->m_hInferior == NULL) {
+ emitError(QProcess::FailedToStart, tr("Cannot obtain a handle to the inferior: %1")
+ .arg(winErrorMessage(GetLastError())));
+ // Uhm, and now what?
+ continue;
+ }
+ d->inferiorFinishedNotifier = new QWinEventNotifier(d->m_hInferior, this);
+ connect(d->inferiorFinishedNotifier, &QWinEventNotifier::activated, this, [this] {
+ DWORD chldStatus;
+
+ if (!GetExitCodeProcess(d->m_hInferior, &chldStatus))
+ emitError(QProcess::UnknownError, tr("Cannot obtain exit status from inferior: %1")
+ .arg(winErrorMessage(GetLastError())));
+ cleanupInferior();
+ d->m_appStatus = QProcess::NormalExit;
+ d->m_appCode = chldStatus;
+ emit processStopped(d->m_appCode, d->m_appStatus);
+ });
+
+ emit processStarted();
+ } else {
+ emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
+ TerminateProcess(d->m_pid->hProcess, (unsigned)-1);
+ break;
+ }
+#else
+ out.chop(1); // \n
+ if (out.startsWith("err:chdir ")) {
+ emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(workingDirectory(), errorMsg(out.mid(10).toInt())));
+ } else if (out.startsWith("err:exec ")) {
+ emitError(QProcess::FailedToStart, msgCannotExecute(d->m_commandLine.executable().toString(), errorMsg(out.mid(9).toInt())));
+ } else if (out.startsWith("spid ")) {
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+
+ d->m_stubPid = out.mid(4).toInt();
+ } else if (out.startsWith("pid ")) {
+ d->m_appPid = out.mid(4).toInt();
+ emit processStarted();
+ } else if (out.startsWith("exit ")) {
+ d->m_appStatus = QProcess::NormalExit;
+ d->m_appCode = out.mid(5).toInt();
+ d->m_appPid = 0;
+ emit processStopped(d->m_appCode, d->m_appStatus);
+ } else if (out.startsWith("crash ")) {
+ d->m_appStatus = QProcess::CrashExit;
+ d->m_appCode = out.mid(6).toInt();
+ d->m_appPid = 0;
+ emit processStopped(d->m_appCode, d->m_appStatus);
+ } else {
+ emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
+ d->m_stubPid = 0;
+ d->m_process.terminate();
+ break;
+ }
+#endif
+ } // while
+}
+
+void ConsoleProcess::stubExited()
+{
+ // The stub exit might get noticed before we read the pid for the kill on Windows
+ // or the error status elsewhere.
+ if (d->m_stubSocket && d->m_stubSocket->state() == QLocalSocket::ConnectedState)
+ d->m_stubSocket->waitForDisconnected();
+
+#ifdef Q_OS_WIN
+ cleanupStub();
+ if (d->m_hInferior != NULL) {
+ TerminateProcess(d->m_hInferior, (unsigned)-1);
+ cleanupInferior();
+ d->m_appStatus = QProcess::CrashExit;
+ d->m_appCode = -1;
+ emit processStopped(d->m_appCode, d->m_appStatus);
+ }
+#else
+ stubServerShutdown();
+ d->m_stubPid = 0;
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+ if (d->m_appPid) {
+ d->m_appStatus = QProcess::CrashExit;
+ d->m_appCode = -1;
+ d->m_appPid = 0;
+ emit processStopped(d->m_appCode, d->m_appStatus); // Maybe it actually did not, but keep state consistent
+ }
+#endif
+ emit stubStopped();
+}
+
+void ConsoleProcess::detachStub()
+{
+ if (HostOsInfo::isAnyUnixHost()) {
+ if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
+ d->m_stubSocket->write("d", 1);
+ d->m_stubSocket->flush();
+ }
+ stubServerShutdown();
+ d->m_stubPid = 0;
+ }
+}
+
+void ConsoleProcess::cleanupInferior()
+{
+#ifdef Q_OS_WIN
+ delete d->inferiorFinishedNotifier;
+ d->inferiorFinishedNotifier = nullptr;
+ CloseHandle(d->m_hInferior);
+ d->m_hInferior = NULL;
+ d->m_appPid = 0;
+#endif
+}
+
+void ConsoleProcess::cleanupStub()
+{
+#ifdef Q_OS_WIN
+ stubServerShutdown();
+ delete d->processFinishedNotifier;
+ d->processFinishedNotifier = nullptr;
+ CloseHandle(d->m_pid->hThread);
+ CloseHandle(d->m_pid->hProcess);
+ delete d->m_pid;
+ d->m_pid = nullptr;
+ delete d->m_tempFile;
+ d->m_tempFile = nullptr;
+#endif
+}
+
void ConsoleProcess::setMode(Mode m)
{
d->m_mode = m;
@@ -174,4 +1010,4 @@ bool TerminalCommand::operator<(const TerminalCommand &other) const
return command < other.command;
}
-}
+} // Utils
diff --git a/src/libs/utils/consoleprocess.h b/src/libs/utils/consoleprocess.h
index 3dec9838c3..4e6e4f12b6 100644
--- a/src/libs/utils/consoleprocess.h
+++ b/src/libs/utils/consoleprocess.h
@@ -35,8 +35,9 @@ class QSettings;
QT_END_NAMESPACE
namespace Utils {
+
class Environment;
-struct ConsoleProcessPrivate;
+class CommandLine;
class QTCREATOR_UTILS_EXPORT TerminalCommand
{
@@ -58,9 +59,13 @@ class QTCREATOR_UTILS_EXPORT ConsoleProcess : public QObject
public:
enum Mode { Run, Debug, Suspend };
- ConsoleProcess(QObject *parent = nullptr);
+
+ explicit ConsoleProcess(QObject *parent = nullptr);
~ConsoleProcess() override;
+ void setCommand(const Utils::CommandLine &command);
+ void setAbortOnMetaChars(bool abort);
+
void setWorkingDirectory(const QString &dir);
QString workingDirectory() const;
@@ -70,10 +75,7 @@ public:
QProcess::ProcessError error() const;
QString errorString() const;
- enum class MetaCharMode { Abort, Ignore };
- bool start(const QString &program, const QString &args,
- MetaCharMode metaCharMode = MetaCharMode::Abort);
-public slots:
+ bool start();
void stop();
public:
@@ -87,36 +89,17 @@ public:
void killStub();
qint64 applicationMainThreadID() const;
-#ifndef Q_OS_WIN
void detachStub();
-#endif
int exitCode() const;
QProcess::ExitStatus exitStatus() const;
-#ifdef Q_OS_WIN
- // Add PATH and SystemRoot environment variables in case they are missing
- static QStringList fixWinEnvironment(const QStringList &env);
- // Quote a Windows command line correctly for the "CreateProcess" API
- static QString createWinCommandline(const QString &program, const QStringList &args);
- static QString createWinCommandline(const QString &program, const QString &args);
-#endif
-
-#ifndef Q_OS_WIN
- void setSettings(QSettings *settings);
+ void setSettings(QSettings *);
static TerminalCommand defaultTerminalEmulator();
static QVector<TerminalCommand> availableTerminalEmulators();
static TerminalCommand terminalEmulator(const QSettings *settings);
static void setTerminalEmulator(QSettings *settings, const TerminalCommand &term);
-#else
- void setSettings(QSettings *) {}
-
- static TerminalCommand defaultTerminalEmulator() { return TerminalCommand(); }
- static QVector<TerminalCommand> availableTerminalEmulators() { return {}; }
- static TerminalCommand terminalEmulator(const QSettings *) { return TerminalCommand(); }
- static void setTerminalEmulator(QSettings *, const TerminalCommand &) {}
-#endif
static bool startTerminalEmulator(QSettings *settings, const QString &workingDir,
const Utils::Environment &env);
@@ -124,6 +107,7 @@ public:
signals:
void error(QProcess::ProcessError error);
void processError(const QString &errorString);
+
// These reflect the state of the actual client process
void processStarted();
void processStopped(int, QProcess::ExitStatus);
@@ -136,9 +120,6 @@ private:
void stubConnectionAvailable();
void readStubOutput();
void stubExited();
-#ifdef Q_OS_WIN
- void inferiorExited();
-#endif
static QString modeOption(Mode m);
static QString msgCommChannelFailed(const QString &error);
@@ -153,14 +134,12 @@ private:
void emitError(QProcess::ProcessError err, const QString &errorString);
QString stubServerListen();
void stubServerShutdown();
-#ifdef Q_OS_WIN
void cleanupStub();
void cleanupInferior();
-#endif
- ConsoleProcessPrivate *d;
+ class ConsoleProcessPrivate *d;
};
-} //namespace Utils
+} // Utils
Q_DECLARE_METATYPE(Utils::TerminalCommand)
diff --git a/src/libs/utils/consoleprocess_p.h b/src/libs/utils/consoleprocess_p.h
deleted file mode 100644
index 5d8d193493..0000000000
--- a/src/libs/utils/consoleprocess_p.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "consoleprocess.h"
-#include "environment.h"
-
-#include <QTemporaryFile>
-
-#include <QLocalSocket>
-#include <QLocalServer>
-
-QT_BEGIN_NAMESPACE
-class QTimer;
-QT_END_NAMESPACE
-
-#ifdef Q_OS_WIN
-# include <QWinEventNotifier>
-# include <windows.h>
-#endif
-
-namespace Utils {
-
-struct ConsoleProcessPrivate {
- ConsoleProcessPrivate();
-
- static QString m_defaultConsoleProcess;
- ConsoleProcess::Mode m_mode = ConsoleProcess::Run;
- QString m_workingDir;
- Environment m_environment;
- qint64 m_appPid = 0;
- int m_appCode;
- QString m_executable;
- QProcess::ExitStatus m_appStatus;
- QLocalServer m_stubServer;
- QLocalSocket *m_stubSocket = nullptr;
- QTemporaryFile *m_tempFile = nullptr;
- QProcess::ProcessError m_error = QProcess::UnknownError;
- QString m_errorString;
-
-#ifdef Q_OS_UNIX
- QProcess m_process;
- QByteArray m_stubServerDir;
- QSettings *m_settings = nullptr;
- bool m_stubConnected = false;
- qint64 m_stubPid = 0;
- QTimer *m_stubConnectTimer = nullptr;
-#else
- qint64 m_appMainThreadId = 0;
- PROCESS_INFORMATION *m_pid = nullptr;
- HANDLE m_hInferior = NULL;
- QWinEventNotifier *inferiorFinishedNotifier = nullptr;
- QWinEventNotifier *processFinishedNotifier = nullptr;
-#endif
-};
-
-} //namespace Utils
diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp
deleted file mode 100644
index 43afffa0a2..0000000000
--- a/src/libs/utils/consoleprocess_unix.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "consoleprocess_p.h"
-
-#include "qtcprocess.h"
-
-#include <utils/algorithm.h>
-#include <utils/hostosinfo.h>
-#include <utils/qtcassert.h>
-
-#include <QCoreApplication>
-#include <QFileInfo>
-#include <QSettings>
-#include <QTimer>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-
-namespace Utils {
-
-ConsoleProcessPrivate::ConsoleProcessPrivate() = default;
-
-ConsoleProcess::ConsoleProcess(QObject *parent) :
- QObject(parent), d(new ConsoleProcessPrivate)
-{
- connect(&d->m_stubServer, &QLocalServer::newConnection,
- this, &ConsoleProcess::stubConnectionAvailable);
-
- d->m_process.setProcessChannelMode(QProcess::ForwardedChannels);
-}
-
-qint64 ConsoleProcess::applicationMainThreadID() const
-{
- return -1;
-}
-
-void ConsoleProcess::setSettings(QSettings *settings)
-{
- d->m_settings = settings;
-}
-
-bool ConsoleProcess::start(const QString &program, const QString &args, MetaCharMode metaCharMode)
-{
- if (isRunning())
- return false;
-
- d->m_errorString.clear();
- d->m_error = QProcess::UnknownError;
-
- QtcProcess::SplitError perr;
- QtcProcess::Arguments pargs = QtcProcess::prepareArgs(args, &perr, HostOsInfo::hostOs(),
- &d->m_environment, &d->m_workingDir,
- metaCharMode == MetaCharMode::Abort);
- QString pcmd;
- if (perr == QtcProcess::SplitOk) {
- pcmd = program;
- } else {
- if (perr != QtcProcess::FoundMeta) {
- emitError(QProcess::FailedToStart, tr("Quoting error in command."));
- return false;
- }
- if (d->m_mode == Debug) {
- // FIXME: QTCREATORBUG-2809
- emitError(QProcess::FailedToStart, tr("Debugging complex shell commands in a terminal"
- " is currently not supported."));
- return false;
- }
- pcmd = QLatin1String("/bin/sh");
- pargs = QtcProcess::Arguments::createUnixArgs(
- QStringList({"-c", (QtcProcess::quoteArg(program) + ' ' + args)}));
- }
-
- QtcProcess::SplitError qerr;
- const TerminalCommand terminal = terminalEmulator(d->m_settings);
- const QtcProcess::Arguments terminalArgs = QtcProcess::prepareArgs(terminal.executeArgs,
- &qerr,
- HostOsInfo::hostOs(),
- &d->m_environment,
- &d->m_workingDir);
- if (qerr != QtcProcess::SplitOk) {
- emitError(QProcess::FailedToStart, qerr == QtcProcess::BadQuoting
- ? tr("Quoting error in terminal command.")
- : tr("Terminal command may not be a shell command."));
- return false;
- }
-
- const QString err = stubServerListen();
- if (!err.isEmpty()) {
- emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
- return false;
- }
-
- d->m_environment.unset(QLatin1String("TERM"));
- QStringList env = d->m_environment.toStringList();
- if (!env.isEmpty()) {
- d->m_tempFile = new QTemporaryFile();
- if (!d->m_tempFile->open()) {
- stubServerShutdown();
- emitError(QProcess::FailedToStart, msgCannotCreateTempFile(d->m_tempFile->errorString()));
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- return false;
- }
- QByteArray contents;
- foreach (const QString &var, env) {
- QByteArray l8b = var.toLocal8Bit();
- contents.append(l8b.constData(), l8b.size() + 1);
- }
- if (d->m_tempFile->write(contents) != contents.size() || !d->m_tempFile->flush()) {
- stubServerShutdown();
- emitError(QProcess::FailedToStart, msgCannotWriteTempFile());
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- return false;
- }
- }
-
- const QString stubPath = QCoreApplication::applicationDirPath()
- + QLatin1String("/" QTC_REL_TOOLS_PATH "/qtcreator_process_stub");
- const QStringList allArgs = terminalArgs.toUnixArgs()
- << stubPath
- << modeOption(d->m_mode)
- << d->m_stubServer.fullServerName()
- << msgPromptToClose()
- << workingDirectory()
- << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
- << QString::number(getpid())
- << pcmd
- << pargs.toUnixArgs();
-
- d->m_process.start(terminal.command, allArgs);
- if (!d->m_process.waitForStarted()) {
- stubServerShutdown();
- emitError(QProcess::UnknownError, tr("Cannot start the terminal emulator \"%1\", change the setting in the "
- "Environment options.").arg(terminal.command));
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- return false;
- }
- d->m_stubConnectTimer = new QTimer(this);
- connect(d->m_stubConnectTimer, &QTimer::timeout, this, &ConsoleProcess::stop);
- d->m_stubConnectTimer->setSingleShot(true);
- d->m_stubConnectTimer->start(10000);
- d->m_executable = program;
- return true;
-}
-
-void ConsoleProcess::killProcess()
-{
- if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
- d->m_stubSocket->write("k", 1);
- d->m_stubSocket->flush();
- }
- d->m_appPid = 0;
-}
-
-void ConsoleProcess::killStub()
-{
- if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
- d->m_stubSocket->write("s", 1);
- d->m_stubSocket->flush();
- }
- stubServerShutdown();
- d->m_stubPid = 0;
-}
-
-void ConsoleProcess::detachStub()
-{
- if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
- d->m_stubSocket->write("d", 1);
- d->m_stubSocket->flush();
- }
- stubServerShutdown();
- d->m_stubPid = 0;
-}
-
-void ConsoleProcess::stop()
-{
- killProcess();
- killStub();
- if (isRunning()) {
- d->m_process.terminate();
- if (!d->m_process.waitForFinished(1000) && d->m_process.state() == QProcess::Running) {
- d->m_process.kill();
- d->m_process.waitForFinished();
- }
- }
-}
-
-bool ConsoleProcess::isRunning() const
-{
- return d->m_process.state() != QProcess::NotRunning
- || (d->m_stubSocket && d->m_stubSocket->isOpen());
-}
-
-QString ConsoleProcess::stubServerListen()
-{
- // We need to put the socket in a private directory, as some systems simply do not
- // check the file permissions of sockets.
- QString stubFifoDir;
- forever {
- {
- QTemporaryFile tf;
- if (!tf.open())
- return msgCannotCreateTempFile(tf.errorString());
- stubFifoDir = tf.fileName();
- }
- // By now the temp file was deleted again
- d->m_stubServerDir = QFile::encodeName(stubFifoDir);
- if (!::mkdir(d->m_stubServerDir.constData(), 0700))
- break;
- if (errno != EEXIST)
- return msgCannotCreateTempDir(stubFifoDir, QString::fromLocal8Bit(strerror(errno)));
- }
- const QString stubServer = stubFifoDir + QLatin1String("/stub-socket");
- if (!d->m_stubServer.listen(stubServer)) {
- ::rmdir(d->m_stubServerDir.constData());
- return tr("Cannot create socket \"%1\": %2").arg(stubServer, d->m_stubServer.errorString());
- }
- return QString();
-}
-
-void ConsoleProcess::stubServerShutdown()
-{
- if (d->m_stubSocket) {
- readStubOutput(); // we could get the shutdown signal before emptying the buffer
- d->m_stubSocket->disconnect(); // avoid getting queued readyRead signals
- d->m_stubSocket->deleteLater(); // we might be called from the disconnected signal of m_stubSocket
- }
- d->m_stubSocket = nullptr;
- if (d->m_stubServer.isListening()) {
- d->m_stubServer.close();
- ::rmdir(d->m_stubServerDir.constData());
- }
-}
-
-void ConsoleProcess::stubConnectionAvailable()
-{
- if (d->m_stubConnectTimer) {
- delete d->m_stubConnectTimer;
- d->m_stubConnectTimer = nullptr;
- }
- d->m_stubConnected = true;
- emit stubStarted();
- d->m_stubSocket = d->m_stubServer.nextPendingConnection();
- connect(d->m_stubSocket, &QIODevice::readyRead, this, &ConsoleProcess::readStubOutput);
- connect(d->m_stubSocket, &QLocalSocket::disconnected, this, &ConsoleProcess::stubExited);
-}
-
-static QString errorMsg(int code)
-{
- return QString::fromLocal8Bit(strerror(code));
-}
-
-void ConsoleProcess::readStubOutput()
-{
- while (d->m_stubSocket->canReadLine()) {
- QByteArray out = d->m_stubSocket->readLine();
- out.chop(1); // \n
- if (out.startsWith("err:chdir ")) {
- emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(workingDirectory(), errorMsg(out.mid(10).toInt())));
- } else if (out.startsWith("err:exec ")) {
- emitError(QProcess::FailedToStart, msgCannotExecute(d->m_executable, errorMsg(out.mid(9).toInt())));
- } else if (out.startsWith("spid ")) {
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
-
- d->m_stubPid = out.mid(4).toInt();
- } else if (out.startsWith("pid ")) {
- d->m_appPid = out.mid(4).toInt();
- emit processStarted();
- } else if (out.startsWith("exit ")) {
- d->m_appStatus = QProcess::NormalExit;
- d->m_appCode = out.mid(5).toInt();
- d->m_appPid = 0;
- emit processStopped(d->m_appCode, d->m_appStatus);
- } else if (out.startsWith("crash ")) {
- d->m_appStatus = QProcess::CrashExit;
- d->m_appCode = out.mid(6).toInt();
- d->m_appPid = 0;
- emit processStopped(d->m_appCode, d->m_appStatus);
- } else {
- emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
- d->m_stubPid = 0;
- d->m_process.terminate();
- break;
- }
- }
-}
-
-void ConsoleProcess::stubExited()
-{
- // The stub exit might get noticed before we read the error status.
- if (d->m_stubSocket && d->m_stubSocket->state() == QLocalSocket::ConnectedState)
- d->m_stubSocket->waitForDisconnected();
- stubServerShutdown();
- d->m_stubPid = 0;
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- if (d->m_appPid) {
- d->m_appStatus = QProcess::CrashExit;
- d->m_appCode = -1;
- d->m_appPid = 0;
- emit processStopped(d->m_appCode, d->m_appStatus); // Maybe it actually did not, but keep state consistent
- }
- emit stubStopped();
-}
-
-Q_GLOBAL_STATIC_WITH_ARGS(const QVector<TerminalCommand>, knownTerminals, (
-{
- {"x-terminal-emulator", "", "-e"},
- {"xterm", "", "-e"},
- {"aterm", "", "-e"},
- {"Eterm", "", "-e"},
- {"rxvt", "", "-e"},
- {"urxvt", "", "-e"},
- {"xfce4-terminal", "", "-x"},
- {"konsole", "--separate", "-e"},
- {"gnome-terminal", "", "--"}
-}));
-
-TerminalCommand ConsoleProcess::defaultTerminalEmulator()
-{
- static TerminalCommand defaultTerm;
- if (defaultTerm.command.isEmpty()) {
- defaultTerm = []() -> TerminalCommand {
- if (HostOsInfo::isMacHost()) {
- const QString termCmd = QCoreApplication::applicationDirPath()
- + "/../Resources/scripts/openTerminal.py";
- if (QFileInfo::exists(termCmd))
- return {termCmd, "", ""};
- return {"/usr/X11/bin/xterm", "", "-e"};
- }
- const Environment env = Environment::systemEnvironment();
- for (const TerminalCommand &term : *knownTerminals) {
- const QString result = env.searchInPath(term.command).toString();
- if (!result.isEmpty())
- return {result, term.openArgs, term.executeArgs};
- }
- return {"xterm", "", "-e"};
- }();
- }
- return defaultTerm;
-}
-
-QVector<TerminalCommand> ConsoleProcess::availableTerminalEmulators()
-{
- QVector<TerminalCommand> result;
- const Environment env = Environment::systemEnvironment();
- for (const TerminalCommand &term : *knownTerminals) {
- const QString command = env.searchInPath(term.command).toString();
- if (!command.isEmpty())
- result.push_back({command, term.openArgs, term.executeArgs});
- }
- // sort and put default terminal on top
- const TerminalCommand defaultTerm = defaultTerminalEmulator();
- result.removeAll(defaultTerm);
- sort(result);
- result.prepend(defaultTerm);
- return result;
-}
-
-const char kTerminalVersion[] = "4.8";
-const char kTerminalVersionKey[] = "General/Terminal/SettingsVersion";
-const char kTerminalCommandKey[] = "General/Terminal/Command";
-const char kTerminalOpenOptionsKey[] = "General/Terminal/OpenOptions";
-const char kTerminalExecuteOptionsKey[] = "General/Terminal/ExecuteOptions";
-
-TerminalCommand ConsoleProcess::terminalEmulator(const QSettings *settings)
-{
- if (settings) {
- if (settings->value(kTerminalVersionKey).toString() == kTerminalVersion) {
- if (settings->contains(kTerminalCommandKey))
- return {settings->value(kTerminalCommandKey).toString(),
- settings->value(kTerminalOpenOptionsKey).toString(),
- settings->value(kTerminalExecuteOptionsKey).toString()};
- } else {
- // TODO remove reading of old settings some time after 4.8
- const QString value = settings->value("General/TerminalEmulator").toString().trimmed();
- if (!value.isEmpty()) {
- // split off command and options
- const QStringList splitCommand = QtcProcess::splitArgs(value);
- if (QTC_GUARD(!splitCommand.isEmpty())) {
- const QString command = splitCommand.first();
- const QStringList quotedArgs = Utils::transform(splitCommand.mid(1),
- &QtcProcess::quoteArgUnix);
- const QString options = quotedArgs.join(' ');
- return {command, "", options};
- }
- }
- }
- }
- return defaultTerminalEmulator();
-}
-
-void ConsoleProcess::setTerminalEmulator(QSettings *settings, const TerminalCommand &term)
-{
- settings->setValue(kTerminalVersionKey, kTerminalVersion);
- if (term == defaultTerminalEmulator()) {
- settings->remove(kTerminalCommandKey);
- settings->remove(kTerminalOpenOptionsKey);
- settings->remove(kTerminalExecuteOptionsKey);
- } else {
- settings->setValue(kTerminalCommandKey, term.command);
- settings->setValue(kTerminalOpenOptionsKey, term.openArgs);
- settings->setValue(kTerminalExecuteOptionsKey, term.executeArgs);
- }
-}
-
-bool ConsoleProcess::startTerminalEmulator(QSettings *settings, const QString &workingDir,
- const Utils::Environment &env)
-{
- const TerminalCommand term = terminalEmulator(settings);
- QProcess process;
- process.setProgram(term.command);
- process.setArguments(QtcProcess::splitArgs(term.openArgs));
- process.setProcessEnvironment(env.toProcessEnvironment());
- process.setWorkingDirectory(workingDir);
-
- return process.startDetached();
-}
-
-} // namespace Utils
diff --git a/src/libs/utils/consoleprocess_win.cpp b/src/libs/utils/consoleprocess_win.cpp
deleted file mode 100644
index a4008dfd2e..0000000000
--- a/src/libs/utils/consoleprocess_win.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "consoleprocess_p.h"
-#include "environment.h"
-#include "qtcprocess.h"
-#include "winutils.h"
-
-#include <QCoreApplication>
-#include <QDir>
-#include <QAbstractEventDispatcher>
-
-#include <stdlib.h>
-#include <cstring>
-
-namespace Utils {
-
-ConsoleProcessPrivate::ConsoleProcessPrivate() = default;
-
-ConsoleProcess::ConsoleProcess(QObject *parent) :
- QObject(parent), d(new ConsoleProcessPrivate)
-{
- connect(&d->m_stubServer, &QLocalServer::newConnection,
- this, &ConsoleProcess::stubConnectionAvailable);
-}
-
-qint64 ConsoleProcess::applicationMainThreadID() const
-{
- return d->m_appMainThreadId;
-}
-
-bool ConsoleProcess::start(const QString &program, const QString &args, MetaCharMode metaCharMode)
-{
- Q_UNUSED(metaCharMode);
-
- if (isRunning())
- return false;
-
- d->m_errorString.clear();
- d->m_error = QProcess::UnknownError;
-
- QString pcmd;
- QString pargs;
- if (d->m_mode != Run) { // The debugger engines already pre-process the arguments.
- pcmd = program;
- pargs = args;
- } else {
- QtcProcess::Arguments outArgs;
- QtcProcess::prepareCommand(program, args, &pcmd, &outArgs, OsTypeWindows,
- &d->m_environment, &d->m_workingDir);
- pargs = outArgs.toWindowsArgs();
- }
-
- const QString err = stubServerListen();
- if (!err.isEmpty()) {
- emitError(QProcess::FailedToStart, msgCommChannelFailed(err));
- return false;
- }
-
- QStringList env = d->m_environment.toStringList();
- if (!env.isEmpty()) {
- d->m_tempFile = new QTemporaryFile();
- if (!d->m_tempFile->open()) {
- stubServerShutdown();
- emitError(QProcess::FailedToStart, msgCannotCreateTempFile(d->m_tempFile->errorString()));
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- return false;
- }
- QTextStream out(d->m_tempFile);
- out.setCodec("UTF-16LE");
- out.setGenerateByteOrderMark(false);
- foreach (const QString &var, fixWinEnvironment(env))
- out << var << QChar(0);
- out << QChar(0);
- out.flush();
- if (out.status() != QTextStream::Ok) {
- stubServerShutdown();
- emitError(QProcess::FailedToStart, msgCannotWriteTempFile());
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- return false;
- }
- }
-
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
-
- d->m_pid = new PROCESS_INFORMATION;
- ZeroMemory(d->m_pid, sizeof(PROCESS_INFORMATION));
-
- QString workDir = QDir::toNativeSeparators(workingDirectory());
- if (!workDir.isEmpty() && !workDir.endsWith(QLatin1Char('\\')))
- workDir.append(QLatin1Char('\\'));
-
- QStringList stubArgs;
- stubArgs << modeOption(d->m_mode)
- << d->m_stubServer.fullServerName()
- << workDir
- << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
- << createWinCommandline(pcmd, pargs)
- << msgPromptToClose();
-
- const QString cmdLine = createWinCommandline(
- QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_process_stub.exe"), stubArgs);
-
- bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(),
- 0, 0, FALSE, CREATE_NEW_CONSOLE,
- 0, 0,
- &si, d->m_pid);
-
- if (!success) {
- delete d->m_pid;
- d->m_pid = nullptr;
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- stubServerShutdown();
- emitError(QProcess::FailedToStart, tr("The process \"%1\" could not be started: %2").arg(cmdLine, winErrorMessage(GetLastError())));
- return false;
- }
-
- d->processFinishedNotifier = new QWinEventNotifier(d->m_pid->hProcess, this);
- connect(d->processFinishedNotifier, &QWinEventNotifier::activated,
- this, &ConsoleProcess::stubExited);
- return true;
-}
-
-
-void ConsoleProcess::killProcess()
-{
- if (d->m_hInferior != NULL) {
- TerminateProcess(d->m_hInferior, (unsigned)-1);
- cleanupInferior();
- }
-}
-
-void ConsoleProcess::killStub()
-{
- if (d->m_pid) {
- TerminateProcess(d->m_pid->hProcess, (unsigned)-1);
- WaitForSingleObject(d->m_pid->hProcess, INFINITE);
- cleanupStub();
- }
-}
-
-void ConsoleProcess::stop()
-{
- killProcess();
- killStub();
-}
-
-bool ConsoleProcess::isRunning() const
-{
- return d->m_pid != nullptr;
-}
-
-QString ConsoleProcess::stubServerListen()
-{
- if (d->m_stubServer.listen(QString::fromLatin1("creator-%1-%2")
- .arg(QCoreApplication::applicationPid())
- .arg(rand())))
- return QString();
- return d->m_stubServer.errorString();
-}
-
-void ConsoleProcess::stubServerShutdown()
-{
- delete d->m_stubSocket;
- d->m_stubSocket = nullptr;
- if (d->m_stubServer.isListening())
- d->m_stubServer.close();
-}
-
-void ConsoleProcess::stubConnectionAvailable()
-{
- emit stubStarted();
- d->m_stubSocket = d->m_stubServer.nextPendingConnection();
- connect(d->m_stubSocket, &QIODevice::readyRead, this, &ConsoleProcess::readStubOutput);
-}
-
-void ConsoleProcess::readStubOutput()
-{
- while (d->m_stubSocket->canReadLine()) {
- QByteArray out = d->m_stubSocket->readLine();
- out.chop(2); // \r\n
- if (out.startsWith("err:chdir ")) {
- emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(workingDirectory(), winErrorMessage(out.mid(10).toInt())));
- } else if (out.startsWith("err:exec ")) {
- emitError(QProcess::FailedToStart, msgCannotExecute(d->m_executable, winErrorMessage(out.mid(9).toInt())));
- } else if (out.startsWith("thread ")) { // Windows only
- d->m_appMainThreadId = out.mid(7).toLongLong();
- } else if (out.startsWith("pid ")) {
- // Will not need it any more
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
- d->m_appPid = out.mid(4).toLongLong();
-
- d->m_hInferior = OpenProcess(
- SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE,
- FALSE, d->m_appPid);
- if (d->m_hInferior == NULL) {
- emitError(QProcess::FailedToStart, tr("Cannot obtain a handle to the inferior: %1")
- .arg(winErrorMessage(GetLastError())));
- // Uhm, and now what?
- continue;
- }
- d->inferiorFinishedNotifier = new QWinEventNotifier(d->m_hInferior, this);
- connect(d->inferiorFinishedNotifier, &QWinEventNotifier::activated,
- this, &ConsoleProcess::inferiorExited);
- emit processStarted();
- } else {
- emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
- TerminateProcess(d->m_pid->hProcess, (unsigned)-1);
- break;
- }
- }
-}
-
-void ConsoleProcess::cleanupInferior()
-{
- delete d->inferiorFinishedNotifier;
- d->inferiorFinishedNotifier = nullptr;
- CloseHandle(d->m_hInferior);
- d->m_hInferior = NULL;
- d->m_appPid = 0;
-}
-
-void ConsoleProcess::inferiorExited()
-{
- DWORD chldStatus;
-
- if (!GetExitCodeProcess(d->m_hInferior, &chldStatus))
- emitError(QProcess::UnknownError, tr("Cannot obtain exit status from inferior: %1")
- .arg(winErrorMessage(GetLastError())));
- cleanupInferior();
- d->m_appStatus = QProcess::NormalExit;
- d->m_appCode = chldStatus;
- emit processStopped(d->m_appCode, d->m_appStatus);
-}
-
-void ConsoleProcess::cleanupStub()
-{
- stubServerShutdown();
- delete d->processFinishedNotifier;
- d->processFinishedNotifier = nullptr;
- CloseHandle(d->m_pid->hThread);
- CloseHandle(d->m_pid->hProcess);
- delete d->m_pid;
- d->m_pid = nullptr;
- delete d->m_tempFile;
- d->m_tempFile = nullptr;
-}
-
-void ConsoleProcess::stubExited()
-{
- // The stub exit might get noticed before we read the pid for the kill.
- if (d->m_stubSocket && d->m_stubSocket->state() == QLocalSocket::ConnectedState)
- d->m_stubSocket->waitForDisconnected();
- cleanupStub();
- if (d->m_hInferior != NULL) {
- TerminateProcess(d->m_hInferior, (unsigned)-1);
- cleanupInferior();
- d->m_appStatus = QProcess::CrashExit;
- d->m_appCode = -1;
- emit processStopped(d->m_appCode, d->m_appStatus);
- }
- emit stubStopped();
-}
-
-QStringList ConsoleProcess::fixWinEnvironment(const QStringList &env)
-{
- QStringList envStrings = env;
- // add PATH if necessary (for DLL loading)
- if (envStrings.filter(QRegExp(QLatin1String("^PATH="),Qt::CaseInsensitive)).isEmpty()) {
- QByteArray path = qgetenv("PATH");
- if (!path.isEmpty())
- envStrings.prepend(QString::fromLatin1("PATH=%1").arg(QString::fromLocal8Bit(path)));
- }
- // add systemroot if needed
- if (envStrings.filter(QRegExp(QLatin1String("^SystemRoot="),Qt::CaseInsensitive)).isEmpty()) {
- QByteArray systemRoot = qgetenv("SystemRoot");
- if (!systemRoot.isEmpty())
- envStrings.prepend(QString::fromLatin1("SystemRoot=%1").arg(QString::fromLocal8Bit(systemRoot)));
- }
- return envStrings;
-}
-
-static QString quoteWinCommand(const QString &program)
-{
- const QChar doubleQuote = QLatin1Char('"');
-
- // add the program as the first arg ... it works better
- QString programName = program;
- programName.replace(QLatin1Char('/'), QLatin1Char('\\'));
- if (!programName.startsWith(doubleQuote) && !programName.endsWith(doubleQuote)
- && programName.contains(QLatin1Char(' '))) {
- programName.prepend(doubleQuote);
- programName.append(doubleQuote);
- }
- return programName;
-}
-
-static QString quoteWinArgument(const QString &arg)
-{
- if (!arg.length())
- return QString::fromLatin1("\"\"");
-
- QString ret(arg);
- // Quotes are escaped and their preceding backslashes are doubled.
- ret.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
- if (ret.contains(QRegExp(QLatin1String("\\s")))) {
- // The argument must not end with a \ since this would be interpreted
- // as escaping the quote -- rather put the \ behind the quote: e.g.
- // rather use "foo"\ than "foo\"
- int i = ret.length();
- while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
- --i;
- ret.insert(i, QLatin1Char('"'));
- ret.prepend(QLatin1Char('"'));
- }
- return ret;
-}
-
-QString ConsoleProcess::createWinCommandline(const QString &program, const QStringList &args)
-{
- QString programName = quoteWinCommand(program);
- foreach (const QString &arg, args) {
- programName += QLatin1Char(' ');
- programName += quoteWinArgument(arg);
- }
- return programName;
-}
-
-QString ConsoleProcess::createWinCommandline(const QString &program, const QString &args)
-{
- QString programName = quoteWinCommand(program);
- if (!args.isEmpty()) {
- programName += QLatin1Char(' ');
- programName += args;
- }
- return programName;
-}
-
-bool ConsoleProcess::startTerminalEmulator(QSettings *, const QString &workingDir,
- const Utils::Environment &env)
-{
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
-
- PROCESS_INFORMATION pinfo;
- ZeroMemory(&pinfo, sizeof(pinfo));
-
- QString cmdLine = createWinCommandline(
- QString::fromLocal8Bit(qgetenv("COMSPEC")), QString());
- // cmdLine is assumed to be detached -
- // https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083
-
-
- QString totalEnvironment = env.toStringList().join(QChar(QChar::Null)) + QChar(QChar::Null);
- LPVOID envPtr = (env != Utils::Environment::systemEnvironment())
- ? (WCHAR *)(totalEnvironment.utf16()) : nullptr;
-
- bool success = CreateProcessW(0, (WCHAR *)cmdLine.utf16(),
- 0, 0, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
- envPtr, workingDir.isEmpty() ? 0 : (WCHAR *)workingDir.utf16(),
- &si, &pinfo);
-
- if (success) {
- CloseHandle(pinfo.hThread);
- CloseHandle(pinfo.hProcess);
- }
-
- return success;
-}
-
-} // namespace Utils
diff --git a/src/libs/utils/cpplanguage_details.h b/src/libs/utils/cpplanguage_details.h
index e9c9a5aa40..06cb050126 100644
--- a/src/libs/utils/cpplanguage_details.h
+++ b/src/libs/utils/cpplanguage_details.h
@@ -72,4 +72,6 @@ constexpr bool operator&&(LanguageExtension first, LanguageExtension second)
return static_cast<unsigned char>(first) & static_cast<unsigned char>(second);
}
+enum class QtVersion { Unknown = -1, None, Qt4, Qt5 };
+
} // namespace Utils
diff --git a/src/libs/utils/delegates.cpp b/src/libs/utils/delegates.cpp
index 2240e8a6a4..1eb281e3af 100644
--- a/src/libs/utils/delegates.cpp
+++ b/src/libs/utils/delegates.cpp
@@ -131,8 +131,8 @@ void PathChooserDelegate::setPromptDialogFilter(const QString &filter)
QWidget *PathChooserDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
- Q_UNUSED(option);
- Q_UNUSED(index);
+ Q_UNUSED(option)
+ Q_UNUSED(index)
auto editor = new Utils::PathChooser(parent);
@@ -167,7 +167,7 @@ void PathChooserDelegate::setModelData(QWidget *editor, QAbstractItemModel *mode
void PathChooserDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
editor->setGeometry(option.rect);
}
@@ -200,8 +200,8 @@ QWidget *CompleterDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
- Q_UNUSED(option);
- Q_UNUSED(index);
+ Q_UNUSED(option)
+ Q_UNUSED(index)
auto edit = new CompletingLineEdit(parent);
@@ -229,7 +229,7 @@ void CompleterDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
editor->setGeometry(option.rect);
}
diff --git a/src/libs/utils/detailsbutton.cpp b/src/libs/utils/detailsbutton.cpp
index 329975afdb..abceff7b2d 100644
--- a/src/libs/utils/detailsbutton.cpp
+++ b/src/libs/utils/detailsbutton.cpp
@@ -200,3 +200,61 @@ QPixmap DetailsButton::cacheRendering(const QSize &size, bool checked)
style()->drawPrimitive(checked ? QStyle::PE_IndicatorArrowUp : QStyle::PE_IndicatorArrowDown, &arrowOpt, &p, this);
return pixmap;
}
+
+ExpandButton::ExpandButton(QWidget *parent) : QAbstractButton(parent)
+{
+ setCheckable(true);
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+}
+
+QSize ExpandButton::sizeHint() const
+{
+ return {fontMetrics().horizontalAdvance(text()) + 26, HostOsInfo::isMacHost() ? 34 : 22};
+}
+
+void ExpandButton::paintEvent(QPaintEvent *e)
+{
+ QWidget::paintEvent(e);
+ QPainter p(this);
+
+ QPixmap &pixmap = isChecked() ? m_checkedPixmap : m_uncheckedPixmap;
+ if (pixmap.isNull() || pixmap.size() / pixmap.devicePixelRatio() != contentsRect().size())
+ pixmap = cacheRendering();
+ p.drawPixmap(contentsRect(), pixmap);
+
+ if (isDown()) {
+ p.setPen(Qt::NoPen);
+ p.setBrush(QColor(0, 0, 0, 20));
+ p.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 1, 1);
+ }
+ if (hasFocus()) {
+ QStyleOptionFocusRect option;
+ option.initFrom(this);
+ style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &p, this);
+ }
+}
+
+QPixmap ExpandButton::cacheRendering()
+{
+ const QSize size = contentsRect().size();
+ const qreal pixelRatio = devicePixelRatio();
+ QPixmap pixmap(size * pixelRatio);
+ pixmap.setDevicePixelRatio(pixelRatio);
+ pixmap.fill(Qt::transparent);
+ QPainter p(&pixmap);
+ p.setRenderHint(QPainter::Antialiasing, true);
+ p.translate(0.5, 0.5);
+ p.setPen(Qt::NoPen);
+ p.drawRoundedRect(0, 0, size.width(), size.height(), 1, 1);
+ int arrowsize = 15;
+ QStyleOption arrowOpt;
+ arrowOpt.initFrom(this);
+ QPalette pal = arrowOpt.palette;
+ pal.setBrush(QPalette::All, QPalette::Text, QColor(0, 0, 0));
+ arrowOpt.rect = QRect(size.width() - arrowsize - 6, height() / 2 - arrowsize / 2,
+ arrowsize, arrowsize);
+ arrowOpt.palette = pal;
+ style()->drawPrimitive(isChecked() ? QStyle::PE_IndicatorArrowUp
+ : QStyle::PE_IndicatorArrowDown, &arrowOpt, &p, this);
+ return pixmap;
+}
diff --git a/src/libs/utils/detailsbutton.h b/src/libs/utils/detailsbutton.h
index f66fa2ad4b..dabbe75918 100644
--- a/src/libs/utils/detailsbutton.h
+++ b/src/libs/utils/detailsbutton.h
@@ -78,4 +78,22 @@ private:
QPixmap m_uncheckedPixmap;
float m_fader;
};
+
+class QTCREATOR_UTILS_EXPORT ExpandButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ ExpandButton(QWidget *parent = nullptr);
+
+private:
+ void paintEvent(QPaintEvent *e) override;
+ QSize sizeHint() const override;
+
+ QPixmap cacheRendering();
+
+ QPixmap m_checkedPixmap;
+ QPixmap m_uncheckedPixmap;
+};
+
} // namespace Utils
diff --git a/src/libs/utils/displayname.cpp b/src/libs/utils/displayname.cpp
new file mode 100644
index 0000000000..819baae495
--- /dev/null
+++ b/src/libs/utils/displayname.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "displayname.h"
+
+namespace Utils {
+
+bool DisplayName::setValue(const QString &name)
+{
+ if (value() == name)
+ return false;
+ if (name == m_defaultValue)
+ m_value.clear();
+ else
+ m_value = name;
+ return true;
+}
+
+bool DisplayName::setDefaultValue(const QString &name)
+{
+ if (m_defaultValue == name)
+ return false;
+ const QString originalName = value();
+ m_defaultValue = name;
+ return originalName != value();
+}
+
+QString DisplayName::value() const
+{
+ return m_value.isEmpty() ? m_defaultValue : m_value;
+}
+
+bool DisplayName::usesDefaultValue() const
+{
+ return m_value.isEmpty();
+}
+
+void DisplayName::toMap(QVariantMap &map, const QString &key) const
+{
+ if (!usesDefaultValue())
+ map.insert(key, m_value);
+}
+
+void DisplayName::fromMap(const QVariantMap &map, const QString &key)
+{
+ m_value = map.value(key).toString();
+}
+
+bool operator==(const DisplayName &dn1, const DisplayName &dn2)
+{
+ return dn1.value() == dn2.value() && dn1.defaultValue() == dn2.defaultValue();
+}
+
+} // namespace Utils
diff --git a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h b/src/libs/utils/displayname.h
index ad7bc4f4d6..efbd25a2b8 100644
--- a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h
+++ b/src/libs/utils/displayname.h
@@ -25,35 +25,39 @@
#pragma once
-#include "filestatus.h"
-#include "symbolsvisitorbase.h"
+#include "utils_global.h"
-#include <filepathid.h>
+#include <QString>
+#include <QVariantMap>
-#include <clang/Lex/PPCallbacks.h>
+namespace Utils {
-namespace ClangBackEnd {
-
-class FileStatusPreprocessorCallbacks final : public clang::PPCallbacks, public SymbolsVisitorBase
+// Can be used for anything with a translatable, user-settable name with a fixed default value
+// that gets set by a constructor or factory.
+class QTCREATOR_UTILS_EXPORT DisplayName
{
public:
- FileStatusPreprocessorCallbacks(FileStatuses &fileStatuses,
- const FilePathCachingInterface &filePathCache,
- const clang::SourceManager *sourceManager,
- FilePathIds &filePathIndices)
- : SymbolsVisitorBase(filePathCache, sourceManager, filePathIndices)
- , m_fileStatuses(fileStatuses)
- {}
+ // These return true if and only if the value of displayName() has changed.
+ bool setValue(const QString &name);
+ bool setDefaultValue(const QString &name);
- void FileChanged(clang::SourceLocation sourceLocation,
- clang::PPCallbacks::FileChangeReason reason,
- clang::SrcMgr::CharacteristicKind,
- clang::FileID) override;
+ QString value() const;
+ QString defaultValue() const { return m_defaultValue; }
+ bool usesDefaultValue() const;
- void addFileStatus(const clang::FileEntry *fileEntry);
+ void toMap(QVariantMap &map, const QString &key) const;
+ void fromMap(const QVariantMap &map, const QString &key);
private:
- FileStatuses &m_fileStatuses;
+ QString m_value;
+ QString m_defaultValue;
};
-} // namespace ClangBackEnd
+bool QTCREATOR_UTILS_EXPORT operator==(const DisplayName &dn1, const DisplayName &dn2);
+inline bool operator!=(const DisplayName &dn1, const DisplayName &dn2)
+{
+ return !(dn1 == dn2);
+}
+
+} // namespace Utils
+
diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp
index d61a75ebf7..b4d3144a42 100644
--- a/src/libs/utils/environment.cpp
+++ b/src/libs/utils/environment.cpp
@@ -39,289 +39,58 @@ Q_GLOBAL_STATIC_WITH_ARGS(Utils::Environment, staticSystemEnvironment,
Q_GLOBAL_STATIC(QVector<Utils::EnvironmentProvider>, environmentProviders)
-static QMap<QString, QString>::iterator findKey(QMap<QString, QString> &input, Utils::OsType osType,
- const QString &key)
-{
- const Qt::CaseSensitivity casing
- = (osType == Utils::OsTypeWindows) ? Qt::CaseInsensitive : Qt::CaseSensitive;
- for (auto it = input.begin(); it != input.end(); ++it) {
- if (key.compare(it.key(), casing) == 0)
- return it;
- }
- return input.end();
-}
-
-static QMap<QString, QString>::const_iterator findKey(const QMap<QString, QString> &input,
- Utils::OsType osType,
- const QString &key)
-{
- const Qt::CaseSensitivity casing
- = (osType == Utils::OsTypeWindows) ? Qt::CaseInsensitive : Qt::CaseSensitive;
- for (auto it = input.constBegin(); it != input.constEnd(); ++it) {
- if (key.compare(it.key(), casing) == 0)
- return it;
- }
- return input.constEnd();
-}
-
namespace Utils {
-enum : char
-{
-#ifdef Q_OS_WIN
- pathSepC = ';'
-#else
- pathSepC = ':'
-#endif
-};
-
-void EnvironmentItem::sort(QList<EnvironmentItem> *list)
-{
- Utils::sort(*list, &EnvironmentItem::name);
-}
-
-QList<EnvironmentItem> EnvironmentItem::fromStringList(const QStringList &list)
-{
- QList<EnvironmentItem> result;
- for (const QString &string : list) {
- int pos = string.indexOf('=', 1);
- if (pos == -1)
- result.append(EnvironmentItem(string, QString(), EnvironmentItem::Unset));
- else
- result.append(EnvironmentItem(string.left(pos), string.mid(pos + 1)));
- }
- return result;
-}
-
-QStringList EnvironmentItem::toStringList(const QList<EnvironmentItem> &list)
-{
- return Utils::transform(list, [](const EnvironmentItem &item) {
- if (item.operation == EnvironmentItem::Unset)
- return QString(item.name);
- return QString(item.name + '=' + item.value);
- });
-}
-
-QList<EnvironmentItem> EnvironmentItem::itemsFromVariantList(const QVariantList &list)
-{
- return Utils::transform(list, [](const QVariant &item) {
- return itemFromVariantList(item.toList());
- });
-}
-
-QVariantList EnvironmentItem::toVariantList(const QList<EnvironmentItem> &list)
-{
- return Utils::transform(list, [](const EnvironmentItem &item) {
- return QVariant(toVariantList(item));
- });
-}
-
-EnvironmentItem EnvironmentItem::itemFromVariantList(const QVariantList &list)
-{
- QTC_ASSERT(list.size() == 3, return EnvironmentItem("", ""));
- QString name = list.value(0).toString();
- Operation operation = Operation(list.value(1).toInt());
- QString value = list.value(2).toString();
- return EnvironmentItem(name, value, operation);
-}
-
-QVariantList EnvironmentItem::toVariantList(const EnvironmentItem &item)
-{
- return QVariantList() << item.name << item.operation << item.value;
-}
-
-static QString expand(const Environment *e, QString value)
-{
- int replaceCount = 0;
- for (int i = 0; i < value.size(); ++i) {
- if (value.at(i) == '$') {
- if ((i + 1) < value.size()) {
- const QChar &c = value.at(i+1);
- int end = -1;
- if (c == '(')
- end = value.indexOf(')', i);
- else if (c == '{')
- end = value.indexOf('}', i);
- if (end != -1) {
- const QString &name = value.mid(i + 2, end - i - 2);
- Environment::const_iterator it = e->constFind(name);
- if (it != e->constEnd())
- value.replace(i, end - i + 1, it.value());
- ++replaceCount;
- QTC_ASSERT(replaceCount < 100, break);
- }
- }
- }
- }
- return value;
-}
-
-QDebug operator<<(QDebug debug, const EnvironmentItem &i)
-{
- QDebugStateSaver saver(debug);
- debug.noquote();
- debug.nospace();
- debug << "EnvironmentItem(";
- switch (i.operation) {
- case EnvironmentItem::Set:
- debug << "set \"" << i.name << "\" to \"" << i.value << '"';
- break;
- case EnvironmentItem::Unset:
- debug << "unset \"" << i.name << '"';
- break;
- case EnvironmentItem::Prepend:
- debug << "prepend to \"" << i.name << "\":\"" << i.value << '"';
- break;
- case EnvironmentItem::Append:
- debug << "append to \"" << i.name << "\":\"" << i.value << '"';
- break;
- }
- debug << ')';
- return debug;
-}
-
-void EnvironmentItem::apply(Environment *e, Operation op) const
-{
- switch (op) {
- case Set:
- e->set(name, expand(e, value));
- break;
- case Unset:
- e->unset(name);
- break;
- case Prepend: {
- const Environment::const_iterator it = e->constFind(name);
- if (it != e->constEnd()) {
- QString v = it.value();
- const QChar pathSep{QLatin1Char(pathSepC)};
- int sepCount = 0;
- if (v.startsWith(pathSep))
- ++sepCount;
- if (value.endsWith(pathSep))
- ++sepCount;
- if (sepCount == 2)
- v.remove(0, 1);
- else if (sepCount == 0)
- v.prepend(pathSep);
- v.prepend(expand(e, value));
- e->set(name, v);
- } else {
- apply(e, Set);
- }
- }
- break;
- case Append: {
- const Environment::const_iterator it = e->constFind(name);
- if (it != e->constEnd()) {
- QString v = it.value();
- const QChar pathSep{QLatin1Char(pathSepC)};
- int sepCount = 0;
- if (v.endsWith(pathSep))
- ++sepCount;
- if (value.startsWith(pathSep))
- ++sepCount;
- if (sepCount == 2)
- v.chop(1);
- else if (sepCount == 0)
- v.append(pathSep);
- v.append(expand(e, value));
- e->set(name, v);
- } else {
- apply(e, Set);
- }
- }
- break;
- }
-}
-
-Environment::Environment(const QStringList &env, OsType osType) : m_osType(osType)
-{
- for (const QString &s : env) {
- int i = s.indexOf('=', 1);
- if (i >= 0) {
- const QString key = s.left(i);
- if (!key.contains('=')) {
- const QString value = s.mid(i + 1);
- set(key, value);
- }
- }
- }
-}
-
-QStringList Environment::toStringList() const
-{
- QStringList result;
- for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it)
- result.append(it.key() + '=' + it.value());
- return result;
-}
-
QProcessEnvironment Environment::toProcessEnvironment() const
{
QProcessEnvironment result;
- for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it)
- result.insert(it.key(), it.value());
+ for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
+ if (it.value().second)
+ result.insert(it.key().name, expandedValueForKey(key(it)));
+ }
return result;
}
-void Environment::set(const QString &key, const QString &value)
+void Environment::appendOrSetPath(const QString &value)
{
- QTC_ASSERT(!key.contains('='), return);
- auto it = findKey(m_values, m_osType, key);
- if (it == m_values.end())
- m_values.insert(key, value);
- else
- it.value() = value;
+ appendOrSet("PATH", QDir::toNativeSeparators(value),
+ QString(OsSpecificAspects::pathListSeparator(m_osType)));
}
-void Environment::unset(const QString &key)
+void Environment::prependOrSetPath(const QString &value)
{
- QTC_ASSERT(!key.contains('='), return);
- auto it = findKey(m_values, m_osType, key);
- if (it != m_values.end())
- m_values.erase(it);
+ prependOrSet("PATH", QDir::toNativeSeparators(value),
+ QString(OsSpecificAspects::pathListSeparator(m_osType)));
}
void Environment::appendOrSet(const QString &key, const QString &value, const QString &sep)
{
- QTC_ASSERT(!key.contains('='), return);
- auto it = findKey(m_values, m_osType, key);
+ QTC_ASSERT(!key.contains('='), return );
+ const auto it = findKey(key);
if (it == m_values.end()) {
- m_values.insert(key, value);
+ m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true));
} else {
// Append unless it is already there
const QString toAppend = sep + value;
- if (!it.value().endsWith(toAppend))
- it.value().append(toAppend);
+ if (!it.value().first.endsWith(toAppend))
+ it.value().first.append(toAppend);
}
}
-void Environment::prependOrSet(const QString&key, const QString &value, const QString &sep)
+void Environment::prependOrSet(const QString &key, const QString &value, const QString &sep)
{
- QTC_ASSERT(!key.contains('='), return);
- auto it = findKey(m_values, m_osType, key);
+ QTC_ASSERT(!key.contains('='), return );
+ const auto it = findKey(key);
if (it == m_values.end()) {
- m_values.insert(key, value);
+ m_values.insert(DictKey(key, nameCaseSensitivity()), qMakePair(value, true));
} else {
// Prepend unless it is already there
const QString toPrepend = value + sep;
- if (!it.value().startsWith(toPrepend))
- it.value().prepend(toPrepend);
+ if (!it.value().first.startsWith(toPrepend))
+ it.value().first.prepend(toPrepend);
}
}
-void Environment::appendOrSetPath(const QString &value)
-{
- appendOrSet("PATH", QDir::toNativeSeparators(value),
- QString(OsSpecificAspects::pathListSeparator(m_osType)));
-}
-
-void Environment::prependOrSetPath(const QString &value)
-{
- prependOrSet("PATH", QDir::toNativeSeparators(value),
- QString(OsSpecificAspects::pathListSeparator(m_osType)));
-}
-
void Environment::prependOrSetLibrarySearchPath(const QString &value)
{
switch (m_osType) {
@@ -387,11 +156,6 @@ void Environment::setupEnglishOutput(QStringList *environment)
*environment = env.toStringList();
}
-void Environment::clear()
-{
- m_values.clear();
-}
-
FilePath Environment::searchInDirectory(const QStringList &execs, const FilePath &directory,
QSet<FilePath> &alreadyChecked) const
{
@@ -420,7 +184,7 @@ QStringList Environment::appendExeExtensions(const QString &executable) const
// Check all the executable extensions on windows:
// PATHEXT is only used if the executable has no extension
if (fi.suffix().isEmpty()) {
- const QStringList extensions = value("PATHEXT").split(';');
+ const QStringList extensions = expandedValueForKey("PATHEXT").split(';');
for (const QString &ext : extensions)
execs << executable + ext.toLower();
@@ -448,6 +212,11 @@ bool Environment::isSameExecutable(const QString &exe1, const QString &exe2) con
return false;
}
+QString Environment::expandedValueForKey(const QString &key) const
+{
+ return expandVariables(value(key));
+}
+
FilePath Environment::searchInPath(const QString &executable,
const FilePathList &additionalDirs,
const PathFilter &func) const
@@ -487,129 +256,58 @@ FilePath Environment::searchInPath(const QString &executable,
return FilePath();
}
-FilePathList Environment::path() const
-{
- const QStringList pathComponents = value("PATH")
- .split(OsSpecificAspects::pathListSeparator(m_osType), QString::SkipEmptyParts);
- return Utils::transform(pathComponents, &FilePath::fromUserInput);
-}
-
-QString Environment::value(const QString &key) const
-{
- const auto it = findKey(m_values, m_osType, key);
- return it != m_values.end() ? it.value() : QString();
-}
-
-QString Environment::key(Environment::const_iterator it) const
-{
- return it.key();
-}
-
-QString Environment::value(Environment::const_iterator it) const
-{
- return it.value();
-}
-
-Environment::const_iterator Environment::constBegin() const
-{
- return m_values.constBegin();
-}
-
-Environment::const_iterator Environment::constEnd() const
+FilePathList Environment::findAllInPath(const QString &executable,
+ const FilePathList &additionalDirs,
+ const Environment::PathFilter &func) const
{
- return m_values.constEnd();
-}
-
-Environment::const_iterator Environment::constFind(const QString &name) const
-{
- return findKey(m_values, m_osType, name);
-}
+ if (executable.isEmpty())
+ return {};
-int Environment::size() const
-{
- return m_values.size();
-}
+ const QString exec = QDir::cleanPath(expandVariables(executable));
+ const QFileInfo fi(exec);
-void Environment::modify(const QList<EnvironmentItem> & list)
-{
- Environment resultEnvironment = *this;
- for (const EnvironmentItem &item : list)
- item.apply(&resultEnvironment);
- *this = resultEnvironment;
-}
+ const QStringList execs = appendExeExtensions(exec);
-QList<EnvironmentItem> Environment::diff(const Environment &other, bool checkAppendPrepend) const
-{
- QMap<QString, QString>::const_iterator thisIt = constBegin();
- QMap<QString, QString>::const_iterator otherIt = other.constBegin();
-
- QList<EnvironmentItem> result;
- while (thisIt != constEnd() || otherIt != other.constEnd()) {
- if (thisIt == constEnd()) {
- result.append(EnvironmentItem(otherIt.key(), otherIt.value()));
- ++otherIt;
- } else if (otherIt == other.constEnd()) {
- result.append(EnvironmentItem(thisIt.key(), QString(), EnvironmentItem::Unset));
- ++thisIt;
- } else if (thisIt.key() < otherIt.key()) {
- result.append(EnvironmentItem(thisIt.key(), QString(), EnvironmentItem::Unset));
- ++thisIt;
- } else if (thisIt.key() > otherIt.key()) {
- result.append(EnvironmentItem(otherIt.key(), otherIt.value()));
- ++otherIt;
- } else {
- const QString &oldValue = thisIt.value();
- const QString &newValue = otherIt.value();
- if (oldValue != newValue) {
- if (checkAppendPrepend && newValue.startsWith(oldValue)) {
- QString appended = newValue.right(newValue.size() - oldValue.size());
- if (appended.startsWith(QLatin1Char(pathSepC)))
- appended.remove(0, 1);
- result.append(EnvironmentItem(otherIt.key(), appended,
- EnvironmentItem::Append));
- } else if (checkAppendPrepend && newValue.endsWith(oldValue)) {
- QString prepended = newValue.left(newValue.size() - oldValue.size());
- if (prepended.endsWith(QLatin1Char(pathSepC)))
- prepended.chop(1);
- result.append(EnvironmentItem(otherIt.key(), prepended,
- EnvironmentItem::Prepend));
- } else {
- result.append(EnvironmentItem(otherIt.key(), newValue));
- }
- }
- ++otherIt;
- ++thisIt;
+ if (fi.isAbsolute()) {
+ for (const QString &path : execs) {
+ QFileInfo pfi = QFileInfo(path);
+ if (pfi.isFile() && pfi.isExecutable())
+ return {FilePath::fromString(path)};
}
+ return {FilePath::fromString(exec)};
}
- return result;
-}
-bool Environment::hasKey(const QString &key) const
-{
- return m_values.contains(key);
-}
-
-OsType Environment::osType() const
-{
- return m_osType;
-}
+ QSet<FilePath> result;
+ QSet<FilePath> alreadyChecked;
+ for (const FilePath &dir : additionalDirs) {
+ FilePath tmp = searchInDirectory(execs, dir, alreadyChecked);
+ if (!tmp.isEmpty() && (!func || func(tmp)))
+ result << tmp;
+ }
-QString Environment::userName() const
-{
- return value(QString::fromLatin1(m_osType == OsTypeWindows ? "USERNAME" : "USER"));
+ if (!executable.contains('/')) {
+ for (const FilePath &p : path()) {
+ FilePath tmp = searchInDirectory(execs, p, alreadyChecked);
+ if (!tmp.isEmpty() && (!func || func(tmp)))
+ result << tmp;
+ }
+ }
+ return result.values();
}
-bool Environment::operator!=(const Environment &other) const
+FilePathList Environment::path() const
{
- return !(*this == other);
+ return pathListValue("PATH");
}
-bool Environment::operator==(const Environment &other) const
+FilePathList Environment::pathListValue(const QString &varName) const
{
- return m_osType == other.m_osType && m_values == other.m_values;
+ const QStringList pathComponents = expandedValueForKey(varName)
+ .split(OsSpecificAspects::pathListSeparator(m_osType), QString::SkipEmptyParts);
+ return transform(pathComponents, &FilePath::fromUserInput);
}
-void Environment::modifySystemEnvironment(const QList<EnvironmentItem> &list)
+void Environment::modifySystemEnvironment(const EnvironmentItems &list)
{
staticSystemEnvironment->modify(list);
}
@@ -629,10 +327,10 @@ QString Environment::expandVariables(const QString &input) const
for (int vStart = -1, i = 0; i < result.length(); ) {
if (result.at(i++) == '%') {
if (vStart > 0) {
- const_iterator it = findKey(m_values, m_osType, result.mid(vStart, i - vStart - 1));
+ const auto it = findKey(result.mid(vStart, i - vStart - 1));
if (it != m_values.constEnd()) {
- result.replace(vStart - 1, i - vStart + 1, *it);
- i = vStart - 1 + it->length();
+ result.replace(vStart - 1, i - vStart + 1, it->first);
+ i = vStart - 1 + it->first.length();
vStart = -1;
} else {
vStart = i;
@@ -663,28 +361,28 @@ QString Environment::expandVariables(const QString &input) const
}
} else if (state == BRACEDVARIABLE) {
if (c == '}') {
- const_iterator it = m_values.constFind(result.mid(vStart, i - 1 - vStart));
+ const_iterator it = constFind(result.mid(vStart, i - 1 - vStart));
if (it != constEnd()) {
- result.replace(vStart - 2, i - vStart + 2, *it);
- i = vStart - 2 + it->length();
+ result.replace(vStart - 2, i - vStart + 2, it->first);
+ i = vStart - 2 + it->first.length();
}
state = BASE;
}
} else if (state == VARIABLE) {
if (!c.isLetterOrNumber() && c != '_') {
- const_iterator it = m_values.constFind(result.mid(vStart, i - vStart - 1));
+ const_iterator it = constFind(result.mid(vStart, i - vStart - 1));
if (it != constEnd()) {
- result.replace(vStart - 1, i - vStart, *it);
- i = vStart - 1 + it->length();
+ result.replace(vStart - 1, i - vStart, it->first);
+ i = vStart - 1 + it->first.length();
}
state = BASE;
}
}
}
if (state == VARIABLE) {
- const_iterator it = m_values.constFind(result.mid(vStart));
+ const_iterator it = constFind(result.mid(vStart));
if (it != constEnd())
- result.replace(vStart - 1, result.length() - vStart + 1, *it);
+ result.replace(vStart - 1, result.length() - vStart + 1, it->first);
}
}
return result;
diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h
index f1e957ab6d..0f97c2c3a8 100644
--- a/src/libs/utils/environment.h
+++ b/src/libs/utils/environment.h
@@ -27,8 +27,9 @@
#include "fileutils.h"
#include "hostosinfo.h"
+#include "namevaluedictionary.h"
+#include "namevalueitem.h"
#include "optional.h"
-#include "utils_global.h"
#include <QMap>
#include <QStringList>
@@ -39,71 +40,18 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QProcessEnvironment)
namespace Utils {
-class Environment;
-class QTCREATOR_UTILS_EXPORT EnvironmentItem
+class QTCREATOR_UTILS_EXPORT Environment final : public NameValueDictionary
{
public:
- enum Operation { Set, Unset, Prepend, Append };
+ using NameValueDictionary::NameValueDictionary;
- EnvironmentItem(const QString &n, const QString &v, Operation op = Set)
- : name(n), value(v), operation(op)
- {}
-
- void apply(Environment *e) const { apply(e, operation); }
-
- QString name;
- QString value;
- Operation operation;
-
- bool operator==(const EnvironmentItem &other) const
- {
- return operation == other.operation && name == other.name && value == other.value;
- }
-
- bool operator!=(const EnvironmentItem &other) const
- {
- return !(*this == other);
- }
-
- static void sort(QList<EnvironmentItem> *list);
- static QList<EnvironmentItem> fromStringList(const QStringList &list);
- static QStringList toStringList(const QList<EnvironmentItem> &list);
- static QList<EnvironmentItem> itemsFromVariantList(const QVariantList &list);
- static QVariantList toVariantList(const QList<EnvironmentItem> &list);
- static EnvironmentItem itemFromVariantList(const QVariantList &list);
- static QVariantList toVariantList(const EnvironmentItem &item);
-
-private:
- void apply(Environment *e, Operation op) const;
-};
-
-QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug debug, const EnvironmentItem &i);
-
-class QTCREATOR_UTILS_EXPORT Environment
-{
-public:
- using const_iterator = QMap<QString, QString>::const_iterator;
-
- explicit Environment(OsType osType = HostOsInfo::hostOs()) : m_osType(osType) {}
- explicit Environment(const QStringList &env, OsType osType = HostOsInfo::hostOs());
static Environment systemEnvironment();
static void setupEnglishOutput(Environment *environment);
static void setupEnglishOutput(QProcessEnvironment *environment);
static void setupEnglishOutput(QStringList *environment);
- QStringList toStringList() const;
QProcessEnvironment toProcessEnvironment() const;
- QString value(const QString &key) const;
- void set(const QString &key, const QString &value);
- void unset(const QString &key);
- void modify(const QList<EnvironmentItem> &list);
- /// Return the Environment changes necessary to modify this into the other environment.
- QList<EnvironmentItem> diff(const Environment &other, bool checkAppendPrepend = false) const;
- bool hasKey(const QString &key) const;
- OsType osType() const;
-
- QString userName() const;
void appendOrSet(const QString &key, const QString &value, const QString &sep = QString());
void prependOrSet(const QString &key, const QString &value, const QString &sep = QString());
@@ -114,40 +62,30 @@ public:
void prependOrSetLibrarySearchPath(const QString &value);
void prependOrSetLibrarySearchPaths(const QStringList &values);
- void clear();
- int size() const;
-
- QString key(Environment::const_iterator it) const;
- QString value(Environment::const_iterator it) const;
-
- Environment::const_iterator constBegin() const;
- Environment::const_iterator constEnd() const;
- Environment::const_iterator constFind(const QString &name) const;
-
using PathFilter = std::function<bool(const FilePath &)>;
FilePath searchInPath(const QString &executable,
const FilePathList &additionalDirs = FilePathList(),
const PathFilter &func = PathFilter()) const;
+ FilePathList findAllInPath(const QString &executable,
+ const FilePathList &additionalDirs = FilePathList(),
+ const PathFilter &func = PathFilter()) const;
FilePathList path() const;
+ FilePathList pathListValue(const QString &varName) const;
QStringList appendExeExtensions(const QString &executable) const;
bool isSameExecutable(const QString &exe1, const QString &exe2) const;
+ QString expandedValueForKey(const QString &key) const;
QString expandVariables(const QString &input) const;
FilePath expandVariables(const FilePath &input) const;
QStringList expandVariables(const QStringList &input) const;
- bool operator!=(const Environment &other) const;
- bool operator==(const Environment &other) const;
-
- static void modifySystemEnvironment(const QList<EnvironmentItem> &list); // use with care!!!
+ static void modifySystemEnvironment(const EnvironmentItems &list); // use with care!!!
private:
FilePath searchInDirectory(const QStringList &execs, const FilePath &directory,
QSet<FilePath> &alreadyChecked) const;
- QMap<QString, QString> m_values;
- OsType m_osType;
};
class QTCREATOR_UTILS_EXPORT EnvironmentProvider
diff --git a/src/libs/utils/environmentdialog.cpp b/src/libs/utils/environmentdialog.cpp
index 07e6155c7d..88311854ec 100644
--- a/src/libs/utils/environmentdialog.cpp
+++ b/src/libs/utils/environmentdialog.cpp
@@ -35,144 +35,20 @@
namespace Utils {
-namespace Internal {
-
-static QList<EnvironmentItem> cleanUp(
- const QList<EnvironmentItem> &items)
-{
- QList<EnvironmentItem> uniqueItems;
- QSet<QString> uniqueSet;
- for (int i = items.count() - 1; i >= 0; i--) {
- EnvironmentItem item = items.at(i);
- if (HostOsInfo::isWindowsHost())
- item.name = item.name.toUpper();
- const QString &itemName = item.name;
- QString emptyName = itemName;
- emptyName.remove(QLatin1Char(' '));
- if (!emptyName.isEmpty() && !uniqueSet.contains(itemName)) {
- uniqueItems.prepend(item);
- uniqueSet.insert(itemName);
- }
- }
- return uniqueItems;
-}
-
-class EnvironmentItemsWidget : public QWidget
-{
- Q_OBJECT
-public:
- explicit EnvironmentItemsWidget(QWidget *parent = nullptr);
-
- void setEnvironmentItems(const QList<EnvironmentItem> &items);
- QList<EnvironmentItem> environmentItems() const;
-
- void setPlaceholderText(const QString &text);
-
-private:
- QPlainTextEdit *m_editor;
-};
-
-EnvironmentItemsWidget::EnvironmentItemsWidget(QWidget *parent) :
- QWidget(parent)
-{
- m_editor = new QPlainTextEdit(this);
- auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
- layout->addWidget(m_editor);
-}
-
-void EnvironmentItemsWidget::setEnvironmentItems(const QList<EnvironmentItem> &items)
-{
- QList<EnvironmentItem> sortedItems = items;
- EnvironmentItem::sort(&sortedItems);
- const QStringList list = EnvironmentItem::toStringList(sortedItems);
- m_editor->document()->setPlainText(list.join(QLatin1Char('\n')));
-}
-
-QList<EnvironmentItem> EnvironmentItemsWidget::environmentItems() const
-{
- const QStringList list = m_editor->document()->toPlainText().split(QLatin1String("\n"));
- QList<EnvironmentItem> items = EnvironmentItem::fromStringList(list);
- return cleanUp(items);
-}
-
-void EnvironmentItemsWidget::setPlaceholderText(const QString &text)
-{
- m_editor->setPlaceholderText(text);
-}
-
-class EnvironmentDialogPrivate
-{
-public:
- EnvironmentItemsWidget *m_editor;
-};
-
-} // namespace Internal
-
-EnvironmentDialog::EnvironmentDialog(QWidget *parent) :
- QDialog(parent), d(new Internal::EnvironmentDialogPrivate)
-{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- resize(640, 480);
- d->m_editor = new Internal::EnvironmentItemsWidget(this);
- auto box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
- connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject);
-
- auto helpLabel = new QLabel(this);
- helpLabel->setText(tr("Enter one environment variable per line.\n"
- "To set or change a variable, use VARIABLE=VALUE.\n"
- "Existing variables can be referenced in a VALUE with ${OTHER}.\n"
- "To clear a variable, put its name on a line with nothing else on it."));
-
- auto layout = new QVBoxLayout(this);
- layout->addWidget(d->m_editor);
- layout->addWidget(helpLabel);
-
- layout->addWidget(box);
-
- setWindowTitle(tr("Edit Environment"));
-}
-
-EnvironmentDialog::~EnvironmentDialog()
-{
- delete d;
-}
-
-void EnvironmentDialog::setEnvironmentItems(const QList<EnvironmentItem> &items)
-{
- d->m_editor->setEnvironmentItems(items);
-}
-
-QList<EnvironmentItem> EnvironmentDialog::environmentItems() const
-{
- return d->m_editor->environmentItems();
-}
-
-void EnvironmentDialog::setPlaceholderText(const QString &text)
-{
- d->m_editor->setPlaceholderText(text);
-}
-
-QList<EnvironmentItem> EnvironmentDialog::getEnvironmentItems(bool *ok,
- QWidget *parent,
- const QList<EnvironmentItem> &initial,
- const QString &placeholderText,
- Polisher polisher)
-{
- EnvironmentDialog dlg(parent);
- if (polisher)
- polisher(&dlg);
- dlg.setEnvironmentItems(initial);
- dlg.setPlaceholderText(placeholderText);
- bool result = dlg.exec() == QDialog::Accepted;
- if (ok)
- *ok = result;
- if (result)
- return dlg.environmentItems();
- return QList<EnvironmentItem>();
+Utils::optional<EnvironmentItems> EnvironmentDialog::getEnvironmentItems(
+ QWidget *parent, const EnvironmentItems &initial, const QString &placeholderText, Polisher polisher)
+{
+ return getNameValueItems(
+ parent,
+ initial,
+ placeholderText,
+ polisher,
+ tr("Edit Environment"),
+ tr("Enter one environment variable per line.\n"
+ "To set or change a variable, use VARIABLE=VALUE.\n"
+ "Existing variables can be referenced in a VALUE with ${OTHER}.\n"
+ "To clear a variable, put its name on a line with nothing else on it.\n"
+ "To disable a variable, prefix the line with \"#\""));
}
} // namespace Utils
-
-#include "environmentdialog.moc"
diff --git a/src/libs/utils/environmentdialog.h b/src/libs/utils/environmentdialog.h
index be8218508b..6dbb38e191 100644
--- a/src/libs/utils/environmentdialog.h
+++ b/src/libs/utils/environmentdialog.h
@@ -25,36 +25,20 @@
#pragma once
-#include "utils_global.h"
#include "environment.h"
-
-#include <QDialog>
+#include "namevaluesdialog.h"
+#include <thread>
namespace Utils {
-namespace Internal { class EnvironmentDialogPrivate; }
-
-class QTCREATOR_UTILS_EXPORT EnvironmentDialog : public QDialog
+class QTCREATOR_UTILS_EXPORT EnvironmentDialog : public NameValuesDialog
{
Q_OBJECT
public:
- explicit EnvironmentDialog(QWidget *parent = nullptr);
- ~EnvironmentDialog() override;
-
- void setEnvironmentItems(const QList<EnvironmentItem> &items);
- QList<EnvironmentItem> environmentItems() const;
-
- void setPlaceholderText(const QString &text);
-
- using Polisher = std::function<void(QWidget*)>;
- static QList<EnvironmentItem> getEnvironmentItems(bool *ok,
- QWidget *parent = nullptr,
- const QList<EnvironmentItem> &initial = QList<EnvironmentItem>(),
- const QString &placeholderText = QString(),
- Polisher polish = Polisher());
-
-private:
- Internal::EnvironmentDialogPrivate *d;
+ static Utils::optional<EnvironmentItems> getEnvironmentItems(QWidget *parent = nullptr,
+ const EnvironmentItems &initial = {},
+ const QString &placeholderText = {},
+ Polisher polish = {});
};
} // namespace Utils
diff --git a/src/libs/utils/environmentfwd.h b/src/libs/utils/environmentfwd.h
new file mode 100644
index 0000000000..04a57418b5
--- /dev/null
+++ b/src/libs/utils/environmentfwd.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+template<typename Type>
+class QList;
+class QTreeView;
+QT_END_NAMESPACE
+
+namespace Utils {
+class NameValueDictionary;
+class NameValueItem;
+using NameValueItems = QVector<NameValueItem>;
+
+class Environment;
+using EnvironmentItem = NameValueItem;
+using EnvironmentItems = NameValueItems;
+
+class PreprocessorMacroDictionary;
+using PreprocessorMacroItem = NameValueItem;
+using PreprocessorMacroItems = NameValueItems;
+
+class NameValueModel;
+class EnvironmentModel;
+} // namespace Utils
diff --git a/src/libs/utils/environmentmodel.cpp b/src/libs/utils/environmentmodel.cpp
index 045a6d2b65..c7efcce930 100644
--- a/src/libs/utils/environmentmodel.cpp
+++ b/src/libs/utils/environmentmodel.cpp
@@ -33,360 +33,12 @@
#include <QFont>
namespace Utils {
-namespace Internal {
-
-class EnvironmentModelPrivate
-{
-public:
- void updateResultEnvironment()
- {
- m_resultEnvironment = m_baseEnvironment;
- m_resultEnvironment.modify(m_items);
- // Add removed variables again and mark them as "<UNSET>" so
- // that the user can actually see those removals:
- foreach (const EnvironmentItem &item, m_items) {
- if (item.operation == EnvironmentItem::Unset)
- m_resultEnvironment.set(item.name, EnvironmentModel::tr("<UNSET>"));
- }
- }
-
- int findInChanges(const QString &name) const
- {
- for (int i=0; i<m_items.size(); ++i)
- if (m_items.at(i).name == name)
- return i;
- return -1;
- }
-
- int findInResultInsertPosition(const QString &name) const
- {
- Environment::const_iterator it;
- int i = 0;
- for (it = m_resultEnvironment.constBegin(); it != m_resultEnvironment.constEnd(); ++it, ++i)
- if (m_resultEnvironment.key(it) > name)
- return i;
- return m_resultEnvironment.size();
- }
-
- int findInResult(const QString &name) const
- {
- Environment::const_iterator it;
- int i = 0;
- for (it = m_resultEnvironment.constBegin(); it != m_resultEnvironment.constEnd(); ++it, ++i)
- if (m_resultEnvironment.key(it) == name)
- return i;
- return -1;
- }
-
- Environment m_baseEnvironment;
- Environment m_resultEnvironment;
- QList<EnvironmentItem> m_items;
-};
-
-} // namespace Internal
-
-EnvironmentModel::EnvironmentModel(QObject *parent) :
- QAbstractTableModel(parent),
- d(new Internal::EnvironmentModelPrivate)
-{ }
-
-EnvironmentModel::~EnvironmentModel()
-{
- delete d;
-}
-
-QString EnvironmentModel::indexToVariable(const QModelIndex &index) const
+const Environment &EnvironmentModel::baseEnvironment() const
{
- return d->m_resultEnvironment.key(d->m_resultEnvironment.constBegin() + index.row());
+ return static_cast<const Environment &>(baseNameValueDictionary());
}
-
void EnvironmentModel::setBaseEnvironment(const Environment &env)
{
- if (d->m_baseEnvironment == env)
- return;
- beginResetModel();
- d->m_baseEnvironment = env;
- d->updateResultEnvironment();
- endResetModel();
-}
-
-int EnvironmentModel::rowCount(const QModelIndex &parent) const
-{
- if (parent.isValid())
- return 0;
-
- return d->m_resultEnvironment.size();
-}
-int EnvironmentModel::columnCount(const QModelIndex &parent) const
-{
- if (parent.isValid())
- return 0;
-
- return 2;
-}
-
-bool EnvironmentModel::changes(const QString &name) const
-{
- return d->findInChanges(name) >= 0;
-}
-
-Environment EnvironmentModel::baseEnvironment() const
-{
- return d->m_baseEnvironment;
-}
-
-QVariant EnvironmentModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole) {
- if (index.column() == 0) {
- return d->m_resultEnvironment.key(d->m_resultEnvironment.constBegin() + index.row());
- } else if (index.column() == 1) {
- // Do not return "<UNSET>" when editing a previously unset variable:
- if (role == Qt::EditRole) {
- int pos = d->findInChanges(indexToVariable(index));
- if (pos >= 0)
- return d->m_items.at(pos).value;
- }
- QString value = d->m_resultEnvironment.value(d->m_resultEnvironment.constBegin() + index.row());
- if (role == Qt::ToolTipRole && value.length() > 80) {
- // Use html to enable text wrapping
- value = value.toHtmlEscaped();
- value.prepend(QLatin1String("<html><body>"));
- value.append(QLatin1String("</body></html>"));
- }
- return value;
- }
- }
- if (role == Qt::FontRole) {
- // check whether this environment variable exists in d->m_items
- if (changes(d->m_resultEnvironment.key(d->m_resultEnvironment.constBegin() + index.row()))) {
- QFont f;
- f.setBold(true);
- return QVariant(f);
- }
- return QFont();
- }
- return QVariant();
-}
-
-Qt::ItemFlags EnvironmentModel::flags(const QModelIndex &index) const
-{
- Q_UNUSED(index)
- return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
-}
-
-QVariant EnvironmentModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Vertical || role != Qt::DisplayRole)
- return QVariant();
- return section == 0 ? tr("Variable") : tr("Value");
+ setBaseNameValueDictionary(env);
}
-
-/// *****************
-/// Utility functions
-/// *****************
-QModelIndex EnvironmentModel::variableToIndex(const QString &name) const
-{
- int row = d->findInResult(name);
- if (row == -1)
- return QModelIndex();
- return index(row, 0);
-}
-
-bool EnvironmentModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- if (!index.isValid() || role != Qt::EditRole)
- return false;
-
- // ignore changes to already set values:
- if (data(index, role) == value)
- return true;
-
- const QString oldName = data(this->index(index.row(), 0, QModelIndex())).toString();
- const QString oldValue = data(this->index(index.row(), 1, QModelIndex()), Qt::EditRole).toString();
- int changesPos = d->findInChanges(oldName);
-
- if (index.column() == 0) {
- //fail if a variable with the same name already exists
- const QString &newName = HostOsInfo::isWindowsHost()
- ? value.toString().toUpper() : value.toString();
- if (newName.isEmpty() || newName.contains('='))
- return false;
- // Does the new name exist already?
- if (d->m_resultEnvironment.hasKey(newName) || newName.isEmpty())
- return false;
-
- EnvironmentItem newVariable(newName, oldValue);
-
- if (changesPos != -1)
- resetVariable(oldName); // restore the original base variable again
-
- QModelIndex newIndex = addVariable(newVariable); // add the new variable
- emit focusIndex(newIndex.sibling(newIndex.row(), 1)); // hint to focus on the value
- return true;
- } else if (index.column() == 1) {
- // We are changing an existing value:
- const QString stringValue = value.toString();
- if (changesPos != -1) {
- // We have already changed this value
- if (d->m_baseEnvironment.hasKey(oldName) && stringValue == d->m_baseEnvironment.value(oldName)) {
- // ... and now went back to the base value
- d->m_items.removeAt(changesPos);
- } else {
- // ... and changed it again
- d->m_items[changesPos].value = stringValue;
- d->m_items[changesPos].operation = EnvironmentItem::Set;
- }
- } else {
- // Add a new change item:
- d->m_items.append(EnvironmentItem(oldName, stringValue));
- }
- d->updateResultEnvironment();
- emit dataChanged(index, index);
- emit userChangesChanged();
- return true;
- }
- return false;
-}
-
-QModelIndex EnvironmentModel::addVariable()
-{
- //: Name when inserting a new variable
- return addVariable(EnvironmentItem(tr("<VARIABLE>"),
- //: Value when inserting a new variable
- tr("<VALUE>")));
-}
-
-QModelIndex EnvironmentModel::addVariable(const EnvironmentItem &item)
-{
-
- // Return existing index if the name is already in the result set:
- int pos = d->findInResult(item.name);
- if (pos >= 0 && pos < d->m_resultEnvironment.size())
- return index(pos, 0, QModelIndex());
-
- int insertPos = d->findInResultInsertPosition(item.name);
- int changePos = d->findInChanges(item.name);
- if (d->m_baseEnvironment.hasKey(item.name)) {
- // We previously unset this!
- Q_ASSERT(changePos >= 0);
- // Do not insert a line here as we listed the variable as <UNSET> before!
- Q_ASSERT(d->m_items.at(changePos).name == item.name);
- Q_ASSERT(d->m_items.at(changePos).operation == EnvironmentItem::Unset);
- Q_ASSERT(d->m_items.at(changePos).value.isEmpty());
- d->m_items[changePos] = item;
- emit dataChanged(index(insertPos, 0, QModelIndex()), index(insertPos, 1, QModelIndex()));
- } else {
- // We add something that is not in the base environment
- // Insert a new line!
- beginInsertRows(QModelIndex(), insertPos, insertPos);
- Q_ASSERT(changePos < 0);
- d->m_items.append(item);
- d->updateResultEnvironment();
- endInsertRows();
- }
- emit userChangesChanged();
- return index(insertPos, 0, QModelIndex());
-}
-
-void EnvironmentModel::resetVariable(const QString &name)
-{
- int rowInChanges = d->findInChanges(name);
- if (rowInChanges < 0)
- return;
-
- int rowInResult = d->findInResult(name);
- if (rowInResult < 0)
- return;
-
- if (d->m_baseEnvironment.hasKey(name)) {
- d->m_items.removeAt(rowInChanges);
- d->updateResultEnvironment();
- emit dataChanged(index(rowInResult, 0, QModelIndex()), index(rowInResult, 1, QModelIndex()));
- emit userChangesChanged();
- } else {
- // Remove the line completely!
- beginRemoveRows(QModelIndex(), rowInResult, rowInResult);
- d->m_items.removeAt(rowInChanges);
- d->updateResultEnvironment();
- endRemoveRows();
- emit userChangesChanged();
- }
-}
-
-void EnvironmentModel::unsetVariable(const QString &name)
-{
- // This does not change the number of rows as we will display a <UNSET>
- // in place of the original variable!
- int row = d->findInResult(name);
- if (row < 0)
- return;
-
- // look in d->m_items for the variable
- int pos = d->findInChanges(name);
- if (pos != -1) {
- d->m_items[pos].operation = EnvironmentItem::Unset;
- d->m_items[pos].value.clear();
- d->updateResultEnvironment();
- emit dataChanged(index(row, 0, QModelIndex()), index(row, 1, QModelIndex()));
- emit userChangesChanged();
- return;
- }
- d->m_items.append(EnvironmentItem(name, QString(), EnvironmentItem::Unset));
- d->updateResultEnvironment();
- emit dataChanged(index(row, 0, QModelIndex()), index(row, 1, QModelIndex()));
- emit userChangesChanged();
-}
-
-bool EnvironmentModel::canUnset(const QString &name)
-{
- int pos = d->findInChanges(name);
- if (pos != -1)
- return d->m_items.at(pos).operation == EnvironmentItem::Unset;
- else
- return false;
-}
-
-bool EnvironmentModel::canReset(const QString &name)
-{
- return d->m_baseEnvironment.hasKey(name);
-}
-
-QList<EnvironmentItem> EnvironmentModel::userChanges() const
-{
- return d->m_items;
-}
-
-void EnvironmentModel::setUserChanges(const QList<EnvironmentItem> &list)
-{
- QList<EnvironmentItem> filtered = Utils::filtered(list, [](const EnvironmentItem &i) {
- return i.name != "export " && !i.name.contains('=');
- });
- // We assume nobody is reordering the items here.
- if (filtered == d->m_items)
- return;
- beginResetModel();
- d->m_items = filtered;
- for (EnvironmentItem &item : d->m_items) {
- QString &name = item.name;
- name = name.trimmed();
- if (name.startsWith("export "))
- name = name.mid(7).trimmed();
- if (d->m_baseEnvironment.osType() == OsTypeWindows) {
- // Environment variable names are case-insensitive under windows, but we still
- // want to preserve the case of pre-existing variables.
- auto it = d->m_baseEnvironment.constFind(name);
- if (it != d->m_baseEnvironment.constEnd())
- name = d->m_baseEnvironment.key(it);
- }
- }
-
- d->updateResultEnvironment();
- endResetModel();
- emit userChangesChanged();
-}
-
} // namespace Utils
diff --git a/src/libs/utils/environmentmodel.h b/src/libs/utils/environmentmodel.h
index db20224651..ac5f017448 100644
--- a/src/libs/utils/environmentmodel.h
+++ b/src/libs/utils/environmentmodel.h
@@ -25,55 +25,17 @@
#pragma once
-#include "utils_global.h"
-
-#include <QAbstractTableModel>
+#include "namevaluemodel.h"
namespace Utils {
-class Environment;
-class EnvironmentItem;
-
-namespace Internal { class EnvironmentModelPrivate; }
-class QTCREATOR_UTILS_EXPORT EnvironmentModel : public QAbstractTableModel
+class QTCREATOR_UTILS_EXPORT EnvironmentModel : public NameValueModel
{
Q_OBJECT
public:
- explicit EnvironmentModel(QObject *parent = nullptr);
- ~EnvironmentModel() override;
-
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const override;
-
- QModelIndex addVariable();
- QModelIndex addVariable(const EnvironmentItem &item);
- void resetVariable(const QString &name);
- void unsetVariable(const QString &name);
- bool canUnset(const QString &name);
- bool canReset(const QString &name);
- QString indexToVariable(const QModelIndex &index) const;
- QModelIndex variableToIndex(const QString &name) const;
- bool changes(const QString &key) const;
- Environment baseEnvironment() const;
+ const Environment &baseEnvironment() const;
void setBaseEnvironment(const Environment &env);
- QList<EnvironmentItem> userChanges() const;
- void setUserChanges(const QList<EnvironmentItem> &list);
-
-signals:
- void userChangesChanged();
- /// Hint to the view where it should make sense to focus on next
- // This is a hack since there is no way for a model to suggest
- // the next interesting place to focus on to the view.
- void focusIndex(const QModelIndex &index);
-
-private:
- Internal::EnvironmentModelPrivate *d;
};
} // namespace Utils
diff --git a/src/libs/utils/fadingindicator.cpp b/src/libs/utils/fadingindicator.cpp
index 4e9b5067be..31ebbb7916 100644
--- a/src/libs/utils/fadingindicator.cpp
+++ b/src/libs/utils/fadingindicator.cpp
@@ -56,7 +56,7 @@ public:
font.setPixelSize(size == FadingIndicator::LargeText ? 45 : 22);
m_label->setFont(font);
QPalette pal = palette();
- pal.setColor(QPalette::Foreground, pal.color(QPalette::Background));
+ pal.setColor(QPalette::WindowText, pal.color(QPalette::Window));
m_label->setPalette(pal);
auto layout = new QHBoxLayout;
setLayout(layout);
@@ -107,7 +107,7 @@ protected:
if (!m_pixmap.isNull()) {
p.drawPixmap(rect(), m_pixmap);
} else {
- p.setBrush(palette().color(QPalette::Foreground));
+ p.setBrush(palette().color(QPalette::WindowText));
p.setPen(Qt::NoPen);
p.drawRoundedRect(rect(), 15, 15);
}
diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp
index 6b5b11995c..d67c336544 100644
--- a/src/libs/utils/fancylineedit.cpp
+++ b/src/libs/utils/fancylineedit.cpp
@@ -23,6 +23,7 @@
**
****************************************************************************/
+#include "camelcasecursor.h"
#include "execmenu.h"
#include "fancylineedit.h"
#include "historycompleter.h"
@@ -35,7 +36,9 @@
#include <QAbstractItemView>
#include <QDebug>
#include <QKeyEvent>
+#include <QKeySequence>
#include <QMenu>
+#include <QShortcut>
#include <QStylePainter>
#include <QPropertyAnimation>
#include <QStyle>
@@ -80,6 +83,31 @@ enum { margin = 6 };
namespace Utils {
+static bool camelCaseNavigation = false;
+
+class CompletionShortcut : public QObject
+{
+ Q_OBJECT
+
+public:
+ void setKeySequence(const QKeySequence &key)
+ {
+ if (m_key != key) {
+ m_key = key;
+ emit keyChanged(key);
+ }
+ }
+ QKeySequence key() const { return m_key; }
+
+signals:
+ void keyChanged(const QKeySequence &key);
+
+private:
+ QKeySequence m_key = Qt::Key_Space + HostOsInfo::controlModifier();
+};
+Q_GLOBAL_STATIC(CompletionShortcut, completionShortcut)
+
+
// --------- FancyLineEditPrivate
class FancyLineEditPrivate : public QObject
{
@@ -91,6 +119,7 @@ public:
FancyLineEdit *m_lineEdit;
IconButton *m_iconbutton[2];
HistoryCompleter *m_historyCompleter = nullptr;
+ QShortcut m_completionShortcut;
FancyLineEdit::ValidationFunction m_validationFunction = &FancyLineEdit::validateWithValidator;
QString m_oldText;
QMenu *m_menu[2];
@@ -110,10 +139,15 @@ public:
FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
QObject(parent),
- m_lineEdit(parent)
+ m_lineEdit(parent),
+ m_completionShortcut(completionShortcut()->key(), parent)
{
m_okTextColor = parent->palette().color(QPalette::Active, QPalette::Text);
+ m_completionShortcut.setContext(Qt::WidgetShortcut);
+ connect(completionShortcut(), &CompletionShortcut::keyChanged,
+ &m_completionShortcut, &QShortcut::setKey);
+
for (int i = 0; i < 2; ++i) {
m_iconbutton[i] = new IconButton(parent);
m_iconbutton[i]->installEventFilter(this);
@@ -163,6 +197,12 @@ FancyLineEdit::FancyLineEdit(QWidget *parent) :
connect(d->m_iconbutton[Left], &QAbstractButton::clicked, this, &FancyLineEdit::iconClicked);
connect(d->m_iconbutton[Right], &QAbstractButton::clicked, this, &FancyLineEdit::iconClicked);
connect(this, &QLineEdit::textChanged, this, &FancyLineEdit::validate);
+ connect(&d->m_completionShortcut, &QShortcut::activated, this, [this] {
+ if (!completer())
+ return;
+ completer()->setCompletionPrefix(text().left(cursorPosition()));
+ completer()->complete();
+ });
}
FancyLineEdit::~FancyLineEdit()
@@ -328,6 +368,29 @@ void FancyLineEdit::onEditingFinished()
d->m_historyCompleter->addEntry(text());
}
+void FancyLineEdit::keyPressEvent(QKeyEvent *event)
+{
+ const QTextCursor::MoveMode mode = (event->modifiers() & Qt::ShiftModifier)
+ ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;
+
+ if (camelCaseNavigation && event == QKeySequence::MoveToPreviousWord)
+ CamelCaseCursor::left(this, mode);
+ else if (camelCaseNavigation && event == QKeySequence::MoveToNextWord)
+ CamelCaseCursor::right(this, mode);
+ else
+ QLineEdit::keyPressEvent(event);
+}
+
+void FancyLineEdit::setCamelCaseNavigationEnabled(bool enabled)
+{
+ camelCaseNavigation = enabled;
+}
+
+void FancyLineEdit::setCompletionShortcut(const QKeySequence &shortcut)
+{
+ completionShortcut()->setKeySequence(shortcut);
+}
+
void FancyLineEdit::setSpecialCompleter(QCompleter *completer)
{
QTC_ASSERT(!d->m_historyCompleter, return);
@@ -416,7 +479,7 @@ FancyLineEdit::ValidationFunction FancyLineEdit::defaultValidationFunction()
bool FancyLineEdit::validateWithValidator(FancyLineEdit *edit, QString *errorMessage)
{
- Q_UNUSED(errorMessage);
+ Q_UNUSED(errorMessage)
if (const QValidator *v = edit->validator()) {
QString tmp = edit->text();
int pos = edit->cursorPosition();
@@ -565,3 +628,5 @@ void IconButton::keyReleaseEvent(QKeyEvent *ke)
}
} // namespace Utils
+
+#include <fancylineedit.moc>
diff --git a/src/libs/utils/fancylineedit.h b/src/libs/utils/fancylineedit.h
index fd0b121d88..9f738fb618 100644
--- a/src/libs/utils/fancylineedit.h
+++ b/src/libs/utils/fancylineedit.h
@@ -34,6 +34,7 @@
QT_BEGIN_NAMESPACE
class QEvent;
+class QKeySequence;
QT_END_NAMESPACE
namespace Utils {
@@ -141,9 +142,13 @@ public:
void validate();
void onEditingFinished();
+ static void setCamelCaseNavigationEnabled(bool enabled);
+ static void setCompletionShortcut(const QKeySequence &shortcut);
+
protected:
// Custom behaviour can be added here.
virtual void handleChanged(const QString &) {}
+ void keyPressEvent(QKeyEvent *event) override;
signals:
void buttonClicked(Utils::FancyLineEdit::Side side);
@@ -170,6 +175,8 @@ private:
void updateMargins();
void updateButtonPositions();
+ bool camelCaseBackward(bool mark);
+ bool camelCaseForward(bool mark);
friend class FancyLineEditPrivate;
FancyLineEditPrivate *d;
diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp
index 9a5c84894c..d49473beb7 100644
--- a/src/libs/utils/fancymainwindow.cpp
+++ b/src/libs/utils/fancymainwindow.cpp
@@ -182,7 +182,7 @@ public:
m_maximumActiveSize = QSize(maxWidth, activeHeight);
auto layout = new QHBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->setContentsMargins(4, 0, 0, 0);
layout->addWidget(m_titleLabel);
@@ -468,12 +468,9 @@ void FancyMainWindow::handleVisibilityChanged(bool visible)
void FancyMainWindow::saveSettings(QSettings *settings) const
{
- QHash<QString, QVariant> hash = saveSettings();
- QHashIterator<QString, QVariant> it(hash);
- while (it.hasNext()) {
- it.next();
+ const QHash<QString, QVariant> hash = saveSettings();
+ for (auto it = hash.cbegin(), end = hash.cend(); it != end; ++it)
settings->setValue(it.key(), it.value());
- }
}
void FancyMainWindow::restoreSettings(const QSettings *settings)
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index acf9c6190d..8608756627 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -74,6 +74,32 @@ namespace Utils {
*/
+CommandLine::CommandLine() = default;
+
+CommandLine::CommandLine(const QString &executable)
+ : m_executable(FilePath::fromString(executable))
+{}
+
+CommandLine::CommandLine(const FilePath &executable)
+ : m_executable(executable)
+{}
+
+CommandLine::CommandLine(const QString &exe, const QStringList &args)
+ : CommandLine(FilePath::fromString(exe), args)
+{}
+
+CommandLine::CommandLine(const FilePath &exe, const QStringList &args)
+ : m_executable(exe)
+{
+ addArgs(args);
+}
+
+CommandLine::CommandLine(const FilePath &exe, const QString &args, RawType)
+ : m_executable(exe)
+{
+ addArgs(args, Raw);
+}
+
void CommandLine::addArg(const QString &arg, OsType osType)
{
QtcProcess::addArg(&m_arguments, arg, osType);
@@ -85,7 +111,7 @@ void CommandLine::addArgs(const QStringList &inArgs, OsType osType)
addArg(arg, osType);
}
-void CommandLine::addArgs(const QString &inArgs)
+void CommandLine::addArgs(const QString &inArgs, RawType)
{
QtcProcess::addArgs(&m_arguments, inArgs);
}
@@ -95,6 +121,11 @@ QString CommandLine::toUserOutput() const
return m_executable.toUserOutput() + ' ' + m_arguments;
}
+QStringList CommandLine::splitArguments(OsType osType) const
+{
+ return QtcProcess::splitArgs(m_arguments, osType);
+}
+
/*! \class Utils::FileUtils
\brief The FileUtils class contains file and directory related convenience
@@ -705,7 +736,13 @@ QString FilePath::toUserOutput() const
return m_url.toString();
}
-QString FilePath::fileName(int pathComponents) const
+QString FilePath::fileName() const
+{
+ const QChar slash = QLatin1Char('/');
+ return m_data.mid(m_data.lastIndexOf(slash) + 1);
+}
+
+QString FilePath::fileNameWithPathComponents(int pathComponents) const
{
if (pathComponents < 0)
return m_data;
@@ -737,6 +774,13 @@ bool FilePath::exists() const
return !isEmpty() && QFileInfo::exists(m_data);
}
+/// \returns a bool indicating whether a path is writable.
+bool FilePath::isWritablePath() const
+{
+ const QFileInfo fi{m_data};
+ return exists() && fi.isDir() && fi.isWritable();
+}
+
/// Find the parent directory of a given directory.
/// Returns an empty FilePath if the current directory is already
@@ -892,6 +936,12 @@ bool FilePath::isLocal() const
return m_url.isEmpty() || m_url.isLocalFile();
}
+bool FilePath::isDir() const
+{
+ QTC_CHECK(m_url.isEmpty()); // FIXME: Not implemented yet.
+ return QFileInfo(m_data).isDir();
+}
+
/// \returns the relativeChildPath of FilePath to parent if FilePath is a child of parent
/// \note returns a empty FilePath if FilePath is not a child of parent
/// That is, this never returns a path starting with "../"
diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h
index ec018b9c3b..2026ad1068 100644
--- a/src/libs/utils/fileutils.h
+++ b/src/libs/utils/fileutils.h
@@ -80,8 +80,10 @@ public:
QString toUserOutput() const;
QString shortNativePath() const;
- QString fileName(int pathComponents = 0) const;
+ QString fileName() const;
+ QString fileNameWithPathComponents(int pathComponents) const;
bool exists() const;
+ bool isWritablePath() const;
FilePath parentDir() const;
@@ -96,8 +98,9 @@ public:
bool isChildOf(const FilePath &s) const;
bool isChildOf(const QDir &dir) const;
bool endsWith(const QString &s) const;
- bool isLocal() const;
+ bool isLocal() const;
+ bool isDir() const;
bool isNewerThan(const QDateTime &timeStamp) const;
FilePath relativeChildPath(const FilePath &parent) const;
@@ -111,7 +114,7 @@ public:
uint hash(uint seed) const;
- // NOTE: FileName operations on FilePath created from URL currenly
+ // NOTE: FilePath operations on FilePath created from URL currenly
// do not work except for .toVariant() and .toUrl().
static FilePath fromUrl(const QUrl &url);
QUrl toUrl() const;
@@ -125,26 +128,28 @@ QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FilePath &f
using FilePathList = QList<FilePath>;
-using FileName = FilePath;
-using FileNameList = FilePathList;
-
class QTCREATOR_UTILS_EXPORT CommandLine
{
public:
- CommandLine() {}
+ enum RawType { Raw };
- CommandLine(const FilePath &executable, const QString &arguments)
- : m_executable(executable), m_arguments(arguments)
- {}
+ CommandLine();
+ explicit CommandLine(const QString &executable);
+ explicit CommandLine(const FilePath &executable);
+ CommandLine(const QString &exe, const QStringList &args);
+ CommandLine(const FilePath &exe, const QStringList &args);
+ CommandLine(const FilePath &exe, const QString &unparsedArgs, RawType);
void addArg(const QString &arg, OsType osType = HostOsInfo::hostOs());
void addArgs(const QStringList &inArgs, OsType osType = HostOsInfo::hostOs());
- void addArgs(const QString &inArgs);
+
+ void addArgs(const QString &inArgs, RawType);
QString toUserOutput() const;
FilePath executable() const { return m_executable; }
QString arguments() const { return m_arguments; }
+ QStringList splitArguments(OsType osType = HostOsInfo::hostOs()) const;
private:
FilePath m_executable;
@@ -298,3 +303,4 @@ template<> struct hash<Utils::FilePath>
} // namespace std
Q_DECLARE_METATYPE(Utils::FilePath)
+Q_DECLARE_METATYPE(Utils::CommandLine)
diff --git a/src/libs/utils/flowlayout.cpp b/src/libs/utils/flowlayout.cpp
index d138a15149..fe8c7900cd 100644
--- a/src/libs/utils/flowlayout.cpp
+++ b/src/libs/utils/flowlayout.cpp
@@ -121,7 +121,9 @@ QSize FlowLayout::minimumSize() const
foreach (item, itemList)
size = size.expandedTo(item->minimumSize());
- size += QSize(2*margin(), 2*margin());
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ size += QSize(left + right, top + bottom);
return size;
}
diff --git a/src/libs/utils/fuzzymatcher.cpp b/src/libs/utils/fuzzymatcher.cpp
index 60b5d3aaa2..6a3e0e5015 100644
--- a/src/libs/utils/fuzzymatcher.cpp
+++ b/src/libs/utils/fuzzymatcher.cpp
@@ -72,10 +72,10 @@ QRegularExpression FuzzyMatcher::createRegExp(
const QLatin1String lowercaseWordFirst("(?<=\\b|[A-Z0-9_])");
const QLatin1String uppercaseWordContinuation("[a-z0-9_]*");
const QLatin1String lowercaseWordContinuation("(?:[a-zA-Z0-9]*_)?");
- const QLatin1String upperSnakeWordContinuation("[A-Z0-9]*_");
+ const QLatin1String upperSnakeWordContinuation("[A-Z0-9]*_?");
keyRegExp += "(?:";
for (const QChar &c : pattern) {
- if (!c.isLetter()) {
+ if (!c.isLetterOrNumber()) {
if (c == question) {
keyRegExp += '.';
plainRegExp += ").(";
@@ -122,6 +122,21 @@ QRegularExpression FuzzyMatcher::createRegExp(
return QRegularExpression('(' + plainRegExp + ")|" + keyRegExp);
}
+/**
+ \overload
+ This overload eases the construction of a fuzzy regexp from a given
+ Qt::CaseSensitivity.
+ */
+QRegularExpression FuzzyMatcher::createRegExp(const QString &pattern,
+ Qt::CaseSensitivity caseSensitivity)
+{
+ const CaseSensitivity sensitivity = (caseSensitivity == Qt::CaseSensitive)
+ ? CaseSensitivity::CaseSensitive
+ : CaseSensitivity::CaseInsensitive;
+
+ return createRegExp(pattern, sensitivity);
+}
+
/*!
* \brief Returns a list of matched character positions and their matched lengths for the
* given regular expression \a match.
diff --git a/src/libs/utils/fuzzymatcher.h b/src/libs/utils/fuzzymatcher.h
index 753742ac22..8e90ebe796 100644
--- a/src/libs/utils/fuzzymatcher.h
+++ b/src/libs/utils/fuzzymatcher.h
@@ -54,5 +54,7 @@ public:
static QRegularExpression createRegExp(const QString &pattern,
CaseSensitivity caseSensitivity = CaseSensitivity::CaseInsensitive);
+ static QRegularExpression createRegExp(const QString &pattern,
+ Qt::CaseSensitivity caseSensitivity);
static HighlightingPositions highlightingPositions(const QRegularExpressionMatch &match);
};
diff --git a/src/libs/utils/images/download_arrow.png b/src/libs/utils/images/download_arrow.png
new file mode 100644
index 0000000000..c73bf628f4
--- /dev/null
+++ b/src/libs/utils/images/download_arrow.png
Binary files differ
diff --git a/src/libs/utils/images/download_arrow@2x.png b/src/libs/utils/images/download_arrow@2x.png
new file mode 100644
index 0000000000..aabf6fce78
--- /dev/null
+++ b/src/libs/utils/images/download_arrow@2x.png
Binary files differ
diff --git a/src/libs/utils/images/download_base.png b/src/libs/utils/images/download_base.png
new file mode 100644
index 0000000000..25163bef64
--- /dev/null
+++ b/src/libs/utils/images/download_base.png
Binary files differ
diff --git a/src/libs/utils/images/download_base@2x.png b/src/libs/utils/images/download_base@2x.png
new file mode 100644
index 0000000000..a5e7405ac3
--- /dev/null
+++ b/src/libs/utils/images/download_base@2x.png
Binary files differ
diff --git a/src/libs/utils/images/online.png b/src/libs/utils/images/online.png
new file mode 100644
index 0000000000..2e053b8792
--- /dev/null
+++ b/src/libs/utils/images/online.png
Binary files differ
diff --git a/src/libs/utils/images/online@2x.png b/src/libs/utils/images/online@2x.png
new file mode 100644
index 0000000000..149a4a0dd6
--- /dev/null
+++ b/src/libs/utils/images/online@2x.png
Binary files differ
diff --git a/src/plugins/autotest/images/run_file.png b/src/libs/utils/images/run_file.png
index 6a3bfc766f..6a3bfc766f 100644
--- a/src/plugins/autotest/images/run_file.png
+++ b/src/libs/utils/images/run_file.png
Binary files differ
diff --git a/src/plugins/autotest/images/run_file@2x.png b/src/libs/utils/images/run_file@2x.png
index 4b386818c9..4b386818c9 100644
--- a/src/plugins/autotest/images/run_file@2x.png
+++ b/src/libs/utils/images/run_file@2x.png
Binary files differ
diff --git a/src/plugins/autotest/images/runselected_boxes.png b/src/libs/utils/images/runselected_boxes.png
index 6e39f2ee0b..6e39f2ee0b 100644
--- a/src/plugins/autotest/images/runselected_boxes.png
+++ b/src/libs/utils/images/runselected_boxes.png
Binary files differ
diff --git a/src/plugins/autotest/images/runselected_boxes@2x.png b/src/libs/utils/images/runselected_boxes@2x.png
index 55e5863a52..55e5863a52 100644
--- a/src/plugins/autotest/images/runselected_boxes@2x.png
+++ b/src/libs/utils/images/runselected_boxes@2x.png
Binary files differ
diff --git a/src/plugins/autotest/images/runselected_tickmarks.png b/src/libs/utils/images/runselected_tickmarks.png
index 6296f8748d..6296f8748d 100644
--- a/src/plugins/autotest/images/runselected_tickmarks.png
+++ b/src/libs/utils/images/runselected_tickmarks.png
Binary files differ
diff --git a/src/plugins/autotest/images/runselected_tickmarks@2x.png b/src/libs/utils/images/runselected_tickmarks@2x.png
index 75252f173c..75252f173c 100644
--- a/src/plugins/autotest/images/runselected_tickmarks@2x.png
+++ b/src/libs/utils/images/runselected_tickmarks@2x.png
Binary files differ
diff --git a/src/libs/utils/listmodel.h b/src/libs/utils/listmodel.h
index 5f4de811e6..4a28041b66 100644
--- a/src/libs/utils/listmodel.h
+++ b/src/libs/utils/listmodel.h
@@ -67,9 +67,9 @@ public:
void clear() { rootItem()->removeChildren(); }
- using const_iterator = typename QVector<TreeItem *>::const_iterator;
- const_iterator begin() const { return rootItem()->begin(); }
- const_iterator end() const { return rootItem()->end(); }
+ using const_iterator = typename QVector<ChildType *>::const_iterator;
+ const_iterator begin() const { return const_iterator(rootItem()->begin()); }
+ const_iterator end() const { return const_iterator(rootItem()->end()); }
};
diff --git a/src/libs/utils/macroexpander.cpp b/src/libs/utils/macroexpander.cpp
index a41fbde31d..6a64398e5b 100644
--- a/src/libs/utils/macroexpander.cpp
+++ b/src/libs/utils/macroexpander.cpp
@@ -313,11 +313,8 @@ QVariant MacroExpander::expandVariant(const QVariant &v) const
} else if (type == QMetaType::QVariantMap) {
const auto map = v.toMap();
QVariantMap result;
- QMapIterator<QString, QVariant> it(map);
- while (it.hasNext()) {
- it.next();
+ for (auto it = map.cbegin(), end = map.cend(); it != end; ++it)
result.insert(it.key(), expandVariant(it.value()));
- }
return result;
}
return v;
diff --git a/src/libs/utils/mimetypes/mimeglobpattern.cpp b/src/libs/utils/mimetypes/mimeglobpattern.cpp
index cdcd77c6b1..097fca365b 100644
--- a/src/libs/utils/mimetypes/mimeglobpattern.cpp
+++ b/src/libs/utils/mimetypes/mimeglobpattern.cpp
@@ -181,10 +181,9 @@ void MimeAllGlobPatterns::addGlob(const MimeGlobPattern &glob)
void MimeAllGlobPatterns::removeMimeType(const QString &mimeType)
{
- QMutableHashIterator<QString, QStringList> it(m_fastPatterns);
- while (it.hasNext()) {
- it.next().value().removeAll(mimeType);
- }
+ for (QStringList &x : m_fastPatterns)
+ x.removeAll(mimeType);
+
m_highWeightGlobs.removeMimeType(mimeType);
m_lowWeightGlobs.removeMimeType(mimeType);
}
diff --git a/src/libs/utils/mimetypes/mimeglobpattern_p.h b/src/libs/utils/mimetypes/mimeglobpattern_p.h
index accbab0646..ecbfb02ce9 100644
--- a/src/libs/utils/mimetypes/mimeglobpattern_p.h
+++ b/src/libs/utils/mimetypes/mimeglobpattern_p.h
@@ -114,11 +114,10 @@ public:
*/
void removeMimeType(const QString &mimeType)
{
- QMutableListIterator<MimeGlobPattern> it(*this);
- while (it.hasNext()) {
- if (it.next().mimeType() == mimeType)
- it.remove();
- }
+ auto isMimeTypeEqual = [&mimeType](const MimeGlobPattern &pattern) {
+ return pattern.mimeType() == mimeType;
+ };
+ erase(std::remove_if(begin(), end(), isMimeTypeEqual), end());
}
void match(MimeGlobMatchResult &result, const QString &fileName) const;
diff --git a/src/libs/utils/mimetypes/mimeprovider.cpp b/src/libs/utils/mimetypes/mimeprovider.cpp
index e9ed226063..11f5a17303 100644
--- a/src/libs/utils/mimetypes/mimeprovider.cpp
+++ b/src/libs/utils/mimetypes/mimeprovider.cpp
@@ -767,13 +767,12 @@ void MimeXMLProvider::setGlobPatternsForMimeType(const MimeType &mimeType, const
void MimeXMLProvider::setMagicRulesForMimeType(const MimeType &mimeType, const QMap<int, QList<MimeMagicRule> > &rules)
{
// remove all previous rules
- QMutableListIterator<MimeMagicRuleMatcher> matcherIt(m_magicMatchers);
- while (matcherIt.hasNext()) {
- if (matcherIt.next().mimetype() == mimeType.name())
- matcherIt.remove();
+ for (int i = 0; i < m_magicMatchers.size(); ++i) {
+ if (m_magicMatchers.at(i).mimetype() == mimeType.name())
+ m_magicMatchers.removeAt(i--);
}
// add new rules
- for (auto it = rules.constBegin(); it != rules.constEnd(); ++it) {
+ for (auto it = rules.cbegin(); it != rules.cend(); ++it) {
MimeMagicRuleMatcher matcher(mimeType.name(), it.key()/*priority*/);
matcher.addRules(it.value());
addMagicMatcher(matcher);
@@ -804,15 +803,14 @@ void MimeXMLProvider::ensureLoaded()
// add custom mime types first, which override any default from freedesktop.org.xml
MimeTypeParser parser(*this);
- QHashIterator<QString, QByteArray> it(m_additionalData);
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_additionalData.constBegin(), end = m_additionalData.constEnd(); it != end; ++it) {
QString errorMessage;
if (!parser.parse(it.value(), it.key(), &errorMessage)) {
qWarning("MimeDatabase: Error loading %s\n%s", qPrintable(it.key()),
qPrintable(errorMessage));
}
}
+
foreach (const QString &file, allFiles)
load(file);
}
diff --git a/src/libs/utils/namevaluedictionary.cpp b/src/libs/utils/namevaluedictionary.cpp
new file mode 100644
index 0000000000..b6218d9592
--- /dev/null
+++ b/src/libs/utils/namevaluedictionary.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "algorithm.h"
+#include "namevaluedictionary.h"
+#include "qtcassert.h"
+
+#include <QDir>
+
+namespace Utils {
+
+NameValueDictionary::NameValueDictionary(const QStringList &env, OsType osType)
+ : m_osType(osType)
+{
+ for (const QString &s : env) {
+ int i = s.indexOf('=', 1);
+ if (i >= 0) {
+ const QString key = s.left(i);
+ if (!key.contains('=')) {
+ const QString value = s.mid(i + 1);
+ set(key, value);
+ }
+ }
+ }
+}
+
+NameValueDictionary::NameValueDictionary(const NameValuePairs &nameValues)
+{
+ for (const auto &nameValue : nameValues)
+ set(nameValue.first, nameValue.second);
+}
+
+NameValueMap::iterator NameValueDictionary::findKey(const QString &key)
+{
+ for (auto it = m_values.begin(); it != m_values.end(); ++it) {
+ if (key.compare(it.key().name, nameCaseSensitivity()) == 0)
+ return it;
+ }
+ return m_values.end();
+}
+
+NameValueMap::const_iterator NameValueDictionary::findKey(const QString &key) const
+{
+ for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
+ if (key.compare(it.key().name, nameCaseSensitivity()) == 0)
+ return it;
+ }
+ return m_values.constEnd();
+}
+
+QStringList NameValueDictionary::toStringList() const
+{
+ QStringList result;
+ for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
+ if (it.value().second)
+ result.append(it.key().name + '=' + it.value().first);
+ }
+ return result;
+}
+
+void NameValueDictionary::set(const QString &key, const QString &value, bool enabled)
+{
+ QTC_ASSERT(!key.contains('='), return );
+ const auto it = findKey(key);
+ const auto valuePair = qMakePair(value, enabled);
+ if (it == m_values.end())
+ m_values.insert(DictKey(key, nameCaseSensitivity()), valuePair);
+ else
+ it.value() = valuePair;
+}
+
+void NameValueDictionary::unset(const QString &key)
+{
+ QTC_ASSERT(!key.contains('='), return );
+ const auto it = findKey(key);
+ if (it != m_values.end())
+ m_values.erase(it);
+}
+
+void NameValueDictionary::clear()
+{
+ m_values.clear();
+}
+
+QString NameValueDictionary::value(const QString &key) const
+{
+ const auto it = findKey(key);
+ return it != m_values.end() && it.value().second ? it.value().first : QString();
+}
+
+NameValueDictionary::const_iterator NameValueDictionary::constFind(const QString &name) const
+{
+ return findKey(name);
+}
+
+int NameValueDictionary::size() const
+{
+ return m_values.size();
+}
+
+void NameValueDictionary::modify(const NameValueItems &items)
+{
+ NameValueDictionary resultKeyValueDictionary = *this;
+ for (const NameValueItem &item : items)
+ item.apply(&resultKeyValueDictionary);
+ *this = resultKeyValueDictionary;
+}
+
+NameValueItems NameValueDictionary::diff(const NameValueDictionary &other, bool checkAppendPrepend) const
+{
+ NameValueMap::const_iterator thisIt = constBegin();
+ NameValueMap::const_iterator otherIt = other.constBegin();
+
+ NameValueItems result;
+ while (thisIt != constEnd() || otherIt != other.constEnd()) {
+ if (thisIt == constEnd()) {
+ result.append({other.key(otherIt), other.value(otherIt),
+ otherIt.value().second ? NameValueItem::SetEnabled : NameValueItem::SetDisabled});
+ ++otherIt;
+ } else if (otherIt == other.constEnd()) {
+ result.append(NameValueItem(key(thisIt), QString(), NameValueItem::Unset));
+ ++thisIt;
+ } else if (thisIt.key() < otherIt.key()) {
+ result.append(NameValueItem(key(thisIt), QString(), NameValueItem::Unset));
+ ++thisIt;
+ } else if (thisIt.key() > otherIt.key()) {
+ result.append({other.key(otherIt), otherIt.value().first,
+ otherIt.value().second ? NameValueItem::SetEnabled : NameValueItem::SetDisabled});
+ ++otherIt;
+ } else {
+ const QString &oldValue = thisIt.value().first;
+ const QString &newValue = otherIt.value().first;
+ const bool oldEnabled = thisIt.value().second;
+ const bool newEnabled = otherIt.value().second;
+ if (oldValue != newValue) {
+ if (checkAppendPrepend && newValue.startsWith(oldValue)
+ && oldEnabled == newEnabled) {
+ QString appended = newValue.right(newValue.size() - oldValue.size());
+ if (appended.startsWith(OsSpecificAspects::pathListSeparator(osType())))
+ appended.remove(0, 1);
+ result.append(NameValueItem(other.key(otherIt), appended, NameValueItem::Append));
+ } else if (checkAppendPrepend && newValue.endsWith(oldValue)
+ && oldEnabled == newEnabled) {
+ QString prepended = newValue.left(newValue.size() - oldValue.size());
+ if (prepended.endsWith(OsSpecificAspects::pathListSeparator(osType())))
+ prepended.chop(1);
+ result.append(NameValueItem(other.key(otherIt), prepended, NameValueItem::Prepend));
+ } else {
+ result.append({other.key(otherIt), newValue, newEnabled
+ ? NameValueItem::SetEnabled : NameValueItem::SetDisabled});
+ }
+ }
+ ++otherIt;
+ ++thisIt;
+ }
+ }
+ return result;
+}
+
+bool NameValueDictionary::hasKey(const QString &key) const
+{
+ return findKey(key) != constEnd();
+}
+
+OsType NameValueDictionary::osType() const
+{
+ return m_osType;
+}
+
+Qt::CaseSensitivity NameValueDictionary::nameCaseSensitivity() const
+{
+ return OsSpecificAspects::envVarCaseSensitivity(osType());
+}
+
+QString NameValueDictionary::userName() const
+{
+ return value(QString::fromLatin1(m_osType == OsTypeWindows ? "USERNAME" : "USER"));
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluedictionary.h b/src/libs/utils/namevaluedictionary.h
new file mode 100644
index 0000000000..bbd80b1f99
--- /dev/null
+++ b/src/libs/utils/namevaluedictionary.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "fileutils.h"
+#include "hostosinfo.h"
+#include "namevalueitem.h"
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT DictKey
+{
+public:
+ DictKey(const QString &name, Qt::CaseSensitivity cs) : name(name), caseSensitivity(cs) {}
+
+ QString name;
+ Qt::CaseSensitivity caseSensitivity;
+};
+inline bool operator<(const DictKey &k1, const DictKey &k2)
+{
+ return k1.name.compare(k2.name, k1.caseSensitivity) < 0;
+}
+inline bool operator>(const DictKey &k1, const DictKey &k2) { return k2 < k1; }
+
+using NameValuePair = std::pair<QString, QString>;
+using NameValuePairs = QVector<NameValuePair>;
+using NameValueMap = QMap<DictKey, QPair<QString, bool>>;
+
+class QTCREATOR_UTILS_EXPORT NameValueDictionary
+{
+public:
+ using const_iterator = NameValueMap::const_iterator;
+
+ explicit NameValueDictionary(OsType osType = HostOsInfo::hostOs())
+ : m_osType(osType)
+ {}
+ explicit NameValueDictionary(const QStringList &env, OsType osType = HostOsInfo::hostOs());
+ explicit NameValueDictionary(const NameValuePairs &nameValues);
+
+ QStringList toStringList() const;
+ QString value(const QString &key) const;
+ void set(const QString &key, const QString &value, bool enabled = true);
+ void unset(const QString &key);
+ void modify(const NameValueItems &items);
+ /// Return the KeyValueDictionary changes necessary to modify this into the other environment.
+ NameValueItems diff(const NameValueDictionary &other, bool checkAppendPrepend = false) const;
+ bool hasKey(const QString &key) const;
+ OsType osType() const;
+ Qt::CaseSensitivity nameCaseSensitivity() const;
+
+ QString userName() const;
+
+ void clear();
+ int size() const;
+
+ QString key(const_iterator it) const { return it.key().name; }
+ QString value(const_iterator it) const { return it.value().first; }
+ bool isEnabled(const_iterator it) const { return it.value().second; }
+
+ const_iterator constBegin() const { return m_values.constBegin(); }
+ const_iterator constEnd() const { return m_values.constEnd(); }
+ const_iterator constFind(const QString &name) const;
+
+ friend bool operator!=(const NameValueDictionary &first, const NameValueDictionary &second)
+ {
+ return !(first == second);
+ }
+
+ friend bool operator==(const NameValueDictionary &first, const NameValueDictionary &second)
+ {
+ return first.m_osType == second.m_osType && first.m_values == second.m_values;
+ }
+
+protected:
+ NameValueMap::iterator findKey(const QString &key);
+ const_iterator findKey(const QString &key) const;
+
+ NameValueMap m_values;
+ OsType m_osType;
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/namevalueitem.cpp b/src/libs/utils/namevalueitem.cpp
new file mode 100644
index 0000000000..0ca80f8083
--- /dev/null
+++ b/src/libs/utils/namevalueitem.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "namevalueitem.h"
+#include "algorithm.h"
+#include "namevaluedictionary.h"
+#include "qtcassert.h"
+
+#include <QDebug>
+
+namespace Utils {
+
+void NameValueItem::sort(NameValueItems *list)
+{
+ Utils::sort(*list, &NameValueItem::name);
+}
+
+NameValueItems NameValueItem::fromStringList(const QStringList &list)
+{
+ NameValueItems result;
+ for (const QString &string : list) {
+ int pos = string.indexOf('=', 1);
+ if (pos == -1) {
+ result.append(NameValueItem(string, QString(), NameValueItem::Unset));
+ continue;
+ }
+ const int hashPos = string.indexOf('#');
+ if (hashPos != -1 && hashPos < pos) {
+ result.append({string.mid(hashPos + 1, pos - hashPos - 1), string.mid(pos + 1),
+ NameValueItem::SetDisabled});
+ } else {
+ result.append({string.left(pos), string.mid(pos + 1)});
+ }
+ }
+ return result;
+}
+
+QStringList NameValueItem::toStringList(const NameValueItems &list)
+{
+ return Utils::transform<QStringList>(list, [](const NameValueItem &item) {
+ if (item.operation == NameValueItem::Unset)
+ return QString(item.name);
+ return QString((item.operation == NameValueItem::SetDisabled ? "#" : "")
+ + item.name + '=' + item.value);
+ });
+}
+
+NameValueItems NameValueItem::itemsFromVariantList(const QVariantList &list)
+{
+ return Utils::transform<NameValueItems>(list, [](const QVariant &item) {
+ return itemFromVariantList(item.toList());
+ });
+}
+
+QVariantList NameValueItem::toVariantList(const NameValueItems &list)
+{
+ return Utils::transform<QVariantList>(list, [](const NameValueItem &item) {
+ return QVariant(toVariantList(item));
+ });
+}
+
+NameValueItem NameValueItem::itemFromVariantList(const QVariantList &list)
+{
+ QTC_ASSERT(list.size() == 3, return NameValueItem("", ""));
+ QString key = list.value(0).toString();
+ Operation operation = Operation(list.value(1).toInt());
+ QString value = list.value(2).toString();
+ return NameValueItem(key, value, operation);
+}
+
+QVariantList NameValueItem::toVariantList(const NameValueItem &item)
+{
+ return QVariantList() << item.name << item.operation << item.value;
+}
+
+static QString expand(const NameValueDictionary *dictionary, QString value)
+{
+ int replaceCount = 0;
+ for (int i = 0; i < value.size(); ++i) {
+ if (value.at(i) == '$') {
+ if ((i + 1) < value.size()) {
+ const QChar &c = value.at(i + 1);
+ int end = -1;
+ if (c == '(')
+ end = value.indexOf(')', i);
+ else if (c == '{')
+ end = value.indexOf('}', i);
+ if (end != -1) {
+ const QString &key = value.mid(i + 2, end - i - 2);
+ NameValueDictionary::const_iterator it = dictionary->constFind(key);
+ if (it != dictionary->constEnd())
+ value.replace(i, end - i + 1, it.value().first);
+ ++replaceCount;
+ QTC_ASSERT(replaceCount < 100, break);
+ }
+ }
+ }
+ }
+ return value;
+}
+
+enum : char {
+#ifdef Q_OS_WIN
+ pathSepC = ';'
+#else
+ pathSepC = ':'
+#endif
+};
+
+void NameValueItem::apply(NameValueDictionary *dictionary, Operation op) const
+{
+ switch (op) {
+ case SetEnabled:
+ dictionary->set(name, expand(dictionary, value));
+ break;
+ case SetDisabled:
+ dictionary->set(name, expand(dictionary, value), false);
+ break;
+ case Unset:
+ dictionary->unset(name);
+ break;
+ case Prepend: {
+ const NameValueDictionary::const_iterator it = dictionary->constFind(name);
+ if (it != dictionary->constEnd()) {
+ QString v = dictionary->value(it);
+ const QChar pathSep{QLatin1Char(pathSepC)};
+ int sepCount = 0;
+ if (v.startsWith(pathSep))
+ ++sepCount;
+ if (value.endsWith(pathSep))
+ ++sepCount;
+ if (sepCount == 2)
+ v.remove(0, 1);
+ else if (sepCount == 0)
+ v.prepend(pathSep);
+ v.prepend(expand(dictionary, value));
+ dictionary->set(name, v);
+ } else {
+ apply(dictionary, SetEnabled);
+ }
+ } break;
+ case Append: {
+ const NameValueDictionary::const_iterator it = dictionary->constFind(name);
+ if (it != dictionary->constEnd()) {
+ QString v = dictionary->value(it);
+ const QChar pathSep{QLatin1Char(pathSepC)};
+ int sepCount = 0;
+ if (v.endsWith(pathSep))
+ ++sepCount;
+ if (value.startsWith(pathSep))
+ ++sepCount;
+ if (sepCount == 2)
+ v.chop(1);
+ else if (sepCount == 0)
+ v.append(pathSep);
+ v.append(expand(dictionary, value));
+ dictionary->set(name, v);
+ } else {
+ apply(dictionary, SetEnabled);
+ }
+ } break;
+ }
+}
+
+QDebug operator<<(QDebug debug, const NameValueItem &i)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "KeyValueItem(";
+ switch (i.operation) {
+ case NameValueItem::SetEnabled:
+ debug << "set \"" << i.name << "\" to \"" << i.value << '"';
+ break;
+ case NameValueItem::SetDisabled:
+ debug << "set \"" << i.name << "\" to \"" << i.value << '"' << "[disabled]";
+ break;
+ case NameValueItem::Unset:
+ debug << "unset \"" << i.name << '"';
+ break;
+ case NameValueItem::Prepend:
+ debug << "prepend to \"" << i.name << "\":\"" << i.value << '"';
+ break;
+ case NameValueItem::Append:
+ debug << "append to \"" << i.name << "\":\"" << i.value << '"';
+ break;
+ }
+ debug << ')';
+ return debug;
+}
+} // namespace Utils
diff --git a/src/libs/utils/namevalueitem.h b/src/libs/utils/namevalueitem.h
new file mode 100644
index 0000000000..1ec203115a
--- /dev/null
+++ b/src/libs/utils/namevalueitem.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "environmentfwd.h"
+#include "utils_global.h"
+
+#include <QStringList>
+#include <QVariantList>
+#include <QVector>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT NameValueItem
+{
+public:
+ enum Operation : char { SetEnabled, Unset, Prepend, Append, SetDisabled };
+ NameValueItem() = default;
+ NameValueItem(const QString &key, const QString &value, Operation operation = SetEnabled)
+ : name(key)
+ , value(value)
+ , operation(operation)
+ {}
+
+ void apply(NameValueDictionary *dictionary) const { apply(dictionary, operation); }
+
+ static void sort(NameValueItems *list);
+ static NameValueItems fromStringList(const QStringList &list);
+ static QStringList toStringList(const NameValueItems &list);
+ static NameValueItems itemsFromVariantList(const QVariantList &list);
+ static QVariantList toVariantList(const NameValueItems &list);
+ static NameValueItem itemFromVariantList(const QVariantList &list);
+ static QVariantList toVariantList(const NameValueItem &item);
+
+ friend bool operator==(const NameValueItem &first, const NameValueItem &second)
+ {
+ return first.operation == second.operation && first.name == second.name
+ && first.value == second.value;
+ }
+
+ friend bool operator!=(const NameValueItem &first, const NameValueItem &second)
+ {
+ return !(first == second);
+ }
+
+public:
+ QString name;
+ QString value;
+ Operation operation = Unset;
+
+private:
+ void apply(NameValueDictionary *dictionary, Operation op) const;
+};
+
+QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug debug, const NameValueItem &i);
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluemodel.cpp b/src/libs/utils/namevaluemodel.cpp
new file mode 100644
index 0000000000..0093df0190
--- /dev/null
+++ b/src/libs/utils/namevaluemodel.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "namevaluemodel.h"
+
+#include <utils/algorithm.h>
+#include <utils/hostosinfo.h>
+#include <utils/namevaluedictionary.h>
+#include <utils/qtcassert.h>
+
+#include <QBrush>
+#include <QColor>
+#include <QFont>
+#include <QString>
+
+namespace Utils {
+
+namespace Internal {
+
+class NameValueModelPrivate
+{
+public:
+ void updateResultNameValueDictionary()
+ {
+ m_resultNameValueDictionary = m_baseNameValueDictionary;
+ m_resultNameValueDictionary.modify(m_items);
+ // Add removed variables again and mark them as "<UNSET>" so
+ // that the user can actually see those removals:
+ foreach (const NameValueItem &item, m_items) {
+ if (item.operation == NameValueItem::Unset)
+ m_resultNameValueDictionary.set(item.name, NameValueModel::tr("<UNSET>"));
+ }
+ }
+
+ int findInChanges(const QString &name) const
+ {
+ for (int i = 0; i < m_items.size(); ++i)
+ if (m_items.at(i).name.compare(name,
+ m_baseNameValueDictionary.nameCaseSensitivity()) == 0) {
+ return i;
+ }
+ return -1;
+ }
+
+ int findInResultInsertPosition(const QString &name) const
+ {
+ NameValueDictionary::const_iterator it;
+ int i = 0;
+ for (it = m_resultNameValueDictionary.constBegin();
+ it != m_resultNameValueDictionary.constEnd();
+ ++it, ++i)
+ if (it.key() > DictKey(name, m_resultNameValueDictionary.nameCaseSensitivity()))
+ return i;
+ return m_resultNameValueDictionary.size();
+ }
+
+ int findInResult(const QString &name) const
+ {
+ NameValueDictionary::const_iterator it;
+ int i = 0;
+ for (it = m_resultNameValueDictionary.constBegin();
+ it != m_resultNameValueDictionary.constEnd();
+ ++it, ++i)
+ if (m_resultNameValueDictionary.key(it)
+ .compare(name, m_resultNameValueDictionary.nameCaseSensitivity()) == 0) {
+ return i;
+ }
+ return -1;
+ }
+
+ NameValueDictionary m_baseNameValueDictionary;
+ NameValueDictionary m_resultNameValueDictionary;
+ NameValueItems m_items;
+};
+
+} // namespace Internal
+
+NameValueModel::NameValueModel(QObject *parent)
+ : QAbstractTableModel(parent)
+ , d(std::make_unique<Internal::NameValueModelPrivate>())
+{}
+
+NameValueModel::~NameValueModel() = default;
+
+QString NameValueModel::indexToVariable(const QModelIndex &index) const
+{
+ return d->m_resultNameValueDictionary.key(d->m_resultNameValueDictionary.constBegin()
+ + index.row());
+}
+
+void NameValueModel::setBaseNameValueDictionary(const NameValueDictionary &dictionary)
+{
+ if (d->m_baseNameValueDictionary == dictionary)
+ return;
+ beginResetModel();
+ d->m_baseNameValueDictionary = dictionary;
+ d->updateResultNameValueDictionary();
+ endResetModel();
+}
+
+int NameValueModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+
+ return d->m_resultNameValueDictionary.size();
+}
+int NameValueModel::columnCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+
+ return 2;
+}
+
+bool NameValueModel::changes(const QString &name) const
+{
+ return d->findInChanges(name) >= 0;
+}
+
+const NameValueDictionary &NameValueModel::baseNameValueDictionary() const
+{
+ return d->m_baseNameValueDictionary;
+}
+
+QVariant NameValueModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ const auto resultIterator = d->m_resultNameValueDictionary.constBegin() + index.row();
+ switch (role) {
+ case Qt::DisplayRole:
+ case Qt::EditRole:
+ case Qt::ToolTipRole:
+ if (index.column() == 0)
+ return d->m_resultNameValueDictionary.key(resultIterator);
+ if (index.column() == 1) {
+ // Do not return "<UNSET>" when editing a previously unset variable:
+ if (role == Qt::EditRole) {
+ int pos = d->findInChanges(indexToVariable(index));
+ if (pos != -1)
+ return d->m_items.at(pos).value;
+ }
+ QString value = d->m_resultNameValueDictionary.value(resultIterator);
+ if (role == Qt::ToolTipRole && value.length() > 80) {
+ // Use html to enable text wrapping
+ value = value.toHtmlEscaped();
+ value.prepend(QLatin1String("<html><body>"));
+ value.append(QLatin1String("</body></html>"));
+ }
+ return value;
+ }
+ break;
+ case Qt::FontRole: {
+ QFont f;
+ f.setStrikeOut(!d->m_resultNameValueDictionary.isEnabled(resultIterator));
+ return f;
+ }
+ case Qt::ForegroundRole:
+ return changes(d->m_resultNameValueDictionary.key(resultIterator))
+ ? QBrush(Qt::blue) : QBrush();
+ }
+ return QVariant();
+}
+
+Qt::ItemFlags NameValueModel::flags(const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
+}
+
+QVariant NameValueModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Vertical || role != Qt::DisplayRole)
+ return QVariant();
+ return section == 0 ? tr("Variable") : tr("Value");
+}
+
+/// *****************
+/// Utility functions
+/// *****************
+QModelIndex NameValueModel::variableToIndex(const QString &name) const
+{
+ int row = d->findInResult(name);
+ if (row == -1)
+ return QModelIndex();
+ return index(row, 0);
+}
+
+bool NameValueModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid() || role != Qt::EditRole)
+ return false;
+
+ // ignore changes to already set values:
+ if (data(index, role) == value)
+ return true;
+
+ const QString oldName = data(this->index(index.row(), 0, QModelIndex())).toString();
+ const QString oldValue = data(this->index(index.row(), 1, QModelIndex()), Qt::EditRole).toString();
+ int changesPos = d->findInChanges(oldName);
+
+ if (index.column() == 0) {
+ //fail if a variable with the same name already exists
+ const QString &newName = HostOsInfo::isWindowsHost() ? value.toString().toUpper()
+ : value.toString();
+ if (newName.isEmpty() || newName.contains('='))
+ return false;
+ // Does the new name exist already?
+ if (d->m_resultNameValueDictionary.hasKey(newName) || newName.isEmpty())
+ return false;
+
+ NameValueItem newVariable(newName, oldValue);
+
+ if (changesPos != -1)
+ resetVariable(oldName); // restore the original base variable again
+
+ QModelIndex newIndex = addVariable(newVariable); // add the new variable
+ emit focusIndex(newIndex.sibling(newIndex.row(), 1)); // hint to focus on the value
+ return true;
+ } else if (index.column() == 1) {
+ // We are changing an existing value:
+ const QString stringValue = value.toString();
+ if (changesPos != -1) {
+ const auto oldIt = d->m_baseNameValueDictionary.constFind(oldName);
+ const auto newIt = d->m_resultNameValueDictionary.constFind(oldName);
+ // We have already changed this value
+ if (oldIt != d->m_baseNameValueDictionary.constEnd()
+ && stringValue == d->m_baseNameValueDictionary.value(oldIt)
+ && d->m_baseNameValueDictionary.isEnabled(oldIt)
+ == d->m_resultNameValueDictionary.isEnabled(newIt)) {
+ // ... and now went back to the base value
+ d->m_items.removeAt(changesPos);
+ } else {
+ // ... and changed it again
+ d->m_items[changesPos].value = stringValue;
+ if (d->m_items[changesPos].operation == NameValueItem::Unset)
+ d->m_items[changesPos].operation = NameValueItem::SetEnabled;
+ }
+ } else {
+ // Add a new change item:
+ d->m_items.append(NameValueItem(oldName, stringValue));
+ }
+ d->updateResultNameValueDictionary();
+ emit dataChanged(index, index);
+ emit userChangesChanged();
+ return true;
+ }
+ return false;
+}
+
+QModelIndex NameValueModel::addVariable()
+{
+ //: Name when inserting a new variable
+ return addVariable(NameValueItem(tr("<VARIABLE>"),
+ //: Value when inserting a new variable
+ tr("<VALUE>")));
+}
+
+QModelIndex NameValueModel::addVariable(const NameValueItem &item)
+{
+ // Return existing index if the name is already in the result set:
+ int pos = d->findInResult(item.name);
+ if (pos >= 0 && pos < d->m_resultNameValueDictionary.size())
+ return index(pos, 0, QModelIndex());
+
+ int insertPos = d->findInResultInsertPosition(item.name);
+ int changePos = d->findInChanges(item.name);
+ if (d->m_baseNameValueDictionary.hasKey(item.name)) {
+ // We previously unset this!
+ Q_ASSERT(changePos >= 0);
+ // Do not insert a line here as we listed the variable as <UNSET> before!
+ Q_ASSERT(d->m_items.at(changePos).name == item.name);
+ Q_ASSERT(d->m_items.at(changePos).operation == NameValueItem::Unset);
+ Q_ASSERT(d->m_items.at(changePos).value.isEmpty());
+ d->m_items[changePos] = item;
+ emit dataChanged(index(insertPos, 0, QModelIndex()), index(insertPos, 1, QModelIndex()));
+ } else {
+ // We add something that is not in the base dictionary
+ // Insert a new line!
+ beginInsertRows(QModelIndex(), insertPos, insertPos);
+ Q_ASSERT(changePos < 0);
+ d->m_items.append(item);
+ d->updateResultNameValueDictionary();
+ endInsertRows();
+ }
+ emit userChangesChanged();
+ return index(insertPos, 0, QModelIndex());
+}
+
+void NameValueModel::resetVariable(const QString &name)
+{
+ int rowInChanges = d->findInChanges(name);
+ if (rowInChanges < 0)
+ return;
+
+ int rowInResult = d->findInResult(name);
+ if (rowInResult < 0)
+ return;
+
+ if (d->m_baseNameValueDictionary.hasKey(name)) {
+ d->m_items.removeAt(rowInChanges);
+ d->updateResultNameValueDictionary();
+ emit dataChanged(index(rowInResult, 0, QModelIndex()), index(rowInResult, 1, QModelIndex()));
+ emit userChangesChanged();
+ } else {
+ // Remove the line completely!
+ beginRemoveRows(QModelIndex(), rowInResult, rowInResult);
+ d->m_items.removeAt(rowInChanges);
+ d->updateResultNameValueDictionary();
+ endRemoveRows();
+ emit userChangesChanged();
+ }
+}
+
+void NameValueModel::unsetVariable(const QString &name)
+{
+ // This does not change the number of rows as we will display a <UNSET>
+ // in place of the original variable!
+ int row = d->findInResult(name);
+ if (row < 0)
+ return;
+
+ // look in d->m_items for the variable
+ int pos = d->findInChanges(name);
+ if (pos != -1) {
+ d->m_items[pos].operation = NameValueItem::Unset;
+ d->m_items[pos].value.clear();
+ d->updateResultNameValueDictionary();
+ emit dataChanged(index(row, 0, QModelIndex()), index(row, 1, QModelIndex()));
+ emit userChangesChanged();
+ return;
+ }
+ d->m_items.append(NameValueItem(name, QString(), NameValueItem::Unset));
+ d->updateResultNameValueDictionary();
+ emit dataChanged(index(row, 0, QModelIndex()), index(row, 1, QModelIndex()));
+ emit userChangesChanged();
+}
+
+void NameValueModel::toggleVariable(const QModelIndex &idx)
+{
+ const QString name = indexToVariable(idx);
+ const auto newIt = d->m_resultNameValueDictionary.constFind(name);
+ QTC_ASSERT(newIt != d->m_resultNameValueDictionary.constEnd(), return);
+ const auto op = d->m_resultNameValueDictionary.isEnabled(newIt)
+ ? NameValueItem::SetDisabled : NameValueItem::SetEnabled;
+ const int changesPos = d->findInChanges(name);
+ if (changesPos != -1) {
+ const auto oldIt = d->m_baseNameValueDictionary.constFind(name);
+ if (oldIt == d->m_baseNameValueDictionary.constEnd()
+ || oldIt.value().first != newIt.value().first) {
+ d->m_items[changesPos].operation = op;
+ } else {
+ d->m_items.removeAt(changesPos);
+ }
+ } else {
+ d->m_items.append({name, d->m_resultNameValueDictionary.value(newIt), op});
+ }
+ d->updateResultNameValueDictionary();
+ emit dataChanged(index(idx.row(), 0), index(idx.row(), 1));
+ emit userChangesChanged();
+}
+
+bool NameValueModel::isUnset(const QString &name)
+{
+ const int pos = d->findInChanges(name);
+ return pos == -1 ? false : d->m_items.at(pos).operation == NameValueItem::Unset;
+}
+
+bool NameValueModel::isEnabled(const QString &name) const
+{
+ return d->m_resultNameValueDictionary.isEnabled(d->m_resultNameValueDictionary.constFind(name));
+}
+
+bool NameValueModel::canReset(const QString &name)
+{
+ return d->m_baseNameValueDictionary.hasKey(name);
+}
+
+NameValueItems NameValueModel::userChanges() const
+{
+ return d->m_items;
+}
+
+void NameValueModel::setUserChanges(const NameValueItems &items)
+{
+ NameValueItems filtered = Utils::filtered(items, [](const NameValueItem &i) {
+ return i.name != "export " && !i.name.contains('=');
+ });
+ // We assume nobody is reordering the items here.
+ if (filtered == d->m_items)
+ return;
+ beginResetModel();
+ d->m_items = filtered;
+ for (NameValueItem &item : d->m_items) {
+ QString &name = item.name;
+ name = name.trimmed();
+ if (name.startsWith("export "))
+ name = name.mid(7).trimmed();
+ if (d->m_baseNameValueDictionary.osType() == OsTypeWindows) {
+ // NameValueDictionary variable names are case-insensitive under windows, but we still
+ // want to preserve the case of pre-existing variables.
+ auto it = d->m_baseNameValueDictionary.constFind(name);
+ if (it != d->m_baseNameValueDictionary.constEnd())
+ name = d->m_baseNameValueDictionary.key(it);
+ }
+ }
+
+ d->updateResultNameValueDictionary();
+ endResetModel();
+ emit userChangesChanged();
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluemodel.h b/src/libs/utils/namevaluemodel.h
new file mode 100644
index 0000000000..ede319a013
--- /dev/null
+++ b/src/libs/utils/namevaluemodel.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "environmentfwd.h"
+#include "utils_global.h"
+
+#include <QAbstractTableModel>
+
+#include <memory>
+
+namespace Utils {
+
+namespace Internal {
+class NameValueModelPrivate;
+}
+
+class QTCREATOR_UTILS_EXPORT NameValueModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ explicit NameValueModel(QObject *parent = nullptr);
+ ~NameValueModel() override;
+
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+ QVariant headerData(int section,
+ Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const override;
+
+ QModelIndex addVariable();
+ QModelIndex addVariable(const NameValueItem &item);
+ void resetVariable(const QString &name);
+ void unsetVariable(const QString &name);
+ void toggleVariable(const QModelIndex &index);
+ bool isUnset(const QString &name);
+ bool isEnabled(const QString &name) const;
+ bool canReset(const QString &name);
+ QString indexToVariable(const QModelIndex &index) const;
+ QModelIndex variableToIndex(const QString &name) const;
+ bool changes(const QString &key) const;
+ const NameValueDictionary &baseNameValueDictionary() const;
+ void setBaseNameValueDictionary(const NameValueDictionary &dictionary);
+ NameValueItems userChanges() const;
+ void setUserChanges(const NameValueItems &items);
+
+signals:
+ void userChangesChanged();
+ /// Hint to the view where it should make sense to focus on next
+ // This is a hack since there is no way for a model to suggest
+ // the next interesting place to focus on to the view.
+ void focusIndex(const QModelIndex &index);
+
+private:
+ std::unique_ptr<Internal::NameValueModelPrivate> d;
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluesdialog.cpp b/src/libs/utils/namevaluesdialog.cpp
new file mode 100644
index 0000000000..4f92a79680
--- /dev/null
+++ b/src/libs/utils/namevaluesdialog.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "namevaluesdialog.h"
+
+#include <utils/environment.h>
+#include <utils/hostosinfo.h>
+
+#include <QDialogButtonBox>
+#include <QLabel>
+#include <QPlainTextEdit>
+#include <QVBoxLayout>
+
+namespace Utils {
+
+namespace Internal {
+
+static EnvironmentItems cleanUp(const EnvironmentItems &items)
+{
+ EnvironmentItems uniqueItems;
+ QSet<QString> uniqueSet;
+ for (int i = items.count() - 1; i >= 0; i--) {
+ EnvironmentItem item = items.at(i);
+ if (HostOsInfo::isWindowsHost())
+ item.name = item.name.toUpper();
+ const QString &itemName = item.name;
+ QString emptyName = itemName;
+ emptyName.remove(QLatin1Char(' '));
+ if (!emptyName.isEmpty() && !uniqueSet.contains(itemName)) {
+ uniqueItems.prepend(item);
+ uniqueSet.insert(itemName);
+ }
+ }
+ return uniqueItems;
+}
+
+NameValueItemsWidget::NameValueItemsWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ m_editor = new QPlainTextEdit(this);
+ auto layout = new QVBoxLayout(this);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(m_editor);
+}
+
+void NameValueItemsWidget::setEnvironmentItems(const EnvironmentItems &items)
+{
+ EnvironmentItems sortedItems = items;
+ EnvironmentItem::sort(&sortedItems);
+ const QStringList list = EnvironmentItem::toStringList(sortedItems);
+ m_editor->document()->setPlainText(list.join(QLatin1Char('\n')));
+}
+
+EnvironmentItems NameValueItemsWidget::environmentItems() const
+{
+ const QStringList list = m_editor->document()->toPlainText().split(QLatin1String("\n"));
+ EnvironmentItems items = EnvironmentItem::fromStringList(list);
+ return cleanUp(items);
+}
+
+void NameValueItemsWidget::setPlaceholderText(const QString &text)
+{
+ m_editor->setPlaceholderText(text);
+}
+} // namespace Internal
+
+NameValuesDialog::NameValuesDialog(const QString &windowTitle, const QString &helpText, QWidget *parent)
+ : QDialog(parent)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ resize(640, 480);
+ m_editor = new Internal::NameValueItemsWidget(this);
+ auto box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal,
+ this);
+ connect(box, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject);
+
+ auto helpLabel = new QLabel(this);
+ helpLabel->setText(helpText);
+
+ auto layout = new QVBoxLayout(this);
+ layout->addWidget(m_editor);
+ layout->addWidget(helpLabel);
+
+ layout->addWidget(box);
+
+ setWindowTitle(windowTitle);
+}
+
+void NameValuesDialog::setNameValueItems(const EnvironmentItems &items)
+{
+ m_editor->setEnvironmentItems(items);
+}
+
+EnvironmentItems NameValuesDialog::nameValueItems() const
+{
+ return m_editor->environmentItems();
+}
+
+void NameValuesDialog::setPlaceholderText(const QString &text)
+{
+ m_editor->setPlaceholderText(text);
+}
+
+Utils::optional<NameValueItems> NameValuesDialog::getNameValueItems(QWidget *parent,
+ const NameValueItems &initial,
+ const QString &placeholderText,
+ Polisher polisher,
+ const QString &windowTitle,
+ const QString &helpText)
+{
+ NameValuesDialog dialog(windowTitle, helpText, parent);
+ if (polisher)
+ polisher(&dialog);
+ dialog.setNameValueItems(initial);
+ dialog.setPlaceholderText(placeholderText);
+ bool result = dialog.exec() == QDialog::Accepted;
+ if (result)
+ return dialog.nameValueItems();
+
+ return {};
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluesdialog.h b/src/libs/utils/namevaluesdialog.h
new file mode 100644
index 0000000000..8170a99a1d
--- /dev/null
+++ b/src/libs/utils/namevaluesdialog.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "environmentfwd.h"
+#include "optional.h"
+#include "utils_global.h"
+
+#include <QDialog>
+
+#include <functional>
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+class QPlainTextEdit;
+QT_END_NAMESPACE
+
+namespace Utils {
+
+namespace Internal {
+class NameValueItemsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit NameValueItemsWidget(QWidget *parent = nullptr);
+
+ void setEnvironmentItems(const EnvironmentItems &items);
+ EnvironmentItems environmentItems() const;
+
+ void setPlaceholderText(const QString &text);
+
+private:
+ QPlainTextEdit *m_editor;
+};
+} // namespace Internal
+
+class QTCREATOR_UTILS_EXPORT NameValuesDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ void setNameValueItems(const NameValueItems &items);
+ NameValueItems nameValueItems() const;
+
+ void setPlaceholderText(const QString &text);
+
+ using Polisher = std::function<void(QWidget *)>;
+ static Utils::optional<NameValueItems> getNameValueItems(QWidget *parent = nullptr,
+ const NameValueItems &initial = {},
+ const QString &placeholderText = {},
+ Polisher polish = {},
+ const QString &windowTitle = {},
+ const QString &helpText = {});
+
+protected:
+ explicit NameValuesDialog(const QString &windowTitle,
+ const QString &helpText,
+ QWidget *parent = {});
+
+private:
+ Internal::NameValueItemsWidget *m_editor;
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluevalidator.cpp b/src/libs/utils/namevaluevalidator.cpp
new file mode 100644
index 0000000000..580a476e01
--- /dev/null
+++ b/src/libs/utils/namevaluevalidator.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "namevaluevalidator.h"
+#include "namevaluemodel.h"
+#include "tooltip/tooltip.h"
+
+#include <QTreeView>
+
+namespace Utils {
+
+NameValueValidator::NameValueValidator(QWidget *parent,
+ Utils::NameValueModel *model,
+ QTreeView *view,
+ const QModelIndex &index,
+ const QString &toolTipText)
+ : QValidator(parent)
+ , m_toolTipText(toolTipText)
+ , m_model(model)
+ , m_view(view)
+ , m_index(index)
+{
+ m_hideTipTimer.setInterval(2000);
+ m_hideTipTimer.setSingleShot(true);
+ connect(&m_hideTipTimer, &QTimer::timeout, this, []() { Utils::ToolTip::hide(); });
+}
+
+QValidator::State NameValueValidator::validate(QString &in, int &pos) const
+{
+ Q_UNUSED(pos)
+ QModelIndex idx = m_model->variableToIndex(in);
+ if (idx.isValid() && idx != m_index)
+ return QValidator::Intermediate;
+ Utils::ToolTip::hide();
+ m_hideTipTimer.stop();
+ return QValidator::Acceptable;
+}
+
+void NameValueValidator::fixup(QString &input) const
+{
+ Q_UNUSED(input)
+
+ QPoint pos = m_view->mapToGlobal(m_view->visualRect(m_index).topLeft());
+ pos -= Utils::ToolTip::offsetFromPosition();
+ Utils::ToolTip::show(pos, m_toolTipText);
+ m_hideTipTimer.start();
+ // do nothing
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/namevaluevalidator.h b/src/libs/utils/namevaluevalidator.h
new file mode 100644
index 0000000000..508fc78e54
--- /dev/null
+++ b/src/libs/utils/namevaluevalidator.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "environmentfwd.h"
+#include "utils_global.h"
+
+#include <QModelIndex>
+#include <QTimer>
+#include <QValidator>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT NameValueValidator : public QValidator
+{
+ Q_OBJECT
+public:
+ NameValueValidator(QWidget *parent,
+ Utils::NameValueModel *model,
+ QTreeView *view,
+ const QModelIndex &index,
+ const QString &toolTipText);
+
+ QValidator::State validate(QString &in, int &pos) const override;
+
+ void fixup(QString &input) const override;
+
+private:
+ const QString m_toolTipText;
+ Utils::NameValueModel *m_model;
+ QTreeView *m_view;
+ QModelIndex m_index;
+ mutable QTimer m_hideTipTimer;
+};
+} // namespace Utils
diff --git a/src/libs/utils/osspecificaspects.h b/src/libs/utils/osspecificaspects.h
index 45541a3bf2..1a5bec02bb 100644
--- a/src/libs/utils/osspecificaspects.h
+++ b/src/libs/utils/osspecificaspects.h
@@ -51,6 +51,11 @@ inline Qt::CaseSensitivity fileNameCaseSensitivity(OsType osType)
return osType == OsTypeWindows || osType == OsTypeMac ? Qt::CaseInsensitive : Qt::CaseSensitive;
}
+inline Qt::CaseSensitivity envVarCaseSensitivity(OsType osType)
+{
+ return fileNameCaseSensitivity(osType);
+}
+
inline QChar pathListSeparator(OsType osType)
{
return QLatin1Char(osType == OsTypeWindows ? ';' : ':');
diff --git a/src/libs/utils/outputformatter.cpp b/src/libs/utils/outputformatter.cpp
index 7926422da6..475d8596e6 100644
--- a/src/libs/utils/outputformatter.cpp
+++ b/src/libs/utils/outputformatter.cpp
@@ -151,7 +151,7 @@ void OutputFormatter::initFormats()
void OutputFormatter::handleLink(const QString &href)
{
- Q_UNUSED(href);
+ Q_UNUSED(href)
}
void OutputFormatter::setBoldFontEnabled(bool enabled)
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index 746805bb12..a4cc97407a 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -84,7 +84,7 @@ public:
QStringList arguments() const { return m_arguments; }
void setArguments(const QStringList &arguments) { m_arguments = arguments; }
- static QString toolVersion(const QString &binary, const QStringList &arguments);
+ static QString toolVersion(const CommandLine &cmd);
private:
// Extension point for concatenating existing tooltips.
@@ -108,7 +108,8 @@ bool BinaryVersionToolTipEventFilter::eventFilter(QObject *o, QEvent *e)
const QString binary = le->text();
if (!binary.isEmpty()) {
- const QString version = BinaryVersionToolTipEventFilter::toolVersion(QDir::cleanPath(binary), m_arguments);
+ const QString version = BinaryVersionToolTipEventFilter::toolVersion(
+ CommandLine(QDir::cleanPath(binary), m_arguments));
if (!version.isEmpty()) {
// Concatenate tooltips.
QString tooltip = "<html><head/><body>";
@@ -127,13 +128,13 @@ bool BinaryVersionToolTipEventFilter::eventFilter(QObject *o, QEvent *e)
return false;
}
-QString BinaryVersionToolTipEventFilter::toolVersion(const QString &binary, const QStringList &arguments)
+QString BinaryVersionToolTipEventFilter::toolVersion(const CommandLine &cmd)
{
- if (binary.isEmpty())
+ if (cmd.executable().isEmpty())
return QString();
SynchronousProcess proc;
proc.setTimeoutS(1);
- SynchronousProcessResponse response = proc.runBlocking(binary, arguments);
+ SynchronousProcessResponse response = proc.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished)
return QString();
return response.allOutput();
@@ -681,7 +682,7 @@ FancyLineEdit *PathChooser::lineEdit() const
QString PathChooser::toolVersion(const QString &binary, const QStringList &arguments)
{
- return BinaryVersionToolTipEventFilter::toolVersion(binary, arguments);
+ return BinaryVersionToolTipEventFilter::toolVersion({binary, arguments});
}
void PathChooser::installLineEditVersionToolTip(QLineEdit *le, const QStringList &arguments)
diff --git a/src/libs/utils/pathlisteditor.cpp b/src/libs/utils/pathlisteditor.cpp
index 70ec975db7..522ea76bc5 100644
--- a/src/libs/utils/pathlisteditor.cpp
+++ b/src/libs/utils/pathlisteditor.cpp
@@ -110,7 +110,7 @@ PathListEditorPrivate::PathListEditorPrivate() :
buttonLayout(new QVBoxLayout),
edit(new PathListPlainTextEdit)
{
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(edit);
layout->addLayout(buttonLayout);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored,
diff --git a/src/libs/utils/process_ctrlc_stub.cpp b/src/libs/utils/process_ctrlc_stub.cpp
index 396ed3c153..e5469e208d 100644
--- a/src/libs/utils/process_ctrlc_stub.cpp
+++ b/src/libs/utils/process_ctrlc_stub.cpp
@@ -45,6 +45,7 @@
const wchar_t szTitle[] = L"qtcctrlcstub";
const wchar_t szWindowClass[] = L"wcqtcctrlcstub";
+const wchar_t szNice[] = L"-nice ";
UINT uiShutDownWindowMessage;
UINT uiInterruptMessage;
HWND hwndMain = nullptr;
@@ -53,7 +54,7 @@ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL WINAPI shutdownHandler(DWORD dwCtrlType);
BOOL WINAPI interruptHandler(DWORD dwCtrlType);
bool isSpaceOrTab(const wchar_t c);
-bool startProcess(wchar_t pCommandLine[]);
+bool startProcess(wchar_t pCommandLine[], bool lowerPriority);
int main(int argc, char **)
{
@@ -93,7 +94,14 @@ int main(int argc, char **)
++pos;
}
- bool bSuccess = startProcess(strCommandLine + pos);
+ const size_t niceLen = wcslen(szNice);
+ bool lowerPriority = !wcsncmp(strCommandLine + pos, szNice, niceLen);
+ if (lowerPriority) {
+ pos += niceLen - 1; // reach the space, then the following line skips all spaces.
+ while (isSpaceOrTab(strCommandLine[++pos]))
+ ;
+ }
+ bool bSuccess = startProcess(strCommandLine + pos, lowerPriority);
free(strCommandLine);
if (!bSuccess)
@@ -166,7 +174,7 @@ DWORD WINAPI processWatcherThread(LPVOID lpParameter)
return 0;
}
-bool startProcess(wchar_t *pCommandLine)
+bool startProcess(wchar_t *pCommandLine, bool lowerPriority)
{
SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa);
@@ -176,7 +184,7 @@ bool startProcess(wchar_t *pCommandLine)
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
- DWORD dwCreationFlags = 0;
+ DWORD dwCreationFlags = lowerPriority ? BELOW_NORMAL_PRIORITY_CLASS : 0;
BOOL bSuccess = CreateProcess(NULL, pCommandLine, &sa, &sa, TRUE, dwCreationFlags, NULL, NULL, &si, &pi);
if (!bSuccess) {
fwprintf(stderr, L"qtcreator_ctrlc_stub: Command line failed: %s\n", pCommandLine);
diff --git a/src/libs/utils/qrcparser.cpp b/src/libs/utils/qrcparser.cpp
index 21904d3716..dcb704abc4 100644
--- a/src/libs/utils/qrcparser.cpp
+++ b/src/libs/utils/qrcparser.cpp
@@ -74,12 +74,12 @@ public:
QrcParserPrivate(QrcParser *q);
bool parseFile(const QString &path, const QString &contents);
QString firstFileAtPath(const QString &path, const QLocale &locale) const;
- void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = 0) const;
- bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
+ void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = nullptr) const;
+ bool hasDirAtPath(const QString &path, const QLocale *locale = nullptr) const;
void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
- const QLocale *locale = 0) const;
+ const QLocale *locale = nullptr) const;
void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res,
- const QLocale *locale = 0) const;
+ const QLocale *locale = nullptr) const;
QStringList errorMessages() const;
QStringList languages() const;
@@ -487,7 +487,7 @@ QrcParser::Ptr QrcCachePrivate::addPath(const QString &path, const QString &cont
QPair<QrcParser::Ptr,int> currentValue;
{
QMutexLocker l(&m_mutex);
- currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
+ currentValue = m_cache.value(path, {QrcParser::Ptr(nullptr), 0});
currentValue.second += 1;
if (currentValue.second > 1) {
m_cache.insert(path, currentValue);
@@ -499,7 +499,7 @@ QrcParser::Ptr QrcCachePrivate::addPath(const QString &path, const QString &cont
qCWarning(qrcParserLog) << "adding invalid qrc " << path << " to the cache:" << newParser->errorMessages();
{
QMutexLocker l(&m_mutex);
- QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
+ QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(nullptr), 0});
if (currentValue.first.isNull())
currentValue.first = newParser;
currentValue.second += 1;
@@ -513,7 +513,7 @@ void QrcCachePrivate::removePath(const QString &path)
QPair<QrcParser::Ptr,int> currentValue;
{
QMutexLocker l(&m_mutex);
- currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
+ currentValue = m_cache.value(path, {QrcParser::Ptr(nullptr), 0});
if (currentValue.second == 1) {
m_cache.remove(path);
} else if (currentValue.second > 1) {
@@ -530,7 +530,7 @@ QrcParser::Ptr QrcCachePrivate::updatePath(const QString &path, const QString &c
QrcParser::Ptr newParser = QrcParser::parseQrcFile(path, contents);
{
QMutexLocker l(&m_mutex);
- QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
+ QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(nullptr), 0});
currentValue.first = newParser;
if (currentValue.second == 0)
currentValue.second = 1; // add qrc files that are not in the resources of a project
@@ -542,7 +542,7 @@ QrcParser::Ptr QrcCachePrivate::updatePath(const QString &path, const QString &c
QrcParser::Ptr QrcCachePrivate::parsedPath(const QString &path)
{
QMutexLocker l(&m_mutex);
- QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
+ QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(nullptr), 0});
return currentValue.first;
}
diff --git a/src/libs/utils/qrcparser.h b/src/libs/utils/qrcparser.h
index b5a7be761b..49e1f9e924 100644
--- a/src/libs/utils/qrcparser.h
+++ b/src/libs/utils/qrcparser.h
@@ -48,12 +48,12 @@ public:
~QrcParser();
bool parseFile(const QString &path, const QString &contents);
QString firstFileAtPath(const QString &path, const QLocale &locale) const;
- void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = 0) const;
- bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
+ void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = nullptr) const;
+ bool hasDirAtPath(const QString &path, const QLocale *locale = nullptr) const;
void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
- const QLocale *locale = 0) const;
+ const QLocale *locale = nullptr) const;
void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *results,
- const QLocale *locale = 0) const;
+ const QLocale *locale = nullptr) const;
QStringList errorMessages() const;
QStringList languages() const;
diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp
index 992e1817c0..6d608a441b 100644
--- a/src/libs/utils/qtcprocess.cpp
+++ b/src/libs/utils/qtcprocess.cpp
@@ -37,6 +37,9 @@
#ifdef Q_OS_WIN
#include <qt_windows.h>
+#else
+#include <errno.h>
+#include <unistd.h>
#endif
@@ -94,7 +97,7 @@ static void envExpandWin(QString &args, const Environment *env, const QString *p
if (prev >= 0) {
const QString var = args.mid(prev + 1, that - prev - 1).toUpper();
const QString val = (var == cdName && pwd && !pwd->isEmpty())
- ? QDir::toNativeSeparators(*pwd) : env->value(var);
+ ? QDir::toNativeSeparators(*pwd) : env->expandedValueForKey(var);
if (!val.isEmpty()) { // Empty values are impossible, so this is an existence check
args.replace(prev, that - prev + 1, val);
off = prev + val.length();
@@ -394,7 +397,7 @@ static QStringList splitArgsUnix(const QString &args, bool abortOnMeta,
if (abortOnMeta)
goto metaerr; // Assume this is a shell builtin
} else {
- cret += env->value(vit);
+ cret += env->expandedValueForKey(env->key(vit));
}
}
if (!braced)
@@ -444,7 +447,7 @@ static QStringList splitArgsUnix(const QString &args, bool abortOnMeta,
if (abortOnMeta)
goto metaerr; // Assume this is a shell builtin
} else {
- val = env->value(vit);
+ val = env->expandedValueForKey(env->key(vit));
}
}
for (int i = 0; i < val.length(); i++) {
@@ -672,8 +675,8 @@ QtcProcess::QtcProcess(QObject *parent)
{
static int qProcessExitStatusMeta = qRegisterMetaType<QProcess::ExitStatus>();
static int qProcessProcessErrorMeta = qRegisterMetaType<QProcess::ProcessError>();
- Q_UNUSED(qProcessExitStatusMeta);
- Q_UNUSED(qProcessProcessErrorMeta);
+ Q_UNUSED(qProcessExitStatusMeta)
+ Q_UNUSED(qProcessProcessErrorMeta)
}
void QtcProcess::setUseCtrlCStub(bool enabled)
@@ -698,7 +701,7 @@ void QtcProcess::start()
qPrintable(m_commandLine.executable().toString()));
env = m_environment;
- QProcess::setEnvironment(env.toStringList());
+ QProcess::setProcessEnvironment(env.toProcessEnvironment());
} else {
env = Environment::systemEnvironment();
}
@@ -712,9 +715,17 @@ void QtcProcess::start()
if (osType == OsTypeWindows) {
QString args;
if (m_useCtrlCStub) {
- args = QtcProcess::quoteArg(QDir::toNativeSeparators(command));
+ if (m_lowPriority)
+ addArg(&args, "-nice");
+ addArg(&args, QDir::toNativeSeparators(command));
command = QCoreApplication::applicationDirPath()
+ QLatin1String("/qtcreator_ctrlc_stub.exe");
+ } else if (m_lowPriority) {
+#ifdef Q_OS_WIN
+ setCreateProcessArgumentsModifier([](CreateProcessArguments *args) {
+ args->flags |= BELOW_NORMAL_PRIORITY_CLASS;
+ });
+#endif
}
QtcProcess::addArgs(&args, arguments.toWindowsArgs());
#ifdef Q_OS_WIN
@@ -1208,6 +1219,19 @@ QString QtcProcess::expandMacros(const QString &str, AbstractMacroExpander *mx,
return ret;
}
+void QtcProcess::setupChildProcess()
+{
+#if defined Q_OS_UNIX
+ // nice value range is -20 to +19 where -20 is highest, 0 default and +19 is lowest
+ if (m_lowPriority) {
+ errno = 0;
+ if (::nice(5) == -1 && errno != 0)
+ qWarning("Failed to set nice value. Error: %d", errno);
+ }
+#endif
+ QProcess::setupChildProcess();
+}
+
bool QtcProcess::ArgIterator::next()
{
// We delay the setting of m_prev so we can still delete the last argument
diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h
index 5eeacf666e..ca3f9a5a86 100644
--- a/src/libs/utils/qtcprocess.h
+++ b/src/libs/utils/qtcprocess.h
@@ -45,6 +45,7 @@ public:
void start();
void terminate();
void interrupt();
+ void setLowPriority() { m_lowPriority = true; }
class QTCREATOR_UTILS_EXPORT Arguments
{
@@ -141,10 +142,13 @@ public:
};
private:
+ void setupChildProcess() override;
+
CommandLine m_commandLine;
Environment m_environment;
bool m_haveEnv = false;
bool m_useCtrlCStub = false;
+ bool m_lowPriority = false;
};
} // namespace Utils
diff --git a/src/libs/utils/savefile.cpp b/src/libs/utils/savefile.cpp
index b25432a280..8d07603ad8 100644
--- a/src/libs/utils/savefile.cpp
+++ b/src/libs/utils/savefile.cpp
@@ -207,15 +207,15 @@ void SaveFile::initializeUmask()
mode_t mask = umask(0); // get current umask
umask(mask); // set it back
- m_umask = ((mask & S_IRUSR) ? QFile::ReadOwner : QFlags<QFile::Permission>(0))
- | ((mask & S_IWUSR) ? QFile::WriteOwner : QFlags<QFile::Permission>(0))
- | ((mask & S_IXUSR) ? QFile::ExeOwner : QFlags<QFile::Permission>(0))
- | ((mask & S_IRGRP) ? QFile::ReadGroup : QFlags<QFile::Permission>(0))
- | ((mask & S_IWGRP) ? QFile::WriteGroup : QFlags<QFile::Permission>(0))
- | ((mask & S_IXGRP) ? QFile::ExeGroup : QFlags<QFile::Permission>(0))
- | ((mask & S_IROTH) ? QFile::ReadOther : QFlags<QFile::Permission>(0))
- | ((mask & S_IWOTH) ? QFile::WriteOther : QFlags<QFile::Permission>(0))
- | ((mask & S_IXOTH) ? QFile::ExeOther : QFlags<QFile::Permission>(0));
+ m_umask = ((mask & S_IRUSR) ? QFile::ReadOwner : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IWUSR) ? QFile::WriteOwner : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IXUSR) ? QFile::ExeOwner : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IRGRP) ? QFile::ReadGroup : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IWGRP) ? QFile::WriteGroup : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IXGRP) ? QFile::ExeGroup : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IROTH) ? QFile::ReadOther : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IWOTH) ? QFile::WriteOther : QFlags<QFile::Permission>(nullptr))
+ | ((mask & S_IXOTH) ? QFile::ExeOther : QFlags<QFile::Permission>(nullptr));
#endif
}
diff --git a/src/libs/utils/settingsaccessor.cpp b/src/libs/utils/settingsaccessor.cpp
index f6d90df7e0..bc34ec7f93 100644
--- a/src/libs/utils/settingsaccessor.cpp
+++ b/src/libs/utils/settingsaccessor.cpp
@@ -100,7 +100,7 @@ bool SettingsAccessor::saveSettings(const QVariantMap &data, QWidget *parent) co
*/
SettingsAccessor::RestoreData SettingsAccessor::readData(const FilePath &path, QWidget *parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
RestoreData result = readFile(path);
if (!result.data.isEmpty())
result.data = preprocessReadSettings(result.data);
@@ -113,7 +113,7 @@ SettingsAccessor::RestoreData SettingsAccessor::readData(const FilePath &path, Q
optional<SettingsAccessor::Issue>
SettingsAccessor::writeData(const FilePath &path, const QVariantMap &data, QWidget *parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return writeFile(path, prepareToWriteSettings(data));
}
@@ -277,7 +277,10 @@ BackingUpSettingsAccessor::readData(const FilePath &path, QWidget *parent) const
QApplication::translate("Utils::SettingsAccessor",
"<p>No valid settings file could be found.</p>"
"<p>All settings files found in directory \"%1\" "
- "were unsuitable for the current version of %2.</p>")
+ "were unsuitable for the current version of %2, "
+ "for instance because they were written by an incompatible "
+ "version of %2, or because a different settings path "
+ "was used.</p>")
.arg(path.toUserOutput()).arg(applicationDisplayName), Issue::Type::ERROR);
i.buttons.insert(QMessageBox::Ok, DiscardAndContinue);
result.issue = i;
@@ -362,7 +365,7 @@ int VersionedBackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
optional<FilePath>
VersionedBackUpStrategy::backupName(const QVariantMap &oldData, const FilePath &path, const QVariantMap &data) const
{
- Q_UNUSED(data);
+ Q_UNUSED(data)
FilePath backupName = path;
const QByteArray oldEnvironmentId = settingsIdFromMap(oldData);
const int oldVersion = versionFromMap(oldData);
@@ -704,8 +707,8 @@ QVariantMap MergingSettingsAccessor::postprocessMerge(const QVariantMap &main,
const QVariantMap &secondary,
const QVariantMap &result) const
{
- Q_UNUSED(main);
- Q_UNUSED(secondary);
+ Q_UNUSED(main)
+ Q_UNUSED(secondary)
return result;
}
diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp
index 5a84c92f15..060c4003fa 100644
--- a/src/libs/utils/shellcommand.cpp
+++ b/src/libs/utils/shellcommand.cpp
@@ -68,12 +68,11 @@ class ShellCommandPrivate
{
public:
struct Job {
- explicit Job(const QString &wd, const FilePath &b, const QStringList &a, int t,
+ explicit Job(const QString &wd, const CommandLine &command, int t,
const ExitCodeInterpreter &interpreter);
QString workingDirectory;
- FilePath binary;
- QStringList arguments;
+ CommandLine command;
ExitCodeInterpreter exitCodeInterpreter;
int timeoutS;
};
@@ -113,11 +112,10 @@ ShellCommandPrivate::~ShellCommandPrivate()
delete m_progressParser;
}
-ShellCommandPrivate::Job::Job(const QString &wd, const FilePath &b, const QStringList &a,
+ShellCommandPrivate::Job::Job(const QString &wd, const CommandLine &command,
int t, const ExitCodeInterpreter &interpreter) :
workingDirectory(wd),
- binary(b),
- arguments(a),
+ command(command),
exitCodeInterpreter(interpreter),
timeoutS(t)
{
@@ -146,14 +144,14 @@ QString ShellCommand::displayName() const
return d->m_displayName;
if (!d->m_jobs.isEmpty()) {
const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(0);
- QString result = job.binary.toFileInfo().baseName();
+ QString result = job.command.executable().toFileInfo().baseName();
if (!result.isEmpty())
result[0] = result.at(0).toTitleCase();
else
result = tr("UNKNOWN");
- if (!job.arguments.isEmpty())
- result += QLatin1Char(' ') + job.arguments.at(0);
+ if (!job.command.arguments().isEmpty())
+ result += ' ' + job.command.arguments().at(0);
return result;
}
@@ -195,17 +193,17 @@ void ShellCommand::addFlags(unsigned f)
d->m_flags |= f;
}
-void ShellCommand::addJob(const FilePath &binary, const QStringList &arguments,
+void ShellCommand::addJob(const CommandLine &command,
const QString &workingDirectory, const ExitCodeInterpreter &interpreter)
{
- addJob(binary, arguments, defaultTimeoutS(), workingDirectory, interpreter);
+ addJob(command, defaultTimeoutS(), workingDirectory, interpreter);
}
-void ShellCommand::addJob(const FilePath &binary, const QStringList &arguments, int timeoutS,
+void ShellCommand::addJob(const CommandLine &command, int timeoutS,
const QString &workingDirectory, const ExitCodeInterpreter &interpreter)
{
- d->m_jobs.push_back(Internal::ShellCommandPrivate::Job(workDirectory(workingDirectory), binary,
- arguments, timeoutS, interpreter));
+ d->m_jobs.push_back(Internal::ShellCommandPrivate::Job(workDirectory(workingDirectory), command,
+ timeoutS, interpreter));
}
void ShellCommand::execute()
@@ -240,7 +238,7 @@ unsigned ShellCommand::processFlags() const
void ShellCommand::addTask(QFuture<void> &future)
{
- Q_UNUSED(future);
+ Q_UNUSED(future)
}
int ShellCommand::timeoutS() const
@@ -287,7 +285,7 @@ void ShellCommand::run(QFutureInterface<void> &future)
for (int j = 0; j < count; j++) {
const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(j);
SynchronousProcessResponse resp
- = runCommand(job.binary, job.arguments, job.timeoutS, job.workingDirectory,
+ = runCommand(job.command, job.timeoutS, job.workingDirectory,
job.exitCodeInterpreter);
stdOut += resp.stdOut();
stdErr += resp.stdErr();
@@ -319,8 +317,7 @@ void ShellCommand::run(QFutureInterface<void> &future)
this->deleteLater();
}
-SynchronousProcessResponse ShellCommand::runCommand(const FilePath &binary,
- const QStringList &arguments, int timeoutS,
+SynchronousProcessResponse ShellCommand::runCommand(const CommandLine &command, int timeoutS,
const QString &workingDirectory,
const ExitCodeInterpreter &interpreter)
{
@@ -328,7 +325,7 @@ SynchronousProcessResponse ShellCommand::runCommand(const FilePath &binary,
const QString dir = workDirectory(workingDirectory);
- if (binary.isEmpty()) {
+ if (command.executable().isEmpty()) {
response.result = SynchronousProcessResponse::StartFailed;
return response;
}
@@ -336,31 +333,30 @@ SynchronousProcessResponse ShellCommand::runCommand(const FilePath &binary,
QSharedPointer<OutputProxy> proxy(d->m_proxyFactory());
if (!(d->m_flags & SuppressCommandLogging))
- emit proxy->appendCommand(dir, binary, arguments);
+ emit proxy->appendCommand(dir, command);
if ((d->m_flags & FullySynchronously)
|| (!(d->m_flags & NoFullySync)
&& QThread::currentThread() == QCoreApplication::instance()->thread())) {
- response = runFullySynchronous(binary, arguments, proxy, timeoutS, dir, interpreter);
+ response = runFullySynchronous(command, proxy, timeoutS, dir, interpreter);
} else {
- response = runSynchronous(binary, arguments, proxy, timeoutS, dir, interpreter);
+ response = runSynchronous(command, proxy, timeoutS, dir, interpreter);
}
if (!d->m_aborted) {
// Success/Fail message in appropriate window?
if (response.result == SynchronousProcessResponse::Finished) {
if (d->m_flags & ShowSuccessMessage)
- emit proxy->appendMessage(response.exitMessage(binary.toUserOutput(), timeoutS));
+ emit proxy->appendMessage(response.exitMessage(command.toUserOutput(), timeoutS));
} else if (!(d->m_flags & SuppressFailMessage)) {
- emit proxy->appendError(response.exitMessage(binary.toUserOutput(), timeoutS));
+ emit proxy->appendError(response.exitMessage(command.toUserOutput(), timeoutS));
}
}
return response;
}
-SynchronousProcessResponse ShellCommand::runFullySynchronous(const FilePath &binary,
- const QStringList &arguments,
+SynchronousProcessResponse ShellCommand::runFullySynchronous(const CommandLine &cmd,
QSharedPointer<OutputProxy> proxy,
int timeoutS,
const QString &workingDirectory,
@@ -380,7 +376,7 @@ SynchronousProcessResponse ShellCommand::runFullySynchronous(const FilePath &bin
process.setTimeoutS(timeoutS);
process.setExitCodeInterpreter(interpreter);
- SynchronousProcessResponse resp = process.runBlocking(binary.toString(), arguments);
+ SynchronousProcessResponse resp = process.runBlocking(cmd);
if (!d->m_aborted) {
const QString stdErr = resp.stdErr();
@@ -399,8 +395,7 @@ SynchronousProcessResponse ShellCommand::runFullySynchronous(const FilePath &bin
return resp;
}
-SynchronousProcessResponse ShellCommand::runSynchronous(const FilePath &binary,
- const QStringList &arguments,
+SynchronousProcessResponse ShellCommand::runSynchronous(const CommandLine &cmd,
QSharedPointer<OutputProxy> proxy,
int timeoutS,
const QString &workingDirectory,
@@ -460,7 +455,7 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const FilePath &binary,
process.setTimeoutS(timeoutS);
process.setExitCodeInterpreter(interpreter);
- return process.run(binary.toString(), arguments);
+ return process.run(cmd);
}
const QVariant &ShellCommand::cookie() const
diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h
index f0c427ef53..a54e8fb401 100644
--- a/src/libs/utils/shellcommand.h
+++ b/src/libs/utils/shellcommand.h
@@ -46,7 +46,7 @@ QT_END_NAMESPACE
namespace Utils {
-class FilePath;
+class CommandLine;
namespace Internal { class ShellCommandPrivate; }
class QTCREATOR_UTILS_EXPORT ProgressParser
@@ -79,8 +79,7 @@ signals:
void append(const QString &text);
void appendSilently(const QString &text);
void appendError(const QString &text);
- void appendCommand(const QString &workingDirectory, const Utils::FilePath &binary,
- const QStringList &args);
+ void appendCommand(const QString &workingDirectory, const Utils::CommandLine &command);
void appendMessage(const QString &text);
};
@@ -112,10 +111,12 @@ public:
QString displayName() const;
void setDisplayName(const QString &name);
- void addJob(const FilePath &binary, const QStringList &arguments,
- const QString &workingDirectory = QString(), const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
- void addJob(const FilePath &binary, const QStringList &arguments, int timeoutS,
- const QString &workingDirectory = QString(), const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
+ void addJob(const CommandLine &command,
+ const QString &workingDirectory = QString(),
+ const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
+ void addJob(const CommandLine &command, int timeoutS,
+ const QString &workingDirectory = QString(),
+ const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
void execute(); // Execute tasks asynchronously!
void abort();
bool lastExecutionSuccess() const;
@@ -145,7 +146,7 @@ public:
// This is called once per job in a thread.
// When called from the UI thread it will execute fully synchronously, so no signals will
// be triggered!
- virtual SynchronousProcessResponse runCommand(const FilePath &binary, const QStringList &arguments,
+ virtual SynchronousProcessResponse runCommand(const CommandLine &command,
int timeoutS,
const QString &workingDirectory = QString(),
const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
@@ -171,12 +172,12 @@ private:
void run(QFutureInterface<void> &future);
// Run without a event loop in fully blocking mode. No signals will be delivered.
- SynchronousProcessResponse runFullySynchronous(const FilePath &binary, const QStringList &arguments,
+ SynchronousProcessResponse runFullySynchronous(const CommandLine &cmd,
QSharedPointer<OutputProxy> proxy,
int timeoutS, const QString &workingDirectory,
const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
// Run with an event loop. Signals will be delivered.
- SynchronousProcessResponse runSynchronous(const FilePath &binary, const QStringList &arguments,
+ SynchronousProcessResponse runSynchronous(const CommandLine &cmd,
QSharedPointer<OutputProxy> proxy,
int timeoutS, const QString &workingDirectory,
const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h
index d3fa44aa78..6708560ac8 100644
--- a/src/libs/utils/smallstring.h
+++ b/src/libs/utils/smallstring.h
@@ -181,7 +181,7 @@ public:
}
BasicSmallString(BasicSmallString &&other) noexcept
- : m_data(other.m_data)
+ : m_data(std::move(other.m_data))
{
other.m_data.reset();
}
@@ -193,8 +193,8 @@ public:
this->~BasicSmallString();
- m_data = other.m_data;
- other.m_data = Internal::StringDataLayout<Size>();
+ m_data = std::move(other.m_data);
+ other.m_data.reset();
return *this;
}
@@ -945,8 +945,8 @@ clone(const std::unordered_map<Key, Value, Hash, KeyEqual, Allocator> &map)
return clonedMap;
}
-template <typename Type>
-std::vector<Type> clone(const std::vector<Type> &vector)
+template<typename Type>
+Type clone(const Type &vector)
{
return vector;
}
diff --git a/src/libs/utils/smallstringio.h b/src/libs/utils/smallstringio.h
index 6e9e2a7bc2..5a0dd71c8a 100644
--- a/src/libs/utils/smallstringio.h
+++ b/src/libs/utils/smallstringio.h
@@ -91,7 +91,9 @@ std::ostream &operator<<(std::ostream &out, const BasicSmallString<Size> &string
inline
std::ostream &operator<<(std::ostream &out, SmallStringView string)
{
- return out << PathString(string);
+ out.write(string.data(), std::streamsize(string.size()));
+
+ return out;
}
template <typename String>
diff --git a/src/libs/utils/smallstringvector.h b/src/libs/utils/smallstringvector.h
index ed1acc2e7b..724cf7e717 100644
--- a/src/libs/utils/smallstringvector.h
+++ b/src/libs/utils/smallstringvector.h
@@ -117,16 +117,7 @@ public:
push_back(std::move(string));
}
- BasicSmallStringVector clone() const
- {
- BasicSmallStringVector clonedVector;
- clonedVector.reserve(Base::size());
-
- for (auto &&entry : *this)
- clonedVector.push_back(entry.clone());
-
- return clonedVector;
- }
+ BasicSmallStringVector clone() const { return *this; }
operator std::vector<std::string>() const
{
diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp
index 161cf44e74..f73e9d8144 100644
--- a/src/libs/utils/stringutils.cpp
+++ b/src/libs/utils/stringutils.cpp
@@ -136,6 +136,7 @@ bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QSt
QString *currArg = &varName;
QChar prev;
QChar c;
+ QChar replacementChar;
bool replaceAll = false;
int i = *pos;
@@ -192,13 +193,14 @@ bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QSt
} else if (currArg == &varName && c == '-' && prev == ':' && validateVarName(varName)) {
varName.chop(1);
currArg = &defaultValue;
- } else if (currArg == &varName && c == '/' && validateVarName(varName)) {
+ } else if (currArg == &varName && (c == '/' || c == '#') && validateVarName(varName)) {
+ replacementChar = c;
currArg = &pattern;
- if (i < strLen && str.at(i) == '/') {
+ if (i < strLen && str.at(i) == replacementChar) {
++i;
replaceAll = true;
}
- } else if (currArg == &pattern && c == '/') {
+ } else if (currArg == &pattern && c == replacementChar) {
currArg = &replace;
} else {
*currArg += c;
diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
index 70e65fc8c9..f197494b4c 100644
--- a/src/libs/utils/synchronousprocess.cpp
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -271,7 +271,7 @@ public:
QTimer m_timer;
QEventLoop m_eventLoop;
SynchronousProcessResponse m_result;
- QString m_binary;
+ FilePath m_binary;
ChannelBuffer m_stdOut;
ChannelBuffer m_stdErr;
ExitCodeInterpreter m_exitCodeInterpreter = defaultExitCodeInterpreter;
@@ -293,7 +293,7 @@ void SynchronousProcessPrivate::clearForRun()
m_result.clear();
m_result.codec = m_codec;
m_startFailure = false;
- m_binary.clear();
+ m_binary = {};
}
// ----------- SynchronousProcess
@@ -446,12 +446,10 @@ static bool isGuiThread()
return QThread::currentThread() == QCoreApplication::instance()->thread();
}
-SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
- const QStringList &args,
+SynchronousProcessResponse SynchronousProcess::run(const CommandLine &cmd,
const QByteArray &writeData)
{
- qCDebug(processLog).noquote() << "Starting:"
- << QtcProcess::joinArgs(QStringList(binary) + args);
+ qCDebug(processLog).noquote() << "Starting:" << cmd.toUserOutput();
ExecuteOnDestruction logResult([this] {
qCDebug(processLog) << d->m_result;
});
@@ -461,12 +459,12 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
// On Windows, start failure is triggered immediately if the
// executable cannot be found in the path. Do not start the
// event loop in that case.
- d->m_binary = binary;
+ d->m_binary = cmd.executable();
// using QProcess::start() and passing program, args and OpenMode results in a different
// quoting of arguments than using QProcess::setArguments() beforehand and calling start()
// only with the OpenMode
- d->m_process.setProgram(binary);
- d->m_process.setArguments(args);
+ d->m_process.setProgram(cmd.executable().toString());
+ d->m_process.setArguments(cmd.splitArguments());
connect(&d->m_process, &QProcess::started, this, [this, writeData] {
if (!writeData.isEmpty()) {
int pos = 0;
@@ -503,10 +501,9 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
return d->m_result;
}
-SynchronousProcessResponse SynchronousProcess::runBlocking(const QString &binary, const QStringList &args)
+SynchronousProcessResponse SynchronousProcess::runBlocking(const CommandLine &cmd)
{
- qCDebug(processLog).noquote() << "Starting blocking:"
- << QtcProcess::joinArgs(QStringList(binary) + args);
+ qCDebug(processLog).noquote() << "Starting blocking:" << cmd.toUserOutput();
ExecuteOnDestruction logResult([this] {
qCDebug(processLog) << d->m_result;
});
@@ -516,8 +513,8 @@ SynchronousProcessResponse SynchronousProcess::runBlocking(const QString &binary
// On Windows, start failure is triggered immediately if the
// executable cannot be found in the path. Do not start the
// event loop in that case.
- d->m_binary = binary;
- d->m_process.start(binary, args, QIODevice::ReadOnly);
+ d->m_binary = cmd.executable();
+ d->m_process.start(cmd.executable().toString(), cmd.splitArguments(), QIODevice::ReadOnly);
if (!d->m_process.waitForStarted(d->m_maxHangTimerCount * 1000)
&& d->m_process.state() == QProcess::NotRunning) {
d->m_result.result = SynchronousProcessResponse::StartFailed;
@@ -585,7 +582,7 @@ void SynchronousProcess::slotTimeout()
if (debug)
qDebug() << Q_FUNC_INFO << "HANG detected, killing";
d->m_waitingForUser = true;
- const bool terminate = !d->m_timeOutMessageBoxEnabled || askToKill(d->m_binary);
+ const bool terminate = !d->m_timeOutMessageBoxEnabled || askToKill(d->m_binary.toString());
d->m_waitingForUser = false;
if (terminate) {
SynchronousProcess::stopProcess(d->m_process);
diff --git a/src/libs/utils/synchronousprocess.h b/src/libs/utils/synchronousprocess.h
index d8e3275030..071e20e007 100644
--- a/src/libs/utils/synchronousprocess.h
+++ b/src/libs/utils/synchronousprocess.h
@@ -38,6 +38,7 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
namespace Utils {
class SynchronousProcessPrivate;
+class CommandLine;
/* Result of SynchronousProcess execution */
class QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
@@ -126,10 +127,10 @@ public:
void setExitCodeInterpreter(const ExitCodeInterpreter &interpreter);
ExitCodeInterpreter exitCodeInterpreter() const;
- // Starts an nested event loop and runs the binary with the arguments
- SynchronousProcessResponse run(const QString &binary, const QStringList &args, const QByteArray &writeData = {});
- // Starts the binary with the arguments blocking the UI fully
- SynchronousProcessResponse runBlocking(const QString &binary, const QStringList &args);
+ // Starts a nested event loop and runs the command
+ SynchronousProcessResponse run(const CommandLine &cmd, const QByteArray &writeData = {});
+ // Starts the command blocking the UI fully
+ SynchronousProcessResponse runBlocking(const CommandLine &cmd);
// Create a (derived) processes with flags applied.
static QSharedPointer<QProcess> createProcess(unsigned flags);
diff --git a/src/libs/utils/textutils.cpp b/src/libs/utils/textutils.cpp
index ba10ca56ae..ad6aa2242a 100644
--- a/src/libs/utils/textutils.cpp
+++ b/src/libs/utils/textutils.cpp
@@ -80,7 +80,7 @@ QString textAt(QTextCursor tc, int pos, int length)
return tc.selectedText().replace(QChar::ParagraphSeparator, QLatin1Char('\n'));
}
-QTextCursor selectAt(QTextCursor textCursor, uint line, uint column, uint length)
+QTextCursor selectAt(QTextCursor textCursor, int line, int column, uint length)
{
if (line < 1)
line = 1;
@@ -190,5 +190,30 @@ QString utf16LineTextInUtf8Buffer(const QByteArray &utf8Buffer, int currentUtf8O
utf8Buffer.mid(lineStartUtf8Offset, lineEndUtf8Offset - lineStartUtf8Offset));
}
+static bool isByteOfMultiByteCodePoint(unsigned char byte)
+{
+ return byte & 0x80; // Check if most significant bit is set
+}
+
+bool utf8AdvanceCodePoint(const char *&current)
+{
+ if (Q_UNLIKELY(*current == '\0'))
+ return false;
+
+ // Process multi-byte UTF-8 code point (non-latin1)
+ if (Q_UNLIKELY(isByteOfMultiByteCodePoint(*current))) {
+ unsigned trailingBytesCurrentCodePoint = 1;
+ for (unsigned char c = (*current) << 2; isByteOfMultiByteCodePoint(c); c <<= 1)
+ ++trailingBytesCurrentCodePoint;
+ current += trailingBytesCurrentCodePoint + 1;
+
+ // Process single-byte UTF-8 code point (latin1)
+ } else {
+ ++current;
+ }
+
+ return true;
+}
+
} // Text
} // Utils
diff --git a/src/libs/utils/textutils.h b/src/libs/utils/textutils.h
index fb0efe3f15..ae088a54ca 100644
--- a/src/libs/utils/textutils.h
+++ b/src/libs/utils/textutils.h
@@ -48,13 +48,14 @@ QTCREATOR_UTILS_EXPORT int positionInText(const QTextDocument *textDocument, int
QTCREATOR_UTILS_EXPORT QString textAt(QTextCursor tc, int pos, int length);
-QTCREATOR_UTILS_EXPORT QTextCursor selectAt(QTextCursor textCursor, uint line, uint column, uint length);
+QTCREATOR_UTILS_EXPORT QTextCursor selectAt(QTextCursor textCursor, int line, int column, uint length);
QTCREATOR_UTILS_EXPORT QTextCursor flippedCursor(const QTextCursor &cursor);
QTCREATOR_UTILS_EXPORT QTextCursor wordStartCursor(const QTextCursor &cursor);
QTCREATOR_UTILS_EXPORT QString wordUnderCursor(const QTextCursor &cursor);
+QTCREATOR_UTILS_EXPORT bool utf8AdvanceCodePoint(const char *&current);
QTCREATOR_UTILS_EXPORT int utf8NthLineOffset(const QTextDocument *textDocument,
const QByteArray &buffer,
int line);
diff --git a/src/libs/utils/tooltip/tips.cpp b/src/libs/utils/tooltip/tips.cpp
index f6927efef5..116b0832ad 100644
--- a/src/libs/utils/tooltip/tips.cpp
+++ b/src/libs/utils/tooltip/tips.cpp
@@ -283,7 +283,7 @@ void WidgetTip::pinToolTipWidget(QWidget *parent)
bool WidgetTip::canHandleContentReplacement(int typeId) const
{
// Always create a new widget.
- Q_UNUSED(typeId);
+ Q_UNUSED(typeId)
return false;
}
diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp
index 1f8fbd5756..89c8d5aa4c 100644
--- a/src/libs/utils/treemodel.cpp
+++ b/src/libs/utils/treemodel.cpp
@@ -521,7 +521,7 @@ void ModelTest::data()
*/
void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
{
- Q_UNUSED(end);
+ Q_UNUSED(end)
Changing c;
c.parent = parent;
c.oldSize = model->rowCount(parent);
@@ -628,22 +628,22 @@ int TreeItem::indexOf(const TreeItem *item) const
QVariant TreeItem::data(int column, int role) const
{
- Q_UNUSED(column);
- Q_UNUSED(role);
+ Q_UNUSED(column)
+ Q_UNUSED(role)
return QVariant();
}
bool TreeItem::setData(int column, const QVariant &data, int role)
{
- Q_UNUSED(column);
- Q_UNUSED(data);
- Q_UNUSED(role);
+ Q_UNUSED(column)
+ Q_UNUSED(data)
+ Q_UNUSED(role)
return false;
}
Qt::ItemFlags TreeItem::flags(int column) const
{
- Q_UNUSED(column);
+ Q_UNUSED(column)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
@@ -1195,7 +1195,7 @@ QVariant StaticTreeItem::data(int column, int role) const
Qt::ItemFlags StaticTreeItem::flags(int column) const
{
- Q_UNUSED(column);
+ Q_UNUSED(column)
return Qt::ItemIsEnabled;
}
diff --git a/src/libs/utils/treeviewcombobox.cpp b/src/libs/utils/treeviewcombobox.cpp
index 36a62d3694..b02bd32410 100644
--- a/src/libs/utils/treeviewcombobox.cpp
+++ b/src/libs/utils/treeviewcombobox.cpp
@@ -83,9 +83,9 @@ QModelIndex TreeViewComboBox::lastIndex(const QModelIndex &index)
void TreeViewComboBox::wheelEvent(QWheelEvent *e)
{
QModelIndex index = m_view->currentIndex();
- if (e->delta() > 0)
+ if (e->angleDelta().y() > 0)
index = indexAbove(index);
- else if (e->delta() < 0)
+ else if (e->angleDelta().y() < 0)
index = indexBelow(index);
e->accept();
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index a4697e0622..e2a3306081 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -24,9 +24,14 @@ win32: LIBS += -liphlpapi -lws2_32
SOURCES += \
$$PWD/globalfilechangeblocker.cpp \
$$PWD/benchmarker.cpp \
+ $$PWD/displayname.cpp \
$$PWD/environment.cpp \
$$PWD/environmentmodel.cpp \
$$PWD/environmentdialog.cpp \
+ $$PWD/namevaluedictionary.cpp \
+ $$PWD/namevalueitem.cpp \
+ $$PWD/namevaluemodel.cpp \
+ $$PWD/namevaluesdialog.cpp \
$$PWD/qrcparser.cpp \
$$PWD/qtcprocess.cpp \
$$PWD/reloadpromptutils.cpp \
@@ -125,19 +130,23 @@ SOURCES += \
$$PWD/fixedsizeclicklabel.cpp \
$$PWD/removefiledialog.cpp \
$$PWD/differ.cpp \
- $$PWD/jsontreeitem.cpp
-
-
-win32:SOURCES += $$PWD/consoleprocess_win.cpp
-else:SOURCES += $$PWD/consoleprocess_unix.cpp
+ $$PWD/jsontreeitem.cpp \
+ $$PWD/namevaluevalidator.cpp \
+ $$PWD/camelcasecursor.cpp
HEADERS += \
+ $$PWD/environmentfwd.h \
$$PWD/genericconstants.h \
$$PWD/globalfilechangeblocker.h \
$$PWD/benchmarker.h \
+ $$PWD/displayname.h \
$$PWD/environment.h \
$$PWD/environmentmodel.h \
$$PWD/environmentdialog.h \
+ $$PWD/namevaluedictionary.h \
+ $$PWD/namevalueitem.h \
+ $$PWD/namevaluemodel.h \
+ $$PWD/namevaluesdialog.h \
$$PWD/pointeralgorithm.h \
$$PWD/qrcparser.h \
$$PWD/qtcprocess.h \
@@ -170,7 +179,6 @@ HEADERS += \
$$PWD/qtcolorbutton.h \
$$PWD/savedaction.h \
$$PWD/consoleprocess.h \
- $$PWD/consoleprocess_p.h \
$$PWD/synchronousprocess.h \
$$PWD/savefile.h \
$$PWD/fileutils.h \
@@ -269,7 +277,9 @@ HEADERS += \
$$PWD/differ.h \
$$PWD/cpplanguage_details.h \
$$PWD/jsontreeitem.h \
- $$PWD/listmodel.h
+ $$PWD/listmodel.h \
+ $$PWD/namevaluevalidator.h \
+ $$PWD/camelcasecursor.h
FORMS += $$PWD/filewizardpage.ui \
$$PWD/newclasswidget.ui \
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 10368cd539..10ddfe1d07 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -50,6 +50,8 @@ Project {
"benchmarker.h",
"buildablehelperlibrary.cpp",
"buildablehelperlibrary.h",
+ "camelcasecursor.cpp",
+ "camelcasecursor.h",
"categorysortfiltermodel.cpp",
"categorysortfiltermodel.h",
"changeset.cpp",
@@ -66,7 +68,6 @@ Project {
"completingtextedit.h",
"consoleprocess.cpp",
"consoleprocess.h",
- "consoleprocess_p.h",
"cpplanguage_details.h",
"crumblepath.cpp",
"crumblepath.h",
@@ -79,6 +80,8 @@ Project {
"detailswidget.h",
"differ.cpp",
"differ.h",
+ "displayname.cpp",
+ "displayname.h",
"dropsupport.cpp",
"dropsupport.h",
"elfreader.cpp",
@@ -151,6 +154,16 @@ Project {
"macroexpander.cpp",
"macroexpander.h",
"mapreduce.h",
+ "namevaluedictionary.cpp",
+ "namevaluedictionary.h",
+ "namevalueitem.cpp",
+ "namevalueitem.h",
+ "namevaluemodel.cpp",
+ "namevaluemodel.h",
+ "namevaluesdialog.cpp",
+ "namevaluesdialog.h",
+ "namevaluevalidator.cpp",
+ "namevaluevalidator.h",
"navigationtreeview.cpp",
"navigationtreeview.h",
"networkaccessmanager.cpp",
@@ -202,7 +215,9 @@ Project {
"qtcprocess.h",
"reloadpromptutils.cpp",
"reloadpromptutils.h",
- "removefiledialog.cpp", "removefiledialog.h", "removefiledialog.ui",
+ "removefiledialog.cpp",
+ "removefiledialog.h",
+ "removefiledialog.ui",
"runextensions.cpp",
"runextensions.h",
"savedaction.cpp",
@@ -301,22 +316,6 @@ Project {
}
Group {
- name: "WindowsUtils"
- condition: qbs.targetOS.contains("windows")
- files: [
- "consoleprocess_win.cpp",
- ]
- }
-
- Group {
- name: "ConsoleProcess_unix"
- condition: qbs.targetOS.contains("unix")
- files: [
- "consoleprocess_unix.cpp",
- ]
- }
-
- Group {
name: "FileUtils_macos"
condition: qbs.targetOS.contains("macos")
files: [
diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc
index 1de3861d65..180c5e5b43 100644
--- a/src/libs/utils/utils.qrc
+++ b/src/libs/utils/utils.qrc
@@ -142,8 +142,14 @@
<file>images/Desktop.png</file>
<file>images/interrupt_small.png</file>
<file>images/interrupt_small@2x.png</file>
+ <file>images/run_file.png</file>
+ <file>images/run_file@2x.png</file>
<file>images/run_small.png</file>
<file>images/run_small@2x.png</file>
+ <file>images/runselected_boxes.png</file>
+ <file>images/runselected_boxes@2x.png</file>
+ <file>images/runselected_tickmarks.png</file>
+ <file>images/runselected_tickmarks@2x.png</file>
<file>images/stop_small.png</file>
<file>images/stop_small@2x.png</file>
<file>images/boundingrect.png</file>
@@ -223,6 +229,12 @@
<file>images/toggleprogressdetails@2x.png</file>
<file>images/unknownfile.png</file>
<file>images/dir.png</file>
+ <file>images/online.png</file>
+ <file>images/online@2x.png</file>
+ <file>images/download_arrow.png</file>
+ <file>images/download_arrow@2x.png</file>
+ <file>images/download_base.png</file>
+ <file>images/download_base@2x.png</file>
<file alias="mimetypes/freedesktop.org.xml" compression-algorithm="best">../3rdparty/xdg/freedesktop.org.xml</file>
</qresource>
<qresource prefix="/codemodel">
diff --git a/src/libs/utils/utilsicons.cpp b/src/libs/utils/utilsicons.cpp
index 2227f530c6..c83f74a5ce 100644
--- a/src/libs/utils/utilsicons.cpp
+++ b/src/libs/utils/utilsicons.cpp
@@ -194,6 +194,11 @@ const Icon SORT_ALPHABETICALLY_TOOLBAR({
{QLatin1String(":/utils/images/sort_alphabetically.png"), Theme::IconsBaseColor}});
const Icon TOGGLE_PROGRESSDETAILS_TOOLBAR({
{QLatin1String(":/utils/images/toggleprogressdetails.png"), Theme::IconsBaseColor}});
+const Icon ONLINE_TOOLBAR({
+ {QLatin1String(":/utils/images/online.png"), Theme::IconsBaseColor}});
+const Icon DOWNLOAD({
+ {QLatin1String(":/utils/images/download_arrow.png"), Theme::IconsRunColor},
+ {QLatin1String(":/utils/images/download_base.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon WARNING({
{QLatin1String(":/utils/images/warningfill.png"), Theme::BackgroundColorNormal},
diff --git a/src/libs/utils/utilsicons.h b/src/libs/utils/utilsicons.h
index ae6cd4d1dc..8505aed941 100644
--- a/src/libs/utils/utilsicons.h
+++ b/src/libs/utils/utilsicons.h
@@ -113,6 +113,8 @@ QTCREATOR_UTILS_EXPORT extern const Icon LINK;
QTCREATOR_UTILS_EXPORT extern const Icon LINK_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon SORT_ALPHABETICALLY_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon TOGGLE_PROGRESSDETAILS_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon ONLINE_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon DOWNLOAD;
QTCREATOR_UTILS_EXPORT extern const Icon INFO;
QTCREATOR_UTILS_EXPORT extern const Icon INFO_TOOLBAR;
diff --git a/src/libs/utils/winutils.cpp b/src/libs/utils/winutils.cpp
index 5190e11fca..69eb0d11e8 100644
--- a/src/libs/utils/winutils.cpp
+++ b/src/libs/utils/winutils.cpp
@@ -131,9 +131,9 @@ QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t,
}
return rc;
#endif
- Q_UNUSED(t);
- Q_UNUSED(name);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(t)
+ Q_UNUSED(name)
+ Q_UNUSED(errorMessage)
return QString();
}
@@ -182,7 +182,7 @@ QTCREATOR_UTILS_EXPORT QString imageName(quint32 processId)
result = QString::fromUtf16(reinterpret_cast<const ushort*>(path));
CloseHandle(handle);
#else
- Q_UNUSED(processId);
+ Q_UNUSED(processId)
#endif
return result;
}
diff --git a/src/libs/utils/wizard.cpp b/src/libs/utils/wizard.cpp
index 2680f41c2d..4efd1495b7 100644
--- a/src/libs/utils/wizard.cpp
+++ b/src/libs/utils/wizard.cpp
@@ -66,7 +66,7 @@ public:
m_indicatorLabel->setFixedSize(m_indicatorPixmap.size());
m_titleLabel = new QLabel(title, this);
auto l = new QHBoxLayout(this);
- l->setMargin(0);
+ l->setContentsMargins(0, 0, 0, 0);
l->addWidget(m_indicatorLabel);
l->addWidget(m_titleLabel);
}
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
index d81318c499..db1a5b5e2a 100644
--- a/src/plugins/CMakeLists.txt
+++ b/src/plugins/CMakeLists.txt
@@ -52,7 +52,7 @@ add_subdirectory(genericprojectmanager)
add_subdirectory(git)
add_subdirectory(mercurial)
add_subdirectory(perforce)
-add_subdirectory(pythoneditor)
+add_subdirectory(python)
add_subdirectory(qmakeprojectmanager)
add_subdirectory(qmljstools)
add_subdirectory(qmlprojectmanager)
@@ -78,7 +78,10 @@ add_subdirectory(valgrind)
add_subdirectory(winrt)
add_subdirectory(perfprofiler)
add_subdirectory(qbsprojectmanager)
+add_subdirectory(ctfvisualizer)
# Level 7:
+add_subdirectory(boot2qt)
add_subdirectory(qmldesigner)
add_subdirectory(qnx)
+add_subdirectory(webassembly)
diff --git a/src/plugins/android/CMakeLists.txt b/src/plugins/android/CMakeLists.txt
index 36bde749a9..aeb808423b 100644
--- a/src/plugins/android/CMakeLists.txt
+++ b/src/plugins/android/CMakeLists.txt
@@ -18,7 +18,6 @@ add_qtc_plugin(Android
androiddevicedialog.cpp androiddevicedialog.h androiddevicedialog.ui
androiderrormessage.cpp androiderrormessage.h
androidextralibrarylistmodel.cpp androidextralibrarylistmodel.h
- androidgdbserverkitinformation.cpp androidgdbserverkitinformation.h
androidglobal.h
androidmanager.cpp androidmanager.h
androidmanifestdocument.cpp androidmanifestdocument.h
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro
index f0a952c622..c00021f48b 100644
--- a/src/plugins/android/android.pro
+++ b/src/plugins/android/android.pro
@@ -24,7 +24,6 @@ HEADERS += \
javaparser.h \
androidplugin.h \
androiddevice.h \
- androidgdbserverkitinformation.h \
androidqmltoolingsupport.h \
androidmanifesteditorfactory.h \
androidmanifesteditor.h \
@@ -69,7 +68,6 @@ SOURCES += \
javaparser.cpp \
androidplugin.cpp \
androiddevice.cpp \
- androidgdbserverkitinformation.cpp \
androidqmltoolingsupport.cpp \
androidmanifesteditorfactory.cpp \
androidmanifesteditor.cpp \
diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs
index 1c6ed28a41..8b6a6aba91 100644
--- a/src/plugins/android/android.qbs
+++ b/src/plugins/android/android.qbs
@@ -49,8 +49,6 @@ Project {
"androiderrormessage.cpp",
"androidextralibrarylistmodel.cpp",
"androidextralibrarylistmodel.h",
- "androidgdbserverkitinformation.cpp",
- "androidgdbserverkitinformation.h",
"androidglobal.h",
"androidmanager.cpp",
"androidmanager.h",
diff --git a/src/plugins/android/android.qrc b/src/plugins/android/android.qrc
index 26b9b148d3..8c7bbb9ec8 100644
--- a/src/plugins/android/android.qrc
+++ b/src/plugins/android/android.qrc
@@ -4,6 +4,5 @@
<file>images/androiddevice@2x.png</file>
<file>images/androiddevicesmall.png</file>
<file>images/androiddevicesmall@2x.png</file>
- <file>images/download.png</file>
</qresource>
</RCC>
diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp
index 17a9eb9b59..f572156323 100644
--- a/src/plugins/android/androidavdmanager.cpp
+++ b/src/plugins/android/androidavdmanager.cpp
@@ -41,6 +41,8 @@
#include <chrono>
#include <functional>
+using namespace Utils;
+
namespace {
Q_LOGGING_CATEGORY(avdManagerLog, "qtc.android.avdManager", QtWarningMsg)
}
@@ -67,11 +69,11 @@ const int avdCreateTimeoutMs = 30000;
*/
static bool avdManagerCommand(const AndroidConfig config, const QStringList &args, QString *output)
{
- QString avdManagerToolPath = config.avdManagerToolPath().toString();
+ CommandLine cmd(config.avdManagerToolPath(), args);
Utils::SynchronousProcess proc;
auto env = AndroidConfigurations::toolsEnvironment(config).toStringList();
proc.setEnvironment(env);
- Utils::SynchronousProcessResponse response = proc.runBlocking(avdManagerToolPath, args);
+ SynchronousProcessResponse response = proc.runBlocking(cmd);
if (response.result == Utils::SynchronousProcessResponse::Finished) {
if (output)
*output = response.allOutput();
@@ -258,8 +260,7 @@ bool AndroidAvdManager::removeAvd(const QString &name) const
Utils::SynchronousProcess proc;
proc.setTimeoutS(5);
Utils::SynchronousProcessResponse response
- = proc.runBlocking(m_config.avdManagerToolPath().toString(),
- QStringList({"delete", "avd", "-n", name}));
+ = proc.runBlocking({m_config.avdManagerToolPath(), {"delete", "avd", "-n", name}});
return response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0;
}
@@ -345,10 +346,9 @@ bool AndroidAvdManager::isAvdBooted(const QString &device) const
QStringList arguments = AndroidDeviceInfo::adbSelector(device);
arguments << "shell" << "getprop" << "init.svc.bootanim";
- Utils::SynchronousProcess adbProc;
+ SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- Utils::SynchronousProcessResponse response =
- adbProc.runBlocking(m_config.adbToolPath().toString(), arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking({m_config.adbToolPath(), arguments});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return false;
QString value = response.allOutput().trimmed();
@@ -376,7 +376,7 @@ bool AndroidAvdManager::waitForBooted(const QString &serialNumber,
AndroidDeviceInfoList AvdManagerOutputParser::listVirtualDevices(const AndroidConfig &config)
{
QString output;
- if (!avdManagerCommand(config, QStringList({"list", "avd"}), &output)) {
+ if (!avdManagerCommand(config, {"list", "avd"}, &output)) {
qCDebug(avdManagerLog) << "Avd list command failed" << output << config.sdkToolsVersion();
return {};
}
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp
index b9d77469b7..df2708c374 100644
--- a/src/plugins/android/androidbuildapkstep.cpp
+++ b/src/plugins/android/androidbuildapkstep.cpp
@@ -94,9 +94,7 @@ static void setupProcessParameters(ProcessParameters *pp,
pp->setWorkingDirectory(bc->buildDirectory());
Utils::Environment env = bc->environment();
pp->setEnvironment(env);
- pp->setCommand(FilePath::fromString(command));
- pp->setArguments(Utils::QtcProcess::joinArgs(arguments));
- pp->resolveAll();
+ pp->setCommandLine({command, arguments});
}
class PasswordInputDialog : public QDialog
@@ -207,8 +205,9 @@ bool AndroidBuildApkStep::init()
setOutputParser(parser);
m_openPackageLocationForRun = m_openPackageLocation;
- m_apkPath = AndroidManager::apkPath(target()).toString();
- qCDebug(buildapkstepLog) << "APK path:" << m_apkPath;
+ m_packagePath = m_buildAAB ? AndroidManager::aabPath(target()).toString()
+ : AndroidManager::apkPath(target()).toString();
+ qCDebug(buildapkstepLog) << "Package path:" << m_packagePath;
if (!AbstractProcessStep::init())
return false;
@@ -248,6 +247,9 @@ bool AndroidBuildApkStep::init()
arguments << "--gradle";
+ if (m_buildAAB)
+ arguments << "--aab" << "--jarsigner";
+
if (m_useMinistro)
arguments << "--deployment" << "ministro";
@@ -288,7 +290,7 @@ bool AndroidBuildApkStep::init()
void AndroidBuildApkStep::showInGraphicalShell()
{
- Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), m_apkPath);
+ Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), m_packagePath);
}
ProjectExplorer::BuildStepConfigWidget *AndroidBuildApkStep::createConfigWidget()
@@ -375,14 +377,15 @@ void AndroidBuildApkStep::doRun()
auto setup = [this] {
auto bc = target()->activeBuildConfiguration();
- Utils::FilePath androidLibsDir = bc->buildDirectory()
- .pathAppended("android-build/libs")
- .pathAppended(AndroidManager::targetArch(target()));
- if (!androidLibsDir.exists() && !QDir{bc->buildDirectory().toString()}.mkpath(androidLibsDir.toString()))
- return false;
-
+ const auto androidAbis = AndroidManager::applicationAbis(target());
+ for (const auto &abi : androidAbis) {
+ Utils::FilePath androidLibsDir = bc->buildDirectory()
+ .pathAppended("android-build/libs")
+ .pathAppended(abi);
+ if (!androidLibsDir.exists() && !QDir{bc->buildDirectory().toString()}.mkpath(androidLibsDir.toString()))
+ return false;
+ }
- QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target());
RunConfiguration *rc = target()->activeRunConfiguration();
const QString buildKey = rc ? rc->buildKey() : QString();
const ProjectNode *node = rc ? target()->project()->findNodeForBuildKey(buildKey) : nullptr;
@@ -394,12 +397,41 @@ void AndroidBuildApkStep::doRun()
if (targets.isEmpty())
return true; // qmake does this job for us
+ QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target());
+ QJsonObject architectures;
+
// Copy targets to android build folder
- for (const auto &target : targets) {
- if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString()))
- return false;
+ QString applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName();
+ for (const auto &abi : androidAbis) {
+ QString targetSuffix = QString{"_%1.so"}.arg(abi);
+ if (applicationBinary.endsWith(targetSuffix)) {
+ // Keep only TargetName from "lib[TargetName]_abi.so"
+ applicationBinary.remove(0, 3).chop(targetSuffix.size());
+ }
+
+ Utils::FilePath androidLibsDir = bc->buildDirectory()
+ .pathAppended("android-build/libs")
+ .pathAppended(abi);
+ for (const auto &target : targets) {
+ if (target.endsWith(targetSuffix)) {
+ if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString()))
+ return false;
+ if (abi == "x86") {
+ architectures[abi] = "i686-linux-android";
+ } else if (abi == "x86_64") {
+ architectures[abi] = "x86_64-linux-android";
+ } else if (abi == "arm64-v8a") {
+ architectures[abi] = "aarch64-linux-android";
+ } else {
+ architectures[abi] = "arm-linux-androideabi";
+ }
+ }
+ }
}
+ deploySettings["application-binary"] = applicationBinary;
+ deploySettings["architectures"] = architectures;
+
QString extraLibs = node->data(Android::Constants::AndroidExtraLibs).toString();
if (!extraLibs.isEmpty())
deploySettings["android-extra-libs"] = extraLibs;
@@ -487,8 +519,8 @@ QVariant AndroidBuildApkStep::data(Core::Id id) const
return AndroidConfigurations::currentConfig().bestNdkPlatformMatch(AndroidManager::minimumSDK(target())).mid(8);
if (id == Constants::NdkLocation)
return QVariant::fromValue(AndroidConfigurations::currentConfig().ndkLocation());
- if (id == Constants::AndroidABI)
- return AndroidManager::targetArch(target());
+ if (id == Constants::AndroidABIs)
+ return AndroidManager::applicationAbis(target());
return AbstractProcessStep::data(id);
}
@@ -525,6 +557,16 @@ void AndroidBuildApkStep::setSignPackage(bool b)
m_signPackage = b;
}
+bool AndroidBuildApkStep::buildAAB() const
+{
+ return m_buildAAB;
+}
+
+void AndroidBuildApkStep::setBuildAAB(bool aab)
+{
+ m_buildAAB = aab;
+}
+
bool AndroidBuildApkStep::openPackageLocation() const
{
return m_openPackageLocation;
@@ -577,8 +619,8 @@ QAbstractItemModel *AndroidBuildApkStep::keystoreCertificates()
Utils::SynchronousProcess keytoolProc;
keytoolProc.setTimeoutS(30);
- const Utils::SynchronousProcessResponse response
- = keytoolProc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), params);
+ const SynchronousProcessResponse response
+ = keytoolProc.run({AndroidConfigurations::currentConfig().keytoolPath(), params});
if (response.result > Utils::SynchronousProcessResponse::FinishedError)
QMessageBox::critical(nullptr, tr("Error"), tr("Failed to run keytool."));
else
diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h
index 9e7ec4a07a..2ed137ccc3 100644
--- a/src/plugins/android/androidbuildapkstep.h
+++ b/src/plugins/android/androidbuildapkstep.h
@@ -61,6 +61,9 @@ public:
bool signPackage() const;
void setSignPackage(bool b);
+ bool buildAAB() const;
+ void setBuildAAB(bool aab);
+
bool openPackageLocation() const;
void setOpenPackageLocation(bool open);
@@ -89,6 +92,7 @@ private:
void doRun() override;
+ bool m_buildAAB = false;
bool m_signPackage = false;
bool m_verbose = false;
bool m_useMinistro = false;
@@ -101,7 +105,7 @@ private:
QString m_keystorePasswd;
QString m_certificateAlias;
QString m_certificatePasswd;
- QString m_apkPath;
+ QString m_packagePath;
QString m_command;
QString m_argumentsPasswordConcealed;
diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp
index ff8441f889..ccb9454225 100644
--- a/src/plugins/android/androidbuildapkwidget.cpp
+++ b/src/plugins/android/androidbuildapkwidget.cpp
@@ -236,6 +236,13 @@ QWidget *AndroidBuildApkWidget::createAdvancedGroup()
m_step, &AndroidBuildApkStep::setUseMinistro);
auto vbox = new QVBoxLayout(group);
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(step()->target()->kit());
+ if (version && version->qtVersion() >= QtSupport::QtVersionNumber{5,14}) {
+ auto buildAAB = new QCheckBox(tr("Build .aab (Android App Bundle)"), group);
+ buildAAB->setChecked(m_step->buildAAB());
+ connect(buildAAB, &QAbstractButton::toggled, m_step, &AndroidBuildApkStep::setBuildAAB);
+ vbox->addWidget(buildAAB);
+ }
vbox->addWidget(openPackageLocationCheckBox);
vbox->addWidget(verboseOutputCheckBox);
vbox->addWidget(m_addDebuggerCheckBox);
diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp
index 292fe361da..87f2d8b60e 100644
--- a/src/plugins/android/androidconfigurations.cpp
+++ b/src/plugins/android/androidconfigurations.cpp
@@ -27,7 +27,6 @@
#include "androidconstants.h"
#include "androidtoolchain.h"
#include "androiddevice.h"
-#include "androidgdbserverkitinformation.h"
#include "androidmanager.h"
#include "androidqtversion.h"
#include "androiddevicedialog.h"
@@ -140,7 +139,7 @@ namespace {
SynchronousProcess proc;
proc.setProcessChannelMode(QProcess::MergedChannels);
proc.setTimeoutS(30);
- SynchronousProcessResponse response = proc.runBlocking(executable, QStringList(shell));
+ SynchronousProcessResponse response = proc.runBlocking({executable, {shell}});
if (response.result != SynchronousProcessResponse::Finished)
return true;
return !response.allOutput().contains("x86-64");
@@ -364,11 +363,9 @@ FilePath AndroidConfig::aaptToolPath() const
return aaptToolPath.pathAppended(toolPath);
}
-FilePath AndroidConfig::clangPath() const
+FilePath AndroidConfig::toolchainPath() const
{
- const FilePath clangPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/");
- const FilePath oldNdkClangPath = m_ndkLocation.pathAppended("toolchains/llvm-3.6/prebuilt/");
- const QVector<FilePath> clangSearchPaths{clangPath, oldNdkClangPath};
+ const FilePath toolchainPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/");
// detect toolchain host
QStringList hostPatterns;
@@ -385,18 +382,23 @@ FilePath AndroidConfig::clangPath() const
default: /* unknown host */ return FilePath();
}
- for (const FilePath &path : clangSearchPaths) {
- QDirIterator iter(path.toString(), hostPatterns, QDir::Dirs);
- if (iter.hasNext()) {
- iter.next();
- return path.pathAppended(iter.fileName())
- .pathAppended(HostOsInfo::withExecutableSuffix("bin/clang"));
- }
+ QDirIterator iter(toolchainPath.toString(), hostPatterns, QDir::Dirs);
+ if (iter.hasNext()) {
+ iter.next();
+ return toolchainPath.pathAppended(iter.fileName());
}
return {};
}
+FilePath AndroidConfig::clangPath() const
+{
+ const FilePath path = toolchainPath();
+ if (path.isEmpty())
+ return {};
+ return path.pathAppended(HostOsInfo::withExecutableSuffix("bin/clang"));
+}
+
FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const
{
const FilePath path = m_ndkLocation.pathAppended(
@@ -429,20 +431,20 @@ FilePath AndroidConfig::keytoolPath() const
QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(QString *error) const
{
- return connectedDevices(adbToolPath().toString(), error);
+ return connectedDevices(adbToolPath(), error);
}
-QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToolPath, QString *error)
+QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const FilePath &adbToolPath, QString *error)
{
QVector<AndroidDeviceInfo> devices;
SynchronousProcess adbProc;
adbProc.setTimeoutS(30);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, QStringList("devices"));
+ CommandLine cmd{adbToolPath, {"devices"}};
+ SynchronousProcessResponse response = adbProc.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished) {
if (error)
- *error = QApplication::translate("AndroidConfiguration",
- "Could not run: %1")
- .arg(adbToolPath + QLatin1String(" devices"));
+ *error = QApplication::translate("AndroidConfiguration", "Could not run: %1")
+ .arg(cmd.toUserOutput());
return devices;
}
QStringList adbDevs = response.allOutput().split('\n', QString::SkipEmptyParts);
@@ -485,7 +487,7 @@ QVector<AndroidDeviceInfo> AndroidConfig::connectedDevices(const QString &adbToo
if (devices.isEmpty() && error)
*error = QApplication::translate("AndroidConfiguration",
"No devices found in output of: %1")
- .arg(adbToolPath + QLatin1String(" devices"));
+ .arg(cmd.toUserOutput());
return devices;
}
@@ -501,33 +503,33 @@ bool AndroidConfig::isConnected(const QString &serialNumber) const
bool AndroidConfig::isBootToQt(const QString &device) const
{
- return isBootToQt(adbToolPath().toString(), device);
+ return isBootToQt(adbToolPath(), device);
}
-bool AndroidConfig::isBootToQt(const QString &adbToolPath, const QString &device)
+bool AndroidConfig::isBootToQt(const FilePath &adbToolPath, const QString &device)
{
// workaround for '????????????' serial numbers
- QStringList arguments = AndroidDeviceInfo::adbSelector(device);
- arguments << QLatin1String("shell")
- << QLatin1String("ls -l /system/bin/appcontroller || ls -l /usr/bin/appcontroller && echo Boot2Qt");
+ CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device));
+ cmd.addArg("shell");
+ cmd.addArg("ls -l /system/bin/appcontroller || ls -l /usr/bin/appcontroller && echo Boot2Qt");
SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking(cmd);
return response.result == SynchronousProcessResponse::Finished
&& response.allOutput().contains(QLatin1String("Boot2Qt"));
}
-QString AndroidConfig::getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property)
+QString AndroidConfig::getDeviceProperty(const FilePath &adbToolPath, const QString &device, const QString &property)
{
// workaround for '????????????' serial numbers
- QStringList arguments = AndroidDeviceInfo::adbSelector(device);
- arguments << QLatin1String("shell") << QLatin1String("getprop") << property;
+ CommandLine cmd(adbToolPath, AndroidDeviceInfo::adbSelector(device));
+ cmd.addArgs({"shell", "getprop", property});
SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished)
return QString();
@@ -536,12 +538,12 @@ QString AndroidConfig::getDeviceProperty(const QString &adbToolPath, const QStri
int AndroidConfig::getSDKVersion(const QString &device) const
{
- return getSDKVersion(adbToolPath().toString(), device);
+ return getSDKVersion(adbToolPath(), device);
}
-int AndroidConfig::getSDKVersion(const QString &adbToolPath, const QString &device)
+int AndroidConfig::getSDKVersion(const FilePath &adbToolPath, const QString &device)
{
- QString tmp = getDeviceProperty(adbToolPath, device, QLatin1String("ro.build.version.sdk"));
+ QString tmp = getDeviceProperty(adbToolPath, device, "ro.build.version.sdk");
if (tmp.isEmpty())
return -1;
return tmp.trimmed().toInt();
@@ -612,7 +614,7 @@ QString AndroidConfig::getProductModel(const QString &device) const
if (m_serialNumberToDeviceName.contains(device))
return m_serialNumberToDeviceName.value(device);
- QString model = getDeviceProperty(adbToolPath().toString(), device, QLatin1String("ro.product.model")).trimmed();
+ QString model = getDeviceProperty(adbToolPath(), device, "ro.product.model").trimmed();
if (model.isEmpty())
return device;
@@ -623,18 +625,18 @@ QString AndroidConfig::getProductModel(const QString &device) const
QStringList AndroidConfig::getAbis(const QString &device) const
{
- return getAbis(adbToolPath().toString(), device);
+ return getAbis(adbToolPath(), device);
}
-QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &device)
+QStringList AndroidConfig::getAbis(const FilePath &adbToolPath, const QString &device)
{
QStringList result;
// First try via ro.product.cpu.abilist
QStringList arguments = AndroidDeviceInfo::adbSelector(device);
- arguments << QLatin1String("shell") << QLatin1String("getprop") << QLatin1String("ro.product.cpu.abilist");
+ arguments << "shell" << "getprop" << "ro.product.cpu.abilist";
SynchronousProcess adbProc;
adbProc.setTimeoutS(10);
- SynchronousProcessResponse response = adbProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse response = adbProc.runBlocking({adbToolPath, arguments});
if (response.result != SynchronousProcessResponse::Finished)
return result;
@@ -656,7 +658,7 @@ QStringList AndroidConfig::getAbis(const QString &adbToolPath, const QString &de
SynchronousProcess abiProc;
abiProc.setTimeoutS(10);
- SynchronousProcessResponse abiResponse = abiProc.runBlocking(adbToolPath, arguments);
+ SynchronousProcessResponse abiResponse = abiProc.runBlocking({adbToolPath, arguments});
if (abiResponse.result != SynchronousProcessResponse::Finished)
return result;
@@ -733,22 +735,26 @@ FilePath AndroidConfig::ndkLocation() const
return m_ndkLocation;
}
-static inline QString gdbServerArch(const Abi &abi)
+static inline QString gdbServerArch(const QString &androidAbi)
{
- switch (abi.architecture()) {
- case Abi::X86Architecture:
- return abi.wordWidth() == 64 ? QString{"x86_64"} : QString{"x86"};
- case Abi::ArmArchitecture:
- return abi.wordWidth() == 64 ? QString{"arm64"} : QString{"arm"};
- default: return {};
- };
+ if (androidAbi == "arm64-v8a") {
+ return QString("arm64");
+ } else if (androidAbi == "armeabi-v7a") {
+ return QString("arm");
+ } else if (androidAbi == "x86_64") {
+ return QString("x86_64");
+ } else if (androidAbi == "x86") {
+ return QString("x86");
+ } else {
+ return {};
+ }
}
-FilePath AndroidConfig::gdbServer(const ProjectExplorer::Abi &abi) const
+FilePath AndroidConfig::gdbServer(const QString &androidAbi) const
{
const FilePath path = AndroidConfigurations::currentConfig().ndkLocation()
.pathAppended(QString("prebuilt/android-%1/gdbserver/gdbserver")
- .arg(gdbServerArch(abi)));
+ .arg(gdbServerArch(androidAbi)));
if (path.exists())
return path;
return {};
@@ -875,16 +881,21 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
}
AndroidDeviceInfo AndroidConfigurations::showDeviceDialog(Project *project,
- int apiLevel, const QString &abi)
+ int apiLevel, const QStringList &abis)
{
- QString serialNumber = defaultDevice(project, abi);
- AndroidDeviceDialog dialog(apiLevel, abi, serialNumber, Core::ICore::mainWindow());
+ QString serialNumber;
+ for (const QString &abi : abis) {
+ serialNumber = defaultDevice(project, abi);
+ if (!serialNumber.isEmpty())
+ break;
+ }
+ AndroidDeviceDialog dialog(apiLevel, abis, serialNumber, Core::ICore::mainWindow());
AndroidDeviceInfo info = dialog.device();
if (dialog.saveDeviceSelection() && info.isValid()) {
const QString serialNumber = info.type == AndroidDeviceInfo::Hardware ?
info.serialNumber : info.avdname;
if (!serialNumber.isEmpty())
- AndroidConfigurations::setDefaultDevice(project, abi, serialNumber);
+ AndroidConfigurations::setDefaultDevice(project, AndroidManager::devicePreferredAbi(info.cpuAbi, abis), serialNumber);
}
return info;
}
@@ -918,7 +929,7 @@ static bool matchToolChain(const ToolChain *atc, const ToolChain *btc)
if (!atc || !btc)
return false;
- if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_ID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
+ if (atc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID || btc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID)
return false;
auto aatc = static_cast<const AndroidToolChain *>(atc);
@@ -930,7 +941,7 @@ void AndroidConfigurations::registerNewToolChains()
{
const QList<ToolChain *> existingAndroidToolChains
= ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId,
- Core::Id(Constants::ANDROID_TOOLCHAIN_ID)));
+ Core::Id(Constants::ANDROID_TOOLCHAIN_TYPEID)));
const QList<ToolChain *> newToolchains
= AndroidToolChainFactory::autodetectToolChainsForNdk(existingAndroidToolChains);
foreach (ToolChain *tc, newToolchains)
@@ -939,7 +950,7 @@ void AndroidConfigurations::registerNewToolChains()
void AndroidConfigurations::removeOldToolChains()
{
- foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_ID)))) {
+ foreach (ToolChain *tc, ToolChainManager::toolChains(Utils::equal(&ToolChain::typeId, Core::Id(Constants::ANDROID_TOOLCHAIN_TYPEID)))) {
if (!tc->isValid())
ToolChainManager::deregisterToolChain(tc);
}
@@ -947,7 +958,7 @@ void AndroidConfigurations::removeOldToolChains()
static QVariant findOrRegisterDebugger(ToolChain *tc)
{
- const FilePath command = tc->suggestedDebugger();
+ const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi());
// check if the debugger is already registered, but ignoring the display name
const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command);
if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected()
@@ -955,7 +966,7 @@ static QVariant findOrRegisterDebugger(ToolChain *tc)
return existing->id();
// debugger not found, register a new one
Debugger::DebuggerItem debugger;
- debugger.setCommand(tc->suggestedDebugger());
+ debugger.setCommand(command);
debugger.setEngineType(Debugger::GdbEngineType);
debugger.setUnexpandedDisplayName(
AndroidConfigurations::tr("Android Debugger for %1").arg(tc->displayName()));
@@ -1016,7 +1027,7 @@ void AndroidConfigurations::updateAutomaticKitList()
const QList<ToolChain *> toolchains = ToolChainManager::toolChains([](const ToolChain *tc) {
return tc->isAutoDetected()
&& tc->isValid()
- && tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID;
+ && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID;
});
for (ToolChain *tc : toolchains) {
if (tc->language() != Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID))
@@ -1049,10 +1060,9 @@ void AndroidConfigurations::updateAutomaticKitList()
QtSupport::QtKitAspect::setQtVersion(k, qt);
DeviceKitAspect::setDevice(k, device);
Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc));
- AndroidGdbServerKitAspect::setGdbSever(k, currentConfig().gdbServer(tc->targetAbi()));
k->makeSticky();
k->setUnexpandedDisplayName(tr("Android for %1 (Clang %2)")
- .arg(static_cast<const AndroidQtVersion *>(qt)->targetArch())
+ .arg(static_cast<const AndroidQtVersion *>(qt)->androidAbis().join(","))
.arg(qt->displayName()));
k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString());
k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString());
@@ -1187,7 +1197,8 @@ void AndroidConfigurations::load()
SynchronousProcess proc;
proc.setTimeoutS(2);
proc.setProcessChannelMode(QProcess::MergedChannels);
- SynchronousProcessResponse response = proc.runBlocking(javaHomeExec.absoluteFilePath(), QStringList());
+ SynchronousProcessResponse response =
+ proc.runBlocking({javaHomeExec.absoluteFilePath(), {}});
if (response.result == SynchronousProcessResponse::Finished) {
const QString &javaHome = response.allOutput().trimmed();
if (!javaHome.isEmpty() && QFileInfo::exists(javaHome))
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index 3b9ecb4bb1..aba533fc27 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -105,7 +105,7 @@ public:
void setSdkManagerToolArgs(const QStringList &args);
Utils::FilePath ndkLocation() const;
- Utils::FilePath gdbServer(const ProjectExplorer::Abi &abi) const;
+ Utils::FilePath gdbServer(const QString &androidAbi) const;
QVersionNumber ndkVersion() const;
void setNdkLocation(const Utils::FilePath &ndkLocation);
@@ -132,14 +132,16 @@ public:
Utils::FilePath avdManagerToolPath() const;
Utils::FilePath aaptToolPath() const;
+ Utils::FilePath toolchainPath() const;
Utils::FilePath clangPath() const;
+
Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi) const;
Utils::FilePath makePath() const;
Utils::FilePath keytoolPath() const;
QVector<AndroidDeviceInfo> connectedDevices(QString *error = nullptr) const;
- static QVector<AndroidDeviceInfo> connectedDevices(const QString &adbToolPath, QString *error = nullptr);
+ static QVector<AndroidDeviceInfo> connectedDevices(const Utils::FilePath &adbToolPath, QString *error = nullptr);
QString bestNdkPlatformMatch(int target) const;
@@ -156,14 +158,15 @@ public:
bool useNativeUiTools() const;
private:
- static QString getDeviceProperty(const QString &adbToolPath, const QString &device, const QString &property);
+ static QString getDeviceProperty(const Utils::FilePath &adbToolPath,
+ const QString &device, const QString &property);
Utils::FilePath openJDKBinPath() const;
int getSDKVersion(const QString &device) const;
- static int getSDKVersion(const QString &adbToolPath, const QString &device);
+ static int getSDKVersion(const Utils::FilePath &adbToolPath, const QString &device);
QStringList getAbis(const QString &device) const;
- static QStringList getAbis(const QString &adbToolPath, const QString &device);
- static bool isBootToQt(const QString &adbToolPath, const QString &device);
+ static QStringList getAbis(const Utils::FilePath &adbToolPath, const QString &device);
+ static bool isBootToQt(const Utils::FilePath &adbToolPath, const QString &device);
bool isBootToQt(const QString &device) const;
static QString getAvdName(const QString &serialnumber);
@@ -195,7 +198,7 @@ public:
static void setConfig(const AndroidConfig &config);
static AndroidConfigurations *instance();
- static AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi);
+ static AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QStringList &abis);
static void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name
static QString defaultDevice(ProjectExplorer::Project *project, const QString &abi); // serial number or avd name
static void clearDefaultDevices(ProjectExplorer::Project *project);
diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h
index f34da07f4e..b617087787 100644
--- a/src/plugins/android/androidconstants.h
+++ b/src/plugins/android/androidconstants.h
@@ -30,14 +30,6 @@
namespace Android {
namespace Internal {
-enum AndroidQemuStatus {
- AndroidQemuStarting,
- AndroidQemuFailedToStart,
- AndroidQemuFinished,
- AndroidQemuCrashed,
- AndroidQemuUserReason
-};
-
#ifdef Q_OS_WIN32
#define ANDROID_BAT_SUFFIX ".bat"
#else
@@ -48,7 +40,7 @@ enum AndroidQemuStatus {
namespace Constants {
const char ANDROID_SETTINGS_ID[] = "BB.Android Configurations";
-const char ANDROID_TOOLCHAIN_ID[] = "Qt4ProjectManager.ToolChain.Android";
+const char ANDROID_TOOLCHAIN_TYPEID[] = "Qt4ProjectManager.ToolChain.Android";
const char ANDROIDQT[] = "Qt4ProjectManager.QtVersion.Android";
const char ANDROID_AMSTARTARGS[] = "Android.AmStartArgs";
@@ -90,7 +82,7 @@ const char AndroidManifest[] = "Android.Manifest"; // QStringList
const char AndroidNdkPlatform[] = "AndroidNdkPlatform"; //QString
const char NdkLocation[] = "NdkLocation"; // FileName
-const char AndroidABI[] = "AndroidABI"; // QString
+const char AndroidABIs[] = "AndroidABIs"; // QString
} // namespace Constants;
} // namespace Android
diff --git a/src/plugins/android/androidcreatekeystorecertificate.cpp b/src/plugins/android/androidcreatekeystorecertificate.cpp
index 1ac6e1ea12..3ff0a02de8 100644
--- a/src/plugins/android/androidcreatekeystorecertificate.cpp
+++ b/src/plugins/android/androidcreatekeystorecertificate.cpp
@@ -32,6 +32,8 @@
#include <QFileDialog>
#include <QMessageBox>
+using namespace Utils;
+
using namespace Android::Internal;
AndroidCreateKeystoreCertificate::AndroidCreateKeystoreCertificate(QWidget *parent) :
@@ -169,24 +171,23 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted()
if (ui->stateNameLineEdit->text().length())
distinguishedNames += QLatin1String(", S=") + ui->stateNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"));
- const QString command = AndroidConfigurations::currentConfig().keytoolPath().toString();
- QStringList params;
- params << QLatin1String("-genkey") << QLatin1String("-keyalg") << QLatin1String("RSA")
- << QLatin1String("-keystore") << m_keystoreFilePath.toString()
- << QLatin1String("-storepass") << keystorePassword()
- << QLatin1String("-alias") << certificateAlias()
- << QLatin1String("-keysize") << ui->keySizeSpinBox->text()
- << QLatin1String("-validity") << ui->validitySpinBox->text()
- << QLatin1String("-keypass") << certificatePassword()
- << QLatin1String("-dname") << distinguishedNames;
-
- Utils::SynchronousProcess genKeyCertProc;
+ const CommandLine command(AndroidConfigurations::currentConfig().keytoolPath(),
+ { "-genkey", "-keyalg", "RSA",
+ "-keystore", m_keystoreFilePath.toString(),
+ "-storepass", keystorePassword(),
+ "-alias", certificateAlias(),
+ "-keysize", ui->keySizeSpinBox->text(),
+ "-validity", ui->validitySpinBox->text(),
+ "-keypass", certificatePassword(),
+ "-dname", distinguishedNames});
+
+ SynchronousProcess genKeyCertProc;
genKeyCertProc.setTimeoutS(15);
- Utils::SynchronousProcessResponse response = genKeyCertProc.run(command, params);
+ SynchronousProcessResponse response = genKeyCertProc.run(command);
if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0) {
QMessageBox::critical(this, tr("Error"),
- response.exitMessage(command, 15) + QLatin1Char('\n') + response.allOutput());
+ response.exitMessage(command.executable().toString(), 15) + '\n' + response.allOutput());
return;
}
accept();
diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp
index 539666dc71..0481df89b2 100644
--- a/src/plugins/android/androiddebugsupport.cpp
+++ b/src/plugins/android/androiddebugsupport.cpp
@@ -60,31 +60,6 @@ using namespace ProjectExplorer;
namespace Android {
namespace Internal {
-static const char * const qMakeVariables[] = {
- "QT_INSTALL_LIBS",
- "QT_INSTALL_PLUGINS",
- "QT_INSTALL_QML"
-};
-
-static QStringList qtSoPaths(QtSupport::BaseQtVersion *qtVersion)
-{
- if (!qtVersion)
- return QStringList();
-
- QSet<QString> paths;
- for (uint i = 0; i < sizeof qMakeVariables / sizeof qMakeVariables[0]; ++i) {
- QString path = qtVersion->qmakeProperty(qMakeVariables[i]);
- if (path.isNull())
- continue;
- QDirIterator it(path, QStringList("*.so"), QDir::Files, QDirIterator::Subdirectories);
- while (it.hasNext()) {
- it.next();
- paths.insert(it.fileInfo().absolutePath());
- }
- }
- return Utils::toList(paths);
-}
-
static QStringList uniquePaths(const QStringList &files)
{
QSet<QString> paths;
@@ -127,15 +102,6 @@ static QStringList getExtraLibs(const ProjectNode *node)
return node->data(Android::Constants::AndroidExtraLibs).toStringList();
}
-static QString toNdkArch(const QString &arch)
-{
- if (arch == QLatin1String("armeabi-v7a") || arch == QLatin1String("armeabi"))
- return QLatin1String("arch-arm");
- if (arch == QLatin1String("arm64-v8a"))
- return QLatin1String("arch-arm64");
- return QLatin1String("arch-") + arch;
-}
-
AndroidDebugSupport::AndroidDebugSupport(RunControl *runControl, const QString &intentName)
: Debugger::DebuggerRunTool(runControl)
{
@@ -170,16 +136,18 @@ void AndroidDebugSupport::start()
const ProjectNode *node = target->project()->findNodeForBuildKey(runControl()->buildKey());
QStringList solibSearchPath = getSoLibSearchPath(node);
QStringList extraLibs = getExtraLibs(node);
- solibSearchPath.append(qtSoPaths(qtVersion));
+ if (qtVersion)
+ solibSearchPath.append(qtVersion->qtSoPaths());
solibSearchPath.append(uniquePaths(extraLibs));
solibSearchPath.append(target->activeBuildConfiguration()->buildDirectory().toString());
solibSearchPath.removeDuplicates();
setSolibSearchPath(solibSearchPath);
qCDebug(androidDebugSupportLog) << "SoLibSearchPath: "<<solibSearchPath;
- setSymbolFile(target->activeBuildConfiguration()->buildDirectory().toString()
- + "/app_process");
+ setSymbolFile(target->activeBuildConfiguration()->buildDirectory().pathAppended("app_process"));
setSkipExecutableValidation(true);
setUseExtendedRemote(true);
+ QString devicePreferredAbi = AndroidManager::devicePreferredAbi(target);
+ setAbi(AndroidManager::androidAbi2Abi(devicePreferredAbi));
QUrl gdbServer;
gdbServer.setHost(QHostAddress(QHostAddress::LocalHost).toString());
gdbServer.setPort(m_runner->gdbServerPort().number());
@@ -190,10 +158,13 @@ void AndroidDebugSupport::start()
const int minimumNdk = qt ? qt->minimumNDK() : 0;
int sdkVersion = qMax(AndroidManager::minimumSDK(kit), minimumNdk);
+ // TODO find a way to use the new sysroot layout
+ // instead ~/android/ndk-bundle/platforms/android-29/arch-arm64
+ // use ~/android/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot
Utils::FilePath sysRoot = AndroidConfigurations::currentConfig().ndkLocation()
.pathAppended("platforms")
.pathAppended(QString("android-%1").arg(sdkVersion))
- .pathAppended(toNdkArch(AndroidManager::targetArch(target)));
+ .pathAppended(devicePreferredAbi);
setSysRoot(sysRoot);
qCDebug(androidDebugSupportLog) << "Sysroot: " << sysRoot;
}
diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp
index 42a3c7d6e0..ab9a0745a6 100644
--- a/src/plugins/android/androiddeployqtstep.cpp
+++ b/src/plugins/android/androiddeployqtstep.cpp
@@ -110,9 +110,6 @@ public:
auto resetDefaultDevices = new QPushButton(this);
resetDefaultDevices->setText(AndroidDeployQtStep::tr("Reset Default Devices"));
- auto cleanLibsPushButton = new QPushButton(this);
- cleanLibsPushButton->setText(AndroidDeployQtStep::tr("Clean Temporary Libraries Directory on Device"));
-
auto installMinistroButton = new QPushButton(this);
installMinistroButton->setText(AndroidDeployQtStep::tr("Install Ministro from APK"));
@@ -126,10 +123,6 @@ public:
AndroidManager::installQASIPackage(step->target(), packagePath);
});
- connect(cleanLibsPushButton, &QAbstractButton::clicked, this, [step] {
- AndroidManager::cleanLibsOnDevice(step->target());
- });
-
connect(resetDefaultDevices, &QAbstractButton::clicked, this, [step] {
AndroidConfigurations::clearDefaultDevices(step->project());
});
@@ -140,7 +133,6 @@ public:
auto layout = new QVBoxLayout(this);
layout->addWidget(uninstallPreviousPackage);
layout->addWidget(resetDefaultDevices);
- layout->addWidget(cleanLibsPushButton);
layout->addWidget(installMinistroButton);
}
};
@@ -173,8 +165,8 @@ bool AndroidDeployQtStep::init()
{
m_androiddeployqtArgs = CommandLine();
- m_targetArch = AndroidManager::targetArch(target());
- if (m_targetArch.isEmpty()) {
+ m_androidABIs = AndroidManager::applicationAbis(target());
+ if (m_androidABIs.isEmpty()) {
emit addOutput(tr("No Android arch set by the .pro file."), OutputFormat::Stderr);
return false;
}
@@ -189,11 +181,11 @@ bool AndroidDeployQtStep::init()
auto androidBuildApkStep = AndroidBuildApkStep::findInBuild(bc);
int minTargetApi = AndroidManager::minimumSDK(target());
- qCDebug(deployStepLog) << "Target architecture:" << m_targetArch
+ qCDebug(deployStepLog) << "Target architecture:" << m_androidABIs
<< "Min target API" << minTargetApi;
// Try to re-use user-provided information from an earlier step of the same type.
- auto bsl = qobject_cast<BuildStepList *>(parent());
+ BuildStepList *bsl = stepList();
QTC_ASSERT(bsl, return false);
auto androidDeployQtStep = bsl->firstOfType<AndroidDeployQtStep>();
QTC_ASSERT(androidDeployQtStep, return false);
@@ -202,7 +194,7 @@ bool AndroidDeployQtStep::init()
info = androidDeployQtStep->m_deviceInfo;
if (!info.isValid()) {
- info = AndroidConfigurations::showDeviceDialog(project(), minTargetApi, m_targetArch);
+ info = AndroidConfigurations::showDeviceDialog(project(), minTargetApi, m_androidABIs);
m_deviceInfo = info; // Keep around for later steps
}
@@ -218,6 +210,7 @@ bool AndroidDeployQtStep::init()
AndroidManager::setDeviceSerialNumber(target(), m_serialNumber);
AndroidManager::setDeviceApiLevel(target(), info.sdk);
+ AndroidManager::setDeviceAbis(target(), info.cpuAbi);
emit addOutput(tr("Deploying to %1").arg(m_serialNumber), OutputFormat::Stdout);
@@ -297,9 +290,9 @@ bool AndroidDeployQtStep::init()
AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy()
{
- CommandLine cmd(m_command, {});
+ CommandLine cmd(m_command);
if (m_useAndroiddeployqt && m_apkPath.isEmpty()) {
- cmd.addArgs(m_androiddeployqtArgs.arguments());
+ cmd.addArgs(m_androiddeployqtArgs.arguments(), CommandLine::Raw);
if (m_uninstallPreviousPackageRun)
cmd.addArg("--install");
else
@@ -345,9 +338,9 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy()
}
qCDebug(deployStepLog) << "Uninstalling previous package";
emit addOutput(tr("Uninstall previous package %1.").arg(packageName), OutputFormat::NormalMessage);
- runCommand(m_adbPath.toString(),
+ runCommand({m_adbPath,
AndroidDeviceInfo::adbSelector(m_serialNumber)
- << QLatin1String("uninstall") << packageName);
+ << "uninstall" << packageName});
}
cmd.addArgs(AndroidDeviceInfo::adbSelector(m_serialNumber));
@@ -489,9 +482,9 @@ bool AndroidDeployQtStep::runImpl()
for (auto itr = m_filesToPull.constBegin(); itr != m_filesToPull.constEnd(); ++itr) {
QFile::remove(itr.value());
- runCommand(m_adbPath.toString(),
+ runCommand({m_adbPath,
AndroidDeviceInfo::adbSelector(m_serialNumber)
- << "pull" << itr.key() << itr.value());
+ << "pull" << itr.key() << itr.value()});
if (!QFileInfo::exists(itr.value())) {
emit addOutput(tr("Package deploy: Failed to pull \"%1\" to \"%2\".")
.arg(itr.key())
@@ -516,17 +509,11 @@ void AndroidDeployQtStep::gatherFilesToPull()
QString linkerName("linker");
QString libDirName("lib");
- if (m_deviceInfo.cpuAbi.contains(QLatin1String("arm64-v8a")) ||
- m_deviceInfo.cpuAbi.contains(QLatin1String("x86_64"))) {
- const Core::Id cxxLanguageId = ProjectExplorer::Constants::CXX_LANGUAGE_ID;
- ToolChain *tc = ToolChainKitAspect::toolChain(target()->kit(), cxxLanguageId);
- if (tc && tc->targetAbi().wordWidth() == 64) {
- m_filesToPull["/system/bin/app_process64"] = buildDir + "app_process";
- libDirName = "lib64";
- linkerName = "linker64";
- } else {
- m_filesToPull["/system/bin/app_process32"] = buildDir + "app_process";
- }
+ auto preferreABI = AndroidManager::devicePreferredAbi(target());
+ if (preferreABI == "arm64-v8a" || preferreABI == "x86_64") {
+ m_filesToPull["/system/bin/app_process64"] = buildDir + "app_process";
+ libDirName = "lib64";
+ linkerName = "linker64";
} else {
m_filesToPull["/system/bin/app_process32"] = buildDir + "app_process";
m_filesToPull["/system/bin/app_process"] = buildDir + "app_process";
@@ -545,14 +532,16 @@ void AndroidDeployQtStep::doRun()
runInThread([this] { return runImpl(); });
}
-void AndroidDeployQtStep::runCommand(const QString &program, const QStringList &arguments)
+void AndroidDeployQtStep::runCommand(const CommandLine &command)
{
- Utils::SynchronousProcess buildProc;
+ SynchronousProcess buildProc;
buildProc.setTimeoutS(2 * 60);
- emit addOutput(tr("Package deploy: Running command \"%1 %2\".").arg(program).arg(arguments.join(QLatin1Char(' '))), BuildStep::OutputFormat::NormalMessage);
- Utils::SynchronousProcessResponse response = buildProc.run(program, arguments);
- if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0)
- emit addOutput(response.exitMessage(program, 2 * 60), BuildStep::OutputFormat::ErrorMessage);
+ emit addOutput(tr("Package deploy: Running command \"%1\".").arg(command.toUserOutput()),
+ OutputFormat::NormalMessage);
+ SynchronousProcessResponse response = buildProc.run(command);
+ if (response.result != SynchronousProcessResponse::Finished || response.exitCode != 0)
+ emit addOutput(response.exitMessage(command.executable().toString(), 2 * 60),
+ OutputFormat::ErrorMessage);
}
ProjectExplorer::BuildStepConfigWidget *AndroidDeployQtStep::createConfigWidget()
diff --git a/src/plugins/android/androiddeployqtstep.h b/src/plugins/android/androiddeployqtstep.h
index 48faf2abf5..6b0091d2ad 100644
--- a/src/plugins/android/androiddeployqtstep.h
+++ b/src/plugins/android/androiddeployqtstep.h
@@ -80,7 +80,7 @@ signals:
void setSerialNumber(const QString &serialNumber);
private:
- void runCommand(const QString &program, const QStringList &arguments);
+ void runCommand(const Utils::CommandLine &command);
bool init() override;
void doRun() override;
@@ -111,7 +111,7 @@ private:
Utils::FilePath m_apkPath;
QMap<QString, QString> m_filesToPull;
- QString m_targetArch;
+ QStringList m_androidABIs;
bool m_uninstallPreviousPackage = false;
bool m_uninstallPreviousPackageRun = false;
bool m_useAndroiddeployqt = false;
diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp
index 3803ac5073..9b9e4d9c13 100644
--- a/src/plugins/android/androiddevice.cpp
+++ b/src/plugins/android/androiddevice.cpp
@@ -49,8 +49,12 @@ AndroidDevice::AndroidDevice()
{
setupId(IDevice::AutoDetected, Constants::ANDROID_DEVICE_ID);
setType(Constants::ANDROID_DEVICE_TYPE);
- setDisplayName(QCoreApplication::translate("Android::Internal::AndroidDevice", "Run on Android"));
+ setDefaultDisplayName(QCoreApplication::translate("Android::Internal::AndroidDevice",
+ "Run on Android"));
+ setDisplayType(QCoreApplication::translate("Android::Internal::AndroidDevice", "Android"));
setMachineType(IDevice::Hardware);
+ setOsType(Utils::OsTypeOtherUnix);
+
setDeviceState(DeviceReadyToUse);
QString activityPath;
const AndroidConfig &config = AndroidConfigurations::currentConfig();
@@ -65,11 +69,6 @@ IDevice::DeviceInfo AndroidDevice::deviceInformation() const
return IDevice::DeviceInfo();
}
-QString AndroidDevice::displayType() const
-{
- return QCoreApplication::translate("Android::Internal::AndroidDevice", "Android");
-}
-
IDeviceWidget *AndroidDevice::createWidget()
{
return nullptr;
@@ -85,11 +84,6 @@ DeviceProcessSignalOperation::Ptr AndroidDevice::signalOperation() const
return DeviceProcessSignalOperation::Ptr(new AndroidSignalOperation());
}
-Utils::OsType AndroidDevice::osType() const
-{
- return Utils::OsTypeOtherUnix;
-}
-
QUrl AndroidDevice::toolControlChannel(const ControlChannelHint &) const
{
QUrl url;
diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h
index 7a66e1d15c..33ea84cf50 100644
--- a/src/plugins/android/androiddevice.h
+++ b/src/plugins/android/androiddevice.h
@@ -34,18 +34,16 @@ namespace Internal {
class AndroidDevice : public ProjectExplorer::IDevice
{
public:
- static IDevice::Ptr create() { return IDevice::Ptr(new AndroidDevice); };
+ static IDevice::Ptr create() { return IDevice::Ptr(new AndroidDevice); }
private:
AndroidDevice();
ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override;
- QString displayType() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
bool canAutoDetectPorts() const override;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
- Utils::OsType osType() const override;
QUrl toolControlChannel(const ControlChannelHint &) const override;
};
diff --git a/src/plugins/android/androiddevicedialog.cpp b/src/plugins/android/androiddevicedialog.cpp
index a0b786ad69..cd8ae2f611 100644
--- a/src/plugins/android/androiddevicedialog.cpp
+++ b/src/plugins/android/androiddevicedialog.cpp
@@ -236,7 +236,7 @@ class AndroidDeviceModel : public QAbstractItemModel
{
Q_OBJECT
public:
- AndroidDeviceModel(int apiLevel, const QString &abi);
+ AndroidDeviceModel(int apiLevel, const QStringList &abis);
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
@@ -251,7 +251,7 @@ public:
QModelIndex indexFor(AndroidDeviceInfo::AndroidDeviceType type, const QString &serial);
private:
int m_apiLevel;
- QString m_abi;
+ QStringList m_abis;
AndroidDeviceModelNode *m_root;
};
@@ -260,8 +260,8 @@ private:
/////////////////
// AndroidDeviceModel
/////////////////
-AndroidDeviceModel::AndroidDeviceModel(int apiLevel, const QString &abi)
- : m_apiLevel(apiLevel), m_abi(abi), m_root(nullptr)
+AndroidDeviceModel::AndroidDeviceModel(int apiLevel, const QStringList &abis)
+ : m_apiLevel(apiLevel), m_abis(abis), m_root(nullptr)
{
}
@@ -316,7 +316,7 @@ int AndroidDeviceModel::rowCount(const QModelIndex &parent) const
int AndroidDeviceModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 1;
}
@@ -364,7 +364,7 @@ void AndroidDeviceModel::setDevices(const QVector<AndroidDeviceInfo> &devices)
}else if (device.state == AndroidDeviceInfo::OfflineState) {
error = AndroidDeviceDialog::tr("Offline. Please check the state of your device %1.")
.arg(device.serialNumber);
- } else if (!device.cpuAbi.contains(m_abi)) {
+ } else if (!AndroidManager::matchedAbis(device.cpuAbi, m_abis)) {
error = AndroidDeviceDialog::tr("ABI is incompatible, device supports ABIs: %1.")
.arg(device.cpuAbi.join(QLatin1Char(' ')));
} else if (device.sdk < m_apiLevel) {
@@ -413,13 +413,13 @@ static inline QString msgAdbListDevices()
return AndroidDeviceDialog::tr("<p>The adb tool in the Android SDK lists all connected devices if run via &quot;adb devices&quot;.</p>");
}
-AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi,
+AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QStringList &abis,
const QString &serialNumber, QWidget *parent) :
QDialog(parent),
- m_model(new AndroidDeviceModel(apiLevel, abi)),
+ m_model(new AndroidDeviceModel(apiLevel, abis)),
m_ui(new Ui::AndroidDeviceDialog),
m_apiLevel(apiLevel),
- m_abi(abi),
+ m_abis(abis),
m_defaultDevice(serialNumber),
m_avdManager(new AndroidAvdManager)
{
@@ -431,7 +431,7 @@ AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi,
m_ui->deviceView->setUniformRowHeights(true);
m_ui->deviceView->setExpandsOnDoubleClick(false);
- m_ui->defaultDeviceCheckBox->setText(tr("Always use this device for architecture %1 for this project").arg(abi));
+ m_ui->defaultDeviceCheckBox->setText(tr("Always use this device for this project"));
m_ui->noDeviceFoundLabel->setText(QLatin1String("<p align=\"center\"><span style=\" font-size:16pt;\">")
+ tr("No Device Found") + QLatin1String("</span></p><br/>")
@@ -473,7 +473,7 @@ AndroidDeviceDialog::AndroidDeviceDialog(int apiLevel, const QString &abi,
connect(m_ui->lookingForDeviceCancel, &QPushButton::clicked,
this, &AndroidDeviceDialog::defaultDeviceClear);
- m_connectedDevices = AndroidConfig::connectedDevices(AndroidConfigurations::currentConfig().adbToolPath().toString());
+ m_connectedDevices = AndroidConfig::connectedDevices(AndroidConfigurations::currentConfig().adbToolPath());
}
AndroidDeviceDialog::~AndroidDeviceDialog()
@@ -512,7 +512,7 @@ void AndroidDeviceDialog::refreshDeviceList()
{
m_ui->refreshDevicesButton->setEnabled(false);
m_progressIndicator->show();
- m_connectedDevices = AndroidConfig::connectedDevices(AndroidConfigurations::currentConfig().adbToolPath().toString());
+ m_connectedDevices = AndroidConfig::connectedDevices(AndroidConfigurations::currentConfig().adbToolPath());
m_futureWatcherRefreshDevices.setFuture(m_avdManager->avdList());
}
@@ -578,7 +578,7 @@ void AndroidDeviceDialog::createAvd()
{
m_ui->createAVDButton->setEnabled(false);
CreateAvdInfo info = AvdDialog::gatherCreateAVDInfo(this, AndroidConfigurations::sdkManager(),
- m_apiLevel, m_abi);
+ m_apiLevel, m_abis);
if (!info.isValid()) {
m_ui->createAVDButton->setEnabled(true);
diff --git a/src/plugins/android/androiddevicedialog.h b/src/plugins/android/androiddevicedialog.h
index e366b18075..26011303c3 100644
--- a/src/plugins/android/androiddevicedialog.h
+++ b/src/plugins/android/androiddevicedialog.h
@@ -52,7 +52,7 @@ class AndroidDeviceDialog : public QDialog
Q_OBJECT
public:
- explicit AndroidDeviceDialog(int apiLevel, const QString &abi,
+ explicit AndroidDeviceDialog(int apiLevel, const QStringList &abis,
const QString &serialNumber, QWidget *parent = nullptr);
~AndroidDeviceDialog() override;
@@ -74,7 +74,7 @@ private:
Ui::AndroidDeviceDialog *m_ui;
Utils::ProgressIndicator *m_progressIndicator;
int m_apiLevel;
- QString m_abi;
+ QStringList m_abis;
QString m_avdNameFromAdd;
QString m_defaultDevice;
std::unique_ptr<AndroidAvdManager> m_avdManager;
diff --git a/src/plugins/android/androiderrormessage.cpp b/src/plugins/android/androiderrormessage.cpp
index 5d87c5ba73..f3d6fbf122 100644
--- a/src/plugins/android/androiderrormessage.cpp
+++ b/src/plugins/android/androiderrormessage.cpp
@@ -32,7 +32,7 @@ namespace Internal {
QString AndroidErrorMessage::getMessage(ErrorCode errorCode, const QVariantList &parameters)
{
- Q_UNUSED(parameters);
+ Q_UNUSED(parameters)
switch (errorCode) {
case SDKInstallationError:
return tr("Android: SDK installation error 0x%1").arg(errorCode, 0, 16);
diff --git a/src/plugins/android/androidextralibrarylistmodel.cpp b/src/plugins/android/androidextralibrarylistmodel.cpp
index b6309aa9c1..0890cbefb3 100644
--- a/src/plugins/android/androidextralibrarylistmodel.cpp
+++ b/src/plugins/android/androidextralibrarylistmodel.cpp
@@ -76,11 +76,9 @@ int AndroidExtraLibraryListModel::columnCount(const QModelIndex &) const
QVariant AndroidExtraLibraryListModel::data(const QModelIndex &index, int role) const
{
Q_ASSERT(index.row() >= 0 && index.row() < m_entries.size());
- const QString &entry = QDir::cleanPath(m_entries.at(index.row()));
- switch (role) {
- case Qt::DisplayRole: return entry;
- default: return QVariant();
- };
+ if (role == Qt::DisplayRole)
+ return QDir::cleanPath(m_entries.at(index.row()));
+ return {};
}
void AndroidExtraLibraryListModel::updateModel()
diff --git a/src/plugins/android/androidgdbserverkitinformation.cpp b/src/plugins/android/androidgdbserverkitinformation.cpp
deleted file mode 100644
index fdc5946c80..0000000000
--- a/src/plugins/android/androidgdbserverkitinformation.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "androidgdbserverkitinformation.h"
-#include "androidconstants.h"
-#include "androidtoolchain.h"
-
-#include <utils/pathchooser.h>
-#include <utils/elidinglabel.h>
-#include <utils/qtcassert.h>
-
-#include <QDialogButtonBox>
-#include <QLabel>
-#include <QPushButton>
-#include <QMenu>
-#include <QDialog>
-#include <QVBoxLayout>
-#include <QFormLayout>
-
-#include <projectexplorer/projectexplorerconstants.h>
-
-#include <qtsupport/baseqtversion.h>
-#include <qtsupport/qtkitinformation.h>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace Android {
-namespace Internal {
-
-class AndroidGdbServerKitAspectWidget : public KitAspectWidget
-{
- Q_DECLARE_TR_FUNCTIONS(Android::Internal::AndroidGdbServerKitAspect)
-public:
- AndroidGdbServerKitAspectWidget(Kit *kit, const KitAspect *ki);
- ~AndroidGdbServerKitAspectWidget() override;
-
- void makeReadOnly() override;
- void refresh() override;
-
- QWidget *mainWidget() const override;
- QWidget *buttonWidget() const override;
-
-private:
- void autoDetectDebugger();
- void showDialog();
-
- QLabel *m_label;
- QPushButton *m_button;
-};
-
-
-AndroidGdbServerKitAspect::AndroidGdbServerKitAspect()
-{
- setId(AndroidGdbServerKitAspect::id());
- setDisplayName(tr("Android GDB server"));
- setDescription(tr("The GDB server to use for this kit."));
- setPriority(27999); // Just one less than Debugger!
-}
-
-void AndroidGdbServerKitAspect::setup(Kit *kit)
-{
- if (kit && !kit->hasValue(id()))
- kit->setValue(id(), autoDetect(kit).toString());
-}
-
-Tasks AndroidGdbServerKitAspect::validate(const Kit *) const
-{
- return {};
-}
-
-bool AndroidGdbServerKitAspect::isApplicableToKit(const Kit *k) const
-{
- return DeviceKitAspect::deviceId(k) == Constants::ANDROID_DEVICE_ID;
-}
-
-KitAspect::ItemList AndroidGdbServerKitAspect::toUserOutput(const Kit *kit) const
-{
- return {{tr("GDB server"), AndroidGdbServerKitAspect::gdbServer(kit).toUserOutput()}};
-}
-
-KitAspectWidget *AndroidGdbServerKitAspect::createConfigWidget(Kit *kit) const
-{
- QTC_ASSERT(kit, return nullptr);
- return new AndroidGdbServerKitAspectWidget(kit, this);
-}
-
-Core::Id AndroidGdbServerKitAspect::id()
-{
- return "Android.GdbServer.Information";
-}
-
-FilePath AndroidGdbServerKitAspect::gdbServer(const Kit *kit)
-{
- QTC_ASSERT(kit, return FilePath());
- return FilePath::fromString(kit->value(AndroidGdbServerKitAspect::id()).toString());
-}
-
-void AndroidGdbServerKitAspect::setGdbSever(Kit *kit, const FilePath &gdbServerCommand)
-{
- QTC_ASSERT(kit, return);
- kit->setValue(AndroidGdbServerKitAspect::id(), gdbServerCommand.toString());
-}
-
-FilePath AndroidGdbServerKitAspect::autoDetect(const Kit *kit)
-{
- ToolChain *tc = ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
- if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
- return FilePath();
- auto atc = static_cast<AndroidToolChain *>(tc);
- return atc->suggestedGdbServer();
-}
-
-///////////////
-// AndroidGdbServerKitAspectWidget
-///////////////
-
-
-AndroidGdbServerKitAspectWidget::AndroidGdbServerKitAspectWidget(Kit *kit, const KitAspect *ki) :
- KitAspectWidget(kit, ki),
- m_label(new ElidingLabel),
- m_button(new QPushButton(tr("Manage...")))
-{
- // ToolButton with Menu, defaulting to 'Autodetect'.
- auto buttonMenu = new QMenu(m_button);
- QAction *autoDetectAction = buttonMenu->addAction(tr("Auto-detect"));
- connect(autoDetectAction, &QAction::triggered,
- this, &AndroidGdbServerKitAspectWidget::autoDetectDebugger);
- QAction *changeAction = buttonMenu->addAction(tr("Edit..."));
- connect(changeAction, &QAction::triggered,
- this, &AndroidGdbServerKitAspectWidget::showDialog);
- m_button->setMenu(buttonMenu);
-
- refresh();
-}
-
-AndroidGdbServerKitAspectWidget::~AndroidGdbServerKitAspectWidget()
-{
- delete m_button;
- delete m_label;
-}
-
-void AndroidGdbServerKitAspectWidget::makeReadOnly()
-{
- m_button->setEnabled(false);
-}
-
-void AndroidGdbServerKitAspectWidget::refresh()
-{
- m_label->setText(AndroidGdbServerKitAspect::gdbServer(m_kit).toString());
-}
-
-QWidget *AndroidGdbServerKitAspectWidget::mainWidget() const
-{
- return m_label;
-}
-
-QWidget *AndroidGdbServerKitAspectWidget::buttonWidget() const
-{
- return m_button;
-}
-
-void AndroidGdbServerKitAspectWidget::autoDetectDebugger()
-{
- AndroidGdbServerKitAspect::setGdbSever(m_kit, AndroidGdbServerKitAspect::autoDetect(m_kit));
-}
-
-void AndroidGdbServerKitAspectWidget::showDialog()
-{
- QDialog dialog;
- auto layout = new QVBoxLayout(&dialog);
- auto formLayout = new QFormLayout;
- formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
-
- auto binaryLabel = new QLabel(tr("&Binary:"));
- auto chooser = new PathChooser;
- chooser->setExpectedKind(PathChooser::ExistingCommand);
- chooser->setPath(AndroidGdbServerKitAspect::gdbServer(m_kit).toString());
- binaryLabel->setBuddy(chooser);
- formLayout->addRow(binaryLabel, chooser);
- layout->addLayout(formLayout);
-
- auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
- connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
- connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
- layout->addWidget(buttonBox);
-
- dialog.setWindowTitle(tr("GDB Server for \"%1\"").arg(m_kit->displayName()));
-
- if (dialog.exec() == QDialog::Accepted)
- AndroidGdbServerKitAspect::setGdbSever(m_kit, chooser->fileName());
-}
-
-} // namespace Internal
-} // namespace Android
diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp
index bccc0e3b2a..2ce27e5d26 100644
--- a/src/plugins/android/androidmanager.cpp
+++ b/src/plugins/android/androidmanager.cpp
@@ -70,6 +70,7 @@ namespace {
const QLatin1String AndroidManifestName("AndroidManifest.xml");
const QLatin1String AndroidDefaultPropertiesName("project.properties");
const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber");
+ const QLatin1String AndroidDeviceAbis("AndroidDeviceAbis");
const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel");
const QString packageNameRegEx("(?<token>package: )(.*?)(name=)'(?<target>.*?)'");
const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'");
@@ -258,10 +259,10 @@ QString AndroidManager::buildTargetSDK(ProjectExplorer::Target *target)
return fallback;
}
-QString AndroidManager::targetArch(const Target *target)
+QStringList AndroidManager::applicationAbis(const Target *target)
{
auto qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitAspect::qtVersion(target->kit()));
- return qt->targetArch();
+ return qt->androidAbis();
}
QJsonObject AndroidManager::deploymentSettings(const Target *target)
@@ -271,24 +272,18 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target)
return {};
auto tc = ProjectExplorer::ToolChainKitAspect::toolChain(target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
- if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_ID)
+ if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID)
return {};
QJsonObject settings;
- settings["description"] = "This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand.";
+ settings["_description"] = "This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand.";
settings["qt"] = qt->qmakeProperty("QT_INSTALL_PREFIX");
settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString();
settings["sdk"] = AndroidConfigurations::currentConfig().sdkLocation().toString();
- settings["sdkBuildToolsRevision"] = AndroidConfigurations::currentConfig().buildToolsVersion().toString();
- settings["application-binary"] = target->activeRunConfiguration()->buildTargetInfo().targetFilePath.toString();
- settings["target-architecture"] = targetArch(target);
+ settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath().pathAppended("sysroot/usr/lib/").toString();
settings["toolchain-prefix"] = "llvm";
settings["tool-prefix"] = "llvm";
settings["useLLVM"] = true;
settings["ndk-host"] = AndroidConfigurations::currentConfig().toolchainHost();
- settings["stdcpp-path"] = AndroidConfigurations::currentConfig().ndkLocation()
- .pathAppended("/sources/cxx-stl/llvm-libc++/libs/"
- + targetArch(target)
- + "/libc++_shared.so").toString();
return settings;
}
@@ -316,6 +311,75 @@ Utils::FilePath AndroidManager::apkPath(const ProjectExplorer::Target *target)
return dirPath(target).pathAppended(apkPath);
}
+FilePath AndroidManager::aabPath(const Target *target)
+{
+ QTC_ASSERT(target, return Utils::FilePath());
+
+ auto buildApkStep = AndroidBuildApkStep::findInBuild(target->activeBuildConfiguration());
+ if (!buildApkStep)
+ return Utils::FilePath();
+
+ QString buildType;
+ if (buildApkStep->buildConfiguration()->buildType() == BuildConfiguration::Release)
+ buildType = "release";
+ else
+ buildType = "debug";
+ return dirPath(target).pathAppended(QString("build/outputs/bundle/%1/android-build-%1.aab").arg(buildType));
+}
+
+bool AndroidManager::matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis)
+{
+ for (const auto &abi : appAbis) {
+ if (deviceAbis.contains(abi))
+ return true;
+ }
+ return false;
+}
+
+QString AndroidManager::devicePreferredAbi(const QStringList &deviceAbis, const QStringList &appAbis)
+{
+ for (const auto &abi : appAbis) {
+ if (deviceAbis.contains(abi))
+ return abi;
+ }
+ return {};
+}
+
+Abi AndroidManager::androidAbi2Abi(const QString &androidAbi)
+{
+ if (androidAbi == "arm64-v8a") {
+ return Abi{Abi::Architecture::ArmArchitecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 64, androidAbi};
+ } else if (androidAbi == "armeabi-v7a") {
+ return Abi{Abi::Architecture::ArmArchitecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 32, androidAbi};
+ } else if (androidAbi == "x86_64") {
+ return Abi{Abi::Architecture::X86Architecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 64, androidAbi};
+ } else if (androidAbi == "x86") {
+ return Abi{Abi::Architecture::X86Architecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 32, androidAbi};
+ } else {
+ return Abi{Abi::Architecture::UnknownArchitecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 0, androidAbi};
+ }
+}
+
Utils::FilePath AndroidManager::manifestSourcePath(ProjectExplorer::Target *target)
{
if (const ProjectNode *node = currentProjectNode(target)) {
@@ -360,6 +424,22 @@ void AndroidManager::setDeviceSerialNumber(ProjectExplorer::Target *target, cons
target->setNamedSettings(AndroidDeviceSn, deviceSerialNumber);
}
+QString AndroidManager::devicePreferredAbi(Target *target)
+{
+ auto appAbis = applicationAbis(target);
+ const auto deviceAbis = target->namedSettings(AndroidDeviceAbis).toStringList();
+ for (const auto &abi : deviceAbis) {
+ if (appAbis.contains(abi))
+ return abi;
+ }
+ return {};
+}
+
+void AndroidManager::setDeviceAbis(ProjectExplorer::Target *target, const QStringList &deviceAbis)
+{
+ target->setNamedSettings(AndroidDeviceAbis, deviceAbis);
+}
+
int AndroidManager::deviceApiLevel(ProjectExplorer::Target *target)
{
return target->namedSettings(ApiLevelKey).toInt();
@@ -374,7 +454,7 @@ void AndroidManager::setDeviceApiLevel(ProjectExplorer::Target *target, int leve
QPair<int, int> AndroidManager::apiLevelRange()
{
- return qMakePair(16, 28);
+ return qMakePair(16, 29);
}
QString AndroidManager::androidNameForApiLevel(int x)
@@ -430,6 +510,8 @@ QString AndroidManager::androidNameForApiLevel(int x)
return QLatin1String("Android 8.1");
case 28:
return QLatin1String("Android 9");
+ case 29:
+ return QLatin1String("Android 10");
default:
return tr("Unknown Android version. API Level: %1").arg(QString::number(x));
}
@@ -472,39 +554,13 @@ static int parseMinSdk(const QDomElement &manifestElem)
return 0;
}
-void AndroidManager::cleanLibsOnDevice(ProjectExplorer::Target *target)
-{
- const QString targetArch = AndroidManager::targetArch(target);
- if (targetArch.isEmpty())
- return;
- const int deviceAPILevel = AndroidManager::minimumSDK(target);
- AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch);
- if (!info.isValid()) // aborted
- return;
-
- QString deviceSerialNumber = info.serialNumber;
-
- if (info.type == AndroidDeviceInfo::Emulator) {
- deviceSerialNumber = AndroidAvdManager().startAvd(info.avdname);
- if (deviceSerialNumber.isEmpty())
- Core::MessageManager::write(tr("Starting Android virtual device failed."));
- }
-
- QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
- arguments << "shell" << "rm" << "-r" << "/data/local/tmp/qt";
-
- QString error;
- if (!runAdbCommandDetached(arguments, &error))
- Core::MessageManager::write(tr("Cleaning Qt libraries on device failed.\n%1").arg(error));
-}
-
void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath)
{
- const QString targetArch = AndroidManager::targetArch(target);
- if (targetArch.isEmpty())
+ const QStringList appAbis = AndroidManager::applicationAbis(target);
+ if (appAbis.isEmpty())
return;
const int deviceAPILevel = AndroidManager::minimumSDK(target);
- AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, targetArch);
+ AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(target->project(), deviceAPILevel, appAbis);
if (!info.isValid()) // aborted
return;
@@ -526,15 +582,11 @@ bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QS
{
if (keystorePasswd.isEmpty())
return false;
- QStringList arguments;
- arguments << QLatin1String("-list")
- << QLatin1String("-keystore")
- << keystorePath
- << QLatin1String("--storepass")
- << keystorePasswd;
- Utils::SynchronousProcess proc;
+ const CommandLine cmd(AndroidConfigurations::currentConfig().keytoolPath(),
+ {"-list", "-keystore", keystorePath, "--storepass", keystorePasswd});
+ SynchronousProcess proc;
proc.setTimeoutS(10);
- Utils::SynchronousProcessResponse response = proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
+ SynchronousProcessResponse response = proc.run(cmd);
return (response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0);
}
@@ -548,11 +600,11 @@ bool AndroidManager::checkCertificatePassword(const QString &keystorePath, const
else
arguments << certificatePasswd;
- Utils::SynchronousProcess proc;
+ SynchronousProcess proc;
proc.setTimeoutS(10);
- Utils::SynchronousProcessResponse response
- = proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
- return response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0;
+ SynchronousProcessResponse response
+ = proc.run({AndroidConfigurations::currentConfig().keytoolPath(), arguments});
+ return response.result == SynchronousProcessResponse::Finished && response.exitCode == 0;
}
bool AndroidManager::checkCertificateExists(const QString &keystorePath,
@@ -562,11 +614,11 @@ bool AndroidManager::checkCertificateExists(const QString &keystorePath,
QStringList arguments = { "-list", "-keystore", keystorePath,
"--storepass", keystorePasswd, "-alias", alias };
- Utils::SynchronousProcess proc;
+ SynchronousProcess proc;
proc.setTimeoutS(10);
- Utils::SynchronousProcessResponse response
- = proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
- return response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0;
+ SynchronousProcessResponse response
+ = proc.run({AndroidConfigurations::currentConfig().keytoolPath(), arguments});
+ return response.result == SynchronousProcessResponse::Finished && response.exitCode == 0;
}
using GradleProperties = QMap<QByteArray, QByteArray>;
@@ -716,35 +768,35 @@ QProcess *AndroidManager::runAdbCommandDetached(const QStringList &args, QString
return nullptr;
}
-SdkToolResult AndroidManager::runCommand(const QString &executable, const QStringList &args,
+SdkToolResult AndroidManager::runCommand(const CommandLine &command,
const QByteArray &writeData, int timeoutS)
{
Android::SdkToolResult cmdResult;
Utils::SynchronousProcess cmdProc;
cmdProc.setTimeoutS(timeoutS);
- qCDebug(androidManagerLog) << "Running command: " << executable << args.join(' ');
- Utils::SynchronousProcessResponse response = cmdProc.run(executable, args, writeData);
+ qCDebug(androidManagerLog) << "Running command: " << command.toUserOutput();
+ SynchronousProcessResponse response = cmdProc.run(command, writeData);
cmdResult.m_stdOut = response.stdOut().trimmed();
cmdResult.m_stdErr = response.stdErr().trimmed();
cmdResult.m_success = response.result == Utils::SynchronousProcessResponse::Finished;
- qCDebug(androidManagerLog) << "Running command finshed:" << executable << args.join(' ')
+ qCDebug(androidManagerLog) << "Running command finshed:" << command.toUserOutput()
<< "Success:" << cmdResult.m_success
<< "Output:" << response.allRawOutput();
if (!cmdResult.success())
- cmdResult.m_exitMessage = response.exitMessage(executable, timeoutS);
+ cmdResult.m_exitMessage = response.exitMessage(command.executable().toString(), timeoutS);
return cmdResult;
}
SdkToolResult AndroidManager::runAdbCommand(const QStringList &args,
const QByteArray &writeData, int timeoutS)
{
- return runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(), args,
+ return runCommand({AndroidConfigurations::currentConfig().adbToolPath(), args},
writeData, timeoutS);
}
SdkToolResult AndroidManager::runAaptCommand(const QStringList &args, int timeoutS)
{
- return runCommand(AndroidConfigurations::currentConfig().aaptToolPath().toString(), args, {},
+ return runCommand({AndroidConfigurations::currentConfig().aaptToolPath(), args}, {},
timeoutS);
}
} // namespace Android
diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h
index 12bf9ddf90..73e0fa79cb 100644
--- a/src/plugins/android/androidmanager.h
+++ b/src/plugins/android/androidmanager.h
@@ -31,6 +31,8 @@
#include <QObject>
#include <QVersionNumber>
+#include <projectexplorer/abi.h>
+
QT_BEGIN_NAMESPACE
class QProcess;
QT_END_NAMESPACE
@@ -40,7 +42,10 @@ class Kit;
class Target;
}
-namespace Utils { class FilePath; }
+namespace Utils {
+class CommandLine;
+class FilePath;
+}
namespace Android {
@@ -79,6 +84,9 @@ public:
static QString deviceSerialNumber(ProjectExplorer::Target *target);
static void setDeviceSerialNumber(ProjectExplorer::Target *target, const QString &deviceSerialNumber);
+ static QString devicePreferredAbi(ProjectExplorer::Target *target);
+ static void setDeviceAbis(ProjectExplorer::Target *target, const QStringList &deviceAbis);
+
static int deviceApiLevel(ProjectExplorer::Target *target);
static void setDeviceApiLevel(ProjectExplorer::Target *target, int level);
@@ -87,7 +95,7 @@ public:
static int minimumSDK(ProjectExplorer::Target *target);
static int minimumSDK(const ProjectExplorer::Kit *kit);
- static QString targetArch(const ProjectExplorer::Target *target);
+ static QStringList applicationAbis(const ProjectExplorer::Target *target);
static Utils::FilePath dirPath(const ProjectExplorer::Target *target);
static Utils::FilePath manifestPath(ProjectExplorer::Target *target);
@@ -95,11 +103,14 @@ public:
static Utils::FilePath manifestSourcePath(ProjectExplorer::Target *target);
static Utils::FilePath defaultPropertiesPath(ProjectExplorer::Target *target);
static Utils::FilePath apkPath(const ProjectExplorer::Target *target);
+ static Utils::FilePath aabPath(const ProjectExplorer::Target *target);
+ static bool matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis);
+ static QString devicePreferredAbi(const QStringList &deviceAbis, const QStringList &appAbis);
+ static ProjectExplorer::Abi androidAbi2Abi(const QString &androidAbi);
static QPair<int, int> apiLevelRange();
static QString androidNameForApiLevel(int x);
- static void cleanLibsOnDevice(ProjectExplorer::Target *target);
static void installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath);
static bool checkKeystorePassword(const QString &keystorePath, const QString &keystorePasswd);
@@ -118,7 +129,7 @@ public:
static QJsonObject deploymentSettings(const ProjectExplorer::Target *target);
private:
- static SdkToolResult runCommand(const QString &executable, const QStringList &args,
+ static SdkToolResult runCommand(const Utils::CommandLine &command,
const QByteArray &writeData = {}, int timeoutS = 30);
};
diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp
index d8e8b003c6..97c56a34b1 100644
--- a/src/plugins/android/androidmanifesteditorwidget.cpp
+++ b/src/plugins/android/androidmanifesteditorwidget.cpp
@@ -165,7 +165,7 @@ void AndroidManifestEditorWidget::initializePage()
m_packageNameWarningIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
auto warningRow = new QHBoxLayout;
- warningRow->setMargin(0);
+ warningRow->setContentsMargins(0, 0, 0, 0);
warningRow->addWidget(m_packageNameWarningIcon);
warningRow->addWidget(m_packageNameWarning);
diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp
index 9ad698bdec..b84202c41a 100644
--- a/src/plugins/android/androidpackageinstallationstep.cpp
+++ b/src/plugins/android/androidpackageinstallationstep.cpp
@@ -70,18 +70,19 @@ bool AndroidPackageInstallationStep::init()
ProjectExplorer::Constants::CXX_LANGUAGE_ID);
QTC_ASSERT(tc, return false);
+ CommandLine cmd{tc->makeCommand(bc->environment())};
+ const QString innerQuoted = QtcProcess::quoteArg(dirPath);
+ const QString outerQuoted = QtcProcess::quoteArg("INSTALL_ROOT=" + innerQuoted);
+ cmd.addArgs(outerQuoted + " install", CommandLine::Raw);
+
ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander());
pp->setWorkingDirectory(bc->buildDirectory());
- pp->setCommand(tc->makeCommand(bc->environment()));
Environment env = bc->environment();
Environment::setupEnglishOutput(&env);
pp->setEnvironment(env);
- const QString innerQuoted = QtcProcess::quoteArg(dirPath);
- const QString outerQuoted = QtcProcess::quoteArg("INSTALL_ROOT=" + innerQuoted);
- pp->setArguments(outerQuoted + " install");
+ pp->setCommandLine(cmd);
- pp->resolveAll();
setOutputParser(new GnuMakeParser());
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
diff --git a/src/plugins/android/androidpackageinstallationstep.h b/src/plugins/android/androidpackageinstallationstep.h
index 0747f77c0b..977d7a23f0 100644
--- a/src/plugins/android/androidpackageinstallationstep.h
+++ b/src/plugins/android/androidpackageinstallationstep.h
@@ -31,12 +31,10 @@
#include <projectexplorer/abstractprocessstep.h>
namespace Android {
-namespace Internal { class AndroidPackageInstallationFactory; }
class ANDROID_EXPORT AndroidPackageInstallationStep : public ProjectExplorer::AbstractProcessStep
{
Q_OBJECT
- friend class Internal::AndroidPackageInstallationFactory;
public:
explicit AndroidPackageInstallationStep(ProjectExplorer::BuildStepList *bsl);
diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp
index 29f4392712..d8225eebae 100644
--- a/src/plugins/android/androidplugin.cpp
+++ b/src/plugins/android/androidplugin.cpp
@@ -30,7 +30,6 @@
#include "androiddebugsupport.h"
#include "androiddeployqtstep.h"
#include "androiddevice.h"
-#include "androidgdbserverkitinformation.h"
#include "androidmanager.h"
#include "androidmanifesteditorfactory.h"
#include "androidpackageinstallationstep.h"
@@ -88,23 +87,12 @@ public:
}
};
-class QmlPreviewRunWorkerFactory : public RunWorkerFactory
+class AndroidQmlPreviewWorker : public AndroidQmlToolingSupport
{
public:
- QmlPreviewRunWorkerFactory()
- {
- addSupportedRunMode(QML_PREVIEW_RUN_MODE);
- setProducer([](RunControl *runControl) -> RunWorker * {
- const Runnable runnable = runControl->runConfiguration()->runnable();
- return new AndroidQmlToolingSupport(runControl, runnable.executable);
- });
- addConstraint([](RunConfiguration *runConfig) {
- return runConfig->isEnabled()
- && runConfig->id().name().startsWith("QmlProjectManager.QmlRunConfiguration")
- && DeviceTypeKitAspect::deviceTypeId(runConfig->target()->kit())
- == Android::Constants::ANDROID_DEVICE_TYPE;
- });
- }
+ AndroidQmlPreviewWorker(RunControl *runControl)
+ : AndroidQmlToolingSupport(runControl, runControl->runnable().executable.toString())
+ {}
};
class AndroidPluginPrivate : public QObject
@@ -151,17 +139,34 @@ public:
AndroidManifestEditorFactory manifestEditorFactory;
AndroidRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<AndroidRunSupport, AndroidRunConfiguration> runWorkerFactory;
- SimpleRunWorkerFactory<AndroidDebugSupport, AndroidRunConfiguration>
- debugWorkerFactory{DEBUG_RUN_MODE};
- SimpleRunWorkerFactory<AndroidQmlToolingSupport, AndroidRunConfiguration>
- profilerWorkerFactory{QML_PROFILER_RUN_MODE};
- SimpleRunWorkerFactory<AndroidQmlToolingSupport, AndroidRunConfiguration>
- qmlPreviewWorkerFactory{QML_PREVIEW_RUN_MODE};
- QmlPreviewRunWorkerFactory qmlPreviewWorkerFactory2;
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<AndroidRunSupport>(),
+ {NORMAL_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+ RunWorkerFactory debugWorkerFactory{
+ RunWorkerFactory::make<AndroidDebugSupport>(),
+ {DEBUG_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+ RunWorkerFactory profilerWorkerFactory{
+ RunWorkerFactory::make<AndroidQmlToolingSupport>(),
+ {QML_PROFILER_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+ RunWorkerFactory qmlPreviewWorkerFactory{
+ RunWorkerFactory::make<AndroidQmlToolingSupport>(),
+ {QML_PREVIEW_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+ RunWorkerFactory qmlPreviewWorkerFactory2{
+ RunWorkerFactory::make<AndroidQmlPreviewWorker>(),
+ {QML_PREVIEW_RUN_MODE},
+ {"QmlProjectManager.QmlRunConfiguration"},
+ {Android::Constants::ANDROID_DEVICE_TYPE}
+ };
AndroidBuildApkStepFactory buildApkStepFactory;
- AndroidGdbServerKitAspect gdbServerKitAspect;
};
AndroidPlugin::~AndroidPlugin()
@@ -171,8 +176,8 @@ AndroidPlugin::~AndroidPlugin()
bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
d = new AndroidPluginPrivate;
diff --git a/src/plugins/android/androidpotentialkit.cpp b/src/plugins/android/androidpotentialkit.cpp
index f755551b28..ce2851875d 100644
--- a/src/plugins/android/androidpotentialkit.cpp
+++ b/src/plugins/android/androidpotentialkit.cpp
@@ -91,7 +91,7 @@ AndroidPotentialKitWidget::AndroidPotentialKitWidget(QWidget *parent)
setWidget(mainWidget);
auto layout = new QGridLayout(mainWidget);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
auto label = new QLabel;
label->setText(tr("%1 needs additional settings to enable Android support."
" You can configure those settings in the Options dialog.")
diff --git a/src/plugins/android/androidqmltoolingsupport.cpp b/src/plugins/android/androidqmltoolingsupport.cpp
index b304fbde72..5a2ef0ee71 100644
--- a/src/plugins/android/androidqmltoolingsupport.cpp
+++ b/src/plugins/android/androidqmltoolingsupport.cpp
@@ -40,11 +40,11 @@ AndroidQmlToolingSupport::AndroidQmlToolingSupport(RunControl *runControl,
auto runner = new AndroidRunner(runControl, intentName);
addStartDependency(runner);
- auto profiler = runControl->createWorker(runControl->runMode());
- profiler->addStartDependency(this);
+ auto worker = runControl->createWorker(QmlDebug::runnerIdForRunMode(runControl->runMode()));
+ worker->addStartDependency(this);
- connect(runner, &AndroidRunner::qmlServerReady, this, [this, profiler](const QUrl &server) {
- profiler->recordData("QmlServerUrl", server);
+ connect(runner, &AndroidRunner::qmlServerReady, this, [this, worker](const QUrl &server) {
+ worker->recordData("QmlServerUrl", server);
reportStarted();
});
}
diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp
index eff95c3f04..4b1696ee78 100644
--- a/src/plugins/android/androidqtversion.cpp
+++ b/src/plugins/android/androidqtversion.cpp
@@ -71,14 +71,42 @@ QString AndroidQtVersion::invalidReason() const
Abis AndroidQtVersion::detectQtAbis() const
{
- Abis abis = BaseQtVersion::detectQtAbis();
- for (int i = 0; i < abis.count(); ++i) {
- abis[i] = Abi(abis.at(i).architecture(),
- abis.at(i).os(),
- Abi::AndroidLinuxFlavor,
- abis.at(i).binaryFormat(),
- abis.at(i).wordWidth());
- }
+ auto androidAbi2Abi = [](const QString &androidAbi) {
+ if (androidAbi == "arm64-v8a") {
+ return Abi{Abi::Architecture::ArmArchitecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 64, androidAbi};
+ } else if (androidAbi == "armeabi-v7a") {
+ return Abi{Abi::Architecture::ArmArchitecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 32, androidAbi};
+ } else if (androidAbi == "x86_64") {
+ return Abi{Abi::Architecture::X86Architecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 64, androidAbi};
+ } else if (androidAbi == "x86") {
+ return Abi{Abi::Architecture::X86Architecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 32, androidAbi};
+ } else {
+ return Abi{Abi::Architecture::UnknownArchitecture,
+ Abi::OS::LinuxOS,
+ Abi::OSFlavor::AndroidLinuxFlavor,
+ Abi::BinaryFormat::ElfFormat,
+ 0, androidAbi};
+ }
+ };
+ Abis abis;
+ for (const auto &abi : androidAbis())
+ abis << androidAbi2Abi(abi);
return abis;
}
@@ -105,10 +133,10 @@ QString AndroidQtVersion::description() const
return tr("Android");
}
-QString AndroidQtVersion::targetArch() const
+const QStringList &AndroidQtVersion::androidAbis() const
{
ensureMkSpecParsed();
- return m_targetArch;
+ return m_androidAbis;
}
int AndroidQtVersion::minimumNDK() const
@@ -119,8 +147,11 @@ int AndroidQtVersion::minimumNDK() const
void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const
{
- m_targetArch = evaluator->value(QLatin1String("ANDROID_TARGET_ARCH"));
- const QString androidPlatform = evaluator->value(QLatin1String("ANDROID_PLATFORM"));
+ if (qtVersion() >= QtSupport::QtVersionNumber{5, 14})
+ m_androidAbis = evaluator->values("ALL_ANDROID_ABIS");
+ else
+ m_androidAbis = QStringList{evaluator->value("ANDROID_TARGET_ARCH")};
+ const QString androidPlatform = evaluator->value("ANDROID_PLATFORM");
if (!androidPlatform.isEmpty()) {
const QRegExp regex("android-(\\d+)");
if (regex.exactMatch(androidPlatform)) {
diff --git a/src/plugins/android/androidqtversion.h b/src/plugins/android/androidqtversion.h
index 519d702ead..c986960819 100644
--- a/src/plugins/android/androidqtversion.h
+++ b/src/plugins/android/androidqtversion.h
@@ -52,13 +52,13 @@ public:
QSet<Core::Id> targetDeviceTypes() const override;
QString description() const override;
- QString targetArch() const;
+ const QStringList &androidAbis() const;
int minimumNDK() const;
protected:
void parseMkSpec(ProFileEvaluator *) const override;
private:
- mutable QString m_targetArch;
+ mutable QStringList m_androidAbis;
mutable int m_minNdk = -1;
};
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp
index fa81749cd4..95eb3e1a2d 100644
--- a/src/plugins/android/androidrunconfiguration.cpp
+++ b/src/plugins/android/androidrunconfiguration.cpp
@@ -35,7 +35,6 @@
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtoutputformatter.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/detailswidget.h>
@@ -133,7 +132,6 @@ AndroidRunConfiguration::AndroidRunConfiguration(Target *target, Core::Id id)
postStartShellCmdAspect->setSettingsKey("Android.PostStartShellCmdListKey");
postStartShellCmdAspect->setLabel(tr("Shell commands to run on Android device after application quits."));
- setOutputFormatter<QtSupport::QtOutputFormatter>();
connect(target->project(), &Project::parsingFinished, this, [this] {
updateTargetInformation();
});
diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp
index 24ac13a4f1..257b40cadd 100644
--- a/src/plugins/android/androidrunner.cpp
+++ b/src/plugins/android/androidrunner.cpp
@@ -127,7 +127,7 @@ AndroidRunner::AndroidRunner(RunControl *runControl, const QString &intentName)
qRegisterMetaType<Utils::Port>("Utils::Port"),
qRegisterMetaType<AndroidDeviceInfo>("Android::AndroidDeviceInfo")
};
- Q_UNUSED(metaTypes);
+ Q_UNUSED(metaTypes)
m_checkAVDTimer.setInterval(2000);
connect(&m_checkAVDTimer, &QTimer::timeout, this, &AndroidRunner::checkAVD);
@@ -246,11 +246,11 @@ void AndroidRunner::launchAVD()
return;
int deviceAPILevel = AndroidManager::minimumSDK(m_target);
- QString targetArch = AndroidManager::targetArch(m_target);
+ QStringList androidAbis = AndroidManager::applicationAbis(m_target);
// Get AVD info.
AndroidDeviceInfo info = AndroidConfigurations::showDeviceDialog(
- m_target->project(), deviceAPILevel, targetArch);
+ m_target->project(), deviceAPILevel, androidAbis);
AndroidManager::setDeviceSerialNumber(m_target, info.serialNumber);
emit androidDeviceInfoChanged(info);
if (info.isValid()) {
diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp
index b84ec9df74..96508910e6 100644
--- a/src/plugins/android/androidrunnerworker.cpp
+++ b/src/plugins/android/androidrunnerworker.cpp
@@ -29,7 +29,6 @@
#include "androidconstants.h"
#include "androidmanager.h"
#include "androidrunconfiguration.h"
-#include "androidgdbserverkitinformation.h"
#include <debugger/debuggerrunconfigurationaspect.h>
@@ -63,6 +62,7 @@ static const int GdbTempFileMaxCounter = 20;
using namespace std;
using namespace std::placeholders;
using namespace ProjectExplorer;
+using namespace Utils;
namespace Android {
namespace Internal {
@@ -126,10 +126,10 @@ static void findProcessPID(QFutureInterface<qint64> &fi, QStringList selector,
chrono::high_resolution_clock::time_point start = chrono::high_resolution_clock::now();
do {
QThread::msleep(200);
- QString adbPath = AndroidConfigurations::currentConfig().adbToolPath().toString();
+ FilePath adbPath = AndroidConfigurations::currentConfig().adbToolPath();
selector.append("shell");
selector.append(preNougat ? pidScriptPreNougat : pidScript.arg(packageName));
- const auto out = Utils::SynchronousProcess().runBlocking(adbPath, selector).allRawOutput();
+ const auto out = SynchronousProcess().runBlocking({adbPath, selector}).allRawOutput();
if (preNougat) {
processPID = extractPID(out, packageName);
} else {
@@ -225,7 +225,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
<< "Extra Start Args:" << m_amStartExtraArgs
<< "Before Start ADB cmds:" << m_beforeStartAdbCommands
<< "After finish ADB cmds:" << m_afterFinishAdbCommands;
- m_gdbserverPath = AndroidGdbServerKitAspect::gdbServer(target->kit()).toString();
+ m_gdbserverPath = AndroidConfigurations::instance()->currentConfig().gdbServer(AndroidManager::devicePreferredAbi(target)).toString();
QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit());
m_useAppParamsForQmlDebugger = version->qtVersion() >= QtSupport::QtVersionNumber(5, 12);
}
diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h
index 30da68fc2d..ead26eed70 100644
--- a/src/plugins/android/androidrunnerworker.h
+++ b/src/plugins/android/androidrunnerworker.h
@@ -26,7 +26,7 @@
#pragma once
-#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/runcontrol.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
diff --git a/src/plugins/android/androidsdkmanager.cpp b/src/plugins/android/androidsdkmanager.cpp
index 8b58cdd1ad..df615f2744 100644
--- a/src/plugins/android/androidsdkmanager.cpp
+++ b/src/plugins/android/androidsdkmanager.cpp
@@ -136,7 +136,7 @@ static bool sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
proc.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(config));
proc.setTimeoutS(timeout);
proc.setTimeOutMessageBoxEnabled(true);
- SynchronousProcessResponse response = proc.run(config.sdkManagerToolPath().toString(), args);
+ SynchronousProcessResponse response = proc.run({config.sdkManagerToolPath(), args});
if (output)
*output = response.allOutput();
return response.result == SynchronousProcessResponse::Finished;
@@ -175,7 +175,7 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
QObject::connect(&sdkManager, &AndroidSdkManager::cancelActiveOperations,
&proc, &SynchronousProcess::terminate);
}
- SynchronousProcessResponse response = proc.run(config.sdkManagerToolPath().toString(), args);
+ SynchronousProcessResponse response = proc.run({config.sdkManagerToolPath(), args});
if (assertionFound) {
output.success = false;
output.stdOutput = response.stdOut();
@@ -227,6 +227,9 @@ private:
QString m_licenseTextCache;
QByteArray m_licenseUserInput;
mutable QReadWriteLock m_licenseInputLock;
+
+public:
+ bool m_packageListingSuccessful = true;
};
/*!
@@ -372,6 +375,11 @@ bool AndroidSdkManager::isBusy() const
return m_d->m_activeOperation && !m_d->m_activeOperation->isFinished();
}
+bool AndroidSdkManager::packageListingSuccessful() const
+{
+ return m_d->m_packageListingSuccessful;
+}
+
QFuture<QString> AndroidSdkManager::availableArguments() const
{
return Utils::runAsync(&AndroidSdkManagerPrivate::parseCommonArguments, m_d.get());
@@ -806,6 +814,7 @@ void AndroidSdkManagerPrivate::reloadSdkPackages()
if (m_config.sdkToolsVersion() < sdkManagerIntroVersion) {
// Old Sdk tools.
+ m_packageListingSuccessful = true;
AndroidToolManager toolManager(m_config);
auto toAndroidSdkPackages = [](SdkPlatform *p) -> AndroidSdkPackage *{
return p;
@@ -815,7 +824,8 @@ void AndroidSdkManagerPrivate::reloadSdkPackages()
QString packageListing;
QStringList args({"--list", "--verbose"});
args << m_config.sdkManagerToolArgs();
- if (sdkManagerCommand(m_config, args, &packageListing)) {
+ m_packageListingSuccessful = sdkManagerCommand(m_config, args, &packageListing);
+ if (m_packageListingSuccessful) {
SdkManagerOutputParser parser(m_allPackages);
parser.parsePackageListing(packageListing);
}
@@ -930,7 +940,7 @@ void AndroidSdkManagerPrivate::getPendingLicense(SdkCmdFutureInterface &fi)
QtcProcess licenseCommand;
licenseCommand.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(m_config));
bool reviewingLicenses = false;
- licenseCommand.setCommand(CommandLine(m_config.sdkManagerToolPath(), "--licenses"));
+ licenseCommand.setCommand(CommandLine(m_config.sdkManagerToolPath(), {"--licenses"}));
if (Utils::HostOsInfo::isWindowsHost())
licenseCommand.setUseCtrlCStub(true);
licenseCommand.start();
diff --git a/src/plugins/android/androidsdkmanager.h b/src/plugins/android/androidsdkmanager.h
index 35b9dd96ad..a78a9fbaab 100644
--- a/src/plugins/android/androidsdkmanager.h
+++ b/src/plugins/android/androidsdkmanager.h
@@ -78,6 +78,8 @@ public:
void reloadPackages(bool forceReload = false);
bool isBusy() const;
+ bool packageListingSuccessful() const;
+
QFuture<QString> availableArguments() const;
QFuture<OperationOutput> updateAll();
QFuture<OperationOutput> update(const QStringList &install, const QStringList &uninstall);
diff --git a/src/plugins/android/androidsettingspage.cpp b/src/plugins/android/androidsettingspage.cpp
index 7be91957e2..67c5d220dd 100644
--- a/src/plugins/android/androidsettingspage.cpp
+++ b/src/plugins/android/androidsettingspage.cpp
@@ -38,8 +38,7 @@ using namespace ProjectExplorer;
namespace Android {
namespace Internal {
-AndroidSettingsPage::AndroidSettingsPage(QObject *parent)
- : Core::IOptionsPage(parent)
+AndroidSettingsPage::AndroidSettingsPage()
{
setId(Constants::ANDROID_SETTINGS_ID);
setDisplayName(tr("Android"));
diff --git a/src/plugins/android/androidsettingspage.h b/src/plugins/android/androidsettingspage.h
index 274653f940..2cdef16852 100644
--- a/src/plugins/android/androidsettingspage.h
+++ b/src/plugins/android/androidsettingspage.h
@@ -39,7 +39,7 @@ class AndroidSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit AndroidSettingsPage(QObject *parent = nullptr);
+ AndroidSettingsPage();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp
index 494af3065f..f633f7eb85 100644
--- a/src/plugins/android/androidsettingswidget.cpp
+++ b/src/plugins/android/androidsettingswidget.cpp
@@ -72,9 +72,11 @@ enum JavaValidation {
enum AndroidValidation {
SdkPathExistsRow,
+ SdkPathWritableRow,
SdkToolsInstalledRow,
PlatformToolsInstalledRow,
BuildToolsInstalledRow,
+ SdkManagerSuccessfulRow,
PlatformSdkInstalledRow,
NdkPathExistsRow,
NdkDirStructureRow,
@@ -101,7 +103,7 @@ public:
{
QTC_CHECK(m_detailsWidget);
auto layout = new QGridLayout(this);
- layout->setMargin(12);
+ layout->setContentsMargins(12, 12, 12, 12);
int row = 0;
for (auto itr = validationPoints.cbegin(); itr != validationPoints.cend(); ++itr) {
RowData data;
@@ -233,7 +235,7 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
m_sdkManagerWidget = new AndroidSdkManagerWidget(m_androidConfig, m_sdkManager.get(),
m_ui->sdkManagerTab);
auto sdkMangerLayout = new QVBoxLayout(m_ui->sdkManagerTab);
- sdkMangerLayout->setMargin(0);
+ sdkMangerLayout->setContentsMargins(0, 0, 0, 0);
sdkMangerLayout->addWidget(m_sdkManagerWidget);
connect(m_sdkManagerWidget, &AndroidSdkManagerWidget::updatingSdk, [this]() {
m_ui->SDKLocationPathChooser->setEnabled(false);
@@ -255,8 +257,11 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
QMap<int, QString> androidValidationPoints;
androidValidationPoints[SdkPathExistsRow] = tr("Android SDK path exists.");
+ androidValidationPoints[SdkPathWritableRow] = tr("Android SDK path writable.");
androidValidationPoints[SdkToolsInstalledRow] = tr("SDK tools installed.");
androidValidationPoints[PlatformToolsInstalledRow] = tr("Platform tools installed.");
+ androidValidationPoints[SdkManagerSuccessfulRow] = tr(
+ "SDK manager runs (requires exactly Java 1.8).");
androidValidationPoints[BuildToolsInstalledRow] = tr("Build tools installed.");
androidValidationPoints[PlatformSdkInstalledRow] = tr("Platform SDK installed.");
androidValidationPoints[NdkPathExistsRow] = tr("Android NDK path exists.");
@@ -283,6 +288,11 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
m_ui->downloadOpenJDKToolButton->setVisible(!Utils::HostOsInfo::isLinuxHost());
+ const QIcon downloadIcon = Utils::Icons::DOWNLOAD.icon();
+ m_ui->downloadSDKToolButton->setIcon(downloadIcon);
+ m_ui->downloadNDKToolButton->setIcon(downloadIcon);
+ m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon);
+
connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished,
this, &AndroidSettingsWidget::updateAvds);
connect(&m_futureWatcher, &QFutureWatcherBase::finished,
@@ -415,6 +425,7 @@ void AndroidSettingsWidget::validateSdk()
{
auto summaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
summaryWidget->setPointValid(SdkPathExistsRow, m_androidConfig.sdkLocation().exists());
+ summaryWidget->setPointValid(SdkPathWritableRow, m_androidConfig.sdkLocation().isWritablePath());
summaryWidget->setPointValid(SdkToolsInstalledRow,
!m_androidConfig.sdkToolsVersion().isNull());
summaryWidget->setPointValid(PlatformToolsInstalledRow,
@@ -422,12 +433,14 @@ void AndroidSettingsWidget::validateSdk()
summaryWidget->setPointValid(BuildToolsInstalledRow,
!m_androidConfig.buildToolsVersion().isNull());
+ summaryWidget->setPointValid(SdkManagerSuccessfulRow, m_sdkManager->packageListingSuccessful());
// installedSdkPlatforms should not trigger a package reload as validate SDK is only called
// after AndroidSdkManager::packageReloadFinished.
summaryWidget->setPointValid(PlatformSdkInstalledRow,
!m_sdkManager->installedSdkPlatforms().isEmpty());
updateUI();
- bool sdkToolsOk = summaryWidget->rowsOk({SdkPathExistsRow, SdkToolsInstalledRow});
+ bool sdkToolsOk = summaryWidget->rowsOk(
+ {SdkPathExistsRow, SdkPathWritableRow, SdkToolsInstalledRow, SdkManagerSuccessfulRow});
bool componentsOk = summaryWidget->rowsOk({PlatformToolsInstalledRow,
BuildToolsInstalledRow,
PlatformSdkInstalledRow});
@@ -528,7 +541,7 @@ void AndroidSettingsWidget::updateUI()
auto javaSummaryWidget = static_cast<SummaryWidget *>(m_ui->javaDetailsWidget->widget());
auto androidSummaryWidget = static_cast<SummaryWidget *>(m_ui->androidDetailsWidget->widget());
bool javaSetupOk = javaSummaryWidget->allRowsOk();
- bool sdkToolsOk = androidSummaryWidget->rowsOk({SdkPathExistsRow, SdkToolsInstalledRow});
+ bool sdkToolsOk = androidSummaryWidget->rowsOk({SdkPathExistsRow, SdkPathWritableRow, SdkToolsInstalledRow});
bool androidSetupOk = androidSummaryWidget->allRowsOk();
m_ui->avdManagerTab->setEnabled(javaSetupOk && androidSetupOk);
diff --git a/src/plugins/android/androidsettingswidget.ui b/src/plugins/android/androidsettingswidget.ui
index ee9b9a8433..037e304c76 100644
--- a/src/plugins/android/androidsettingswidget.ui
+++ b/src/plugins/android/androidsettingswidget.ui
@@ -53,10 +53,6 @@
<property name="toolTip">
<string>Download JDK</string>
</property>
- <property name="icon">
- <iconset resource="android.qrc">
- <normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
- </property>
</widget>
</item>
<item row="0" column="0">
@@ -112,10 +108,6 @@
<property name="toolTip">
<string>Download Android NDK</string>
</property>
- <property name="icon">
- <iconset resource="android.qrc">
- <normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
- </property>
</widget>
</item>
<item row="1" column="0">
@@ -155,10 +147,6 @@
<property name="toolTip">
<string>Download Android SDK</string>
</property>
- <property name="icon">
- <iconset resource="android.qrc">
- <normaloff>:/android/images/download.png</normaloff>:/android/images/download.png</iconset>
- </property>
</widget>
</item>
<item row="2" column="0" colspan="3">
diff --git a/src/plugins/android/androidsignaloperation.cpp b/src/plugins/android/androidsignaloperation.cpp
index 2410ed4732..6a43b03062 100644
--- a/src/plugins/android/androidsignaloperation.cpp
+++ b/src/plugins/android/androidsignaloperation.cpp
@@ -127,7 +127,7 @@ void Android::Internal::AndroidSignalOperation::killProcess(qint64 pid)
void Android::Internal::AndroidSignalOperation::killProcess(const QString &filePath)
{
- Q_UNUSED(filePath);
+ Q_UNUSED(filePath)
m_errorMessage = QLatin1String("The android signal operation does "
"not support killing by filepath.");
emit finished(m_errorMessage);
@@ -140,7 +140,7 @@ void Android::Internal::AndroidSignalOperation::interruptProcess(qint64 pid)
void Android::Internal::AndroidSignalOperation::interruptProcess(const QString &filePath)
{
- Q_UNUSED(filePath);
+ Q_UNUSED(filePath)
m_errorMessage = QLatin1String("The android signal operation does "
"not support interrupting by filepath.");
emit finished(m_errorMessage);
diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp
index e3b103012b..be8a9a79bf 100644
--- a/src/plugins/android/androidtoolchain.cpp
+++ b/src/plugins/android/androidtoolchain.cpp
@@ -61,10 +61,10 @@ static const QList<Core::Id> LanguageIds = {ProjectExplorer::Constants::CXX_LANG
ProjectExplorer::Constants::C_LANGUAGE_ID};
static ToolChain *findToolChain(Utils::FilePath &compilerPath, Core::Id lang, const QString &target,
- CToolChainList &alreadyKnown)
+ const ToolChainList &alreadyKnown)
{
ToolChain * tc = Utils::findOrDefault(alreadyKnown, [target, compilerPath, lang](ToolChain *tc) {
- return tc->typeId() == Constants::ANDROID_TOOLCHAIN_ID
+ return tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID
&& tc->language() == lang
&& tc->targetAbi() == ClangTargets[target]
&& tc->compilerCommand() == compilerPath;
@@ -72,17 +72,18 @@ static ToolChain *findToolChain(Utils::FilePath &compilerPath, Core::Id lang, co
return tc;
}
-AndroidToolChain::~AndroidToolChain() = default;
-
-QString AndroidToolChain::typeDisplayName() const
+AndroidToolChain::AndroidToolChain()
+ : ClangToolChain(Constants::ANDROID_TOOLCHAIN_TYPEID)
{
- return AndroidToolChainFactory::tr("Android Clang");
+ setTypeDisplayName(AndroidToolChainFactory::tr("Android Clang"));
}
+AndroidToolChain::~AndroidToolChain() = default;
+
bool AndroidToolChain::isValid() const
{
return ClangToolChain::isValid()
- && typeId() == Constants::ANDROID_TOOLCHAIN_ID
+ && typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID
&& targetAbi().isValid()
&& compilerCommand().isChildOf(AndroidConfigurations::currentConfig().ndkLocation())
&& !originalTargetTriple().isEmpty();
@@ -96,7 +97,8 @@ void AndroidToolChain::addToEnvironment(Environment &env) const
if (javaHome.exists()) {
env.set(QLatin1String("JAVA_HOME"), javaHome.toString());
const FilePath javaBin = javaHome.pathAppended("bin");
- if (!Utils::contains(env.path(), [&javaBin](const Utils::FilePath &p) { return p == javaBin; }))
+ const FilePath currentJavaFilePath = env.searchInPath("java");
+ if (!currentJavaFilePath.isChildOf(javaBin))
env.prependOrSetPath(javaBin.toUserOutput());
}
env.set(QLatin1String("ANDROID_HOME"),
@@ -105,17 +107,6 @@ void AndroidToolChain::addToEnvironment(Environment &env) const
AndroidConfigurations::currentConfig().sdkLocation().toString());
}
-FilePath AndroidToolChain::suggestedDebugger() const
-{
- // TODO: Make use of LLDB if available.
- return AndroidConfigurations::currentConfig().gdbPath(targetAbi());
-}
-
-FilePath AndroidToolChain::suggestedGdbServer() const
-{
- return AndroidConfigurations::currentConfig().gdbServer(targetAbi());
-}
-
bool AndroidToolChain::fromMap(const QVariantMap &data)
{
if (!ClangToolChain::fromMap(data))
@@ -130,7 +121,7 @@ QStringList AndroidToolChain::suggestedMkspecList() const
FilePath AndroidToolChain::makeCommand(const Environment &env) const
{
- Q_UNUSED(env);
+ Q_UNUSED(env)
FilePath makePath = AndroidConfigurations::currentConfig().makePath();
return makePath.exists() ? makePath : FilePath::fromString("make");
}
@@ -152,12 +143,12 @@ GccToolChain::DetectedAbisResult AndroidToolChain::detectSupportedAbis() const
AndroidToolChainFactory::AndroidToolChainFactory()
{
setDisplayName(tr("Android Clang"));
- setSupportedToolChainType(Constants::ANDROID_TOOLCHAIN_ID);
+ setSupportedToolChainType(Constants::ANDROID_TOOLCHAIN_TYPEID);
setSupportedLanguages({ProjectExplorer::Constants::CXX_LANGUAGE_ID});
setToolchainConstructor([] { return new AndroidToolChain; });
}
-ToolChainList AndroidToolChainFactory::autoDetect(CToolChainList &alreadyKnown)
+ToolChainList AndroidToolChainFactory::autoDetect(const ToolChainList &alreadyKnown)
{
return autodetectToolChainsForNdk(alreadyKnown);
}
@@ -169,7 +160,7 @@ static FilePath clangPlusPlusPath(const FilePath &clangPath)
QFileInfo(clangPath.toString()).baseName() + "++"));
}
-ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(CToolChainList &alreadyKnown)
+ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(const ToolChainList &alreadyKnown)
{
QList<ToolChain *> result;
FilePath clangPath = AndroidConfigurations::currentConfig().clangPath();
@@ -222,12 +213,5 @@ ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(CToolChainList
return result;
}
-// for fromMap
-AndroidToolChain::AndroidToolChain()
- : ClangToolChain(Constants::ANDROID_TOOLCHAIN_ID)
-{
-}
-
-
} // namespace Internal
} // namespace Android
diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h
index 1665f49b6a..7f620dd980 100644
--- a/src/plugins/android/androidtoolchain.h
+++ b/src/plugins/android/androidtoolchain.h
@@ -31,19 +31,15 @@ namespace Android {
namespace Internal {
using ToolChainList = QList<ProjectExplorer::ToolChain *>;
-using CToolChainList = const QList<ProjectExplorer::ToolChain *>;
class AndroidToolChain : public ProjectExplorer::ClangToolChain
{
public:
~AndroidToolChain() override;
- QString typeDisplayName() const override;
bool isValid() const override;
void addToEnvironment(Utils::Environment &env) const override;
- Utils::FilePath suggestedDebugger() const override;
- Utils::FilePath suggestedGdbServer() const;
QStringList suggestedMkspecList() const override;
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
bool fromMap(const QVariantMap &data) override;
@@ -64,7 +60,7 @@ class AndroidToolChainFactory : public ProjectExplorer::ToolChainFactory
public:
AndroidToolChainFactory();
- ToolChainList autoDetect(CToolChainList &alreadyKnown) override;
+ ToolChainList autoDetect(const ToolChainList &alreadyKnown) override;
class AndroidToolChainInformation
{
@@ -75,7 +71,7 @@ public:
QString version;
};
- static ToolChainList autodetectToolChainsForNdk(CToolChainList &alreadyKnown);
+ static ToolChainList autodetectToolChainsForNdk(const ToolChainList &alreadyKnown);
};
} // namespace Internal
diff --git a/src/plugins/android/androidtoolmanager.cpp b/src/plugins/android/androidtoolmanager.cpp
index be26329f98..2db6cecb26 100644
--- a/src/plugins/android/androidtoolmanager.cpp
+++ b/src/plugins/android/androidtoolmanager.cpp
@@ -60,10 +60,9 @@ public:
static bool androidToolCommand(Utils::FilePath toolPath, const QStringList &args,
const QProcessEnvironment &environment, QString *output)
{
- QString androidToolPath = toolPath.toString();
SynchronousProcess proc;
proc.setProcessEnvironment(environment);
- SynchronousProcessResponse response = proc.runBlocking(androidToolPath, args);
+ SynchronousProcessResponse response = proc.runBlocking({toolPath, args});
if (response.result == SynchronousProcessResponse::Finished) {
if (output)
*output = response.allOutput();
@@ -131,8 +130,7 @@ bool AndroidToolManager::removeAvd(const QString &name) const
proc.setTimeoutS(5);
proc.setProcessEnvironment(AndroidConfigurations::toolsEnvironment(m_config));
SynchronousProcessResponse response
- = proc.runBlocking(m_config.androidToolPath().toString(),
- QStringList({"delete", "avd", "-n", name}));
+ = proc.runBlocking({m_config.androidToolPath(), {"delete", "avd", "-n", name}});
return response.result == SynchronousProcessResponse::Finished && response.exitCode == 0;
}
diff --git a/src/plugins/android/avddialog.cpp b/src/plugins/android/avddialog.cpp
index c0f692734c..29f60b506f 100644
--- a/src/plugins/android/avddialog.cpp
+++ b/src/plugins/android/avddialog.cpp
@@ -38,7 +38,7 @@
using namespace Android;
using namespace Android::Internal;
-AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QString &targetArch,
+AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStringList &abis,
QWidget *parent) :
QDialog(parent),
m_sdkManager(sdkManager),
@@ -50,11 +50,11 @@ AvdDialog::AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStri
m_hideTipTimer.setInterval(2000);
m_hideTipTimer.setSingleShot(true);
- if (targetArch.isEmpty()) {
+ if (abis.isEmpty()) {
m_avdDialog.abiComboBox->addItems(QStringList({"armeabi-v7a", "armeabi", "x86",
"arm64-v8a", "x86_64"}));
} else {
- m_avdDialog.abiComboBox->addItems(QStringList(targetArch));
+ m_avdDialog.abiComboBox->addItems(abis);
}
auto v = new QRegExpValidator(m_allowedNameChars, this);
@@ -79,10 +79,10 @@ bool AvdDialog::isValid() const
}
CreateAvdInfo AvdDialog::gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
- int minApiLevel, QString targetArch)
+ int minApiLevel, const QStringList &abis)
{
CreateAvdInfo result;
- AvdDialog d(minApiLevel, sdkManager, targetArch, parent);
+ AvdDialog d(minApiLevel, sdkManager, abis, parent);
if (d.exec() != QDialog::Accepted || !d.isValid())
return result;
diff --git a/src/plugins/android/avddialog.h b/src/plugins/android/avddialog.h
index d0e3fe0324..6f32cd43a6 100644
--- a/src/plugins/android/avddialog.h
+++ b/src/plugins/android/avddialog.h
@@ -40,7 +40,7 @@ class AvdDialog : public QDialog
{
Q_OBJECT
public:
- explicit AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QString &targetArch,
+ explicit AvdDialog(int minApiLevel, AndroidSdkManager *sdkManager, const QStringList &abis,
QWidget *parent = nullptr);
const SdkPlatform *sdkPlatform() const;
@@ -49,7 +49,7 @@ public:
int sdcardSize() const;
bool isValid() const;
static CreateAvdInfo gatherCreateAVDInfo(QWidget *parent, AndroidSdkManager *sdkManager,
- int minApiLevel = 0, QString targetArch = QString());
+ int minApiLevel = 0, const QStringList &abis = {});
private:
void updateApiLevelComboBox();
diff --git a/src/plugins/android/images/download.png b/src/plugins/android/images/download.png
deleted file mode 100644
index 366a2913bc..0000000000
--- a/src/plugins/android/images/download.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/autotest/CMakeLists.txt b/src/plugins/autotest/CMakeLists.txt
index a5291ce315..2c2051647f 100644
--- a/src/plugins/autotest/CMakeLists.txt
+++ b/src/plugins/autotest/CMakeLists.txt
@@ -36,6 +36,7 @@ add_qtc_plugin(AutoTest
itestframework.h
itestparser.cpp itestparser.h
itestsettingspage.h
+ projectsettingswidget.cpp projectsettingswidget.h
qtest/qttest_utils.cpp qtest/qttest_utils.h
qtest/qttestconfiguration.cpp qtest/qttestconfiguration.h
qtest/qttestconstants.h
@@ -59,6 +60,7 @@ add_qtc_plugin(AutoTest
testframeworkmanager.cpp testframeworkmanager.h
testnavigationwidget.cpp testnavigationwidget.h
testoutputreader.cpp testoutputreader.h
+ testprojectsettings.cpp testprojectsettings.h
testresult.cpp testresult.h
testresultdelegate.cpp testresultdelegate.h
testresultmodel.cpp testresultmodel.h
diff --git a/src/plugins/autotest/autotest.pro b/src/plugins/autotest/autotest.pro
index 22e2b594c9..c849d8c4d4 100644
--- a/src/plugins/autotest/autotest.pro
+++ b/src/plugins/autotest/autotest.pro
@@ -6,23 +6,27 @@ include(../../qtcreatorplugin.pri)
DEFINES += AUTOTEST_LIBRARY
SOURCES += \
- testtreeview.cpp \
- testtreemodel.cpp \
- testtreeitem.cpp \
- testcodeparser.cpp \
autotestplugin.cpp \
- testrunner.cpp \
+ itestparser.cpp \
+ projectsettingswidget.cpp \
+ testcodeparser.cpp \
testconfiguration.cpp \
+ testeditormark.cpp \
+ testframeworkmanager.cpp \
+ testnavigationwidget.cpp \
+ testoutputreader.cpp \
+ testprojectsettings.cpp \
testresult.cpp \
- testresultspane.cpp \
- testresultmodel.cpp \
testresultdelegate.cpp \
- testtreeitemdelegate.cpp \
+ testresultmodel.cpp \
+ testresultspane.cpp \
+ testrunner.cpp \
testsettings.cpp \
testsettingspage.cpp \
- testnavigationwidget.cpp \
- testoutputreader.cpp \
- itestparser.cpp \
+ testtreeitem.cpp \
+ testtreeitemdelegate.cpp \
+ testtreemodel.cpp \
+ testtreeview.cpp \
gtest/gtestconfiguration.cpp \
gtest/gtestparser.cpp \
gtest/gtesttreeitem.cpp \
@@ -57,34 +61,37 @@ SOURCES += \
boost/boosttestoutputreader.cpp \
boost/boosttestresult.cpp \
boost/boosttestsettings.cpp \
- boost/boosttestsettingspage.cpp \
- testframeworkmanager.cpp \
- testeditormark.cpp
-
+ boost/boosttestsettingspage.cpp
HEADERS += \
- testtreeview.h \
- testtreemodel.h \
- testtreeitem.h \
- testcodeparser.h \
- autotestplugin.h \
autotest_global.h \
autotestconstants.h \
- testrunner.h \
+ autotesticons.h \
+ autotestplugin.h \
+ iframeworksettings.h \
+ itestframework.h \
+ itestparser.h \
+ itestsettingspage.h \
+ projectsettingswidget.h \
+ testcodeparser.h \
testconfiguration.h \
+ testeditormark.h \
+ testframeworkmanager.h \
+ testnavigationwidget.h \
+ testoutputreader.h \
+ testprojectsettings.h \
testresult.h \
- testresultspane.h \
- testresultmodel.h \
testresultdelegate.h \
- testtreeitemdelegate.h \
+ testresultmodel.h \
+ testresultspane.h \
+ testrunconfiguration.h \
+ testrunner.h \
testsettings.h \
testsettingspage.h \
- testnavigationwidget.h \
- testoutputreader.h \
- autotesticons.h \
- itestframework.h \
- iframeworksettings.h \
- itestparser.h \
+ testtreeitem.h \
+ testtreeitemdelegate.h \
+ testtreemodel.h \
+ testtreeview.h \
gtest/gtestconfiguration.h \
gtest/gtestparser.h \
gtest/gtesttreeitem.h \
@@ -122,11 +129,7 @@ HEADERS += \
boost/boosttestoutputreader.h \
boost/boosttestresult.h \
boost/boosttestsettingspage.h \
- boost/boosttestsettings.h \
- testframeworkmanager.h \
- testrunconfiguration.h \
- itestsettingspage.h \
- testeditormark.h
+ boost/boosttestsettings.h
RESOURCES += \
autotest.qrc
diff --git a/src/plugins/autotest/autotest.qbs b/src/plugins/autotest/autotest.qbs
index 9d31d53646..0336ec75eb 100644
--- a/src/plugins/autotest/autotest.qbs
+++ b/src/plugins/autotest/autotest.qbs
@@ -37,6 +37,8 @@ QtcPlugin {
"autotestconstants.h",
"autotestplugin.cpp",
"autotestplugin.h",
+ "projectsettingswidget.cpp",
+ "projectsettingswidget.h",
"testcodeparser.cpp",
"testcodeparser.h",
"testconfiguration.cpp",
@@ -70,6 +72,8 @@ QtcPlugin {
"testtreeview.h",
"testoutputreader.cpp",
"testoutputreader.h",
+ "testprojectsettings.cpp",
+ "testprojectsettings.h",
"itestparser.cpp",
"itestparser.h",
"itestframework.h",
diff --git a/src/plugins/autotest/autotest.qrc b/src/plugins/autotest/autotest.qrc
index 51d19022da..c7b86214e7 100644
--- a/src/plugins/autotest/autotest.qrc
+++ b/src/plugins/autotest/autotest.qrc
@@ -6,18 +6,12 @@
<file>images/leafsort@2x.png</file>
<file>images/benchmark.png</file>
<file>images/benchmark@2x.png</file>
- <file>images/runselected_boxes.png</file>
- <file>images/runselected_boxes@2x.png</file>
- <file>images/runselected_tickmarks.png</file>
- <file>images/runselected_tickmarks@2x.png</file>
<file>images/data.png</file>
<file>images/data@2x.png</file>
<file>images/text.png</file>
<file>images/text@2x.png</file>
<file>images/visual.png</file>
<file>images/visual@2x.png</file>
- <file>images/run_file.png</file>
- <file>images/run_file@2x.png</file>
<file>images/suite.png</file>
<file>images/suite@2x.png</file>
</qresource>
diff --git a/src/plugins/autotest/autotestconstants.h b/src/plugins/autotest/autotestconstants.h
index 1f92aba915..7bed3cf346 100644
--- a/src/plugins/autotest/autotestconstants.h
+++ b/src/plugins/autotest/autotestconstants.h
@@ -47,15 +47,16 @@ const char FRAMEWORK_PREFIX[] = "AutoTest.Framework.";
const char SETTINGSPAGE_PREFIX[] = "A.AutoTest.";
const char SETTINGSGROUP[] = "Autotest";
const char TASK_MARK_ID[] = "Autotest.TaskMark";
+const char SK_USE_GLOBAL[] = "AutoTest.UseGlobal";
} // namespace Constants
-namespace Internal {
enum class TestRunMode
{
+ None,
Run,
RunWithoutDeploy,
Debug,
- DebugWithoutDeploy
+ DebugWithoutDeploy,
+ RunAfterBuild
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/autotesticons.h b/src/plugins/autotest/autotesticons.h
index c8bfb63bbf..7b6714d861 100644
--- a/src/plugins/autotest/autotesticons.h
+++ b/src/plugins/autotest/autotesticons.h
@@ -32,12 +32,12 @@ namespace Icons {
const Utils::Icon SORT_NATURALLY({
{":/autotest/images/leafsort.png", Utils::Theme::IconsBaseColor}});
+
const Utils::Icon RUN_SELECTED_OVERLAY({
- {":/autotest/images/runselected_boxes.png", Utils::Theme::BackgroundColorDark},
- {":/autotest/images/runselected_tickmarks.png", Utils::Theme::IconsBaseColor}});
+ {":/utils/images/runselected_boxes.png", Utils::Theme::BackgroundColorDark},
+ {":/utils/images/runselected_tickmarks.png", Utils::Theme::IconsBaseColor}});
const Utils::Icon RUN_FILE_OVERLAY({
- {":/autotest/images/run_file.png", Utils::Theme::IconsBaseColor}});
-
+ {":/utils/images/run_file.png", Utils::Theme::IconsBaseColor}});
const Utils::Icon RESULT_PASS({
{":/utils/images/filledcircle.png", Utils::Theme::OutputPanes_TestPassTextColor}},
Utils::Icon::Tint);
diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp
index 5f90f33aca..c4980478db 100644
--- a/src/plugins/autotest/autotestplugin.cpp
+++ b/src/plugins/autotest/autotestplugin.cpp
@@ -26,8 +26,10 @@
#include "autotestplugin.h"
#include "autotestconstants.h"
#include "autotesticons.h"
+#include "projectsettingswidget.h"
#include "testcodeparser.h"
#include "testframeworkmanager.h"
+#include "testprojectsettings.h"
#include "testrunner.h"
#include "testsettings.h"
#include "testsettingspage.h"
@@ -54,6 +56,7 @@
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorericons.h>
+#include <projectexplorer/projectpanelfactory.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
@@ -64,6 +67,7 @@
#include <QAction>
#include <QList>
+#include <QMap>
#include <QMessageBox>
#include <QMainWindow>
#include <QMenu>
@@ -74,10 +78,34 @@
#include "autotestunittests.h"
#endif
-using namespace Autotest::Internal;
using namespace Core;
+namespace Autotest {
+namespace Internal {
+
+class AutotestPluginPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AutotestPluginPrivate(AutotestPlugin *parent);
+ ~AutotestPluginPrivate() override;
+
+ AutotestPlugin *q = nullptr;
+ TestFrameworkManager *m_frameworkManager = nullptr;
+ TestSettingsPage *m_testSettingPage = nullptr;
+ TestNavigationWidgetFactory *m_navigationWidgetFactory = nullptr;
+ TestResultsPane *m_resultsPane = nullptr;
+ QMap<QString, ChoicePair> m_runconfigCache;
+
+ void initializeMenuEntries();
+ void onRunAllTriggered();
+ void onRunSelectedTriggered();
+ void onRunFileTriggered();
+ void onRunUnderCursorTriggered(TestRunMode mode);
+};
+
static AutotestPlugin *s_instance = nullptr;
+static QHash<ProjectExplorer::Project *, TestProjectSettings *> s_projectSettings;
AutotestPlugin::AutotestPlugin()
: m_settings(new TestSettings)
@@ -92,6 +120,45 @@ AutotestPlugin::AutotestPlugin()
AutotestPlugin::~AutotestPlugin()
{
+ delete d;
+}
+
+AutotestPluginPrivate::AutotestPluginPrivate(AutotestPlugin *parent)
+ : q(parent)
+{
+ m_frameworkManager = TestFrameworkManager::instance();
+ initializeMenuEntries();
+ m_frameworkManager->registerTestFramework(new QtTestFramework);
+ m_frameworkManager->registerTestFramework(new QuickTestFramework);
+ m_frameworkManager->registerTestFramework(new GTestFramework);
+ m_frameworkManager->registerTestFramework(new BoostTestFramework);
+
+ m_frameworkManager->synchronizeSettings(ICore::settings());
+ m_testSettingPage = new TestSettingsPage(q->settings());
+ m_navigationWidgetFactory = new TestNavigationWidgetFactory;
+ m_resultsPane = TestResultsPane::instance();
+
+ auto panelFactory = new ProjectExplorer::ProjectPanelFactory();
+ panelFactory->setPriority(666);
+// panelFactory->setIcon(); // TODO ?
+ panelFactory->setDisplayName(tr("Testing"));
+ panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) {
+ return new ProjectTestSettingsWidget(project);
+ });
+ ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
+
+ m_frameworkManager->activateFrameworksFromSettings(q->settings());
+ TestTreeModel::instance()->synchronizeTestFrameworks();
+
+ connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::startupProjectChanged, this, [this] {
+ m_runconfigCache.clear();
+ });
+
+}
+
+AutotestPluginPrivate::~AutotestPluginPrivate()
+{
delete m_navigationWidgetFactory;
delete m_resultsPane;
delete m_testSettingPage;
@@ -103,7 +170,16 @@ QSharedPointer<TestSettings> AutotestPlugin::settings()
return s_instance->m_settings;
}
-void AutotestPlugin::initializeMenuEntries()
+TestProjectSettings *AutotestPlugin::projectSettings(ProjectExplorer::Project *project)
+{
+ auto &settings = s_projectSettings[project];
+ if (!settings)
+ settings = new TestProjectSettings(project);
+
+ return settings;
+}
+
+void AutotestPluginPrivate::initializeMenuEntries()
{
ActionContainer *menu = ActionManager::createMenu(Constants::MENU_ID);
menu->menu()->setTitle(tr("&Tests"));
@@ -115,7 +191,7 @@ void AutotestPlugin::initializeMenuEntries()
Command *command = ActionManager::registerAction(action, Constants::ACTION_RUN_ALL_ID);
command->setDefaultKeySequence(
QKeySequence(useMacShortcuts ? tr("Ctrl+Meta+T, Ctrl+Meta+A") : tr("Alt+Shift+T,Alt+A")));
- connect(action, &QAction::triggered, this, &AutotestPlugin::onRunAllTriggered);
+ connect(action, &QAction::triggered, this, &AutotestPluginPrivate::onRunAllTriggered);
action->setEnabled(false);
menu->addAction(command);
@@ -128,7 +204,7 @@ void AutotestPlugin::initializeMenuEntries()
command = ActionManager::registerAction(action, Constants::ACTION_RUN_SELECTED_ID);
command->setDefaultKeySequence(
QKeySequence(useMacShortcuts ? tr("Ctrl+Meta+T, Ctrl+Meta+R") : tr("Alt+Shift+T,Alt+R")));
- connect(action, &QAction::triggered, this, &AutotestPlugin::onRunSelectedTriggered);
+ connect(action, &QAction::triggered, this, &AutotestPluginPrivate::onRunSelectedTriggered);
action->setEnabled(false);
menu->addAction(command);
@@ -141,7 +217,7 @@ void AutotestPlugin::initializeMenuEntries()
command = ActionManager::registerAction(action, Constants::ACTION_RUN_FILE_ID);
command->setDefaultKeySequence(
QKeySequence(useMacShortcuts ? tr("Ctrl+Meta+T, Ctrl+Meta+F") : tr("Alt+Shift+T,Alt+F")));
- connect(action, &QAction::triggered, this, &AutotestPlugin::onRunFileTriggered);
+ connect(action, &QAction::triggered, this, &AutotestPluginPrivate::onRunFileTriggered);
action->setEnabled(false);
menu->addAction(command);
@@ -172,25 +248,7 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri
Q_UNUSED(arguments)
Q_UNUSED(errorString)
- m_frameworkManager = TestFrameworkManager::instance();
- initializeMenuEntries();
- m_frameworkManager->registerTestFramework(new QtTestFramework);
- m_frameworkManager->registerTestFramework(new QuickTestFramework);
- m_frameworkManager->registerTestFramework(new GTestFramework);
- m_frameworkManager->registerTestFramework(new BoostTestFramework);
-
- m_frameworkManager->synchronizeSettings(ICore::settings());
- m_testSettingPage = new TestSettingsPage(m_settings);
- m_navigationWidgetFactory = new TestNavigationWidgetFactory;
- m_resultsPane = TestResultsPane::instance();
-
- m_frameworkManager->activateFrameworksFromSettings(m_settings);
- TestTreeModel::instance()->syncTestFrameworks();
-
- connect(ProjectExplorer::SessionManager::instance(),
- &ProjectExplorer::SessionManager::startupProjectChanged, this, [this] {
- m_runconfigCache.clear();
- });
+ d = new AutotestPluginPrivate(this);
return true;
}
@@ -205,19 +263,18 @@ void AutotestPlugin::extensionsInitialized()
action->setIcon(Utils::Icons::RUN_SMALL_TOOLBAR.icon());
Command *command = ActionManager::registerAction(action, Constants::ACTION_RUN_UCURSOR);
- connect(action, &QAction::triggered, std::bind(&AutotestPlugin::onRunUnderCursorTriggered, this,
- TestRunMode::Run));
+ connect(action, &QAction::triggered,
+ std::bind(&AutotestPluginPrivate::onRunUnderCursorTriggered, d, TestRunMode::Run));
contextMenu->addSeparator();
contextMenu->addAction(command);
- action = new QAction(tr("&Debug Test Under Cursor"), this);;
+ action = new QAction(tr("&Debug Test Under Cursor"), this);
action->setEnabled(false);
action->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL.icon());
-
command = ActionManager::registerAction(action, Constants::ACTION_RUN_DBG_UCURSOR);
- connect(action, &QAction::triggered, std::bind(&AutotestPlugin::onRunUnderCursorTriggered, this,
- TestRunMode::Debug));
+ connect(action, &QAction::triggered,
+ std::bind(&AutotestPluginPrivate::onRunUnderCursorTriggered, d, TestRunMode::Debug));
contextMenu->addAction(command);
contextMenu->addSeparator();
}
@@ -228,7 +285,7 @@ ExtensionSystem::IPlugin::ShutdownFlag AutotestPlugin::aboutToShutdown()
return SynchronousShutdown;
}
-void AutotestPlugin::onRunAllTriggered()
+void AutotestPluginPrivate::onRunAllTriggered()
{
TestRunner *runner = TestRunner::instance();
TestTreeModel *model = TestTreeModel::instance();
@@ -236,7 +293,7 @@ void AutotestPlugin::onRunAllTriggered()
runner->prepareToRunTests(TestRunMode::Run);
}
-void AutotestPlugin::onRunSelectedTriggered()
+void AutotestPluginPrivate::onRunSelectedTriggered()
{
TestRunner *runner = TestRunner::instance();
TestTreeModel *model = TestTreeModel::instance();
@@ -244,7 +301,7 @@ void AutotestPlugin::onRunSelectedTriggered()
runner->prepareToRunTests(TestRunMode::Run);
}
-void AutotestPlugin::onRunFileTriggered()
+void AutotestPluginPrivate::onRunFileTriggered()
{
const IDocument *document = EditorManager::currentDocument();
if (!document)
@@ -275,7 +332,7 @@ static QList<TestConfiguration *> testItemsToTestConfigurations(const QList<Test
return configs;
}
-void AutotestPlugin::onRunUnderCursorTriggered(TestRunMode mode)
+void AutotestPluginPrivate::onRunUnderCursorTriggered(TestRunMode mode)
{
TextEditor::BaseTextEditor *currentEditor = TextEditor::BaseTextEditor::currentTextEditor();
QTextCursor cursor = currentEditor->editorWidget()->textCursor();
@@ -289,7 +346,7 @@ void AutotestPlugin::onRunUnderCursorTriggered(TestRunMode mode)
return; // Wrong location triggered
// check whether we have been triggered on a test function definition
- const uint line = uint(currentEditor->currentLine());
+ const int line = currentEditor->currentLine();
const QString &filePath = currentEditor->textDocument()->filePath().toString();
const QList<TestTreeItem *> filteredItems = Utils::filtered(testsItems, [&](TestTreeItem *it){
return it->line() == line && it->filePath() == filePath;
@@ -337,24 +394,24 @@ void AutotestPlugin::updateMenuItemsEnabledState()
void AutotestPlugin::cacheRunConfigChoice(const QString &buildTargetKey, const ChoicePair &choice)
{
if (s_instance)
- s_instance->m_runconfigCache.insert(buildTargetKey, choice);
+ s_instance->d->m_runconfigCache.insert(buildTargetKey, choice);
}
ChoicePair AutotestPlugin::cachedChoiceFor(const QString &buildTargetKey)
{
- return s_instance ? s_instance->m_runconfigCache.value(buildTargetKey) : ChoicePair();
+ return s_instance ? s_instance->d->m_runconfigCache.value(buildTargetKey) : ChoicePair();
}
void AutotestPlugin::clearChoiceCache()
{
if (s_instance)
- s_instance->m_runconfigCache.clear();
+ s_instance->d->m_runconfigCache.clear();
}
void AutotestPlugin::popupResultsPane()
{
if (s_instance)
- s_instance->m_resultsPane->popup(Core::IOutputPane::NoModeSwitch);
+ s_instance->d->m_resultsPane->popup(Core::IOutputPane::NoModeSwitch);
}
QVector<QObject *> AutotestPlugin::createTestObjects() const
@@ -368,6 +425,10 @@ QVector<QObject *> AutotestPlugin::createTestObjects() const
bool ChoicePair::matches(const ProjectExplorer::RunConfiguration *rc) const
{
- return rc ? (rc->displayName() == displayName && rc->runnable().executable == executable)
- : false;
+ return rc && rc->displayName() == displayName && rc->runnable().executable.toString() == executable;
}
+
+} // Internal
+} // Autotest
+
+#include "autotestplugin.moc"
diff --git a/src/plugins/autotest/autotestplugin.h b/src/plugins/autotest/autotestplugin.h
index c846d3e0b0..b34fd95c36 100644
--- a/src/plugins/autotest/autotestplugin.h
+++ b/src/plugins/autotest/autotestplugin.h
@@ -31,17 +31,16 @@
#include <QMap>
-namespace ProjectExplorer { class RunConfiguration; }
+namespace ProjectExplorer {
+class Project;
+class RunConfiguration;
+}
namespace Autotest {
namespace Internal {
-class TestFrameworkManager;
-class TestNavigationWidgetFactory;
-class TestResultsPane;
+class TestProjectSettings;
struct TestSettings;
-class TestSettingsPage;
-enum class TestRunMode;
struct ChoicePair
{
@@ -67,6 +66,7 @@ public:
ShutdownFlag aboutToShutdown() override;
static QSharedPointer<TestSettings> settings();
+ static TestProjectSettings *projectSettings(ProjectExplorer::Project *project);
static void updateMenuItemsEnabledState();
static void cacheRunConfigChoice(const QString &buildTargetKey, const ChoicePair &choice);
static ChoicePair cachedChoiceFor(const QString &buildTargetKey);
@@ -74,18 +74,9 @@ public:
static void popupResultsPane();
private:
- void initializeMenuEntries();
- void onRunAllTriggered();
- void onRunSelectedTriggered();
- void onRunFileTriggered();
- void onRunUnderCursorTriggered(TestRunMode mode);
QVector<QObject *> createTestObjects() const override;
+ class AutotestPluginPrivate *d = nullptr;
const QSharedPointer<TestSettings> m_settings;
- TestFrameworkManager *m_frameworkManager = nullptr;
- TestSettingsPage *m_testSettingPage = nullptr;
- TestNavigationWidgetFactory *m_navigationWidgetFactory = nullptr;
- TestResultsPane *m_resultsPane = nullptr;
- QMap<QString, ChoicePair> m_runconfigCache;
};
} // namespace Internal
diff --git a/src/plugins/autotest/autotestunittests.h b/src/plugins/autotest/autotestunittests.h
index 3b464fc709..0007875a3e 100644
--- a/src/plugins/autotest/autotestunittests.h
+++ b/src/plugins/autotest/autotestunittests.h
@@ -30,10 +30,11 @@
namespace CppTools { namespace Tests { class TemporaryCopiedDir; } }
namespace Autotest {
-namespace Internal {
class TestTreeModel;
+namespace Internal {
+
class AutoTestUnitTests : public QObject
{
Q_OBJECT
diff --git a/src/plugins/autotest/boost/boostcodeparser.cpp b/src/plugins/autotest/boost/boostcodeparser.cpp
index 79c612285b..42504a0562 100644
--- a/src/plugins/autotest/boost/boostcodeparser.cpp
+++ b/src/plugins/autotest/boost/boostcodeparser.cpp
@@ -70,7 +70,7 @@ static BoostTestCodeLocationAndType locationAndTypeFromToken(const Token &tkn,
static Tokens tokensForSource(const QByteArray &source, const LanguageFeatures &features)
{
- CPlusPlus::SimpleLexer lexer;
+ SimpleLexer lexer;
lexer.setPreprocessorMode(false); // or true? does not make a difference so far..
lexer.setLanguageFeatures(features);
return lexer(QString::fromUtf8(source));
diff --git a/src/plugins/autotest/boost/boostcodeparser.h b/src/plugins/autotest/boost/boostcodeparser.h
index 23fd4b3c03..ecdc4f84d0 100644
--- a/src/plugins/autotest/boost/boostcodeparser.h
+++ b/src/plugins/autotest/boost/boostcodeparser.h
@@ -75,7 +75,7 @@ private:
QVector<BoostTestInfo> m_suites;
QString m_currentSuite;
BoostTestTreeItem::TestStates m_currentState = BoostTestTreeItem::Enabled;
- unsigned m_lineNo = 0;
+ int m_lineNo = 0;
};
} // Internal
diff --git a/src/plugins/autotest/boost/boosttestoutputreader.h b/src/plugins/autotest/boost/boosttestoutputreader.h
index 91c38cb62f..41d0dbdf78 100644
--- a/src/plugins/autotest/boost/boosttestoutputreader.h
+++ b/src/plugins/autotest/boost/boosttestoutputreader.h
@@ -31,7 +31,6 @@ namespace Autotest {
namespace Internal {
class BoostTestResult;
-class TestTreeItem;
enum class LogLevel;
enum class ReportLevel;
diff --git a/src/plugins/autotest/boost/boosttestsettingspage.h b/src/plugins/autotest/boost/boosttestsettingspage.h
index 5e0e65f7b9..609bcf0b71 100644
--- a/src/plugins/autotest/boost/boosttestsettingspage.h
+++ b/src/plugins/autotest/boost/boosttestsettingspage.h
@@ -31,9 +31,11 @@
#include <QPointer>
namespace Autotest {
-namespace Internal {
class IFrameworkSettings;
+
+namespace Internal {
+
class BoostTestSettings;
class BoostTestSettingsWidget : public QWidget
diff --git a/src/plugins/autotest/boost/boosttesttreeitem.h b/src/plugins/autotest/boost/boosttesttreeitem.h
index 1149720f9d..a3676c39de 100644
--- a/src/plugins/autotest/boost/boosttesttreeitem.h
+++ b/src/plugins/autotest/boost/boosttesttreeitem.h
@@ -88,7 +88,7 @@ struct BoostTestInfo
{
QString fullName; // formatted like UNIX path
BoostTestTreeItem::TestStates state;
- unsigned line;
+ int line;
};
typedef QVector<BoostTestInfo> BoostTestInfoList;
diff --git a/src/plugins/autotest/gtest/gtestoutputreader.h b/src/plugins/autotest/gtest/gtestoutputreader.h
index 6684b77f44..96502255b8 100644
--- a/src/plugins/autotest/gtest/gtestoutputreader.h
+++ b/src/plugins/autotest/gtest/gtestoutputreader.h
@@ -33,7 +33,6 @@ namespace Autotest {
namespace Internal {
class GTestResult;
-class TestTreeItem;
class GTestOutputReader : public TestOutputReader
{
diff --git a/src/plugins/autotest/gtest/gtestsettingspage.cpp b/src/plugins/autotest/gtest/gtestsettingspage.cpp
index a500a10753..f1d4d2a827 100644
--- a/src/plugins/autotest/gtest/gtestsettingspage.cpp
+++ b/src/plugins/autotest/gtest/gtestsettingspage.cpp
@@ -40,8 +40,7 @@ static bool validateFilter(Utils::FancyLineEdit *edit, QString * /*error*/)
return edit && GTestUtils::isValidGTestFilter(edit->text());
}
-GTestSettingsWidget::GTestSettingsWidget(QWidget *parent)
- : QWidget(parent)
+GTestSettingsWidget::GTestSettingsWidget()
{
m_ui.setupUi(this);
m_ui.filterLineEdit->setValidationFunction(&validateFilter);
diff --git a/src/plugins/autotest/gtest/gtestsettingspage.h b/src/plugins/autotest/gtest/gtestsettingspage.h
index 5bee96ec33..3aa28fbe86 100644
--- a/src/plugins/autotest/gtest/gtestsettingspage.h
+++ b/src/plugins/autotest/gtest/gtestsettingspage.h
@@ -32,16 +32,19 @@
#include <QPointer>
namespace Autotest {
-namespace Internal {
class IFrameworkSettings;
+
+namespace Internal {
+
class GTestSettings;
class GTestSettingsWidget : public QWidget
{
Q_OBJECT
+
public:
- explicit GTestSettingsWidget(QWidget *parent = nullptr);
+ GTestSettingsWidget();
void setSettings(const GTestSettings &settings);
GTestSettings settings() const;
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp
index c344669b3c..fdae1fa309 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.cpp
+++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp
@@ -486,7 +486,7 @@ QSet<QString> GTestTreeItem::internalTargets() const
return pf.path == file;
})) {
result.insert(projectPart->buildSystemTarget);
- if (projectPart->buildTargetType != CppTools::ProjectPart::Executable)
+ if (projectPart->buildTargetType != ProjectExplorer::BuildTargetType::Executable)
result.unite(TestTreeItem::dependingInternalTargets(cppMM, file));
}
}
diff --git a/src/plugins/autotest/gtest/gtestvisitors.cpp b/src/plugins/autotest/gtest/gtestvisitors.cpp
index f7104ff93d..14198d76ae 100644
--- a/src/plugins/autotest/gtest/gtestvisitors.cpp
+++ b/src/plugins/autotest/gtest/gtestvisitors.cpp
@@ -69,8 +69,8 @@ bool GTestVisitor::visit(CPlusPlus::FunctionDefinitionAST *ast)
const bool disabled = testName.startsWith(disabledPrefix);
const bool disabledCase = testCaseName.startsWith(disabledPrefix);
- unsigned line = 0;
- unsigned column = 0;
+ int line = 0;
+ int column = 0;
unsigned token = id->firstToken();
m_document->translationUnit()->getTokenStartPosition(token, &line, &column);
diff --git a/src/plugins/autotest/iframeworksettings.h b/src/plugins/autotest/iframeworksettings.h
index 51ff6a79fa..3b09fad3d4 100644
--- a/src/plugins/autotest/iframeworksettings.h
+++ b/src/plugins/autotest/iframeworksettings.h
@@ -30,7 +30,6 @@
#include <QSettings>
namespace Autotest {
-namespace Internal {
class IFrameworkSettings
{
@@ -63,5 +62,4 @@ protected:
virtual void fromFrameworkSettings(const QSettings *s) = 0;
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/itestframework.h b/src/plugins/autotest/itestframework.h
index abcc218406..9753ccc12a 100644
--- a/src/plugins/autotest/itestframework.h
+++ b/src/plugins/autotest/itestframework.h
@@ -29,7 +29,6 @@
#include "itestparser.h"
namespace Autotest {
-namespace Internal {
class IFrameworkSettings;
class ITestSettingsPage;
@@ -50,7 +49,7 @@ public:
virtual IFrameworkSettings *createFrameworkSettings() const { return nullptr; }
virtual ITestSettingsPage *createSettingsPage(QSharedPointer<IFrameworkSettings> settings) const
{
- Q_UNUSED(settings);
+ Q_UNUSED(settings)
return nullptr;
}
@@ -84,5 +83,4 @@ private:
bool m_grouping = false;
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/itestparser.cpp b/src/plugins/autotest/itestparser.cpp
index b7e1f15245..f0310041d7 100644
--- a/src/plugins/autotest/itestparser.cpp
+++ b/src/plugins/autotest/itestparser.cpp
@@ -30,7 +30,6 @@
#include <utils/textfileformat.h>
namespace Autotest {
-namespace Internal {
static CppParser *s_parserInstance = nullptr;
@@ -41,8 +40,8 @@ CppParser::CppParser()
void CppParser::init(const QStringList &filesToParse, bool fullParse)
{
- Q_UNUSED(filesToParse);
- Q_UNUSED(fullParse);
+ Q_UNUSED(filesToParse)
+ Q_UNUSED(fullParse)
m_cppSnapshot = CppTools::CppModelManager::instance()->snapshot();
m_workingCopy = CppTools::CppModelManager::instance()->workingCopy();
}
@@ -83,5 +82,4 @@ CPlusPlus::Document::Ptr CppParser::document(const QString &fileName)
return selectedForBuilding(fileName) ? m_cppSnapshot.document(fileName) : nullptr;
}
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/itestparser.h b/src/plugins/autotest/itestparser.h
index b69b23b253..d9a8c92801 100644
--- a/src/plugins/autotest/itestparser.h
+++ b/src/plugins/autotest/itestparser.h
@@ -34,7 +34,6 @@
#include <qmljs/qmljsdocument.h>
namespace Autotest {
-namespace Internal {
class TestParseResult
{
@@ -51,8 +50,8 @@ public:
QString fileName;
QString proFile;
QString name;
- unsigned line = 0;
- unsigned column = 0;
+ int line = 0;
+ int column = 0;
};
using TestParseResultPtr = QSharedPointer<TestParseResult>;
@@ -88,7 +87,6 @@ protected:
CppTools::WorkingCopy m_workingCopy;
};
-} // namespace Internal
} // namespace Autotest
-Q_DECLARE_METATYPE(Autotest::Internal::TestParseResultPtr)
+Q_DECLARE_METATYPE(Autotest::TestParseResultPtr)
diff --git a/src/plugins/autotest/itestsettingspage.h b/src/plugins/autotest/itestsettingspage.h
index be4f05f491..c985efca61 100644
--- a/src/plugins/autotest/itestsettingspage.h
+++ b/src/plugins/autotest/itestsettingspage.h
@@ -31,7 +31,6 @@
#include <coreplugin/dialogs/ioptionspage.h>
namespace Autotest {
-namespace Internal {
class IFrameworkSettings;
@@ -64,5 +63,4 @@ private:
}
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/projectsettingswidget.cpp b/src/plugins/autotest/projectsettingswidget.cpp
new file mode 100644
index 0000000000..4fb66be7f8
--- /dev/null
+++ b/src/plugins/autotest/projectsettingswidget.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "autotestplugin.h"
+#include "projectsettingswidget.h"
+#include "testframeworkmanager.h"
+#include "testprojectsettings.h"
+
+#include <QBoxLayout>
+#include <QComboBox>
+#include <QLabel>
+#include <QTreeWidget>
+
+namespace Autotest {
+namespace Internal {
+
+enum ItemDataRole { FrameworkIdRole = Qt::UserRole + 1 };
+
+static QSpacerItem *createSpacer(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
+{
+ return new QSpacerItem(20, 10, horizontal, vertical);
+}
+
+ProjectTestSettingsWidget::ProjectTestSettingsWidget(ProjectExplorer::Project *project,
+ QWidget *parent)
+ : QWidget(parent)
+ , m_projectSettings(AutotestPlugin::projectSettings(project))
+{
+ auto verticalLayout = new QVBoxLayout(this);
+ m_useGlobalSettings = new QComboBox;
+ m_useGlobalSettings->addItem(tr("Global"));
+ m_useGlobalSettings->addItem(tr("Custom"));
+
+ auto generalWidget = new QWidget;
+ auto groupBoxLayout = new QVBoxLayout;
+ m_activeFrameworks = new QTreeWidget;
+ m_activeFrameworks->setHeaderHidden(true);
+ m_activeFrameworks->setRootIsDecorated(false);
+ groupBoxLayout->addWidget(new QLabel(tr("Active frameworks:")));
+ groupBoxLayout->addWidget(m_activeFrameworks);
+ auto horizontalLayout = new QHBoxLayout;
+ horizontalLayout->addWidget(new QLabel(tr("Automatically run tests after build")));
+ m_runAfterBuild = new QComboBox;
+ m_runAfterBuild->addItem(tr("None"));
+ m_runAfterBuild->addItem(tr("All"));
+ m_runAfterBuild->addItem(tr("Selected"));
+ m_runAfterBuild->setCurrentIndex(int(m_projectSettings->runAfterBuild()));
+ horizontalLayout->addWidget(m_runAfterBuild);
+ horizontalLayout->addItem(createSpacer(QSizePolicy::Expanding, QSizePolicy::Minimum));
+ groupBoxLayout->addLayout(horizontalLayout);
+ generalWidget->setLayout(groupBoxLayout);
+
+ horizontalLayout = new QHBoxLayout;
+ horizontalLayout->addWidget(m_useGlobalSettings);
+ horizontalLayout->addItem(createSpacer(QSizePolicy::Expanding, QSizePolicy::Minimum));
+ verticalLayout->addLayout(horizontalLayout);
+ horizontalLayout = new QHBoxLayout;
+ verticalLayout->addItem(createSpacer(QSizePolicy::Minimum, QSizePolicy::Fixed));
+ horizontalLayout->addWidget(generalWidget);
+ horizontalLayout->addItem(createSpacer(QSizePolicy::Expanding, QSizePolicy::Minimum));
+ verticalLayout->addLayout(horizontalLayout);
+ verticalLayout->addItem(createSpacer(QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ m_useGlobalSettings->setCurrentIndex(m_projectSettings->useGlobalSettings() ? 0 : 1);
+ generalWidget->setDisabled(m_projectSettings->useGlobalSettings());
+
+ populateFrameworks(m_projectSettings->activeFrameworks());
+
+ connect(m_useGlobalSettings, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, [this, generalWidget](int index) {
+ generalWidget->setEnabled(index != 0);
+ m_projectSettings->setUseGlobalSettings(index == 0);
+ m_syncFrameworksTimer.start(3000);
+ });
+ connect(m_activeFrameworks, &QTreeWidget::itemChanged,
+ this, &ProjectTestSettingsWidget::onActiveFrameworkChanged);
+ connect(m_runAfterBuild, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, [this](int index) {
+ m_projectSettings->setRunAfterBuild(RunAfterBuildMode(index));
+ });
+ m_syncFrameworksTimer.setSingleShot(true);
+ connect(&m_syncFrameworksTimer, &QTimer::timeout,
+ TestTreeModel::instance(), &TestTreeModel::synchronizeTestFrameworks);
+}
+
+void ProjectTestSettingsWidget::populateFrameworks(const QMap<Core::Id, bool> &frameworks)
+{
+ TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
+ auto end = frameworks.cend();
+ for (auto it = frameworks.cbegin(); it != end; ++it) {
+ auto *item = new QTreeWidgetItem(m_activeFrameworks,
+ QStringList(frameworkManager->frameworkNameForId(it.key())));
+ item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
+ item->setCheckState(0, it.value() ? Qt::Checked : Qt::Unchecked);
+ item->setData(0, FrameworkIdRole, it.key().toSetting());
+ }
+}
+
+void ProjectTestSettingsWidget::onActiveFrameworkChanged(QTreeWidgetItem *item, int column)
+{
+ auto id = Core::Id::fromSetting(item->data(column, FrameworkIdRole));
+ m_projectSettings->activateFramework(id, item->data(0, Qt::CheckStateRole) == Qt::Checked);
+ m_syncFrameworksTimer.start(3000);
+}
+
+} // namespace Internal
+} // namespace Autotest
diff --git a/src/plugins/qmakeprojectmanager/wizards/modulespage.h b/src/plugins/autotest/projectsettingswidget.h
index b867a434a4..66da382f02 100644
--- a/src/plugins/qmakeprojectmanager/wizards/modulespage.h
+++ b/src/plugins/autotest/projectsettingswidget.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,37 +25,38 @@
#pragma once
-#include <QMap>
-#include <QStringList>
-#include <QWizard>
+#include <QTimer>
+#include <QWidget>
QT_BEGIN_NAMESPACE
-class QCheckBox;
+class QComboBox;
+class QTreeWidget;
+class QTreeWidgetItem;
QT_END_NAMESPACE
-namespace QmakeProjectManager {
+namespace Core { class Id; }
+namespace ProjectExplorer { class Project; }
+
+namespace Autotest {
namespace Internal {
-class ModulesPage : public QWizardPage
+class TestProjectSettings;
+
+class ProjectTestSettingsWidget : public QWidget
{
Q_OBJECT
-
public:
- explicit ModulesPage(QWidget* parent = nullptr);
-
- QStringList selectedModulesList() const;
- QStringList deselectedModulesList() const;
-
- void setModuleSelected(const QString &module, bool selected = true) const;
- void setModuleEnabled(const QString &module, bool enabled = true) const;
-
- // Return the key that goes into the Qt config line for a module
- static QString idOfModule(const QString &module);
-
+ explicit ProjectTestSettingsWidget(ProjectExplorer::Project *project,
+ QWidget *parent = nullptr);
private:
- QMap<QString, QCheckBox*> m_moduleCheckBoxMap;
- QStringList modules(bool selected = true) const;
+ void populateFrameworks(const QMap<Core::Id, bool> &frameworks);
+ void onActiveFrameworkChanged(QTreeWidgetItem *item, int column);
+ TestProjectSettings *m_projectSettings;
+ QComboBox *m_useGlobalSettings = nullptr;
+ QTreeWidget *m_activeFrameworks = nullptr;
+ QComboBox *m_runAfterBuild = nullptr;
+ QTimer m_syncFrameworksTimer;
};
} // namespace Internal
-} // namespace QmakeProjectManager
+} // namespace Autotest
diff --git a/src/plugins/autotest/qtest/qttestparser.cpp b/src/plugins/autotest/qtest/qttestparser.cpp
index f03d9da923..fe0b3db70c 100644
--- a/src/plugins/autotest/qtest/qttestparser.cpp
+++ b/src/plugins/autotest/qtest/qttestparser.cpp
@@ -126,8 +126,8 @@ static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
const CPlusPlus::Snapshot &snapshot,
const QString &testCaseName,
const QStringList &alternativeFiles = {},
- unsigned *line = nullptr,
- unsigned *column = nullptr)
+ int *line = nullptr,
+ int *column = nullptr)
{
CPlusPlus::Document::Ptr declaringDoc;
CPlusPlus::TypeOfExpression typeOfExpr;
@@ -293,8 +293,8 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
if (testCaseName.isEmpty())
testCaseName = oldTestCaseName;
if (!testCaseName.isEmpty()) {
- unsigned line = 0;
- unsigned column = 0;
+ int line = 0;
+ int column = 0;
CPlusPlus::Document::Ptr declaringDoc = declaringDocument(document, snapshot, testCaseName,
alternativeFiles, &line, &column);
if (declaringDoc.isNull())
diff --git a/src/plugins/autotest/qtest/qttestsettingspage.cpp b/src/plugins/autotest/qtest/qttestsettingspage.cpp
index 8652738425..f7471f99f2 100644
--- a/src/plugins/autotest/qtest/qttestsettingspage.cpp
+++ b/src/plugins/autotest/qtest/qttestsettingspage.cpp
@@ -35,8 +35,7 @@
namespace Autotest {
namespace Internal {
-QtTestSettingsWidget::QtTestSettingsWidget(QWidget *parent)
- : QWidget(parent)
+QtTestSettingsWidget::QtTestSettingsWidget()
{
m_ui.setupUi(this);
m_ui.callgrindRB->setEnabled(Utils::HostOsInfo::isAnyUnixHost()); // valgrind available on UNIX
diff --git a/src/plugins/autotest/qtest/qttestsettingspage.h b/src/plugins/autotest/qtest/qttestsettingspage.h
index cb4e5850dc..aa1e39a48e 100644
--- a/src/plugins/autotest/qtest/qttestsettingspage.h
+++ b/src/plugins/autotest/qtest/qttestsettingspage.h
@@ -32,16 +32,19 @@
#include <QPointer>
namespace Autotest {
-namespace Internal {
class IFrameworkSettings;
+
+namespace Internal {
+
class QtTestSettings;
class QtTestSettingsWidget : public QWidget
{
Q_OBJECT
+
public:
- explicit QtTestSettingsWidget(QWidget *parent = nullptr);
+ QtTestSettingsWidget();
void setSettings(const QtTestSettings &settings);
QtTestSettings settings() const;
diff --git a/src/plugins/autotest/qtest/qttestvisitors.cpp b/src/plugins/autotest/qtest/qttestvisitors.cpp
index 58a69f2dbf..48177921bf 100644
--- a/src/plugins/autotest/qtest/qttestvisitors.cpp
+++ b/src/plugins/autotest/qtest/qttestvisitors.cpp
@@ -32,6 +32,8 @@
#include <cpptools/cppmodelmanager.h>
#include <utils/qtcassert.h>
+using namespace CPlusPlus;
+
namespace Autotest {
namespace Internal {
@@ -39,21 +41,21 @@ static QStringList specialFunctions({"initTestCase", "cleanupTestCase", "init",
/************************** Cpp Test Symbol Visitor ***************************/
-TestVisitor::TestVisitor(const QString &fullQualifiedClassName, const CPlusPlus::Snapshot &snapshot)
+TestVisitor::TestVisitor(const QString &fullQualifiedClassName, const Snapshot &snapshot)
: m_className(fullQualifiedClassName),
m_snapshot(snapshot)
{
}
-bool TestVisitor::visit(CPlusPlus::Class *symbol)
+bool TestVisitor::visit(Class *symbol)
{
- const CPlusPlus::Overview o;
- CPlusPlus::LookupContext lc;
+ const Overview o;
+ LookupContext lc;
- unsigned count = symbol->memberCount();
- for (unsigned i = 0; i < count; ++i) {
- CPlusPlus::Symbol *member = symbol->memberAt(i);
- CPlusPlus::Type *type = member->type().type();
+ int count = symbol->memberCount();
+ for (int i = 0; i < count; ++i) {
+ Symbol *member = symbol->memberAt(i);
+ Type *type = member->type().type();
const QString className = o.prettyName(lc.fullyQualifiedName(member->enclosingClass()));
if (className != m_className)
@@ -66,7 +68,7 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
const QString name = o.prettyName(func->name());
QtTestCodeLocationAndType locationAndType;
- CPlusPlus::Function *functionDefinition = m_symbolFinder.findMatchingDefinition(
+ Function *functionDefinition = m_symbolFinder.findMatchingDefinition(
func, m_snapshot, true);
if (functionDefinition && functionDefinition->fileId()) {
locationAndType.m_name = QString::fromUtf8(functionDefinition->fileName());
@@ -87,8 +89,8 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
m_privSlots.insert(className + "::" + name, locationAndType);
}
}
- for (unsigned counter = 0, end = symbol->baseClassCount(); counter < end; ++counter) {
- if (CPlusPlus::BaseClass *base = symbol->baseClassAt(counter)) {
+ for (int counter = 0, end = symbol->baseClassCount(); counter < end; ++counter) {
+ if (BaseClass *base = symbol->baseClassAt(counter)) {
const QString &baseClassName = o.prettyName(lc.fullyQualifiedName(base));
if (baseClassName != "QObject")
m_baseClasses.insert(baseClassName);
@@ -100,14 +102,14 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
/**************************** Cpp Test AST Visitor ****************************/
-TestAstVisitor::TestAstVisitor(CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot)
+TestAstVisitor::TestAstVisitor(Document::Ptr doc, const Snapshot &snapshot)
: ASTVisitor(doc->translationUnit()),
m_currentDoc(doc),
m_snapshot(snapshot)
{
}
-bool TestAstVisitor::visit(CPlusPlus::CallAST *ast)
+bool TestAstVisitor::visit(CallAST *ast)
{
if (!m_currentScope || m_currentDoc.isNull())
return false;
@@ -115,15 +117,15 @@ bool TestAstVisitor::visit(CPlusPlus::CallAST *ast)
if (const auto expressionAST = ast->base_expression) {
if (const auto idExpressionAST = expressionAST->asIdExpression()) {
if (const auto qualifiedNameAST = idExpressionAST->name->asQualifiedName()) {
- const CPlusPlus::Overview o;
+ const Overview o;
const QString prettyName = o.prettyName(qualifiedNameAST->name);
if (prettyName == "QTest::qExec") {
if (const auto expressionListAST = ast->expression_list) {
// first argument is the one we need
if (const auto argumentExpressionAST = expressionListAST->value) {
- CPlusPlus::TypeOfExpression toe;
+ TypeOfExpression toe;
toe.init(m_currentDoc, m_snapshot);
- QList<CPlusPlus::LookupItem> toeItems
+ QList<LookupItem> toeItems
= toe(argumentExpressionAST, m_currentDoc, m_currentScope);
if (toeItems.size()) {
@@ -139,7 +141,7 @@ bool TestAstVisitor::visit(CPlusPlus::CallAST *ast)
return false;
}
-bool TestAstVisitor::visit(CPlusPlus::CompoundStatementAST *ast)
+bool TestAstVisitor::visit(CompoundStatementAST *ast)
{
if (!ast || !ast->symbol) {
m_currentScope = nullptr;
@@ -151,13 +153,13 @@ bool TestAstVisitor::visit(CPlusPlus::CompoundStatementAST *ast)
/********************** Test Data Function AST Visitor ************************/
-TestDataFunctionVisitor::TestDataFunctionVisitor(CPlusPlus::Document::Ptr doc)
- : CPlusPlus::ASTVisitor(doc->translationUnit()),
+TestDataFunctionVisitor::TestDataFunctionVisitor(Document::Ptr doc)
+ : ASTVisitor(doc->translationUnit()),
m_currentDoc(doc)
{
}
-bool TestDataFunctionVisitor::visit(CPlusPlus::UsingDirectiveAST *ast)
+bool TestDataFunctionVisitor::visit(UsingDirectiveAST *ast)
{
if (auto nameAST = ast->name) {
if (m_overview.prettyName(nameAST->name) == "QTest") {
@@ -169,14 +171,14 @@ bool TestDataFunctionVisitor::visit(CPlusPlus::UsingDirectiveAST *ast)
return true;
}
-bool TestDataFunctionVisitor::visit(CPlusPlus::FunctionDefinitionAST *ast)
+bool TestDataFunctionVisitor::visit(FunctionDefinitionAST *ast)
{
if (ast->declarator) {
- CPlusPlus::DeclaratorIdAST *id = ast->declarator->core_declarator->asDeclaratorId();
+ DeclaratorIdAST *id = ast->declarator->core_declarator->asDeclaratorId();
if (!id || !ast->symbol || ast->symbol->argumentCount() != 0)
return false;
- CPlusPlus::LookupContext lc;
+ LookupContext lc;
const QString prettyName = m_overview.prettyName(lc.fullyQualifiedName(ast->symbol));
// do not handle functions that aren't real test data functions
if (!prettyName.endsWith("_data"))
@@ -190,7 +192,7 @@ bool TestDataFunctionVisitor::visit(CPlusPlus::FunctionDefinitionAST *ast)
return false;
}
-QString TestDataFunctionVisitor::extractNameFromAST(CPlusPlus::StringLiteralAST *ast, bool *ok) const
+QString TestDataFunctionVisitor::extractNameFromAST(StringLiteralAST *ast, bool *ok) const
{
auto token = m_currentDoc->translationUnit()->tokenAt(ast->literal_token);
if (!token.isStringLiteral()) {
@@ -200,7 +202,7 @@ QString TestDataFunctionVisitor::extractNameFromAST(CPlusPlus::StringLiteralAST
*ok = true;
QString name = QString::fromUtf8(token.spell());
if (ast->next) {
- CPlusPlus::StringLiteralAST *current = ast;
+ StringLiteralAST *current = ast;
do {
auto nextToken = m_currentDoc->translationUnit()->tokenAt(current->next->literal_token);
name.append(QString::fromUtf8(nextToken.spell()));
@@ -210,7 +212,7 @@ QString TestDataFunctionVisitor::extractNameFromAST(CPlusPlus::StringLiteralAST
return name;
}
-bool TestDataFunctionVisitor::visit(CPlusPlus::CallAST *ast)
+bool TestDataFunctionVisitor::visit(CallAST *ast)
{
if (m_currentFunction.isEmpty())
return true;
@@ -224,8 +226,8 @@ bool TestDataFunctionVisitor::visit(CPlusPlus::CallAST *ast)
bool ok = false;
QString name = extractNameFromAST(stringLiteral, &ok);
if (ok) {
- unsigned line = 0;
- unsigned column = 0;
+ int line = 0;
+ int column = 0;
m_currentDoc->translationUnit()->getTokenStartPosition(
firstToken, &line, &column);
QtTestCodeLocationAndType locationAndType;
@@ -242,13 +244,13 @@ bool TestDataFunctionVisitor::visit(CPlusPlus::CallAST *ast)
return true;
}
-bool TestDataFunctionVisitor::preVisit(CPlusPlus::AST *)
+bool TestDataFunctionVisitor::preVisit(AST *)
{
++m_currentAstDepth;
return true;
}
-void TestDataFunctionVisitor::postVisit(CPlusPlus::AST *ast)
+void TestDataFunctionVisitor::postVisit(AST *ast)
{
--m_currentAstDepth;
m_insideUsingQTest &= m_currentAstDepth >= m_insideUsingQTestDepth;
@@ -263,7 +265,7 @@ void TestDataFunctionVisitor::postVisit(CPlusPlus::AST *ast)
m_currentTags.clear();
}
-bool TestDataFunctionVisitor::newRowCallFound(CPlusPlus::CallAST *ast, unsigned *firstToken) const
+bool TestDataFunctionVisitor::newRowCallFound(CallAST *ast, unsigned *firstToken) const
{
QTC_ASSERT(firstToken, return false);
@@ -272,7 +274,7 @@ bool TestDataFunctionVisitor::newRowCallFound(CPlusPlus::CallAST *ast, unsigned
bool found = false;
- if (const CPlusPlus::IdExpressionAST *exp = ast->base_expression->asIdExpression()) {
+ if (const IdExpressionAST *exp = ast->base_expression->asIdExpression()) {
if (!exp->name)
return false;
diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp
index 72592b32a0..478735048c 100644
--- a/src/plugins/autotest/quick/quicktestparser.cpp
+++ b/src/plugins/autotest/quick/quicktestparser.cpp
@@ -39,6 +39,8 @@
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
+using namespace QmlJS;
+
namespace Autotest {
namespace Internal {
@@ -137,18 +139,18 @@ static QString quickTestName(const CPlusPlus::Document::Ptr &doc,
return astVisitor.testBaseName();
}
-QList<QmlJS::Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const
+QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const
{
QStringList dirs(srcDir);
- QmlJS::ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance();
+ ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance();
// make sure even files not listed in pro file are available inside the snapshot
QFutureInterface<void> future;
- QmlJS::PathsAndLanguages paths;
- paths.maybeInsert(Utils::FilePath::fromString(srcDir), QmlJS::Dialect::Qml);
- QmlJS::ModelManagerInterface::importScan(future, qmlJsMM->workingCopy(), paths, qmlJsMM,
+ PathsAndLanguages paths;
+ paths.maybeInsert(Utils::FilePath::fromString(srcDir), Dialect::Qml);
+ ModelManagerInterface::importScan(future, qmlJsMM->workingCopy(), paths, qmlJsMM,
false /*emitDocumentChanges*/, false /*onlyTheLib*/, true /*forceRescan*/ );
- const QmlJS::Snapshot snapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
+ const Snapshot snapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
QDirIterator it(srcDir, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
@@ -157,11 +159,11 @@ QList<QmlJS::Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(c
}
emit updateWatchPaths(dirs);
- QList<QmlJS::Document::Ptr> foundDocs;
+ QList<Document::Ptr> foundDocs;
for (const QString &path : dirs) {
- const QList<QmlJS::Document::Ptr> docs = snapshot.documentsInDirectory(path);
- for (const QmlJS::Document::Ptr &doc : docs) {
+ const QList<Document::Ptr> docs = snapshot.documentsInDirectory(path);
+ for (const Document::Ptr &doc : docs) {
const QFileInfo fi(doc->fileName());
// using working copy above might provide no more existing files
if (!fi.exists())
@@ -176,17 +178,17 @@ QList<QmlJS::Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(c
}
static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr> futureInterface,
- const QmlJS::Document::Ptr &qmlJSDoc,
+ const Document::Ptr &qmlJSDoc,
const Core::Id &id,
const QString &proFile = QString())
{
if (qmlJSDoc.isNull())
return false;
- QmlJS::AST::Node *ast = qmlJSDoc->ast();
+ AST::Node *ast = qmlJSDoc->ast();
QTC_ASSERT(ast, return false);
- QmlJS::Snapshot snapshot = QmlJS::ModelManagerInterface::instance()->snapshot();
+ Snapshot snapshot = ModelManagerInterface::instance()->snapshot();
TestQmlVisitor qmlVisitor(qmlJSDoc, snapshot);
- QmlJS::AST::Node::accept(ast, &qmlVisitor);
+ AST::Node::accept(ast, &qmlVisitor);
if (!qmlVisitor.isValid())
return false;
@@ -243,9 +245,9 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> fut
if (futureInterface.isCanceled())
return false;
- const QList<QmlJS::Document::Ptr> qmlDocs = scanDirectoryForQuickTestQmlFiles(srcDir);
+ const QList<Document::Ptr> qmlDocs = scanDirectoryForQuickTestQmlFiles(srcDir);
bool result = false;
- for (const QmlJS::Document::Ptr &qmlJSDoc : qmlDocs) {
+ for (const Document::Ptr &qmlJSDoc : qmlDocs) {
if (futureInterface.isCanceled())
break;
result |= checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, id, proFile);
@@ -276,14 +278,14 @@ void QuickTestParser::handleDirectoryChanged(const QString &directory)
return filesAndDates.value(file) != watched.value(file);
});
if (timestampChanged) {
- QmlJS::PathsAndLanguages paths;
- paths.maybeInsert(Utils::FilePath::fromString(directory), QmlJS::Dialect::Qml);
+ PathsAndLanguages paths;
+ paths.maybeInsert(Utils::FilePath::fromString(directory), Dialect::Qml);
QFutureInterface<void> future;
- QmlJS::ModelManagerInterface *qmlJsMM = QmlJS::ModelManagerInterface::instance();
- QmlJS::ModelManagerInterface::importScan(future, qmlJsMM->workingCopy(), paths, qmlJsMM,
- true /*emitDocumentChanges*/,
- false /*onlyTheLib*/,
- true /*forceRescan*/ );
+ ModelManagerInterface *qmlJsMM = ModelManagerInterface::instance();
+ ModelManagerInterface::importScan(future, qmlJsMM->workingCopy(), paths, qmlJsMM,
+ true /*emitDocumentChanges*/,
+ false /*onlyTheLib*/,
+ true /*forceRescan*/ );
}
}
}
@@ -335,7 +337,7 @@ void QuickTestParser::init(const QStringList &filesToParse, bool fullParse)
void QuickTestParser::release()
{
- m_qmlSnapshot = QmlJS::Snapshot();
+ m_qmlSnapshot = Snapshot();
m_proFilesForQmlFiles.clear();
CppParser::release();
}
@@ -347,7 +349,7 @@ bool QuickTestParser::processDocument(QFutureInterface<TestParseResultPtr> futur
const QString &proFile = m_proFilesForQmlFiles.value(fileName);
if (proFile.isEmpty())
return false;
- QmlJS::Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName);
+ Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName);
return checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, id(), proFile);
}
if (!m_cppSnapshot.contains(fileName) || !selectedForBuilding(fileName))
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp
index 85f459ea01..bb09159af1 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.cpp
+++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp
@@ -418,7 +418,7 @@ QSet<QString> QuickTestTreeItem::internalTargets() const
const auto cppMM = CppTools::CppModelManager::instance();
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo.projectParts()) {
- if (projectPart->buildTargetType != CppTools::ProjectPart::Executable)
+ if (projectPart->buildTargetType != ProjectExplorer::BuildTargetType::Executable)
continue;
if (projectPart->projectFile == proFile()) {
result.insert(projectPart->buildSystemTarget);
@@ -456,7 +456,7 @@ TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const QString &fileP
}
TestTreeItem *QuickTestTreeItem::findChildByNameFileAndLine(const QString &name,
- const QString &filePath, unsigned line)
+ const QString &filePath, int line)
{
return findFirstLevelChild([name, filePath, line](const TestTreeItem *other) {
return other->filePath() == filePath && other->line() == line && other->name() == name;
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h
index 551d0865a2..f99db4ce54 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.h
+++ b/src/plugins/autotest/quick/quicktesttreeitem.h
@@ -60,7 +60,7 @@ private:
TestTreeItem *findChildByFileNameAndType(const QString &filePath, const QString &name,
Type tType);
TestTreeItem *findChildByNameFileAndLine(const QString &name, const QString &filePath,
- unsigned line);
+ int line);
TestTreeItem *unnamedQuickTests() const;
};
diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp
index 755d0e57de..deb5085ade 100644
--- a/src/plugins/autotest/testcodeparser.cpp
+++ b/src/plugins/autotest/testcodeparser.cpp
@@ -30,7 +30,6 @@
#include "testsettings.h"
#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <cpptools/cpptoolsconstants.h>
@@ -81,10 +80,6 @@ TestCodeParser::TestCodeParser(TestTreeModel *parent)
m_threadPool->setMaxThreadCount(std::max(QThread::idealThreadCount()/4, 1));
}
-TestCodeParser::~TestCodeParser()
-{
-}
-
void TestCodeParser::setState(State state)
{
if (m_parserState == Shutdown)
@@ -115,7 +110,7 @@ void TestCodeParser::setState(State state)
}
}
-void TestCodeParser::syncTestFrameworks(const QVector<Core::Id> &frameworkIds)
+void TestCodeParser::syncTestFrameworks(const QList<Core::Id> &frameworkIds)
{
if (m_parserState != Idle) {
// there's a running parse
@@ -131,35 +126,39 @@ void TestCodeParser::syncTestFrameworks(const QVector<Core::Id> &frameworkIds)
QTC_ASSERT(testParser, continue);
m_testCodeParsers.append(testParser);
}
- updateTestTree();
}
void TestCodeParser::emitUpdateTestTree(ITestParser *parser)
{
if (m_testCodeParsers.isEmpty())
return;
+ if (parser)
+ m_updateParsers.insert(parser->id());
+ else
+ m_updateParsers.clear();
if (m_singleShotScheduled) {
- if (m_updateParser && parser != m_updateParser)
- m_updateParser = nullptr;
qCDebug(LOG) << "not scheduling another updateTestTree";
return;
}
qCDebug(LOG) << "adding singleShot";
m_singleShotScheduled = true;
- m_updateParser = parser;
- QTimer::singleShot(1000, this, [this](){ updateTestTree(m_updateParser); });
+ QTimer::singleShot(1000, this, [this]() { updateTestTree(m_updateParsers); });
}
-void TestCodeParser::updateTestTree(ITestParser *parser)
+void TestCodeParser::updateTestTree(const QSet<Core::Id> &frameworkIds)
{
m_singleShotScheduled = false;
if (m_codeModelParsing) {
m_fullUpdatePostponed = true;
m_partialUpdatePostponed = false;
m_postponedFiles.clear();
- if (!parser || parser != m_updateParser)
- m_updateParser = nullptr;
+ if (frameworkIds.isEmpty()) {
+ m_updateParsers.clear();
+ } else {
+ for (const Core::Id &id : frameworkIds)
+ m_updateParsers.insert(id);
+ }
return;
}
@@ -168,7 +167,12 @@ void TestCodeParser::updateTestTree(ITestParser *parser)
m_fullUpdatePostponed = false;
qCDebug(LOG) << "calling scanForTests (updateTestTree)";
- scanForTests(QStringList(), parser);
+ QList<Core::Id> sortedFrameworks = Utils::toList(frameworkIds);
+ Utils::sort(sortedFrameworks, [manager = TestFrameworkManager::instance()]
+ (const Core::Id &lhs, const Core::Id &rhs) {
+ return manager->priority(lhs) < manager->priority(rhs);
+ });
+ scanForTests(QStringList(), sortedFrameworks);
}
// used internally to indicate a parse that failed due to having triggered a parse for a file that
@@ -206,6 +210,7 @@ void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
void TestCodeParser::onStartupProjectChanged(Project *project)
{
+ m_model->synchronizeTestFrameworks(); // we might have project settings
if (m_parserState == FullParse || m_parserState == PartialParse) {
qCDebug(LOG) << "Canceling scanForTest (startup project changed)";
Core::ProgressManager::instance()->cancelTasks(Constants::TASK_PARSE);
@@ -290,7 +295,7 @@ bool TestCodeParser::postponed(const QStringList &fileList)
QTC_ASSERT(false, return false); // should not happen at all
}
-static void parseFileForTests(const QVector<ITestParser *> &parsers,
+static void parseFileForTests(const QList<ITestParser *> &parsers,
QFutureInterface<TestParseResultPtr> &futureInterface,
const QString &fileName)
{
@@ -302,12 +307,10 @@ static void parseFileForTests(const QVector<ITestParser *> &parsers,
}
}
-void TestCodeParser::scanForTests(const QStringList &fileList, ITestParser *parser)
+void TestCodeParser::scanForTests(const QStringList &fileList, const QList<Core::Id> &parserIds)
{
if (m_parserState == Shutdown || m_testCodeParsers.isEmpty())
return;
- if (parser && !m_testCodeParsers.contains(parser))
- return;
if (postponed(fileList))
return;
@@ -338,42 +341,37 @@ void TestCodeParser::scanForTests(const QStringList &fileList, ITestParser *pars
}
parsingHasFailed = false;
-
+ TestFrameworkManager *manager = TestFrameworkManager::instance();
if (isFullParse) {
// remove qml files as they will be found automatically by the referencing cpp file
list = Utils::filtered(list, [] (const QString &fn) {
return !fn.endsWith(".qml");
});
- if (parser)
- TestFrameworkManager::instance()->rootNodeForTestFramework(parser->id())->markForRemovalRecursively(true);
- else
+ if (!parserIds.isEmpty()) {
+ for (const Core::Id &id : parserIds)
+ manager->rootNodeForTestFramework(id)->markForRemovalRecursively(true);
+ } else {
m_model->markAllForRemoval();
- } else if (parser) {
- TestTreeItem *root = TestFrameworkManager::instance()->rootNodeForTestFramework(parser->id());
- for (const QString &filePath : list)
- root->markForRemovalRecursively(filePath);
+ }
+ } else if (!parserIds.isEmpty()) {
+ for (const Core::Id &id : parserIds) {
+ TestTreeItem *root = manager->rootNodeForTestFramework(id);
+ for (const QString &filePath : list)
+ root->markForRemovalRecursively(filePath);
+ }
} else {
for (const QString &filePath : list)
m_model->markForRemoval(filePath);
}
- if (list.isEmpty()) {
- if (isFullParse) {
- Core::MessageManager::instance()->write(
- tr("AutoTest Plugin WARNING: No files left after filtering test scan "
- "folders. Check test filter settings."),
- Core::MessageManager::Flash);
- }
- onFinished();
- return;
- }
+ QTC_ASSERT(!(isFullParse && list.isEmpty()), onFinished(); return);
// use only a single parser or all current active?
- QVector<ITestParser *> codeParsers;
- if (parser)
- codeParsers.append(parser);
- else
- codeParsers.append(m_testCodeParsers);
+ const QList<ITestParser *> codeParsers
+ = parserIds.isEmpty() ? m_testCodeParsers
+ : Utils::transform(parserIds, [](const Core::Id &id) {
+ return TestFrameworkManager::instance()->testParserForTestFramework(id);
+ });
qCDebug(LOG) << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "StartParsing";
for (ITestParser *parser : codeParsers)
parser->init(list, isFullParse);
@@ -441,7 +439,7 @@ void TestCodeParser::onFinished()
} else {
qCDebug(LOG) << "emitting parsingFinished"
<< "(onFinished, FullParse, nothing postponed, parsing succeeded)";
- m_updateParser = nullptr;
+ m_updateParsers.clear();
emit parsingFinished();
qCDebug(LOG) << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "ParsingFin";
}
@@ -464,7 +462,7 @@ void TestCodeParser::onPartialParsingFinished()
if (m_fullUpdatePostponed) {
m_fullUpdatePostponed = false;
qCDebug(LOG) << "calling updateTestTree (onPartialParsingFinished)";
- updateTestTree(m_updateParser);
+ updateTestTree(m_updateParsers);
} else if (m_partialUpdatePostponed) {
m_partialUpdatePostponed = false;
qCDebug(LOG) << "calling scanForTests with postponed files (onPartialParsingFinished)";
@@ -478,7 +476,7 @@ void TestCodeParser::onPartialParsingFinished()
} else if (!m_singleShotScheduled) {
qCDebug(LOG) << "emitting parsingFinished"
<< "(onPartialParsingFinished, nothing postponed, not dirty)";
- m_updateParser = nullptr;
+ m_updateParsers.clear();
emit parsingFinished();
qCDebug(LOG) << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "ParsingFin";
} else {
diff --git a/src/plugins/autotest/testcodeparser.h b/src/plugins/autotest/testcodeparser.h
index 0bd9fa85a5..867a6349e6 100644
--- a/src/plugins/autotest/testcodeparser.h
+++ b/src/plugins/autotest/testcodeparser.h
@@ -57,12 +57,11 @@ public:
};
explicit TestCodeParser(TestTreeModel *parent = nullptr);
- virtual ~TestCodeParser();
void setState(State state);
State state() const { return m_parserState; }
bool isParsing() const { return m_parserState == PartialParse || m_parserState == FullParse; }
void setDirty() { m_dirty = true; }
- void syncTestFrameworks(const QVector<Core::Id> &frameworkIds);
+ void syncTestFrameworks(const QList<Core::Id> &frameworkIds);
#ifdef WITH_TESTS
bool furtherParsingExpected() const
{ return m_singleShotScheduled || m_fullUpdatePostponed || m_partialUpdatePostponed; }
@@ -77,7 +76,7 @@ signals:
public:
void emitUpdateTestTree(ITestParser *parser = nullptr);
- void updateTestTree(ITestParser *parser = nullptr);
+ void updateTestTree(const QSet<Core::Id> &frameworkIds = {});
void onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document);
void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document);
void onStartupProjectChanged(ProjectExplorer::Project *project);
@@ -86,7 +85,8 @@ public:
private:
bool postponed(const QStringList &fileList);
- void scanForTests(const QStringList &fileList = QStringList(), ITestParser *parser = nullptr);
+ void scanForTests(const QStringList &fileList = QStringList(),
+ const QList<Core::Id> &parserIds = {});
// qml files must be handled slightly different
void onDocumentUpdated(const QString &fileName, bool isQmlFile = false);
@@ -108,9 +108,9 @@ private:
QSet<QString> m_postponedFiles;
State m_parserState = Idle;
QFutureWatcher<TestParseResultPtr> m_futureWatcher;
- QVector<ITestParser *> m_testCodeParsers; // ptrs are still owned by TestFrameworkManager
+ QList<ITestParser *> m_testCodeParsers; // ptrs are still owned by TestFrameworkManager
QTimer m_reparseTimer;
- ITestParser *m_updateParser = nullptr;
+ QSet<Core::Id> m_updateParsers;
QThreadPool *m_threadPool = nullptr;
};
diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp
index 6f7078eefb..38704fe07c 100644
--- a/src/plugins/autotest/testconfiguration.cpp
+++ b/src/plugins/autotest/testconfiguration.cpp
@@ -44,9 +44,9 @@
static Q_LOGGING_CATEGORY(LOG, "qtc.autotest.testconfiguration", QtWarningMsg)
using namespace ProjectExplorer;
+using namespace Utils;
namespace Autotest {
-namespace Internal {
TestConfiguration::~TestConfiguration()
{
@@ -59,11 +59,11 @@ static bool isLocal(Target *target)
return DeviceTypeKitAspect::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
}
-static QString ensureExeEnding(const QString& file)
+static FilePath ensureExeEnding(const FilePath &file)
{
- if (!Utils::HostOsInfo::isWindowsHost() || file.isEmpty() || file.toLower().endsWith(".exe"))
+ if (!HostOsInfo::isWindowsHost() || file.isEmpty() || file.toString().toLower().endsWith(".exe"))
return file;
- return Utils::HostOsInfo::withExecutableSuffix(file);
+ return FilePath::fromString(HostOsInfo::withExecutableSuffix(file.toString()));
}
void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguration *rc,
@@ -84,17 +84,15 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
if (!target)
return;
- if (!Utils::findOr(target->runConfigurations(), nullptr,
- [&rc] (RunConfiguration *config) { return rc == config; })) {
+ if (!target->runConfigurations().contains(rc))
return;
- }
m_runnable = rc->runnable();
m_displayName = rc->displayName();
BuildTargetInfo targetInfo = rc->buildTargetInfo();
if (!targetInfo.targetFilePath.isEmpty())
- m_runnable.executable = ensureExeEnding(targetInfo.targetFilePath.toString());
+ m_runnable.executable = ensureExeEnding(targetInfo.targetFilePath);
QString buildBase;
if (auto buildConfig = target->activeBuildConfiguration()) {
@@ -104,7 +102,7 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
}
if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy)
- m_runConfig = new TestRunConfiguration(rc->target(), this);
+ m_runConfig = new Internal::TestRunConfiguration(rc->target(), this);
}
void TestConfiguration::completeTestInformation(TestRunMode runMode)
@@ -157,7 +155,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
}
}
- const QString localExecutable = ensureExeEnding(targetInfo.targetFilePath.toString());
+ const FilePath localExecutable = ensureExeEnding(targetInfo.targetFilePath);
if (localExecutable.isEmpty())
return;
@@ -174,8 +172,8 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
const DeploymentData &deployData = target->deploymentData();
const DeployableFile deploy = deployData.deployableForLocalFile(localExecutable);
// we might have a deployable executable
- const QString deployedExecutable = ensureExeEnding((deploy.isValid() && deploy.isExecutable())
- ? QDir::cleanPath(deploy.remoteFilePath()) : localExecutable);
+ const FilePath deployedExecutable = ensureExeEnding((deploy.isValid() && deploy.isExecutable())
+ ? FilePath::fromString(QDir::cleanPath(deploy.remoteFilePath())) : localExecutable);
qCDebug(LOG) << " LocalExecutable" << localExecutable;
qCDebug(LOG) << " DeployedExecutable" << deployedExecutable;
@@ -190,7 +188,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
const Runnable runnable = runConfig->runnable();
// not the best approach - but depending on the build system and whether the executables
// are going to get installed or not we have to soften the condition...
- const QString currentExecutable = ensureExeEnding(runnable.executable);
+ const FilePath currentExecutable = ensureExeEnding(runnable.executable);
const QString currentBST = runConfig->buildKey();
qCDebug(LOG) << " CurrentExecutable" << currentExecutable;
qCDebug(LOG) << " BST of RunConfig" << currentBST;
@@ -203,7 +201,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
m_runnable.executable = currentExecutable;
m_displayName = runConfig->displayName();
if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy)
- m_runConfig = new TestRunConfiguration(target, this);
+ m_runConfig = new Internal::TestRunConfiguration(target, this);
break;
}
}
@@ -224,7 +222,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
m_deducedConfiguration = true;
m_deducedFrom = rc->displayName();
if (runMode == TestRunMode::Debug)
- m_runConfig = new TestRunConfiguration(rc->target(), this);
+ m_runConfig = new Internal::TestRunConfiguration(rc->target(), this);
} else {
qCDebug(LOG) << "not using the fallback as the current active run configuration "
"appears to be non-Desktop";
@@ -258,7 +256,7 @@ void TestConfiguration::setTestCaseCount(int count)
void TestConfiguration::setExecutableFile(const QString &executableFile)
{
- m_runnable.executable = executableFile;
+ m_runnable.executable = Utils::FilePath::fromString(executableFile);
}
void TestConfiguration::setProjectFile(const QString &projectFile)
@@ -312,11 +310,11 @@ QString TestConfiguration::executableFilePath() const
if (!hasExecutable())
return QString();
- QFileInfo commandFileInfo(m_runnable.executable);
+ QFileInfo commandFileInfo = m_runnable.executable.toFileInfo();
if (commandFileInfo.isExecutable() && commandFileInfo.path() != ".") {
return commandFileInfo.absoluteFilePath();
} else if (commandFileInfo.path() == "."){
- QString fullCommandFileName = m_runnable.executable;
+ QString fullCommandFileName = m_runnable.executable.toString();
// TODO: check if we can use searchInPath() from Utils::Environment
const QStringList &pathList = m_runnable.environment.toProcessEnvironment().value("PATH")
.split(Utils::HostOsInfo::pathListSeparator());
@@ -352,5 +350,4 @@ bool TestConfiguration::hasExecutable() const
return !m_runnable.executable.isEmpty();
}
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h
index fcd778c8ec..56533f8a52 100644
--- a/src/plugins/autotest/testconfiguration.h
+++ b/src/plugins/autotest/testconfiguration.h
@@ -42,10 +42,12 @@ QT_END_NAMESPACE
namespace Autotest {
namespace Internal {
+class TestRunConfiguration;
+} // namespace Internal
class TestOutputReader;
class TestResult;
-class TestRunConfiguration;
+enum class TestRunMode;
using TestResultPtr = QSharedPointer<TestResult>;
@@ -82,7 +84,7 @@ public:
ProjectExplorer::Project *project() const { return m_project.data(); }
QSet<QString> internalTargets() const { return m_buildTargets; }
ProjectExplorer::RunConfiguration *originalRunConfiguration() const { return m_origRunConfig; }
- TestRunConfiguration *runConfiguration() const { return m_runConfig; }
+ Internal::TestRunConfiguration *runConfiguration() const { return m_runConfig; }
bool hasExecutable() const;
bool isDeduced() const { return m_deducedConfiguration; }
QString runConfigDisplayName() const { return m_deducedConfiguration ? m_deducedFrom
@@ -102,7 +104,7 @@ private:
QString m_deducedFrom;
QPointer<ProjectExplorer::Project> m_project;
bool m_deducedConfiguration = false;
- TestRunConfiguration *m_runConfig = nullptr;
+ Internal::TestRunConfiguration *m_runConfig = nullptr;
QSet<QString> m_buildTargets;
ProjectExplorer::RunConfiguration *m_origRunConfig = nullptr;
ProjectExplorer::Runnable m_runnable;
@@ -124,5 +126,4 @@ private:
bool m_mixedDebugging = false;
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testframeworkmanager.cpp b/src/plugins/autotest/testframeworkmanager.cpp
index e96ee536ff..c6233d6026 100644
--- a/src/plugins/autotest/testframeworkmanager.cpp
+++ b/src/plugins/autotest/testframeworkmanager.cpp
@@ -42,15 +42,16 @@
static Q_LOGGING_CATEGORY(LOG, "qtc.autotest.frameworkmanager", QtWarningMsg)
+using namespace Core;
+
namespace Autotest {
-namespace Internal {
static TestFrameworkManager *s_instance = nullptr;
TestFrameworkManager::TestFrameworkManager()
{
m_testTreeModel = TestTreeModel::instance();
- m_testRunner = TestRunner::instance();
+ m_testRunner = Internal::TestRunner::instance();
s_instance = this;
}
@@ -74,7 +75,7 @@ TestFrameworkManager::~TestFrameworkManager()
bool TestFrameworkManager::registerTestFramework(ITestFramework *framework)
{
QTC_ASSERT(framework, return false);
- Core::Id id = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(framework->name());
+ Id id = Id(Constants::FRAMEWORK_PREFIX).withSuffix(framework->name());
QTC_ASSERT(!m_registeredFrameworks.contains(id), delete framework; return false);
// TODO check for unique priority before registering
qCDebug(LOG) << "Registering" << id;
@@ -89,7 +90,7 @@ bool TestFrameworkManager::registerTestFramework(ITestFramework *framework)
return true;
}
-void TestFrameworkManager::activateFrameworksFromSettings(QSharedPointer<TestSettings> settings)
+void TestFrameworkManager::activateFrameworksFromSettings(QSharedPointer<Internal::TestSettings> settings)
{
FrameworkIterator it = m_registeredFrameworks.begin();
FrameworkIterator end = m_registeredFrameworks.end();
@@ -99,30 +100,30 @@ void TestFrameworkManager::activateFrameworksFromSettings(QSharedPointer<TestSet
}
}
-QString TestFrameworkManager::frameworkNameForId(const Core::Id &id) const
+QString TestFrameworkManager::frameworkNameForId(const Id &id) const
{
ITestFramework *framework = m_registeredFrameworks.value(id, nullptr);
return framework ? QString::fromLatin1(framework->name()) : QString();
}
-QList<Core::Id> TestFrameworkManager::registeredFrameworkIds() const
+QList<Id> TestFrameworkManager::registeredFrameworkIds() const
{
return m_registeredFrameworks.keys();
}
-QList<Core::Id> TestFrameworkManager::sortedRegisteredFrameworkIds() const
+QList<Id> TestFrameworkManager::sortedRegisteredFrameworkIds() const
{
- QList<Core::Id> registered = m_registeredFrameworks.keys();
- Utils::sort(registered, [this] (const Core::Id &lhs, const Core::Id &rhs) {
+ QList<Id> registered = m_registeredFrameworks.keys();
+ Utils::sort(registered, [this] (const Id &lhs, const Id &rhs) {
return m_registeredFrameworks[lhs]->priority() < m_registeredFrameworks[rhs]->priority();
});
qCDebug(LOG) << "Registered frameworks sorted by priority" << registered;
return registered;
}
-QVector<Core::Id> TestFrameworkManager::activeFrameworkIds() const
+QList<Id> TestFrameworkManager::activeFrameworkIds() const
{
- QVector<Core::Id> active;
+ QList<Id> active;
FrameworkIterator it = m_registeredFrameworks.begin();
FrameworkIterator end = m_registeredFrameworks.end();
for ( ; it != end; ++it) {
@@ -132,23 +133,23 @@ QVector<Core::Id> TestFrameworkManager::activeFrameworkIds() const
return active;
}
-QVector<Core::Id> TestFrameworkManager::sortedActiveFrameworkIds() const
+QList<Id> TestFrameworkManager::sortedActiveFrameworkIds() const
{
- QVector<Core::Id> active = activeFrameworkIds();
- Utils::sort(active, [this] (const Core::Id &lhs, const Core::Id &rhs) {
+ QList<Id> active = activeFrameworkIds();
+ Utils::sort(active, [this] (const Id &lhs, const Id &rhs) {
return m_registeredFrameworks[lhs]->priority() < m_registeredFrameworks[rhs]->priority();
});
qCDebug(LOG) << "Active frameworks sorted by priority" << active;
return active;
}
-TestTreeItem *TestFrameworkManager::rootNodeForTestFramework(const Core::Id &frameworkId) const
+TestTreeItem *TestFrameworkManager::rootNodeForTestFramework(const Id &frameworkId) const
{
ITestFramework *framework = m_registeredFrameworks.value(frameworkId, nullptr);
return framework ? framework->rootNode() : nullptr;
}
-ITestParser *TestFrameworkManager::testParserForTestFramework(const Core::Id &frameworkId) const
+ITestParser *TestFrameworkManager::testParserForTestFramework(const Id &frameworkId) const
{
ITestFramework *framework = m_registeredFrameworks.value(frameworkId, nullptr);
if (!framework)
@@ -160,7 +161,7 @@ ITestParser *TestFrameworkManager::testParserForTestFramework(const Core::Id &fr
}
QSharedPointer<IFrameworkSettings> TestFrameworkManager::settingsForTestFramework(
- const Core::Id &frameworkId) const
+ const Id &frameworkId) const
{
return m_frameworkSettings.contains(frameworkId) ? m_frameworkSettings.value(frameworkId)
: QSharedPointer<IFrameworkSettings>();
@@ -168,33 +169,33 @@ QSharedPointer<IFrameworkSettings> TestFrameworkManager::settingsForTestFramewor
void TestFrameworkManager::synchronizeSettings(QSettings *s)
{
- AutotestPlugin::settings()->fromSettings(s);
- for (const Core::Id &id : m_frameworkSettings.keys()) {
+ Internal::AutotestPlugin::settings()->fromSettings(s);
+ for (const Id &id : m_frameworkSettings.keys()) {
QSharedPointer<IFrameworkSettings> fSettings = settingsForTestFramework(id);
if (!fSettings.isNull())
fSettings->fromSettings(s);
}
}
-bool TestFrameworkManager::isActive(const Core::Id &frameworkId) const
+bool TestFrameworkManager::isActive(const Id &frameworkId) const
{
ITestFramework *framework = m_registeredFrameworks.value(frameworkId);
return framework ? framework->active() : false;
}
-bool TestFrameworkManager::groupingEnabled(const Core::Id &frameworkId) const
+bool TestFrameworkManager::groupingEnabled(const Id &frameworkId) const
{
ITestFramework *framework = m_registeredFrameworks.value(frameworkId);
return framework ? framework->grouping() : false;
}
-void TestFrameworkManager::setGroupingEnabledFor(const Core::Id &frameworkId, bool enabled)
+void TestFrameworkManager::setGroupingEnabledFor(const Id &frameworkId, bool enabled)
{
if (ITestFramework *framework = m_registeredFrameworks.value(frameworkId))
framework->setGrouping(enabled);
}
-QString TestFrameworkManager::groupingToolTip(const Core::Id &frameworkId) const
+QString TestFrameworkManager::groupingToolTip(const Id &frameworkId) const
{
if (ITestFramework *framework = m_registeredFrameworks.value(frameworkId))
return framework->groupingToolTip();
@@ -210,5 +211,11 @@ bool TestFrameworkManager::hasActiveFrameworks() const
return false;
}
-} // namespace Internal
+unsigned TestFrameworkManager::priority(const Id &frameworkId) const
+{
+ if (ITestFramework *framework = m_registeredFrameworks.value(frameworkId))
+ return framework->priority();
+ return unsigned(-1);
+}
+
} // namespace Autotest
diff --git a/src/plugins/autotest/testframeworkmanager.h b/src/plugins/autotest/testframeworkmanager.h
index 2753202024..9d1c81079e 100644
--- a/src/plugins/autotest/testframeworkmanager.h
+++ b/src/plugins/autotest/testframeworkmanager.h
@@ -37,14 +37,19 @@ QT_END_NAMESPACE
namespace Core { class Id; }
namespace Autotest {
+
+class TestTreeItem;
+
namespace Internal {
+class TestRunner;
+struct TestSettings;
+
+}
+
class IFrameworkSettings;
class ITestParser;
class ITestSettingsPage;
-class TestRunner;
-struct TestSettings;
-class TestTreeItem;
class TestTreeModel;
class TestFrameworkManager
@@ -54,11 +59,11 @@ public:
virtual ~TestFrameworkManager();
bool registerTestFramework(ITestFramework *framework);
- void activateFrameworksFromSettings(QSharedPointer<TestSettings> settings);
+ void activateFrameworksFromSettings(QSharedPointer<Internal::TestSettings> settings);
QString frameworkNameForId(const Core::Id &id) const;
QList<Core::Id> registeredFrameworkIds() const;
QList<Core::Id> sortedRegisteredFrameworkIds() const;
- QVector<Core::Id> sortedActiveFrameworkIds() const;
+ QList<Core::Id> sortedActiveFrameworkIds() const;
TestTreeItem *rootNodeForTestFramework(const Core::Id &frameworkId) const;
ITestParser *testParserForTestFramework(const Core::Id &frameworkId) const;
@@ -69,18 +74,17 @@ public:
void setGroupingEnabledFor(const Core::Id &frameworkId, bool enabled);
QString groupingToolTip(const Core::Id &frameworkId) const;
bool hasActiveFrameworks() const;
-
+ unsigned priority(const Core::Id &frameworkId) const;
private:
- QVector<Core::Id> activeFrameworkIds() const;
+ QList<Core::Id> activeFrameworkIds() const;
explicit TestFrameworkManager();
QHash<Core::Id, ITestFramework *> m_registeredFrameworks;
QHash<Core::Id, QSharedPointer<IFrameworkSettings> > m_frameworkSettings;
QVector<ITestSettingsPage *> m_frameworkSettingsPages;
TestTreeModel *m_testTreeModel;
- TestRunner *m_testRunner;
+ Internal::TestRunner *m_testRunner;
typedef QHash<Core::Id, ITestFramework *>::ConstIterator FrameworkIterator;
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp
index 9899fcc32a..cf5db81364 100644
--- a/src/plugins/autotest/testnavigationwidget.cpp
+++ b/src/plugins/autotest/testnavigationwidget.cpp
@@ -78,7 +78,7 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) :
hLayout->addWidget(new QLabel(tr("No active test frameworks.")));
m_missingFrameworksWidget->setVisible(!TestFrameworkManager::instance()->hasActiveFrameworks());
QVBoxLayout *layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_missingFrameworksWidget);
layout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_view));
diff --git a/src/plugins/autotest/testnavigationwidget.h b/src/plugins/autotest/testnavigationwidget.h
index 422ade8c58..1160046b0b 100644
--- a/src/plugins/autotest/testnavigationwidget.h
+++ b/src/plugins/autotest/testnavigationwidget.h
@@ -47,9 +47,11 @@ class ProgressIndicator;
}
namespace Autotest {
-namespace Internal {
class TestTreeModel;
+
+namespace Internal {
+
class TestTreeSortFilterModel;
class TestTreeView;
diff --git a/src/plugins/autotest/testoutputreader.cpp b/src/plugins/autotest/testoutputreader.cpp
index 36da35543b..087189f394 100644
--- a/src/plugins/autotest/testoutputreader.cpp
+++ b/src/plugins/autotest/testoutputreader.cpp
@@ -33,7 +33,6 @@
#include <QProcess>
namespace Autotest {
-namespace Internal {
TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
QProcess *testApplication, const QString &buildDirectory)
@@ -102,5 +101,4 @@ void TestOutputReader::reportResult(const TestResultPtr &result)
m_hadValidOutput = true;
}
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h
index 87216a2570..763fe52ae7 100644
--- a/src/plugins/autotest/testoutputreader.h
+++ b/src/plugins/autotest/testoutputreader.h
@@ -33,7 +33,6 @@
#include <QString>
namespace Autotest {
-namespace Internal {
class TestOutputReader : public QObject
{
@@ -72,5 +71,4 @@ private:
bool m_hadValidOutput = false;
};
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testprojectsettings.cpp b/src/plugins/autotest/testprojectsettings.cpp
new file mode 100644
index 0000000000..47f672ea0f
--- /dev/null
+++ b/src/plugins/autotest/testprojectsettings.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "testprojectsettings.h"
+#include "autotestconstants.h"
+#include "testframeworkmanager.h"
+
+#include <projectexplorer/session.h>
+#include <utils/algorithm.h>
+
+namespace Autotest {
+namespace Internal {
+
+static const char SK_ACTIVE_FRAMEWORKS[] = "AutoTest.ActiveFrameworks";
+static const char SK_RUN_AFTER_BUILD[] = "AutoTest.RunAfterBuild";
+
+TestProjectSettings::TestProjectSettings(ProjectExplorer::Project *project)
+ : m_project(project)
+{
+ load();
+ connect(project, &ProjectExplorer::Project::settingsLoaded,
+ this, &TestProjectSettings::load);
+ connect(project, &ProjectExplorer::Project::aboutToSaveSettings,
+ this, &TestProjectSettings::save);
+}
+
+TestProjectSettings::~TestProjectSettings()
+{
+ save();
+}
+
+void TestProjectSettings::setUseGlobalSettings(bool useGlobal)
+{
+ if (m_useGlobalSettings == useGlobal)
+ return;
+ m_useGlobalSettings = useGlobal;
+}
+
+void TestProjectSettings::activateFramework(const Core::Id &id, bool activate)
+{
+ if (m_activeTestFrameworks.value(id) != activate) {
+ m_activeTestFrameworks[id] = activate;
+ }
+}
+
+void TestProjectSettings::load()
+{
+ const QVariant useGlobal = m_project->namedSettings(Constants::SK_USE_GLOBAL);
+ m_useGlobalSettings = useGlobal.isValid() ? useGlobal.toBool() : true;
+
+ TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
+ const QList<Core::Id> registered = frameworkManager->sortedRegisteredFrameworkIds();
+ const QVariant activeFrameworks = m_project->namedSettings(SK_ACTIVE_FRAMEWORKS);
+
+ m_activeTestFrameworks.clear();
+ if (activeFrameworks.isValid()) {
+ const QMap<QString, QVariant> frameworksMap = activeFrameworks.toMap();
+ for (const Core::Id &id : registered) {
+ const QString idStr = id.toString();
+ bool active = frameworksMap.value(idStr, frameworkManager->isActive(id)).toBool();
+ m_activeTestFrameworks.insert(id, active);
+ }
+ } else {
+ for (const Core::Id &id : registered)
+ m_activeTestFrameworks.insert(id, frameworkManager->isActive(id));
+ }
+
+ const QVariant runAfterBuild = m_project->namedSettings(SK_RUN_AFTER_BUILD);
+ m_runAfterBuild = runAfterBuild.isValid() ? RunAfterBuildMode(runAfterBuild.toInt())
+ : RunAfterBuildMode::None;
+}
+
+void TestProjectSettings::save()
+{
+ m_project->setNamedSettings(Constants::SK_USE_GLOBAL, m_useGlobalSettings);
+ QVariantMap activeFrameworks;
+ auto end = m_activeTestFrameworks.cend();
+ for (auto it = m_activeTestFrameworks.cbegin(); it != end; ++it)
+ activeFrameworks.insert(it.key().toString(), it.value());
+ m_project->setNamedSettings(SK_ACTIVE_FRAMEWORKS, activeFrameworks);
+ m_project->setNamedSettings(SK_RUN_AFTER_BUILD, int(m_runAfterBuild));
+}
+
+} // namespace Internal
+} // namespace Autotest
diff --git a/src/plugins/autotest/testprojectsettings.h b/src/plugins/autotest/testprojectsettings.h
new file mode 100644
index 0000000000..595032ff0c
--- /dev/null
+++ b/src/plugins/autotest/testprojectsettings.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "testsettings.h"
+
+#include <projectexplorer/project.h>
+
+namespace Autotest {
+namespace Internal {
+
+class TestProjectSettings : public QObject
+{
+ Q_OBJECT
+public:
+ TestProjectSettings(ProjectExplorer::Project *project);
+ ~TestProjectSettings();
+
+ void setUseGlobalSettings(bool useGlobal);
+ bool useGlobalSettings() const { return m_useGlobalSettings; }
+ void setRunAfterBuild(RunAfterBuildMode mode) {m_runAfterBuild = mode; }
+ RunAfterBuildMode runAfterBuild() const { return m_runAfterBuild; }
+ void setActiveFrameworks(const QMap<Core::Id, bool> enabledFrameworks)
+ { m_activeTestFrameworks = enabledFrameworks; }
+ QMap<Core::Id, bool> activeFrameworks() const { return m_activeTestFrameworks; }
+ void activateFramework(const Core::Id &id, bool activate);
+private:
+ void load();
+ void save();
+
+ ProjectExplorer::Project *m_project;
+ bool m_useGlobalSettings = true;
+ RunAfterBuildMode m_runAfterBuild = RunAfterBuildMode::None;
+ QMap<Core::Id, bool> m_activeTestFrameworks;
+};
+
+} // namespace Internal
+} // namespace Autotest
diff --git a/src/plugins/autotest/testresult.cpp b/src/plugins/autotest/testresult.cpp
index e9ff367ef9..13e120f3cc 100644
--- a/src/plugins/autotest/testresult.cpp
+++ b/src/plugins/autotest/testresult.cpp
@@ -29,7 +29,6 @@
#include <utils/theme/theme.h>
namespace Autotest {
-namespace Internal {
TestResult::TestResult(const QString &id, const QString &name)
: m_id(id)
@@ -189,5 +188,4 @@ TestResult *TestResult::createIntermediateResultFor(const TestResult *other)
return intermediate;
}
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testresult.h b/src/plugins/autotest/testresult.h
index 84fc2c144a..0c7be084c3 100644
--- a/src/plugins/autotest/testresult.h
+++ b/src/plugins/autotest/testresult.h
@@ -33,7 +33,6 @@
#include <QSharedPointer>
namespace Autotest {
-namespace Internal {
class TestTreeItem;
@@ -119,8 +118,7 @@ private:
using TestResultPtr = QSharedPointer<TestResult>;
-} // namespace Internal
} // namespace Autotest
-Q_DECLARE_METATYPE(Autotest::Internal::TestResult)
-Q_DECLARE_METATYPE(Autotest::Internal::ResultType)
+Q_DECLARE_METATYPE(Autotest::TestResult)
+Q_DECLARE_METATYPE(Autotest::ResultType)
diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp
index 468cc9e32c..c84be8481c 100644
--- a/src/plugins/autotest/testresultspane.cpp
+++ b/src/plugins/autotest/testresultspane.cpp
@@ -61,6 +61,8 @@
#include <QToolButton>
#include <QVBoxLayout>
+using namespace Core;
+
namespace Autotest {
namespace Internal {
@@ -80,14 +82,14 @@ void ResultsTreeView::keyPressEvent(QKeyEvent *event)
}
TestResultsPane::TestResultsPane(QObject *parent) :
- Core::IOutputPane(parent),
- m_context(new Core::IContext(this))
+ IOutputPane(parent),
+ m_context(new IContext(this))
{
m_outputWidget = new QStackedWidget;
QWidget *visualOutputWidget = new QWidget;
m_outputWidget->addWidget(visualOutputWidget);
QVBoxLayout *outputLayout = new QVBoxLayout;
- outputLayout->setMargin(0);
+ outputLayout->setContentsMargins(0, 0, 0, 0);
outputLayout->setSpacing(0);
visualOutputWidget->setLayout(outputLayout);
@@ -100,7 +102,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
m_summaryWidget->setPalette(pal);
m_summaryWidget->setAutoFillBackground(true);
QHBoxLayout *layout = new QHBoxLayout;
- layout->setMargin(6);
+ layout->setContentsMargins(6, 6, 6, 6);
m_summaryWidget->setLayout(layout);
m_summaryLabel = new QLabel;
m_summaryLabel->setPalette(pal);
@@ -123,7 +125,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
TestResultDelegate *trd = new TestResultDelegate(this);
m_treeView->setItemDelegate(trd);
- outputLayout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_treeView));
+ outputLayout->addWidget(ItemViewFind::createSearchableWrapper(m_treeView));
m_textOutput = new QPlainTextEdit;
m_textOutput->setPalette(pal);
@@ -136,7 +138,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
auto agg = new Aggregation::Aggregate;
agg->add(m_textOutput);
- agg->add(new Core::BaseTextFind(m_textOutput));
+ agg->add(new BaseTextFind(m_textOutput));
createToolButtons();
@@ -176,13 +178,13 @@ void TestResultsPane::createToolButtons()
});
m_runAll = new QToolButton(m_treeView);
- m_runAll->setDefaultAction(Core::ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action());
+ m_runAll->setDefaultAction(ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action());
m_runSelected = new QToolButton(m_treeView);
- m_runSelected->setDefaultAction(Core::ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action());
+ m_runSelected->setDefaultAction(ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action());
m_runFile = new QToolButton(m_treeView);
- m_runFile->setDefaultAction(Core::ActionManager::command(Constants::ACTION_RUN_FILE_ID)->action());
+ m_runFile->setDefaultAction(ActionManager::command(Constants::ACTION_RUN_FILE_ID)->action());
m_stopTestRun = new QToolButton(m_treeView);
m_stopTestRun->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon());
@@ -402,7 +404,7 @@ void TestResultsPane::onItemActivated(const QModelIndex &index)
const TestResult *testResult = m_filterModel->testResult(index);
if (testResult && !testResult->fileName().isEmpty())
- Core::EditorManager::openEditorAt(testResult->fileName(), testResult->line(), 0);
+ EditorManager::openEditorAt(testResult->fileName(), testResult->line(), 0);
}
void TestResultsPane::onRunAllTriggered()
@@ -530,7 +532,7 @@ void TestResultsPane::onTestRunFinished()
this, &TestResultsPane::onScrollBarRangeChanged);
if (AutotestPlugin::settings()->popupOnFinish
&& (!AutotestPlugin::settings()->popupOnFail || hasFailedTests(m_model))) {
- popup(Core::IOutputPane::NoModeSwitch);
+ popup(IOutputPane::NoModeSwitch);
}
createMarks();
}
@@ -608,14 +610,14 @@ void TestResultsPane::onCopyWholeTriggered()
void TestResultsPane::onSaveWholeTriggered()
{
- const QString fileName = QFileDialog::getSaveFileName(Core::ICore::dialogParent(),
+ const QString fileName = QFileDialog::getSaveFileName(ICore::dialogParent(),
tr("Save Output To"));
if (fileName.isEmpty())
return;
Utils::FileSaver saver(fileName, QIODevice::Text);
if (!saver.write(getWholeOutput().toUtf8()) || !saver.finalize()) {
- QMessageBox::critical(Core::ICore::dialogParent(), tr("Error"),
+ QMessageBox::critical(ICore::dialogParent(), tr("Error"),
tr("Failed to write \"%1\".\n\n%2").arg(fileName)
.arg(saver.errorString()));
}
@@ -692,7 +694,7 @@ void TestResultsPane::showTestResult(const QModelIndex &index)
{
QModelIndex mapped = m_filterModel->mapFromSource(index);
if (mapped.isValid()) {
- popup(Core::IOutputPane::NoModeSwitch);
+ popup(IOutputPane::NoModeSwitch);
m_treeView->setCurrentIndex(mapped);
}
}
diff --git a/src/plugins/autotest/testresultspane.h b/src/plugins/autotest/testresultspane.h
index 3f3a5b31f5..2b24ee3801 100644
--- a/src/plugins/autotest/testresultspane.h
+++ b/src/plugins/autotest/testresultspane.h
@@ -48,11 +48,13 @@ class IContext;
}
namespace Autotest {
+
+class TestResult;
+
namespace Internal {
class TestResultModel;
class TestResultFilterModel;
-class TestResult;
class TestEditorMark;
class ResultsTreeView : public Utils::TreeView
diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h
index f9110a8ece..1c86f66359 100644
--- a/src/plugins/autotest/testrunconfiguration.h
+++ b/src/plugins/autotest/testrunconfiguration.h
@@ -68,7 +68,7 @@ public:
{
ProjectExplorer::Runnable r;
QTC_ASSERT(m_testConfig, return r);
- r.executable = m_testConfig->executableFilePath();
+ r.executable = Utils::FilePath::fromString(m_testConfig->executableFilePath());
r.commandLineArguments = m_testConfig->argumentsForTestRunner().join(' ');
r.workingDirectory = m_testConfig->workingDirectory();
r.environment = m_testConfig->environment();
diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp
index ca3b1cebb9..16104d4413 100644
--- a/src/plugins/autotest/testrunner.cpp
+++ b/src/plugins/autotest/testrunner.cpp
@@ -27,16 +27,19 @@
#include "autotestconstants.h"
#include "autotestplugin.h"
+#include "testprojectsettings.h"
#include "testresultspane.h"
#include "testrunconfiguration.h"
#include "testsettings.h"
#include "testoutputreader.h"
#include "testtreeitem.h"
+#include "testtreemodel.h"
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/progressmanager/progressmanager.h>
+#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
@@ -65,6 +68,9 @@
#include <utils/algorithm.h>
+using namespace ProjectExplorer;
+using namespace Utils;
+
namespace Autotest {
namespace Internal {
@@ -91,6 +97,8 @@ TestRunner::TestRunner(QObject *parent) :
cancelCurrent(UserCanceled);
reportResult(ResultType::MessageFatal, tr("Test run canceled by user."));
});
+ connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
+ this, &TestRunner::onBuildQueueFinished);
}
TestRunner::~TestRunner()
@@ -150,7 +158,7 @@ static QString constructOmittedDetailsString(const QStringList &omitted)
"configuration page for \"%1\":") + '\n' + omitted.join('\n');
}
-static QString constructOmittedVariablesDetailsString(const QList<Utils::EnvironmentItem> &diff)
+static QString constructOmittedVariablesDetailsString(const Utils::EnvironmentItems &diff)
{
auto removedVars = Utils::transform<QStringList>(diff, [](const Utils::EnvironmentItem &it) {
return it.name;
@@ -207,10 +215,10 @@ void TestRunner::scheduleNext()
m_currentProcess->setWorkingDirectory(m_currentConfig->workingDirectory());
const Utils::Environment &original = m_currentConfig->environment();
Utils::Environment environment = m_currentConfig->filteredEnvironment(original);
- const QList<Utils::EnvironmentItem> removedVariables
- = Utils::filtered(original.diff(environment), [](const Utils::EnvironmentItem &it) {
- return it.operation == Utils::EnvironmentItem::Unset;
- });
+ const Utils::EnvironmentItems removedVariables = Utils::filtered(
+ original.diff(environment), [](const Utils::EnvironmentItem &it) {
+ return it.operation == Utils::EnvironmentItem::Unset;
+ });
if (!removedVariables.isEmpty()) {
const QString &details = constructOmittedVariablesDetailsString(removedVariables)
.arg(m_currentConfig->displayName());
@@ -303,9 +311,10 @@ void TestRunner::prepareToRunTests(TestRunMode mode)
QTC_ASSERT(!m_executingTests, return);
m_runMode = mode;
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
- ProjectExplorer::ProjectExplorerPlugin::projectExplorerSettings();
- if (projectExplorerSettings.buildBeforeDeploy && !projectExplorerSettings.saveBeforeBuild) {
- if (!ProjectExplorer::ProjectExplorerPlugin::saveModifiedFiles())
+ ProjectExplorerPlugin::projectExplorerSettings();
+ if (mode != TestRunMode::RunAfterBuild && projectExplorerSettings.buildBeforeDeploy
+ && !projectExplorerSettings.saveBeforeBuild) {
+ if (!ProjectExplorerPlugin::saveModifiedFiles())
return;
}
@@ -322,7 +331,7 @@ void TestRunner::prepareToRunTests(TestRunMode mode)
return;
}
- ProjectExplorer::Project *project = m_selectedTests.at(0)->project();
+ Project *project = m_selectedTests.at(0)->project();
if (!project) {
reportResult(ResultType::MessageWarn,
tr("Project is null. Canceling test run.\n"
@@ -332,13 +341,17 @@ void TestRunner::prepareToRunTests(TestRunMode mode)
return;
}
- m_targetConnect = connect(project, &ProjectExplorer::Project::activeTargetChanged,
+ m_targetConnect = connect(project, &Project::activeTargetChanged,
[this]() { cancelCurrent(KitChanged); });
if (!projectExplorerSettings.buildBeforeDeploy || mode == TestRunMode::DebugWithoutDeploy
- || mode == TestRunMode::RunWithoutDeploy) {
+ || mode == TestRunMode::RunWithoutDeploy || mode == TestRunMode::RunAfterBuild) {
runOrDebugTests();
- } else if (project->hasActiveBuildSettings()) {
+ return;
+ }
+
+ Target *target = project->activeTarget();
+ if (target && BuildConfigurationFactory::find(target)) {
buildProject(project);
} else {
reportResult(ResultType::MessageFatal,
@@ -354,9 +367,8 @@ static QString firstNonEmptyTestCaseTarget(const TestConfiguration *config)
});
}
-static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &buildTargetKey)
+static RunConfiguration *getRunConfiguration(const QString &buildTargetKey)
{
- using namespace ProjectExplorer;
const Project *project = SessionManager::startupProject();
if (!project)
return nullptr;
@@ -393,7 +405,7 @@ static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &bui
runConfig = Utils::findOr(runConfigurations, nullptr, [&dName, &exe] (const RunConfiguration *rc) {
if (rc->displayName() != dName)
return false;
- return rc->runnable().executable == exe;
+ return rc->runnable().executable.toString() == exe;
});
if (runConfig && dialog.rememberChoice())
AutotestPlugin::cacheRunConfigChoice(buildTargetKey, ChoicePair(dName, exe));
@@ -542,7 +554,7 @@ void TestRunner::debugTests()
}
QString errorMessage;
- auto runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
+ auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
runControl->setRunConfiguration(config->runConfiguration());
if (!runControl) {
reportResult(ResultType::MessageFatal,
@@ -552,8 +564,8 @@ void TestRunner::debugTests()
}
QStringList omitted;
- ProjectExplorer::Runnable inferior = config->runnable();
- inferior.executable = commandFilePath;
+ Runnable inferior = config->runnable();
+ inferior.executable = FilePath::fromString(commandFilePath);
const QStringList args = config->argumentsForTestRunner(&omitted);
inferior.commandLineArguments = Utils::QtcProcess::joinArgs(args);
@@ -563,10 +575,10 @@ void TestRunner::debugTests()
}
Utils::Environment original(inferior.environment);
inferior.environment = config->filteredEnvironment(original);
- const QList<Utils::EnvironmentItem> removedVariables
- = Utils::filtered(original.diff(inferior.environment), [](const Utils::EnvironmentItem &it) {
- return it.operation == Utils::EnvironmentItem::Unset;
- });
+ const Utils::EnvironmentItems removedVariables = Utils::filtered(
+ original.diff(inferior.environment), [](const Utils::EnvironmentItem &it) {
+ return it.operation == Utils::EnvironmentItem::Unset;
+ });
if (!removedVariables.isEmpty()) {
const QString &details = constructOmittedVariablesDetailsString(removedVariables)
.arg(config->displayName());
@@ -577,7 +589,7 @@ void TestRunner::debugTests()
debugger->setRunControlName(config->displayName());
bool useOutputProcessor = true;
- if (ProjectExplorer::Target *targ = config->project()->activeTarget()) {
+ if (Target *targ = config->project()->activeTarget()) {
if (Debugger::DebuggerKitAspect::engineType(targ->kit()) == Debugger::CdbEngineType) {
reportResult(ResultType::MessageWarn,
tr("Unable to display test results when using CDB."));
@@ -592,23 +604,23 @@ void TestRunner::debugTests()
if (useOutputProcessor) {
TestOutputReader *outputreader = config->outputReader(*futureInterface, nullptr);
- outputreader->setId(inferior.executable);
+ outputreader->setId(inferior.executable.toString());
connect(outputreader, &TestOutputReader::newOutputAvailable,
TestResultsPane::instance(), &TestResultsPane::addOutput);
- connect(runControl, &ProjectExplorer::RunControl::appendMessage,
+ connect(runControl, &RunControl::appendMessage,
this, [outputreader](const QString &msg, Utils::OutputFormat format) {
processOutput(outputreader, msg, format);
});
- connect(runControl, &ProjectExplorer::RunControl::stopped,
+ connect(runControl, &RunControl::stopped,
outputreader, &QObject::deleteLater);
}
m_stopDebugConnect = connect(this, &TestRunner::requestStopTestRun,
- runControl, &ProjectExplorer::RunControl::initiateStop);
+ runControl, &RunControl::initiateStop);
- connect(runControl, &ProjectExplorer::RunControl::stopped, this, &TestRunner::onFinished);
- ProjectExplorer::ProjectExplorerPlugin::startRunControl(runControl);
+ connect(runControl, &RunControl::stopped, this, &TestRunner::onFinished);
+ ProjectExplorerPlugin::startRunControl(runControl);
if (useOutputProcessor && AutotestPlugin::settings()->popupOnStart)
AutotestPlugin::popupResultsPane();
}
@@ -618,25 +630,28 @@ void TestRunner::runOrDebugTests()
switch (m_runMode) {
case TestRunMode::Run:
case TestRunMode::RunWithoutDeploy:
+ case TestRunMode::RunAfterBuild:
runTests();
return;
case TestRunMode::Debug:
case TestRunMode::DebugWithoutDeploy:
debugTests();
return;
+ default:
+ break;
}
+ QTC_ASSERT(false, qDebug() << "Unexpected run mode" << int(m_runMode)); // unexpected run mode
onFinished();
- QTC_ASSERT(false, return); // unexpected run mode
}
-void TestRunner::buildProject(ProjectExplorer::Project *project)
+void TestRunner::buildProject(Project *project)
{
- ProjectExplorer::BuildManager *buildManager = ProjectExplorer::BuildManager::instance();
+ BuildManager *buildManager = BuildManager::instance();
m_buildConnect = connect(this, &TestRunner::requestStopTestRun,
- buildManager, &ProjectExplorer::BuildManager::cancel);
- connect(buildManager, &ProjectExplorer::BuildManager::buildQueueFinished,
+ buildManager, &BuildManager::cancel);
+ connect(buildManager, &BuildManager::buildQueueFinished,
this, &TestRunner::buildFinished);
- ProjectExplorer::ProjectExplorerPlugin::buildProject(project);
+ ProjectExplorerPlugin::buildProject(project);
if (!buildManager->isBuilding())
buildFinished(false);
}
@@ -644,8 +659,8 @@ void TestRunner::buildProject(ProjectExplorer::Project *project)
void TestRunner::buildFinished(bool success)
{
disconnect(m_buildConnect);
- ProjectExplorer::BuildManager *buildManager = ProjectExplorer::BuildManager::instance();
- disconnect(buildManager, &ProjectExplorer::BuildManager::buildQueueFinished,
+ BuildManager *buildManager = BuildManager::instance();
+ disconnect(buildManager, &BuildManager::buildQueueFinished,
this, &TestRunner::buildFinished);
if (success) {
@@ -659,6 +674,41 @@ void TestRunner::buildFinished(bool success)
}
}
+static RunAfterBuildMode runAfterBuild()
+{
+ Project *project = SessionManager::startupProject();
+ if (!project)
+ return RunAfterBuildMode::None;
+
+ if (!project->namedSettings(Constants::SK_USE_GLOBAL).isValid())
+ return AutotestPlugin::settings()->runAfterBuild;
+
+ TestProjectSettings *projectSettings = AutotestPlugin::projectSettings(project);
+ return projectSettings->useGlobalSettings() ? AutotestPlugin::settings()->runAfterBuild
+ : projectSettings->runAfterBuild();
+}
+
+void TestRunner::onBuildQueueFinished(bool success)
+{
+ if (m_executingTests || !m_selectedTests.isEmpty()) // paranoia!
+ return;
+
+ if (!success || m_runMode != TestRunMode::None)
+ return;
+
+ RunAfterBuildMode mode = runAfterBuild();
+ if (mode == RunAfterBuildMode::None)
+ return;
+
+ auto testTreeModel = TestTreeModel::instance();
+ if (!testTreeModel->hasTests())
+ return;
+
+ setSelectedTests(mode == RunAfterBuildMode::All ? testTreeModel->getAllTestCases()
+ : testTreeModel->getSelectedTests());
+ prepareToRunTests(TestRunMode::RunAfterBuild);
+}
+
void TestRunner::onFinished()
{
// if we've been canceled and we still have test configurations queued just throw them away
@@ -668,6 +718,7 @@ void TestRunner::onFinished()
disconnect(m_stopDebugConnect);
disconnect(m_targetConnect);
m_fakeFutureInterface = nullptr;
+ m_runMode = TestRunMode::None;
m_executingTests = false;
emit testRunFinished();
}
@@ -754,11 +805,11 @@ void RunConfigurationSelectionDialog::populate()
{
m_rcCombo->addItem(QString(), QStringList({QString(), QString(), QString()})); // empty default
- if (auto project = ProjectExplorer::SessionManager::startupProject()) {
+ if (auto project = SessionManager::startupProject()) {
if (auto target = project->activeTarget()) {
- for (ProjectExplorer::RunConfiguration *rc : target->runConfigurations()) {
+ for (RunConfiguration *rc : target->runConfigurations()) {
auto runnable = rc->runnable();
- const QStringList rcDetails = { runnable.executable,
+ const QStringList rcDetails = { runnable.executable.toString(),
runnable.commandLineArguments,
runnable.workingDirectory };
m_rcCombo->addItem(rc->displayName(), rcDetails);
diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h
index 5628a6d29e..48d9f2ecab 100644
--- a/src/plugins/autotest/testrunner.h
+++ b/src/plugins/autotest/testrunner.h
@@ -48,6 +48,9 @@ class Project;
}
namespace Autotest {
+
+enum class TestRunMode;
+
namespace Internal {
class AUTOTESTSHARED_EXPORT TestRunner : public QObject
@@ -76,6 +79,7 @@ signals:
private:
void buildProject(ProjectExplorer::Project *project);
void buildFinished(bool success);
+ void onBuildQueueFinished(bool success);
void onFinished();
int precheckTestConfigurations();
@@ -98,7 +102,7 @@ private:
TestConfiguration *m_currentConfig = nullptr;
QProcess *m_currentProcess = nullptr;
TestOutputReader *m_currentOutputReader = nullptr;
- TestRunMode m_runMode = TestRunMode::Run;
+ TestRunMode m_runMode = TestRunMode::None;
// temporarily used if building before running is necessary
QMetaObject::Connection m_buildConnect;
diff --git a/src/plugins/autotest/testsettings.cpp b/src/plugins/autotest/testsettings.cpp
index ddb4f49e81..b8d9571f9d 100644
--- a/src/plugins/autotest/testsettings.cpp
+++ b/src/plugins/autotest/testsettings.cpp
@@ -44,6 +44,7 @@ static const char displayApplicationKey[] = "DisplayApp";
static const char popupOnStartKey[] = "PopupOnStart";
static const char popupOnFinishKey[] = "PopupOnFinish";
static const char popupOnFailKey[] = "PopupOnFail";
+static const char runAfterBuildKey[] = "RunAfterBuild";
static const char groupSuffix[] = ".group";
constexpr int defaultTimeout = 60000;
@@ -66,6 +67,7 @@ void TestSettings::toSettings(QSettings *s) const
s->setValue(popupOnStartKey, popupOnStart);
s->setValue(popupOnFinishKey, popupOnFinish);
s->setValue(popupOnFailKey, popupOnFail);
+ s->setValue(runAfterBuildKey, int(runAfterBuild));
// store frameworks and their current active and grouping state
for (const Core::Id &id : frameworks.keys()) {
s->setValue(QLatin1String(id.name()), frameworks.value(id));
@@ -87,6 +89,8 @@ void TestSettings::fromSettings(QSettings *s)
popupOnStart = s->value(popupOnStartKey, true).toBool();
popupOnFinish = s->value(popupOnFinishKey, true).toBool();
popupOnFail = s->value(popupOnFailKey, false).toBool();
+ runAfterBuild = RunAfterBuildMode(s->value(runAfterBuildKey,
+ int(RunAfterBuildMode::None)).toInt());
// try to get settings for registered frameworks
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
const QList<Core::Id> &registered = frameworkManager->registeredFrameworkIds();
diff --git a/src/plugins/autotest/testsettings.h b/src/plugins/autotest/testsettings.h
index 92c4ef9933..e3279009b3 100644
--- a/src/plugins/autotest/testsettings.h
+++ b/src/plugins/autotest/testsettings.h
@@ -36,6 +36,13 @@ QT_END_NAMESPACE
namespace Autotest {
namespace Internal {
+enum class RunAfterBuildMode
+{
+ None,
+ All,
+ Selected
+};
+
struct TestSettings
{
TestSettings();
@@ -52,6 +59,7 @@ struct TestSettings
bool popupOnStart = true;
bool popupOnFinish = true;
bool popupOnFail = false;
+ RunAfterBuildMode runAfterBuild = RunAfterBuildMode::None;
QHash<Core::Id, bool> frameworks;
QHash<Core::Id, bool> frameworksGrouping;
};
diff --git a/src/plugins/autotest/testsettingspage.cpp b/src/plugins/autotest/testsettingspage.cpp
index 169bab7320..7292ff82db 100644
--- a/src/plugins/autotest/testsettingspage.cpp
+++ b/src/plugins/autotest/testsettingspage.cpp
@@ -69,6 +69,7 @@ void TestSettingsWidget::setSettings(const TestSettings &settings)
m_ui.openResultsOnStartCB->setChecked(settings.popupOnStart);
m_ui.openResultsOnFinishCB->setChecked(settings.popupOnFinish);
m_ui.openResultsOnFailCB->setChecked(settings.popupOnFail);
+ m_ui.runAfterBuildCB->setCurrentIndex(int(settings.runAfterBuild));
populateFrameworksListWidget(settings.frameworks);
}
@@ -85,6 +86,7 @@ TestSettings TestSettingsWidget::settings() const
result.popupOnStart = m_ui.openResultsOnStartCB->isChecked();
result.popupOnFinish = m_ui.openResultsOnFinishCB->isChecked();
result.popupOnFail = m_ui.openResultsOnFailCB->isChecked();
+ result.runAfterBuild = RunAfterBuildMode(m_ui.runAfterBuildCB->currentIndex());
frameworkSettings(result);
return result;
}
@@ -165,7 +167,6 @@ void TestSettingsPage::apply()
if (!m_widget) // page was not shown at all
return;
const TestSettings newSettings = m_widget->settings();
- bool frameworkSyncNecessary = newSettings.frameworks != m_settings->frameworks;
const QList<Core::Id> changedIds = Utils::filtered(newSettings.frameworksGrouping.keys(),
[newSettings, this] (const Core::Id &id) {
return newSettings.frameworksGrouping[id] != m_settings->frameworksGrouping[id];
@@ -174,9 +175,8 @@ void TestSettingsPage::apply()
m_settings->toSettings(Core::ICore::settings());
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
frameworkManager->activateFrameworksFromSettings(m_settings);
- if (frameworkSyncNecessary)
- TestTreeModel::instance()->syncTestFrameworks();
- else if (!changedIds.isEmpty())
+ TestTreeModel::instance()->synchronizeTestFrameworks();
+ if (!changedIds.isEmpty())
TestTreeModel::instance()->rebuild(changedIds);
}
diff --git a/src/plugins/autotest/testsettingspage.ui b/src/plugins/autotest/testsettingspage.ui
index cb65055bc3..a182708c84 100644
--- a/src/plugins/autotest/testsettingspage.ui
+++ b/src/plugins/autotest/testsettingspage.ui
@@ -145,6 +145,52 @@ Warning: this is an experimental feature and might lead to failing to execute th
</widget>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Automatically run</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="runAfterBuildCB">
+ <property name="toolTip">
+ <string>Runs chosen tests automatically if a build succeeded.</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>None</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>All</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Selected</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0">
<property name="spacing">
<number>6</number>
diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp
index bc3c4f16be..4dd62f88ec 100644
--- a/src/plugins/autotest/testtreeitem.cpp
+++ b/src/plugins/autotest/testtreeitem.cpp
@@ -37,7 +37,6 @@
#include <QIcon>
namespace Autotest {
-namespace Internal {
TestTreeItem::TestTreeItem(const QString &name, const QString &filePath, Type type)
: m_name(name),
@@ -245,6 +244,8 @@ TestConfiguration *TestTreeItem::asConfiguration(TestRunMode mode) const
case TestRunMode::Debug:
case TestRunMode::DebugWithoutDeploy:
return debugConfiguration();
+ default:
+ break;
}
return nullptr;
}
@@ -316,7 +317,7 @@ QSet<QString> TestTreeItem::internalTargets() const
QSet<QString> targets;
for (const CppTools::ProjectPart::Ptr &part : projectParts) {
targets.insert(part->buildSystemTarget);
- if (part->buildTargetType != CppTools::ProjectPart::Executable)
+ if (part->buildTargetType != ProjectExplorer::BuildTargetType::Executable)
targets.unite(TestTreeItem::dependingInternalTargets(cppMM, m_filePath));
}
return targets;
@@ -377,5 +378,4 @@ QSet<QString> TestTreeItem::dependingInternalTargets(CppTools::CppModelManager *
return result;
}
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h
index e6d47bb820..ad86dcb842 100644
--- a/src/plugins/autotest/testtreeitem.h
+++ b/src/plugins/autotest/testtreeitem.h
@@ -45,10 +45,9 @@ namespace CppTools { class CppModelManager; }
namespace Utils { class FilePath; }
namespace Autotest {
-namespace Internal {
-class TestParseResult;
class TestConfiguration;
+class TestParseResult;
enum class TestRunMode;
class TestTreeItem : public Utils::TypedTreeItem<TestTreeItem>
@@ -88,10 +87,10 @@ public:
void setName(const QString &name) { m_name = name; }
const QString filePath() const { return m_filePath; }
void setFilePath(const QString &filePath) { m_filePath = filePath; }
- void setLine(unsigned line) { m_line = line;}
- unsigned line() const { return m_line; }
- void setColumn(unsigned column) { m_column = column; }
- unsigned column() const { return m_column; }
+ void setLine(int line) { m_line = line;}
+ int line() const { return m_line; }
+ void setColumn(int column) { m_column = column; }
+ int column() const { return m_column; }
QString proFile() const { return m_proFile; }
void setProFile(const QString &proFile) { m_proFile = proFile; }
virtual Qt::CheckState checked() const;
@@ -151,8 +150,8 @@ private:
QString m_filePath;
Qt::CheckState m_checked;
Type m_type;
- unsigned m_line = 0;
- unsigned m_column = 0;
+ int m_line = 0;
+ int m_column = 0;
QString m_proFile;
Status m_status = NewlyAdded;
@@ -163,15 +162,14 @@ class TestCodeLocationAndType
{
public:
QString m_name; // tag name for m_type == TestDataTag, file name for other values
- unsigned m_line = 0;
- unsigned m_column = 0;
+ int m_line = 0;
+ int m_column = 0;
TestTreeItem::Type m_type = TestTreeItem::Root;
};
typedef QVector<TestCodeLocationAndType> TestCodeLocationList;
-} // namespace Internal
} // namespace Autotest
-Q_DECLARE_METATYPE(Autotest::Internal::TestTreeItem *)
-Q_DECLARE_METATYPE(Autotest::Internal::TestCodeLocationAndType)
+Q_DECLARE_METATYPE(Autotest::TestTreeItem *)
+Q_DECLARE_METATYPE(Autotest::TestCodeLocationAndType)
diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp
index 953e93dc9c..1520dcd6f2 100644
--- a/src/plugins/autotest/testtreemodel.cpp
+++ b/src/plugins/autotest/testtreemodel.cpp
@@ -27,6 +27,7 @@
#include "autotestplugin.h"
#include "testcodeparser.h"
#include "testframeworkmanager.h"
+#include "testprojectsettings.h"
#include "testsettings.h"
#include "testtreeitem.h"
#include "testtreemodel.h"
@@ -39,7 +40,8 @@
#include <utils/qtcassert.h>
namespace Autotest {
-namespace Internal {
+
+using namespace Internal;
TestTreeModel::TestTreeModel(QObject *parent) :
TreeModel<>(parent),
@@ -53,6 +55,7 @@ TestTreeModel::TestTreeModel(QObject *parent) :
this, &TestTreeModel::sweep, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::parsingFailed,
this, &TestTreeModel::sweep, Qt::QueuedConnection);
+
setupParsingConnections();
}
@@ -198,17 +201,45 @@ QList<TestTreeItem *> TestTreeModel::testItemsByName(const QString &testName)
return result;
}
-void TestTreeModel::syncTestFrameworks()
-{
- // remove all currently registered
- removeTestRootNodes();
+void TestTreeModel::synchronizeTestFrameworks()
+{
+ ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
+ QList<Core::Id> sortedIds;
+ TestFrameworkManager *manager = TestFrameworkManager::instance();
+ const QVariant useGlobal = project ? project->namedSettings(Constants::SK_USE_GLOBAL)
+ : QVariant();
+ if (!useGlobal.isValid() || AutotestPlugin::projectSettings(project)->useGlobalSettings()) {
+ sortedIds = manager->sortedActiveFrameworkIds();
+ } else { // we've got custom project settings
+ const TestProjectSettings *settings = AutotestPlugin::projectSettings(project);
+ const QMap<Core::Id, bool> active = settings->activeFrameworks();
+ sortedIds = Utils::filtered(active.keys(), [active](const Core::Id &id) {
+ return active.value(id);
+ });
+ }
- TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
- QVector<Core::Id> sortedIds = frameworkManager->sortedActiveFrameworkIds();
- for (const Core::Id &id : sortedIds)
- rootItem()->appendChild(frameworkManager->rootNodeForTestFramework(id));
+ // pre-check to avoid further processing when frameworks are unchanged
+ Utils::TreeItem *invisibleRoot = rootItem();
+ QSet<Core::Id> newlyAdded;
+ QList<Utils::TreeItem *> oldFrameworkRoots;
+ for (Utils::TreeItem *oldFrameworkRoot : *invisibleRoot)
+ oldFrameworkRoots.append(oldFrameworkRoot);
+
+ for (Utils::TreeItem *oldFrameworkRoot : oldFrameworkRoots)
+ takeItem(oldFrameworkRoot); // do NOT delete the ptr is still held by TestFrameworkManager
+
+ for (const Core::Id &id : sortedIds) {
+ TestTreeItem *frameworkRootNode = manager->rootNodeForTestFramework(id);
+ invisibleRoot->appendChild(frameworkRootNode);
+ if (!oldFrameworkRoots.removeOne(frameworkRootNode))
+ newlyAdded.insert(id);
+ }
+ for (Utils::TreeItem *oldFrameworkRoot : oldFrameworkRoots)
+ oldFrameworkRoot->removeChildren();
m_parser->syncTestFrameworks(sortedIds);
+ if (!newlyAdded.isEmpty())
+ m_parser->updateTestTree(newlyAdded);
emit updatedActiveFrameworks(sortedIds.size());
}
@@ -666,5 +697,4 @@ bool TestTreeSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex
}
}
-} // namespace Internal
} // namespace Autotest
diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h
index 895a9a582e..c22a8f8d49 100644
--- a/src/plugins/autotest/testtreemodel.h
+++ b/src/plugins/autotest/testtreemodel.h
@@ -36,10 +36,10 @@
namespace Autotest {
namespace Internal {
-
class TestCodeParser;
-class TestParseResult;
+} // namespace Internal
+class TestParseResult;
using TestParseResultPtr = QSharedPointer<TestParseResult>;
class AUTOTESTSHARED_EXPORT TestTreeModel : public Utils::TreeModel<>
@@ -52,13 +52,13 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
- TestCodeParser *parser() const { return m_parser; }
+ Internal::TestCodeParser *parser() const { return m_parser; }
bool hasTests() const;
QList<TestConfiguration *> getAllTestCases() const;
QList<TestConfiguration *> getSelectedTests() const;
QList<TestConfiguration *> getTestsForFile(const Utils::FilePath &fileName) const;
QList<TestTreeItem *> testItemsByName(const QString &testName);
- void syncTestFrameworks();
+ void synchronizeTestFrameworks();
void rebuild(const QList<Core::Id> &frameworkIds);
#ifdef WITH_TESTS
@@ -99,9 +99,11 @@ private:
void filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
QList<TestTreeItem *> testItemsByName(TestTreeItem *root, const QString &testName);
- TestCodeParser *m_parser;
+ Internal::TestCodeParser *m_parser = nullptr;
};
+namespace Internal {
+
class TestTreeSortFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
@@ -114,7 +116,7 @@ public:
};
explicit TestTreeSortFilterModel(TestTreeModel *sourceModel, QObject *parent = nullptr);
- void setSortMode(TestTreeItem::SortMode sortMode);
+ void setSortMode(Autotest::TestTreeItem::SortMode sortMode);
void setFilterMode(FilterMode filterMode);
void toggleFilter(FilterMode filterMode);
static FilterMode toFilterMode(int f);
@@ -124,7 +126,7 @@ protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
private:
- TestTreeItem::SortMode m_sortMode = TestTreeItem::Alphabetically;
+ Autotest::TestTreeItem::SortMode m_sortMode = Autotest::TestTreeItem::Alphabetically;
FilterMode m_filterMode = Basic;
};
diff --git a/src/plugins/autotoolsprojectmanager/CMakeLists.txt b/src/plugins/autotoolsprojectmanager/CMakeLists.txt
index ca8765cba9..ac341c3eaf 100644
--- a/src/plugins/autotoolsprojectmanager/CMakeLists.txt
+++ b/src/plugins/autotoolsprojectmanager/CMakeLists.txt
@@ -4,8 +4,8 @@ add_qtc_plugin(AutotoolsProjectManager
autogenstep.cpp autogenstep.h
autoreconfstep.cpp autoreconfstep.h
autotoolsbuildconfiguration.cpp autotoolsbuildconfiguration.h
+ autotoolsbuildsystem.cpp autotoolsbuildsystem.h
autotoolsopenprojectwizard.cpp autotoolsopenprojectwizard.h
- autotoolsproject.cpp autotoolsproject.h
autotoolsprojectconstants.h
autotoolsprojectplugin.cpp autotoolsprojectplugin.h
configurestep.cpp configurestep.h
diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp
index fcb6b5c9ac..2541c1169c 100644
--- a/src/plugins/autotoolsprojectmanager/autogenstep.cpp
+++ b/src/plugins/autotoolsprojectmanager/autogenstep.cpp
@@ -26,14 +26,12 @@
****************************************************************************/
#include "autogenstep.h"
+
#include "autotoolsprojectconstants.h"
#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/buildsteplist.h>
-#include <projectexplorer/project.h>
#include <projectexplorer/processparameters.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <QDateTime>
@@ -41,16 +39,13 @@
using namespace AutotoolsProjectManager;
using namespace AutotoolsProjectManager::Internal;
using namespace ProjectExplorer;
-
-const char AUTOGEN_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.AutogenStep.AdditionalArguments";
-const char AUTOGEN_STEP_ID[] = "AutotoolsProjectManager.AutogenStep";
-
+using namespace Utils;
// AutogenStepFactory
AutogenStepFactory::AutogenStepFactory()
{
- registerStep<AutogenStep>(AUTOGEN_STEP_ID);
+ registerStep<AutogenStep>(Constants::AUTOGEN_STEP_ID);
setDisplayName(AutogenStep::tr("Autogen", "Display name for AutotoolsProjectManager::AutogenStep id."));
setSupportedProjectType(Constants::AUTOTOOLS_PROJECT_ID);
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
@@ -59,15 +54,34 @@ AutogenStepFactory::AutogenStepFactory()
// AutogenStep
-AutogenStep::AutogenStep(BuildStepList *bsl) : AbstractProcessStep(bsl, AUTOGEN_STEP_ID)
+AutogenStep::AutogenStep(BuildStepList *bsl) : AbstractProcessStep(bsl, Constants::AUTOGEN_STEP_ID)
{
setDefaultDisplayName(tr("Autogen"));
m_additionalArgumentsAspect = addAspect<BaseStringAspect>();
- m_additionalArgumentsAspect->setSettingsKey(AUTOGEN_ADDITIONAL_ARGUMENTS_KEY);
+ m_additionalArgumentsAspect->setSettingsKey(
+ "AutotoolsProjectManager.AutogenStep.AdditionalArguments");
m_additionalArgumentsAspect->setLabelText(tr("Arguments:"));
m_additionalArgumentsAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
m_additionalArgumentsAspect->setHistoryCompleter("AutotoolsPM.History.AutogenStepArgs");
+
+ connect(m_additionalArgumentsAspect, &ProjectConfigurationAspect::changed, this, [this] {
+ m_runAutogen = true;
+ });
+
+ setSummaryUpdater([this] {
+ BuildConfiguration *bc = buildConfiguration();
+
+ ProcessParameters param;
+ param.setMacroExpander(bc->macroExpander());
+ param.setEnvironment(bc->environment());
+ param.setWorkingDirectory(bc->target()->project()->projectDirectory());
+ param.setCommandLine({FilePath::fromString("./autogen.sh"),
+ m_additionalArgumentsAspect->value(),
+ CommandLine::Raw});
+
+ return param.summary(displayName());
+ });
}
bool AutogenStep::init()
@@ -78,9 +92,9 @@ bool AutogenStep::init()
pp->setMacroExpander(bc->macroExpander());
pp->setEnvironment(bc->environment());
pp->setWorkingDirectory(bc->target()->project()->projectDirectory());
- pp->setCommand(Utils::FilePath::fromString("./autogen.sh"));
- pp->setArguments(m_additionalArgumentsAspect->value());
- pp->resolveAll();
+ pp->setCommandLine({FilePath::fromString("./autogen.sh"),
+ m_additionalArgumentsAspect->value(),
+ CommandLine::Raw});
return AbstractProcessStep::init();
}
@@ -110,30 +124,3 @@ void AutogenStep::doRun()
m_runAutogen = false;
AbstractProcessStep::doRun();
}
-
-BuildStepConfigWidget *AutogenStep::createConfigWidget()
-{
- auto widget = AbstractProcessStep::createConfigWidget();
-
- auto updateDetails = [this, widget] {
- BuildConfiguration *bc = buildConfiguration();
-
- ProcessParameters param;
- param.setMacroExpander(bc->macroExpander());
- param.setEnvironment(bc->environment());
- param.setWorkingDirectory(bc->target()->project()->projectDirectory());
- param.setCommand(Utils::FilePath::fromString("./autogen.sh"));
- param.setArguments(m_additionalArgumentsAspect->value());
-
- widget->setSummaryText(param.summary(displayName()));
- };
-
- updateDetails();
-
- connect(m_additionalArgumentsAspect, &ProjectConfigurationAspect::changed, this, [=] {
- updateDetails();
- m_runAutogen = true;
- });
-
- return widget;
-}
diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.h b/src/plugins/autotoolsprojectmanager/autogenstep.h
index 2de5f7e24a..e11f01f39b 100644
--- a/src/plugins/autotoolsprojectmanager/autogenstep.h
+++ b/src/plugins/autotoolsprojectmanager/autogenstep.h
@@ -66,8 +66,6 @@ class AutogenStep : public ProjectExplorer::AbstractProcessStep
public:
explicit AutogenStep(ProjectExplorer::BuildStepList *bsl);
- ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
-
private:
bool init() override;
void doRun() override;
diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp
index 58ee0f383b..eeb3da1118 100644
--- a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp
+++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp
@@ -26,28 +26,23 @@
****************************************************************************/
#include "autoreconfstep.h"
+
#include "autotoolsprojectconstants.h"
#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/buildsteplist.h>
-#include <projectexplorer/project.h>
#include <projectexplorer/processparameters.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
using namespace AutotoolsProjectManager;
using namespace AutotoolsProjectManager::Internal;
using namespace ProjectExplorer;
-const char AUTORECONF_STEP_ID[] = "AutotoolsProjectManager.AutoreconfStep";
-
-
// AutoreconfStepFactory class
AutoreconfStepFactory::AutoreconfStepFactory()
{
- registerStep<AutoreconfStep>(AUTORECONF_STEP_ID);
+ registerStep<AutoreconfStep>(Constants::AUTORECONF_STEP_ID);
setDisplayName(AutoreconfStep::tr("Autoreconf", "Display name for AutotoolsProjectManager::AutoreconfStep id."));
setSupportedProjectType(Constants::AUTOTOOLS_PROJECT_ID);
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
@@ -56,7 +51,8 @@ AutoreconfStepFactory::AutoreconfStepFactory()
// AutoreconfStep class
-AutoreconfStep::AutoreconfStep(BuildStepList *bsl) : AbstractProcessStep(bsl, AUTORECONF_STEP_ID)
+AutoreconfStep::AutoreconfStep(BuildStepList *bsl)
+ : AbstractProcessStep(bsl, Constants::AUTORECONF_STEP_ID)
{
setDefaultDisplayName(tr("Autoreconf"));
@@ -66,6 +62,24 @@ AutoreconfStep::AutoreconfStep(BuildStepList *bsl) : AbstractProcessStep(bsl, AU
m_additionalArgumentsAspect->setValue("--force --install");
m_additionalArgumentsAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
m_additionalArgumentsAspect->setHistoryCompleter("AutotoolsPM.History.AutoreconfStepArgs");
+
+ connect(m_additionalArgumentsAspect, &ProjectConfigurationAspect::changed, this, [this] {
+ m_runAutoreconf = true;
+ });
+
+ setSummaryUpdater([this] {
+ BuildConfiguration *bc = buildConfiguration();
+
+ ProcessParameters param;
+ param.setMacroExpander(bc->macroExpander());
+ param.setEnvironment(bc->environment());
+ param.setWorkingDirectory(bc->target()->project()->projectDirectory());
+ param.setCommandLine({Utils::FilePath::fromString("autoreconf"),
+ m_additionalArgumentsAspect->value(),
+ Utils::CommandLine::Raw});
+
+ return param.summary(displayName());
+ });
}
bool AutoreconfStep::init()
@@ -76,9 +90,8 @@ bool AutoreconfStep::init()
pp->setMacroExpander(bc->macroExpander());
pp->setEnvironment(bc->environment());
pp->setWorkingDirectory(bc->target()->project()->projectDirectory());
- pp->setCommand(Utils::FilePath::fromString("autoreconf"));
- pp->setArguments(m_additionalArgumentsAspect->value());
- pp->resolveAll();
+ pp->setCommandLine({Utils::FilePath::fromString("autoreconf"),
+ m_additionalArgumentsAspect->value(), Utils::CommandLine::Raw});
return AbstractProcessStep::init();
}
@@ -102,30 +115,3 @@ void AutoreconfStep::doRun()
m_runAutoreconf = false;
AbstractProcessStep::doRun();
}
-
-BuildStepConfigWidget *AutoreconfStep::createConfigWidget()
-{
- auto widget = AbstractProcessStep::createConfigWidget();
-
- auto updateDetails = [this, widget] {
- BuildConfiguration *bc = buildConfiguration();
-
- ProcessParameters param;
- param.setMacroExpander(bc->macroExpander());
- param.setEnvironment(bc->environment());
- param.setWorkingDirectory(bc->target()->project()->projectDirectory());
- param.setCommand(Utils::FilePath::fromString("autoreconf"));
- param.setArguments(m_additionalArgumentsAspect->value());
-
- widget->setSummaryText(param.summary(displayName()));
- };
-
- updateDetails();
-
- connect(m_additionalArgumentsAspect, &ProjectConfigurationAspect::changed, this, [=] {
- updateDetails();
- m_runAutoreconf = true;
- });
-
- return widget;
-}
diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.h b/src/plugins/autotoolsprojectmanager/autoreconfstep.h
index 244b9d964b..48348bb14a 100644
--- a/src/plugins/autotoolsprojectmanager/autoreconfstep.h
+++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.h
@@ -68,7 +68,6 @@ public:
bool init() override;
void doRun() override;
- ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
private:
ProjectExplorer::BaseStringAspect *m_additionalArgumentsAspect = nullptr;
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp
index 0007ddf447..42f665b0e6 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp
@@ -26,22 +26,14 @@
****************************************************************************/
#include "autotoolsbuildconfiguration.h"
-#include "makestep.h"
-#include "autotoolsproject.h"
+
#include "autotoolsprojectconstants.h"
-#include "autogenstep.h"
-#include "autoreconfstep.h"
-#include "configurestep.h"
-#include <coreplugin/icore.h>
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildsteplist.h>
-#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-#include <utils/mimetypes/mimedatabase.h>
-#include <utils/qtcassert.h>
using namespace AutotoolsProjectManager::Constants;
using namespace ProjectExplorer;
@@ -63,37 +55,29 @@ AutotoolsBuildConfiguration::AutotoolsBuildConfiguration(Target *parent, Core::I
setConfigWidgetDisplayName(tr("Autotools Manager"));
}
-void AutotoolsBuildConfiguration::initialize(const BuildInfo &info)
+void AutotoolsBuildConfiguration::initialize()
{
- BuildConfiguration::initialize(info);
+ BuildConfiguration::initialize();
BuildStepList *buildSteps = stepList(BUILDSTEPS_BUILD);
// ### Build Steps Build ###
// autogen.sh or autoreconf
QFile autogenFile(target()->project()->projectDirectory().toString() + "/autogen.sh");
- if (autogenFile.exists()) {
- auto autogenStep = new AutogenStep(buildSteps);
- buildSteps->appendStep(autogenStep);
- } else {
- auto autoreconfStep = new AutoreconfStep(buildSteps);
- buildSteps->appendStep(autoreconfStep);
- }
+ if (autogenFile.exists())
+ buildSteps->appendStep(Constants::AUTOGEN_STEP_ID);
+ else
+ buildSteps->appendStep(Constants::AUTORECONF_STEP_ID);
// ./configure.
- auto configureStep = new ConfigureStep(buildSteps);
- buildSteps->appendStep(configureStep);
- connect(this, &BuildConfiguration::buildDirectoryChanged,
- configureStep, &ConfigureStep::notifyBuildDirectoryChanged);
+ buildSteps->appendStep(Constants::CONFIGURE_STEP_ID);
// make
- auto makeStep = new MakeStep(buildSteps);
- buildSteps->appendStep(makeStep);
+ buildSteps->appendStep(Constants::MAKE_STEP_ID);
// ### Build Steps Clean ###
BuildStepList *cleanSteps = stepList(BUILDSTEPS_CLEAN);
- auto cleanMakeStep = new MakeStep(cleanSteps);
- cleanSteps->appendStep(cleanMakeStep);
+ cleanSteps->appendStep(Constants::MAKE_STEP_ID);
}
@@ -108,34 +92,18 @@ AutotoolsBuildConfigurationFactory::AutotoolsBuildConfigurationFactory()
setSupportedProjectMimeTypeName(Constants::MAKEFILE_MIMETYPE);
}
-QList<BuildInfo> AutotoolsBuildConfigurationFactory::availableBuilds(const Target *parent) const
-{
- return {createBuildInfo(parent->kit(), parent->project()->projectDirectory())};
-}
-
-QList<BuildInfo> AutotoolsBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
-{
- const QString path = QFileInfo(projectPath).absolutePath();
- BuildInfo info = createBuildInfo(k, Utils::FilePath::fromString(path));
- //: The name of the build configuration created by default for a autotools project.
- info.displayName = tr("Default");
- return {info};
-}
-
-BuildInfo AutotoolsBuildConfigurationFactory::createBuildInfo(const Kit *k,
- const Utils::FilePath &buildDir) const
+QList<BuildInfo> AutotoolsBuildConfigurationFactory::availableBuilds
+ (const Kit *k, const FilePath &projectPath, bool forSetup) const
{
BuildInfo info(this);
info.typeName = tr("Build");
- info.buildDirectory = buildDir;
+ info.buildDirectory = forSetup ? FilePath::fromString(projectPath.toFileInfo().absolutePath()) : projectPath;
info.kitId = k->id();
- return info;
-}
-
-BuildConfiguration::BuildType AutotoolsBuildConfiguration::buildType() const
-{
- // TODO: Should I return something different from Unknown?
- return Unknown;
+ if (forSetup) {
+ //: The name of the build configuration created by default for a autotools project.
+ info.displayName = tr("Default");
+ }
+ return {info};
}
} // Internal
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h
index ec33f6a224..1b2bcf8021 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.h
@@ -29,8 +29,6 @@
#include <projectexplorer/buildconfiguration.h>
-namespace Utils { class FilePath; }
-
namespace AutotoolsProjectManager {
namespace Internal {
@@ -41,8 +39,7 @@ class AutotoolsBuildConfiguration : public ProjectExplorer::BuildConfiguration
friend class ProjectExplorer::BuildConfigurationFactory;
AutotoolsBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id);
- void initialize(const ProjectExplorer::BuildInfo &info) override;
- BuildType buildType() const override;
+ void initialize() override;
};
class AutotoolsBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
@@ -53,11 +50,9 @@ public:
AutotoolsBuildConfigurationFactory();
private:
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override;
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
-
- ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k, const Utils::FilePath &buildDir) const;
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k,
+ const Utils::FilePath &projectPath,
+ bool forSetup) const override;
};
} // namespace Internal
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
index baafa22bfa..177ebdad2f 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp
@@ -25,65 +25,36 @@
**
****************************************************************************/
-#include "autotoolsproject.h"
-#include "autotoolsbuildconfiguration.h"
-#include "autotoolsprojectconstants.h"
-#include "autotoolsopenprojectwizard.h"
-#include "makestep.h"
+#include "autotoolsbuildsystem.h"
+
#include "makefileparserthread.h"
+#include "makestep.h"
-#include <projectexplorer/abi.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/kitmanager.h>
-#include <projectexplorer/kitinformation.h>
+#include <cpptools/cppprojectupdater.h>
#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/buildsteplist.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/projectnodes.h>
#include <projectexplorer/target.h>
-#include <projectexplorer/headerpath.h>
-#include <extensionsystem/pluginmanager.h>
-#include <cpptools/cppmodelmanager.h>
-#include <cpptools/projectinfo.h>
-#include <cpptools/cppprojectupdater.h>
-#include <coreplugin/icore.h>
-#include <coreplugin/icontext.h>
-#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtcppkitinfo.h>
-#include <qtsupport/qtkitinformation.h>
-#include <utils/algorithm.h>
-#include <utils/qtcassert.h>
+
#include <utils/filesystemwatcher.h>
-#include <QFileInfo>
-#include <QTimer>
-#include <QPointer>
-#include <QApplication>
-#include <QCursor>
-#include <QLabel>
-#include <QPushButton>
-#include <QVBoxLayout>
-
-using namespace AutotoolsProjectManager;
-using namespace AutotoolsProjectManager::Internal;
using namespace ProjectExplorer;
-AutotoolsProject::AutotoolsProject(const Utils::FilePath &fileName) :
- Project(Constants::MAKEFILE_MIMETYPE, fileName),
- m_fileWatcher(new Utils::FileSystemWatcher(this)),
- m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
+namespace AutotoolsProjectManager {
+namespace Internal {
+
+AutotoolsBuildSystem::AutotoolsBuildSystem(Project *project)
+ : BuildSystem(project)
+ , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{
- setId(Constants::AUTOTOOLS_PROJECT_ID);
- setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
- setDisplayName(projectDirectory().fileName());
+ connect(project, &Project::activeBuildConfigurationChanged, this, [this]() { requestParse(); });
+
+ connect(project, &Project::projectFileIsDirty, this, [this]() { requestParse(); });
}
-AutotoolsProject::~AutotoolsProject()
+AutotoolsBuildSystem::~AutotoolsBuildSystem()
{
delete m_cppCodeModelUpdater;
- setRootProjectNode(nullptr);
-
if (m_makefileParserThread) {
m_makefileParserThread->wait();
delete m_makefileParserThread;
@@ -91,69 +62,42 @@ AutotoolsProject::~AutotoolsProject()
}
}
-// This function, is called at the very beginning, to
-// restore the settings if there are some stored.
-Project::RestoreResult AutotoolsProject::fromMap(const QVariantMap &map, QString *errorMessage)
+void AutotoolsBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
{
- RestoreResult result = Project::fromMap(map, errorMessage);
- if (result != RestoreResult::Ok)
- return result;
-
- connect(m_fileWatcher, &Utils::FileSystemWatcher::fileChanged,
- this, &AutotoolsProject::onFileChanged);
-
- // Load the project tree structure.
- loadProjectTree();
-
- Kit *defaultKit = KitManager::defaultKit();
- if (!activeTarget() && defaultKit)
- addTarget(createTarget(defaultKit));
-
- return RestoreResult::Ok;
-}
-
-void AutotoolsProject::loadProjectTree()
-{
- emitParsingStarted();
if (m_makefileParserThread) {
- // The thread is still busy parsing a previus configuration.
+ // The thread is still busy parsing a previous configuration.
// Wait until the thread has been finished and delete it.
// TODO: Discuss whether blocking is acceptable.
- disconnect(m_makefileParserThread, &QThread::finished,
- this, &AutotoolsProject::makefileParsingFinished);
+ disconnect(m_makefileParserThread,
+ &QThread::finished,
+ this,
+ &AutotoolsBuildSystem::makefileParsingFinished);
m_makefileParserThread->wait();
delete m_makefileParserThread;
m_makefileParserThread = nullptr;
}
// Parse the makefile asynchronously in a thread
- m_makefileParserThread = new MakefileParserThread(projectFilePath().toString());
-
- connect(m_makefileParserThread, &MakefileParserThread::started,
- this, &AutotoolsProject::makefileParsingStarted);
+ m_makefileParserThread = new MakefileParserThread(project()->projectFilePath().toString(),
+ std::move(ctx.guard));
- connect(m_makefileParserThread, &MakefileParserThread::finished,
- this, &AutotoolsProject::makefileParsingFinished);
+ connect(m_makefileParserThread,
+ &MakefileParserThread::finished,
+ this,
+ &AutotoolsBuildSystem::makefileParsingFinished);
m_makefileParserThread->start();
}
-void AutotoolsProject::makefileParsingStarted()
-{
- QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-}
-
-void AutotoolsProject::makefileParsingFinished()
+void AutotoolsBuildSystem::makefileParsingFinished()
{
// The finished() signal is from a previous makefile-parser-thread
// and can be skipped. This can happen, if the thread has emitted the
- // finished() signal during the execution of AutotoolsProject::loadProjectTree().
+ // finished() signal during the execution of AutotoolsBuildSystem::loadProjectTree().
// In this case the signal is in the message queue already and deleting
// the thread of course does not remove the signal again.
if (sender() != m_makefileParserThread)
return;
- QApplication::restoreOverrideCursor();
-
if (m_makefileParserThread->isCanceled()) {
// The parsing has been cancelled by the user. Don't show any
// project data at all.
@@ -165,15 +109,12 @@ void AutotoolsProject::makefileParsingFinished()
if (m_makefileParserThread->hasError())
qWarning("Parsing of makefile contained errors.");
- // Remove file watches for the current project state.
- // The file watches will be added again after the parsing.
- m_fileWatcher->removeFiles(m_watchedFiles);
-
m_files.clear();
- m_watchedFiles.clear();
- // Apply sources to m_files, which are returned at AutotoolsProject::files()
- const QFileInfo fileInfo = projectFilePath().toFileInfo();
+ QVector<Utils::FilePath> filesToWatch;
+
+ // Apply sources to m_files, which are returned at AutotoolsBuildSystem::files()
+ const QFileInfo fileInfo = project()->projectFilePath().toFileInfo();
const QDir dir = fileInfo.absoluteDir();
const QStringList files = m_makefileParserThread->sources();
foreach (const QString& file, files)
@@ -187,8 +128,7 @@ void AutotoolsProject::makefileParsingFinished()
m_files.append(absMakefile);
- m_fileWatcher->addFile(absMakefile, Utils::FileSystemWatcher::WatchAllChanges);
- m_watchedFiles.append(absMakefile);
+ filesToWatch.append(Utils::FilePath::fromString(absMakefile));
}
// Add configure.ac file to project and watch for changes.
@@ -198,38 +138,22 @@ void AutotoolsProject::makefileParsingFinished()
const QString absConfigureAc = dir.absoluteFilePath(configureAc);
m_files.append(absConfigureAc);
- m_fileWatcher->addFile(absConfigureAc, Utils::FileSystemWatcher::WatchAllChanges);
- m_watchedFiles.append(absConfigureAc);
+ filesToWatch.append(Utils::FilePath::fromString(absConfigureAc));
}
- auto newRoot = std::make_unique<ProjectNode>(projectDirectory());
+ auto newRoot = std::make_unique<ProjectNode>(project()->projectDirectory());
for (const QString &f : m_files) {
const Utils::FilePath path = Utils::FilePath::fromString(f);
newRoot->addNestedNode(std::make_unique<FileNode>(path,
FileNode::fileTypeForFileName(path)));
}
- setRootProjectNode(std::move(newRoot));
+ project()->setRootProjectNode(std::move(newRoot));
+ project()->setExtraProjectFiles(filesToWatch);
updateCppCodeModel();
m_makefileParserThread->deleteLater();
m_makefileParserThread = nullptr;
-
- emitParsingFinished(true);
-}
-
-void AutotoolsProject::onFileChanged(const QString &file)
-{
- Q_UNUSED(file);
- loadProjectTree();
-}
-
-QStringList AutotoolsProject::buildTargets() const
-{
- QStringList targets;
- targets.append(QLatin1String("all"));
- targets.append(QLatin1String("clean"));
- return targets;
}
static QStringList filterIncludes(const QString &absSrc, const QString &absBuild,
@@ -250,14 +174,16 @@ static QStringList filterIncludes(const QString &absSrc, const QString &absBuild
return result;
}
-void AutotoolsProject::updateCppCodeModel()
+void AutotoolsBuildSystem::updateCppCodeModel()
{
- QtSupport::CppKitInfo kitInfo(this);
- QTC_ASSERT(kitInfo.isValid(), return);
+ QtSupport::CppKitInfo kitInfo(project());
+ QTC_ASSERT(kitInfo.isValid(), return );
+
+ const Utils::FilePath projectFilePath = project()->projectFilePath();
- CppTools::RawProjectPart rpp;
- rpp.setDisplayName(displayName());
- rpp.setProjectFileLocation(projectFilePath().toString());
+ RawProjectPart rpp;
+ rpp.setDisplayName(project()->displayName());
+ rpp.setProjectFileLocation(projectFilePath.toString());
rpp.setQtVersion(kitInfo.projectPartQtVersion);
const QStringList cflags = m_makefileParserThread->cflags();
QStringList cxxflags = m_makefileParserThread->cxxflags();
@@ -266,14 +192,18 @@ void AutotoolsProject::updateCppCodeModel()
rpp.setFlagsForC({kitInfo.cToolChain, cflags});
rpp.setFlagsForCxx({kitInfo.cxxToolChain, cxxflags});
- const QString absSrc = projectDirectory().toString();
- const Target *target = activeTarget();
- const QString absBuild = (target && target->activeBuildConfiguration())
- ? target->activeBuildConfiguration()->buildDirectory().toString() : QString();
+ const QString absSrc = project()->projectDirectory().toString();
+ const Target *target = project()->activeTarget();
+ BuildConfiguration *bc = target ? target->activeBuildConfiguration() : nullptr;
+
+ const QString absBuild = bc ? bc->buildDirectory().toString() : QString();
rpp.setIncludePaths(filterIncludes(absSrc, absBuild, m_makefileParserThread->includePaths()));
rpp.setMacros(m_makefileParserThread->macros());
rpp.setFiles(m_files);
- m_cppCodeModelUpdater->update({this, kitInfo, {rpp}});
+ m_cppCodeModelUpdater->update({project(), kitInfo, project()->activeParseEnvironment(), {rpp}});
}
+
+} // namespace Internal
+} // namespace AutotoolsProjectManager
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h
index fcd81d093b..8bbad6a580 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.h
+++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h
@@ -27,54 +27,30 @@
#pragma once
-#include <projectexplorer/project.h>
-
-#include <utils/fileutils.h>
+#include <projectexplorer/buildsystem.h>
namespace Utils { class FileSystemWatcher; }
namespace CppTools { class CppProjectUpdater; }
namespace AutotoolsProjectManager {
+
namespace Internal {
class MakefileParserThread;
-/**
- * @brief Implementation of the ProjectExplorer::Project interface.
- *
- * Loads the autotools project and embeds it into the QtCreator project tree.
- * The class AutotoolsProject is the core of the autotools project plugin.
- * It is responsible to parse the Makefile.am files and do trigger project
- * updates if a Makefile.am file or a configure.ac file has been changed.
- */
-class AutotoolsProject : public ProjectExplorer::Project
+class AutotoolsBuildSystem : public ProjectExplorer::BuildSystem
{
Q_OBJECT
public:
- explicit AutotoolsProject(const Utils::FilePath &fileName);
- ~AutotoolsProject() override;
-
- QStringList buildTargets() const;
+ explicit AutotoolsBuildSystem(ProjectExplorer::Project *project);
+ ~AutotoolsBuildSystem() override;
protected:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
+ void parseProject(ParsingContext &&ctx) final;
private:
- bool hasMakeInstallEquivalent() const override { return true; }
-
- /**
- * Loads the project tree by parsing the makefiles.
- */
- void loadProjectTree();
-
- /**
- * Is invoked when the makefile parsing by m_makefileParserThread has
- * been started. Turns the mouse cursor into a busy cursor.
- */
- void makefileParsingStarted();
-
/**
* Is invoked when the makefile parsing by m_makefileParserThread has
* been finished. Adds all sources and files into the project tree and
@@ -84,13 +60,6 @@ private:
void makefileParsingFinished();
/**
- * Is invoked, if a file of the project tree has been changed by the user.
- * If a Makefile.am or a configure.ac file has been changed, the project
- * configuration must be updated.
- */
- void onFileChanged(const QString &file);
-
- /**
* This function is in charge of the code completion.
*/
void updateCppCodeModel();
@@ -98,10 +67,6 @@ private:
/// Return value for AutotoolsProject::files()
QStringList m_files;
- /// Watches project files for changes.
- Utils::FileSystemWatcher *m_fileWatcher;
- QStringList m_watchedFiles;
-
/// Responsible for parsing the makefiles asynchronously in a thread
MakefileParserThread *m_makefileParserThread = nullptr;
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp
index cbfbe47173..ef57ca24ea 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsopenprojectwizard.cpp
@@ -29,10 +29,9 @@
#include <utils/pathchooser.h>
-#include <QVBoxLayout>
+#include <QDir>
#include <QFormLayout>
#include <QLabel>
-#include <QDir>
using namespace AutotoolsProjectManager;
using namespace AutotoolsProjectManager::Internal;
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h
index 74cf14a103..fdfbf9a338 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h
@@ -32,9 +32,17 @@ namespace AutotoolsProjectManager {
* Collects project constants, that are shared between several classes.
*/
namespace Constants {
- const char MAKEFILE_MIMETYPE[] = "text/x-makefile";
+
+const char MAKEFILE_MIMETYPE[] = "text/x-makefile";
+
+// Steps
+const char AUTOGEN_STEP_ID[] = "AutotoolsProjectManager.AutogenStep";
+const char AUTORECONF_STEP_ID[] = "AutotoolsProjectManager.AutoreconfStep";
+const char CONFIGURE_STEP_ID[] = "AutotoolsProjectManager.ConfigureStep";
+const char MAKE_STEP_ID[] = "AutotoolsProjectManager.MakeStep";
//Project
- const char AUTOTOOLS_PROJECT_ID[] = "AutotoolsProjectManager.AutotoolsProject";
+const char AUTOTOOLS_PROJECT_ID[] = "AutotoolsProjectManager.AutotoolsProject";
+
} // namespace Constants
} // namespace AutotoolsProjectManager
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro
index 92b6dd8e7d..37dce96bbb 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.pro
@@ -1,8 +1,8 @@
include(../../qtcreatorplugin.pri)
-HEADERS = autotoolsprojectplugin.h\
+HEADERS = autotoolsbuildsystem.h \
+ autotoolsprojectplugin.h\
autotoolsopenprojectwizard.h\
- autotoolsproject.h\
autotoolsbuildconfiguration.h\
autotoolsprojectconstants.h\
makestep.h\
@@ -12,9 +12,9 @@ HEADERS = autotoolsprojectplugin.h\
makefileparserthread.h\
makefileparser.h
-SOURCES = autotoolsprojectplugin.cpp\
+SOURCES = autotoolsbuildsystem.cpp \
+ autotoolsprojectplugin.cpp\
autotoolsopenprojectwizard.cpp\
- autotoolsproject.cpp\
autotoolsbuildconfiguration.cpp\
makestep.cpp\
autogenstep.cpp\
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs
index a6e4a2721b..75f81d09b7 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs
@@ -18,10 +18,10 @@ QtcPlugin {
"autoreconfstep.h",
"autotoolsbuildconfiguration.cpp",
"autotoolsbuildconfiguration.h",
+ "autotoolsbuildsystem.cpp",
+ "autotoolsbuildsystem.h",
"autotoolsopenprojectwizard.cpp",
"autotoolsopenprojectwizard.h",
- "autotoolsproject.cpp",
- "autotoolsproject.h",
"autotoolsprojectconstants.h",
"autotoolsprojectplugin.cpp",
"autotoolsprojectplugin.h",
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
index 5b3643dcd3..e3cd87f0ce 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp
@@ -26,19 +26,33 @@
****************************************************************************/
#include "autotoolsprojectplugin.h"
-#include "autotoolsproject.h"
-#include "autotoolsprojectconstants.h"
-#include "autotoolsbuildconfiguration.h"
-#include "makestep.h"
+
#include "autogenstep.h"
#include "autoreconfstep.h"
+#include "autotoolsbuildconfiguration.h"
+#include "autotoolsbuildsystem.h"
+#include "autotoolsprojectconstants.h"
#include "configurestep.h"
+#include "makestep.h"
+#include <coreplugin/icontext.h>
#include <projectexplorer/projectmanager.h>
namespace AutotoolsProjectManager {
namespace Internal {
+AutotoolsProject::AutotoolsProject(const Utils::FilePath &fileName)
+ : Project(Constants::MAKEFILE_MIMETYPE, fileName)
+{
+ setId(Constants::AUTOTOOLS_PROJECT_ID);
+ setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
+ setDisplayName(projectDirectory().fileName());
+
+ setHasMakeInstallEquivalent(true);
+
+ setBuildSystem(std::make_unique<AutotoolsBuildSystem>(this));
+}
+
class AutotoolsProjectPluginPrivate
{
public:
@@ -69,5 +83,5 @@ bool AutotoolsProjectPlugin::initialize(const QStringList &arguments,
return true;
}
-} // Internal
+} // namespace Internal
} // AutotoolsProjectManager
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h
index dd08cbd1c8..bdf319150f 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h
+++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.h
@@ -27,6 +27,8 @@
#pragma once
+#include <projectexplorer/project.h>
+
#include <extensionsystem/iplugin.h>
namespace AutotoolsProjectManager {
@@ -73,5 +75,19 @@ class AutotoolsProjectPlugin : public ExtensionSystem::IPlugin
class AutotoolsProjectPluginPrivate *d;
};
+/**
+ * @brief Implementation of the ProjectExplorer::Project interface.
+ *
+ * Loads the autotools project and embeds it into the QtCreator project tree.
+ * The class AutotoolsProject is the core of the autotools project plugin.
+ * It is responsible to parse the Makefile.am files and do trigger project
+ * updates if a Makefile.am file or a configure.ac file has been changed.
+ */
+class AutotoolsProject : public ProjectExplorer::Project
+{
+public:
+ explicit AutotoolsProject(const Utils::FilePath &fileName);
+};
+
} // namespace Internal
} // namespace AutotoolsProjectManager
diff --git a/src/plugins/autotoolsprojectmanager/configurestep.cpp b/src/plugins/autotoolsprojectmanager/configurestep.cpp
index 91b72eb4af..c722aa3a9f 100644
--- a/src/plugins/autotoolsprojectmanager/configurestep.cpp
+++ b/src/plugins/autotoolsprojectmanager/configurestep.cpp
@@ -26,30 +26,21 @@
****************************************************************************/
#include "configurestep.h"
-#include "autotoolsproject.h"
+
#include "autotoolsbuildconfiguration.h"
#include "autotoolsprojectconstants.h"
-#include <projectexplorer/buildsteplist.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/processparameters.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <utils/qtcprocess.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
-#include <QVariantMap>
#include <QDateTime>
-#include <QLineEdit>
-#include <QFormLayout>
+#include <QDir>
using namespace AutotoolsProjectManager;
using namespace AutotoolsProjectManager::Internal;
using namespace ProjectExplorer;
-
-const char CONFIGURE_ADDITIONAL_ARGUMENTS_KEY[] = "AutotoolsProjectManager.ConfigureStep.AdditionalArguments";
-const char CONFIGURE_STEP_ID[] = "AutotoolsProjectManager.ConfigureStep";
+using namespace Utils;
/////////////////////
// Helper Function
@@ -57,7 +48,7 @@ const char CONFIGURE_STEP_ID[] = "AutotoolsProjectManager.ConfigureStep";
static QString projectDirRelativeToBuildDir(BuildConfiguration *bc) {
const QDir buildDir(bc->buildDirectory().toString());
QString projDirToBuildDir = buildDir.relativeFilePath(
- bc->target()->project()->projectDirectory().toString());
+ bc->project()->projectDirectory().toString());
if (projDirToBuildDir.isEmpty())
return QString("./");
if (!projDirToBuildDir.endsWith('/'))
@@ -70,7 +61,7 @@ static QString projectDirRelativeToBuildDir(BuildConfiguration *bc) {
ConfigureStepFactory::ConfigureStepFactory()
{
- registerStep<ConfigureStep>(CONFIGURE_STEP_ID);
+ registerStep<ConfigureStep>(Constants::CONFIGURE_STEP_ID);
setDisplayName(ConfigureStep::tr("Configure", "Display name for AutotoolsProjectManager::ConfigureStep id."));
setSupportedProjectType(Constants::AUTOTOOLS_PROJECT_ID);
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
@@ -79,15 +70,35 @@ ConfigureStepFactory::ConfigureStepFactory()
// ConfigureStep
-ConfigureStep::ConfigureStep(BuildStepList *bsl) : AbstractProcessStep(bsl, CONFIGURE_STEP_ID)
+ConfigureStep::ConfigureStep(BuildStepList *bsl)
+ : AbstractProcessStep(bsl, Constants::CONFIGURE_STEP_ID)
{
setDefaultDisplayName(tr("Configure"));
m_additionalArgumentsAspect = addAspect<BaseStringAspect>();
m_additionalArgumentsAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
- m_additionalArgumentsAspect->setSettingsKey(CONFIGURE_ADDITIONAL_ARGUMENTS_KEY);
+ m_additionalArgumentsAspect->setSettingsKey(
+ "AutotoolsProjectManager.ConfigureStep.AdditionalArguments");
m_additionalArgumentsAspect->setLabelText(tr("Arguments:"));
m_additionalArgumentsAspect->setHistoryCompleter("AutotoolsPM.History.ConfigureArgs");
+
+ connect(m_additionalArgumentsAspect, &ProjectConfigurationAspect::changed, this, [this] {
+ m_runConfigure = true;
+ });
+
+ setSummaryUpdater([this] {
+ BuildConfiguration *bc = buildConfiguration();
+
+ ProcessParameters param;
+ param.setMacroExpander(bc->macroExpander());
+ param.setEnvironment(bc->environment());
+ param.setWorkingDirectory(bc->buildDirectory());
+ param.setCommandLine({FilePath::fromString(projectDirRelativeToBuildDir(bc) + "configure"),
+ m_additionalArgumentsAspect->value(),
+ CommandLine::Raw});
+
+ return param.summaryInWorkdir(displayName());
+ });
}
bool ConfigureStep::init()
@@ -98,9 +109,9 @@ bool ConfigureStep::init()
pp->setMacroExpander(bc->macroExpander());
pp->setEnvironment(bc->environment());
pp->setWorkingDirectory(bc->buildDirectory());
- pp->setCommand(Utils::FilePath::fromString(projectDirRelativeToBuildDir(bc) + "configure"));
- pp->setArguments(m_additionalArgumentsAspect->value());
- pp->resolveAll();
+ pp->setCommandLine({FilePath::fromString(projectDirRelativeToBuildDir(bc) + "configure"),
+ m_additionalArgumentsAspect->value(),
+ CommandLine::Raw});
return AbstractProcessStep::init();
}
@@ -128,39 +139,3 @@ void ConfigureStep::doRun()
m_runConfigure = false;
AbstractProcessStep::doRun();
}
-
-BuildStepConfigWidget *ConfigureStep::createConfigWidget()
-{
- m_widget = AbstractProcessStep::createConfigWidget();
-
- updateDetails();
-
- connect(m_additionalArgumentsAspect, &ProjectConfigurationAspect::changed, this, [this] {
- m_runConfigure = true;
- updateDetails();
- });
-
- return m_widget.data();
-}
-
-void ConfigureStep::notifyBuildDirectoryChanged()
-{
- updateDetails();
-}
-
-void ConfigureStep::updateDetails()
-{
- if (!m_widget)
- return;
-
- BuildConfiguration *bc = buildConfiguration();
-
- ProcessParameters param;
- param.setMacroExpander(bc->macroExpander());
- param.setEnvironment(bc->environment());
- param.setWorkingDirectory(bc->buildDirectory());
- param.setCommand(Utils::FilePath::fromString(projectDirRelativeToBuildDir(bc) + "configure"));
- param.setArguments(m_additionalArgumentsAspect->value());
-
- m_widget->setSummaryText(param.summaryInWorkdir(displayName()));
-}
diff --git a/src/plugins/autotoolsprojectmanager/configurestep.h b/src/plugins/autotoolsprojectmanager/configurestep.h
index 4faa7a24b7..380eb413c0 100644
--- a/src/plugins/autotoolsprojectmanager/configurestep.h
+++ b/src/plugins/autotoolsprojectmanager/configurestep.h
@@ -67,20 +67,14 @@ class ConfigureStep : public ProjectExplorer::AbstractProcessStep
public:
explicit ConfigureStep(ProjectExplorer::BuildStepList *bsl);
- ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
-
void setAdditionalArguments(const QString &list);
- void notifyBuildDirectoryChanged();
private:
bool init() override;
void doRun() override;
- void updateDetails();
-
ProjectExplorer::BaseStringAspect *m_additionalArgumentsAspect = nullptr;
bool m_runConfigure = false;
- QPointer<ProjectExplorer::BuildStepConfigWidget> m_widget;
};
} // namespace Internal
diff --git a/src/plugins/autotoolsprojectmanager/makefileparser.cpp b/src/plugins/autotoolsprojectmanager/makefileparser.cpp
index 39596a724e..8c379ee823 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparser.cpp
+++ b/src/plugins/autotoolsprojectmanager/makefileparser.cpp
@@ -30,10 +30,9 @@
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
-#include <QFile>
#include <QDir>
-#include <QFileInfoList>
-#include <QMutexLocker>
+#include <QFile>
+#include <QFileInfo>
using namespace AutotoolsProjectManager::Internal;
@@ -49,7 +48,7 @@ bool MakefileParser::parse()
{
m_mutex.lock();
m_cancel = false;
- m_mutex.unlock(),
+ m_mutex.unlock();
m_success = true;
m_executable.clear();
diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
index a33d39599b..fa225f6945 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
+++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.cpp
@@ -31,7 +31,10 @@
using namespace AutotoolsProjectManager::Internal;
-MakefileParserThread::MakefileParserThread(const QString &makefile) : m_parser(makefile)
+MakefileParserThread::MakefileParserThread(const QString &makefile,
+ ProjectExplorer::Project::ParseGuard &&guard)
+ : m_parser(makefile)
+ , m_guard(std::move(guard))
{
connect(&m_parser, &MakefileParser::status,
this, &MakefileParserThread::status);
@@ -82,7 +85,7 @@ QStringList MakefileParserThread::cxxflags() const
bool MakefileParserThread::hasError() const
{
QMutexLocker locker(&m_mutex);
- return m_hasError;
+ return !m_guard.isSuccess();
}
bool MakefileParserThread::isCanceled() const
@@ -104,7 +107,8 @@ void MakefileParserThread::run()
// this prevents long locks if the caller reads a value before the signal
// finished() has been emitted.
QMutexLocker locker(&m_mutex);
- m_hasError = !success;
+ if (success)
+ m_guard.markAsSuccess();
m_executable = m_parser.executable();
m_sources = m_parser.sources();
m_makefiles = m_parser.makefiles();
diff --git a/src/plugins/autotoolsprojectmanager/makefileparserthread.h b/src/plugins/autotoolsprojectmanager/makefileparserthread.h
index fa300e8d35..63d86190e2 100644
--- a/src/plugins/autotoolsprojectmanager/makefileparserthread.h
+++ b/src/plugins/autotoolsprojectmanager/makefileparserthread.h
@@ -29,6 +29,7 @@
#include "makefileparser.h"
+#include <projectexplorer/project.h>
#include <projectexplorer/projectmacro.h>
#include <QMutex>
@@ -53,7 +54,7 @@ class MakefileParserThread : public QThread
using Macros = ProjectExplorer::Macros;
public:
- MakefileParserThread(const QString &makefile);
+ MakefileParserThread(const QString &makefile, ProjectExplorer::Project::ParseGuard &&guard);
/** @see QThread::run() */
void run() override;
@@ -134,7 +135,6 @@ private:
MakefileParser m_parser; ///< Is not accessible outside the thread
mutable QMutex m_mutex;
- bool m_hasError = false; ///< Return value for MakefileParserThread::hasError()
QString m_executable; ///< Return value for MakefileParserThread::executable()
QStringList m_sources; ///< Return value for MakefileParserThread::sources()
QStringList m_makefiles; ///< Return value for MakefileParserThread::makefiles()
@@ -142,6 +142,8 @@ private:
Macros m_macros; ///< Return value for MakefileParserThread::macros()
QStringList m_cflags; ///< Return value for MakefileParserThread::cflags()
QStringList m_cxxflags; ///< Return value for MakefileParserThread::cxxflags()
+
+ ProjectExplorer::Project::ParseGuard m_guard;
};
} // namespace Internal
diff --git a/src/plugins/autotoolsprojectmanager/makestep.cpp b/src/plugins/autotoolsprojectmanager/makestep.cpp
index f8f3fb2596..7a7fbbddb3 100644
--- a/src/plugins/autotoolsprojectmanager/makestep.cpp
+++ b/src/plugins/autotoolsprojectmanager/makestep.cpp
@@ -26,9 +26,7 @@
****************************************************************************/
#include "makestep.h"
-#include "autotoolsproject.h"
#include "autotoolsprojectconstants.h"
-#include "autotoolsbuildconfiguration.h"
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/projectexplorerconstants.h>
@@ -37,8 +35,6 @@ using namespace AutotoolsProjectManager;
using namespace AutotoolsProjectManager::Internal;
using namespace AutotoolsProjectManager::Constants;
-const char MAKE_STEP_ID[] = "AutotoolsProjectManager.MakeStep";
-
// MakeStepFactory
MakeStepFactory::MakeStepFactory()
@@ -51,8 +47,9 @@ MakeStepFactory::MakeStepFactory()
// MakeStep
MakeStep::MakeStep(ProjectExplorer::BuildStepList *bsl)
- : ProjectExplorer::MakeStep(bsl, MAKE_STEP_ID, QString(), {"all", "clean"})
+ : ProjectExplorer::MakeStep(bsl, MAKE_STEP_ID)
{
+ setAvailableBuildTargets({"all", "clean"});
if (bsl->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
setBuildTarget("clean", true);
setClean(true);
diff --git a/src/plugins/baremetal/CMakeLists.txt b/src/plugins/baremetal/CMakeLists.txt
index f9d9bc0dc5..0a811d37b9 100644
--- a/src/plugins/baremetal/CMakeLists.txt
+++ b/src/plugins/baremetal/CMakeLists.txt
@@ -10,7 +10,6 @@ add_qtc_plugin(BareMetal
baremetaldeviceconfigurationwidget.cpp baremetaldeviceconfigurationwidget.h
baremetaldeviceconfigurationwizard.cpp baremetaldeviceconfigurationwizard.h
baremetaldeviceconfigurationwizardpages.cpp baremetaldeviceconfigurationwizardpages.h
- baremetalgdbcommandsdeploystep.cpp baremetalgdbcommandsdeploystep.h
baremetalplugin.cpp baremetalplugin.h
baremetalrunconfiguration.cpp baremetalrunconfiguration.h
defaultgdbserverprovider.cpp defaultgdbserverprovider.h
diff --git a/src/plugins/baremetal/baremetal.pro b/src/plugins/baremetal/baremetal.pro
index ac49b0041f..76cd5ac308 100644
--- a/src/plugins/baremetal/baremetal.pro
+++ b/src/plugins/baremetal/baremetal.pro
@@ -7,7 +7,6 @@ SOURCES += baremetalplugin.cpp \
baremetalcustomrunconfiguration.cpp\
baremetaldevice.cpp \
baremetalrunconfiguration.cpp \
- baremetalgdbcommandsdeploystep.cpp \
baremetaldeviceconfigurationwizardpages.cpp \
baremetaldeviceconfigurationwizard.cpp \
baremetaldeviceconfigurationwidget.cpp \
@@ -32,7 +31,6 @@ HEADERS += baremetalplugin.h \
baremetalcustomrunconfiguration.h \
baremetaldevice.h \
baremetalrunconfiguration.h \
- baremetalgdbcommandsdeploystep.h \
baremetaldeviceconfigurationwidget.h \
baremetaldeviceconfigurationwizard.h \
baremetaldeviceconfigurationwizardpages.h \
diff --git a/src/plugins/baremetal/baremetal.qbs b/src/plugins/baremetal/baremetal.qbs
index 018c2dc23b..b50db5769e 100644
--- a/src/plugins/baremetal/baremetal.qbs
+++ b/src/plugins/baremetal/baremetal.qbs
@@ -20,7 +20,6 @@ QtcPlugin {
"baremetaldeviceconfigurationwidget.cpp", "baremetaldeviceconfigurationwidget.h",
"baremetaldeviceconfigurationwizard.cpp", "baremetaldeviceconfigurationwizard.h",
"baremetaldeviceconfigurationwizardpages.cpp", "baremetaldeviceconfigurationwizardpages.h",
- "baremetalgdbcommandsdeploystep.cpp", "baremetalgdbcommandsdeploystep.h",
"baremetalplugin.cpp", "baremetalplugin.h",
"baremetalrunconfiguration.cpp", "baremetalrunconfiguration.h",
"baremetaldebugsupport.cpp", "baremetaldebugsupport.h",
diff --git a/src/plugins/baremetal/baremetaldebugsupport.cpp b/src/plugins/baremetal/baremetaldebugsupport.cpp
index cda24139df..a8f20e197a 100644
--- a/src/plugins/baremetal/baremetaldebugsupport.cpp
+++ b/src/plugins/baremetal/baremetaldebugsupport.cpp
@@ -25,7 +25,6 @@
#include "baremetaldebugsupport.h"
#include "baremetaldevice.h"
-#include "baremetalgdbcommandsdeploystep.h"
#include "gdbserverprovider.h"
#include "gdbserverprovidermanager.h"
@@ -48,12 +47,25 @@
using namespace Debugger;
using namespace ProjectExplorer;
+using namespace Utils;
namespace BareMetal {
namespace Internal {
// BareMetalDebugSupport
+class BareMetalGdbServer : public SimpleTargetRunner
+{
+public:
+ BareMetalGdbServer(RunControl *runControl, const Runnable &runnable)
+ : SimpleTargetRunner(runControl)
+ {
+ setId("BareMetalGdbServer");
+ // Baremetal's GDB servers are launched on the host, not on the target.
+ setStarter([this, runnable] { doStart(runnable, {}); });
+ }
+};
+
BareMetalDebugSupport::BareMetalDebugSupport(RunControl *runControl)
: Debugger::DebuggerRunTool(runControl)
{
@@ -75,9 +87,8 @@ BareMetalDebugSupport::BareMetalDebugSupport(RunControl *runControl)
r.setCommandLine(p->command());
// Command arguments are in host OS style as the bare metal's GDB servers are launched
// on the host, not on that target.
- m_gdbServer = new SimpleTargetRunner(runControl);
- m_gdbServer->setRunnable(r);
- addStartDependency(m_gdbServer);
+ auto gdbServer = new BareMetalGdbServer(runControl, r);
+ addStartDependency(gdbServer);
}
}
@@ -86,40 +97,21 @@ void BareMetalDebugSupport::start()
const auto exeAspect = runControl()->aspect<ExecutableAspect>();
QTC_ASSERT(exeAspect, reportFailure(); return);
- const QString bin = exeAspect->executable().toString();
+ const FilePath bin = exeAspect->executable();
if (bin.isEmpty()) {
reportFailure(tr("Cannot debug: Local executable is not set."));
return;
}
- if (!QFile::exists(bin)) {
- reportFailure(tr("Cannot debug: Could not find executable for \"%1\".").arg(bin));
+ if (!bin.exists()) {
+ reportFailure(tr("Cannot debug: Could not find executable for \"%1\".").arg(bin.toString()));
return;
}
- const Target *target = runControl()->target();
- QTC_ASSERT(target, reportFailure(); return);
-
const auto dev = qSharedPointerCast<const BareMetalDevice>(device());
QTC_ASSERT(dev, reportFailure(); return);
const GdbServerProvider *p = GdbServerProviderManager::findProvider(dev->gdbServerProviderId());
QTC_ASSERT(p, reportFailure(); return);
-#if 0
- // Currently baremetal plugin does not provide way to configure deployments steps
- // FIXME: Should it?
- QString commands;
- if (const BuildConfiguration *bc = target->activeBuildConfiguration()) {
- if (BuildStepList *bsl = bc->stepList(BareMetalGdbCommandsDeployStep::stepId())) {
- for (const BareMetalGdbCommandsDeployStep *bs : bsl->allOfType<BareMetalGdbCommandsDeployStep>()) {
- if (!commands.endsWith("\n"))
- commands.append("\n");
- commands.append(bs->gdbCommands());
- }
- }
- }
- setCommandsAfterConnect(commands);
-#endif
-
Runnable inferior;
inferior.executable = bin;
if (const auto aspect = runControl()->aspect<ArgumentsAspect>())
@@ -129,7 +121,7 @@ void BareMetalDebugSupport::start()
setStartMode(AttachToRemoteServer);
setCommandsAfterConnect(p->initCommands()); // .. and here?
setCommandsForReset(p->resetCommands());
- setRemoteChannel(p->channel());
+ setRemoteChannel(p->channelString());
setUseContinueInsteadOfRun(true);
setUseExtendedRemote(p->useExtendedRemote());
diff --git a/src/plugins/baremetal/baremetaldebugsupport.h b/src/plugins/baremetal/baremetaldebugsupport.h
index 3a59343a9e..cfc31017fb 100644
--- a/src/plugins/baremetal/baremetaldebugsupport.h
+++ b/src/plugins/baremetal/baremetaldebugsupport.h
@@ -41,8 +41,6 @@ public:
private:
void start() final;
-
- ProjectExplorer::SimpleTargetRunner *m_gdbServer = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/baremetal/baremetaldevice.cpp b/src/plugins/baremetal/baremetaldevice.cpp
index 340ca1a229..d9901ccc58 100644
--- a/src/plugins/baremetal/baremetaldevice.cpp
+++ b/src/plugins/baremetal/baremetaldevice.cpp
@@ -50,12 +50,24 @@ const char gdbServerProviderIdKeyC[] = "GdbServerProviderId";
// BareMetalDevice
+BareMetalDevice::BareMetalDevice()
+{
+ setDisplayType(QCoreApplication::translate("BareMetal::Internal::BareMetalDevice", "Bare Metal"));
+ setDefaultDisplayName(defaultDisplayName());
+ setOsType(Utils::OsTypeOther);
+}
+
BareMetalDevice::~BareMetalDevice()
{
if (GdbServerProvider *provider = GdbServerProviderManager::findProvider(m_gdbServerProviderId))
provider->unregisterDevice(this);
}
+QString BareMetalDevice::defaultDisplayName()
+{
+ return QCoreApplication::translate("BareMetal::Internal::BareMetalDevice", "Bare Metal Device");
+}
+
QString BareMetalDevice::gdbServerProviderId() const
{
return m_gdbServerProviderId;
@@ -90,7 +102,7 @@ void BareMetalDevice::providerUpdated(GdbServerProvider *provider)
void BareMetalDevice::setChannelByServerProvider(GdbServerProvider *provider)
{
QTC_ASSERT(provider, return);
- const QString channel = provider->channel();
+ const QString channel = provider->channelString();
const int colon = channel.indexOf(QLatin1Char(':'));
if (colon < 0)
return;
@@ -111,9 +123,8 @@ void BareMetalDevice::fromMap(const QVariantMap &map)
} else {
const QSsh::SshConnectionParameters sshParams = sshParameters();
const auto newProvider = new DefaultGdbServerProvider;
+ newProvider->setChannel(sshParams.url);
newProvider->setDisplayName(name);
- newProvider->m_host = sshParams.host();
- newProvider->m_port = sshParams.port();
if (GdbServerProviderManager::registerProvider(newProvider))
gdbServerProvider = newProvider->id();
else
@@ -135,21 +146,11 @@ DeviceProcessSignalOperation::Ptr BareMetalDevice::signalOperation() const
return DeviceProcessSignalOperation::Ptr();
}
-QString BareMetalDevice::displayType() const
-{
- return QCoreApplication::translate("BareMetal::Internal::BareMetalDevice", "Bare Metal");
-}
-
IDeviceWidget *BareMetalDevice::createWidget()
{
return new BareMetalDeviceConfigurationWidget(sharedFromThis());
}
-Utils::OsType BareMetalDevice::osType() const
-{
- return Utils::OsTypeOther;
-}
-
DeviceProcess *BareMetalDevice::createProcess(QObject *parent) const
{
return new GdbServerProviderProcess(sharedFromThis(), parent);
diff --git a/src/plugins/baremetal/baremetaldevice.h b/src/plugins/baremetal/baremetaldevice.h
index b4d1b3afce..eda3f957f2 100644
--- a/src/plugins/baremetal/baremetaldevice.h
+++ b/src/plugins/baremetal/baremetaldevice.h
@@ -45,9 +45,9 @@ public:
static Ptr create() { return Ptr(new BareMetalDevice); }
~BareMetalDevice() final;
- QString displayType() const final;
+ static QString defaultDisplayName();
+
ProjectExplorer::IDeviceWidget *createWidget() final;
- Utils::OsType osType() const final;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const final;
@@ -63,7 +63,7 @@ public:
QVariantMap toMap() const final;
private:
- explicit BareMetalDevice() = default;
+ BareMetalDevice();
void setChannelByServerProvider(GdbServerProvider *provider);
QString m_gdbServerProviderId;
diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp
index a528bd4b8e..26257ef128 100644
--- a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp
+++ b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp
@@ -30,6 +30,7 @@
#include "gdbserverprovider.h"
#include "gdbserverproviderchooser.h"
+#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <QFormLayout>
@@ -40,8 +41,8 @@ namespace Internal {
// BareMetalDeviceConfigurationWidget
BareMetalDeviceConfigurationWidget::BareMetalDeviceConfigurationWidget(
- const ProjectExplorer::IDevice::Ptr &deviceConfig, QWidget *parent)
- : IDeviceWidget(deviceConfig, parent)
+ const ProjectExplorer::IDevice::Ptr &deviceConfig)
+ : IDeviceWidget(deviceConfig)
{
const auto dev = qSharedPointerCast<const BareMetalDevice>(device());
QTC_ASSERT(dev, return);
@@ -56,6 +57,19 @@ BareMetalDeviceConfigurationWidget::BareMetalDeviceConfigurationWidget(
connect(m_gdbServerProviderChooser, &GdbServerProviderChooser::providerChanged,
this, &BareMetalDeviceConfigurationWidget::gdbServerProviderChanged);
+
+ m_peripheralDescriptionFileChooser = new Utils::PathChooser(this);
+ m_peripheralDescriptionFileChooser->setExpectedKind(Utils::PathChooser::File);
+ m_peripheralDescriptionFileChooser->setPromptDialogFilter(
+ tr("Peripheral description files (*.svd)"));
+ m_peripheralDescriptionFileChooser->setPromptDialogTitle(
+ tr("Select Peripheral Description File"));
+ m_peripheralDescriptionFileChooser->setPath(dev->peripheralDescriptionFilePath());
+ formLayout->addRow(tr("Peripheral description file:"),
+ m_peripheralDescriptionFileChooser);
+
+ connect(m_peripheralDescriptionFileChooser, &Utils::PathChooser::pathChanged,
+ this, &BareMetalDeviceConfigurationWidget::peripheralDescriptionFileChanged);
}
void BareMetalDeviceConfigurationWidget::gdbServerProviderChanged()
@@ -65,6 +79,13 @@ void BareMetalDeviceConfigurationWidget::gdbServerProviderChanged()
dev->setGdbServerProviderId(m_gdbServerProviderChooser->currentProviderId());
}
+void BareMetalDeviceConfigurationWidget::peripheralDescriptionFileChanged()
+{
+ const auto dev = qSharedPointerCast<BareMetalDevice>(device());
+ QTC_ASSERT(dev, return);
+ dev->setPeripheralDescriptionFilePath(m_peripheralDescriptionFileChooser->path());
+}
+
void BareMetalDeviceConfigurationWidget::updateDeviceFromUi()
{
gdbServerProviderChanged();
diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h
index ad8017f53f..abf0c3f3e1 100644
--- a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h
+++ b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h
@@ -28,6 +28,8 @@
#include <projectexplorer/devicesupport/idevicewidget.h>
+namespace Utils { class PathChooser; }
+
namespace BareMetal {
namespace Internal {
@@ -41,14 +43,15 @@ class BareMetalDeviceConfigurationWidget final
Q_OBJECT
public:
- explicit BareMetalDeviceConfigurationWidget(
- const ProjectExplorer::IDevice::Ptr &deviceConfig, QWidget *parent = nullptr);
+ explicit BareMetalDeviceConfigurationWidget(const ProjectExplorer::IDevice::Ptr &deviceConfig);
private:
void gdbServerProviderChanged();
+ void peripheralDescriptionFileChanged();
void updateDeviceFromUi() final;
GdbServerProviderChooser *m_gdbServerProviderChooser = nullptr;
+ Utils::PathChooser *m_peripheralDescriptionFileChooser = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp
index 4e0e69b4f8..53634ec239 100644
--- a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp
+++ b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp
@@ -62,7 +62,7 @@ BareMetalDeviceConfigurationWizardSetupPage::BareMetalDeviceConfigurationWizardS
void BareMetalDeviceConfigurationWizardSetupPage::initializePage()
{
- m_nameLineEdit->setText(defaultConfigurationName());
+ m_nameLineEdit->setText(BareMetalDevice::defaultDisplayName());
}
bool BareMetalDeviceConfigurationWizardSetupPage::isComplete() const
@@ -80,10 +80,5 @@ QString BareMetalDeviceConfigurationWizardSetupPage::gdbServerProviderId() const
return m_gdbServerProviderChooser->currentProviderId();
}
-QString BareMetalDeviceConfigurationWizardSetupPage::defaultConfigurationName() const
-{
- return tr("Bare Metal Device");
-}
-
} // namespace Internal
} // namespace BareMetal
diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h
index 27ac808108..05f16ba290 100644
--- a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h
+++ b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h
@@ -51,8 +51,6 @@ public:
QString configurationName() const;
QString gdbServerProviderId() const;
- virtual QString defaultConfigurationName() const;
-
private:
QLineEdit *m_nameLineEdit = nullptr;
GdbServerProviderChooser *m_gdbServerProviderChooser = nullptr;
diff --git a/src/plugins/baremetal/baremetalplugin.cpp b/src/plugins/baremetal/baremetalplugin.cpp
index 0ce4c51835..d45367ac7d 100644
--- a/src/plugins/baremetal/baremetalplugin.cpp
+++ b/src/plugins/baremetal/baremetalplugin.cpp
@@ -63,6 +63,12 @@ public:
BareMetalCustomRunConfigurationFactory customRunConfigurationFactory;
GdbServerProvidersSettingsPage gdbServerProviderSettinsPage;
GdbServerProviderManager gdbServerProviderManager;
+
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<BareMetalDebugSupport>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE, ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ {runConfigurationFactory.id(), customRunConfigurationFactory.id()}
+ };
};
// BareMetalPlugin
@@ -78,19 +84,6 @@ bool BareMetalPlugin::initialize(const QStringList &arguments, QString *errorStr
Q_UNUSED(errorString)
d = new BareMetalPluginPrivate;
-
- auto constraint = [](RunConfiguration *runConfig) {
- const QByteArray idStr = runConfig->id().name();
- const bool res = idStr.startsWith(BareMetalRunConfiguration::IdPrefix)
- || idStr == BareMetalCustomRunConfiguration::Id;
- return res;
- };
-
- RunControl::registerWorker<BareMetalDebugSupport>
- (ProjectExplorer::Constants::NORMAL_RUN_MODE, constraint);
- RunControl::registerWorker<BareMetalDebugSupport>
- (ProjectExplorer::Constants::DEBUG_RUN_MODE, constraint);
-
return true;
}
diff --git a/src/plugins/baremetal/defaultgdbserverprovider.cpp b/src/plugins/baremetal/defaultgdbserverprovider.cpp
index 49d126479d..189e64524b 100644
--- a/src/plugins/baremetal/defaultgdbserverprovider.cpp
+++ b/src/plugins/baremetal/defaultgdbserverprovider.cpp
@@ -38,62 +38,14 @@
namespace BareMetal {
namespace Internal {
-static const char hostKeyC[] = "BareMetal.DefaultGdbServerProvider.Host";
-static const char portKeyC[] = "BareMetal.DefaultGdbServerProvider.Port";
-
// DefaultGdbServerProvider
DefaultGdbServerProvider::DefaultGdbServerProvider()
: GdbServerProvider(QLatin1String(Constants::DEFAULT_PROVIDER_ID))
{
-}
-
-DefaultGdbServerProvider::DefaultGdbServerProvider(const DefaultGdbServerProvider &other) = default;
-
-quint16 DefaultGdbServerProvider::port() const
-{
- return m_port;
-}
-
-void DefaultGdbServerProvider::setPort(const quint16 &port)
-{
- m_port = port;
-}
-
-QString DefaultGdbServerProvider::host() const
-{
- return m_host;
-}
-
-void DefaultGdbServerProvider::setHost(const QString &host)
-{
- if (m_host == host)
- return;
- m_host = host;
- providerUpdated();
-}
-
-QString DefaultGdbServerProvider::typeDisplayName() const
-{
- return DefaultGdbServerProviderFactory::tr("Default");
-}
-
-QString DefaultGdbServerProvider::channel() const
-{
- // Just return as "host:port" form.
- if (m_port == 0)
- return m_host;
- return m_host + QLatin1Char(':') + QString::number(m_port);
-}
-
-bool DefaultGdbServerProvider::isValid() const
-{
- if (!GdbServerProvider::isValid())
- return false;
-
- if (m_host.isEmpty())
- return false;
- return true;
+ setDefaultChannel("localhost", 3333);
+ setSettingsKeyBase("BareMetal.DefaultGdbServerProvider");
+ setTypeDisplayName(DefaultGdbServerProviderFactory::tr("Default"));
}
GdbServerProvider *DefaultGdbServerProvider::clone() const
@@ -101,33 +53,6 @@ GdbServerProvider *DefaultGdbServerProvider::clone() const
return new DefaultGdbServerProvider(*this);
}
-QVariantMap DefaultGdbServerProvider::toMap() const
-{
- auto data = GdbServerProvider::toMap();
- data.insert(QLatin1String(hostKeyC), m_host);
- data.insert(QLatin1String(portKeyC), m_port);
- return data;
-}
-
-bool DefaultGdbServerProvider::fromMap(const QVariantMap &data)
-{
- if (!GdbServerProvider::fromMap(data))
- return false;
-
- m_host = data.value(QLatin1String(hostKeyC)).toString();
- m_port = data.value(QLatin1String(portKeyC)).toInt();
- return true;
-}
-
-bool DefaultGdbServerProvider::operator==(const GdbServerProvider &other) const
-{
- if (!GdbServerProvider::operator==(other))
- return false;
-
- const auto p = static_cast<const DefaultGdbServerProvider *>(&other);
- return m_host == p->m_host && m_port == p->m_port;
-}
-
GdbServerProviderConfigWidget *DefaultGdbServerProvider::configurationWidget()
{
return new DefaultGdbServerProviderConfigWidget(this);
@@ -206,8 +131,7 @@ void DefaultGdbServerProviderConfigWidget::applyImpl()
auto p = static_cast<DefaultGdbServerProvider *>(provider());
Q_ASSERT(p);
- p->setHost(m_hostWidget->host());
- p->setPort(m_hostWidget->port());
+ p->setChannel(m_hostWidget->channel());
p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked());
p->setInitCommands(m_initCommandsTextEdit->toPlainText());
p->setResetCommands(m_resetCommandsTextEdit->toPlainText());
@@ -224,8 +148,7 @@ void DefaultGdbServerProviderConfigWidget::setFromProvider()
Q_ASSERT(p);
const QSignalBlocker blocker(this);
- m_hostWidget->setHost(p->m_host);
- m_hostWidget->setPort(p->m_port);
+ m_hostWidget->setChannel(p->channel());
m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote());
m_initCommandsTextEdit->setPlainText(p->initCommands());
m_resetCommandsTextEdit->setPlainText(p->resetCommands());
diff --git a/src/plugins/baremetal/defaultgdbserverprovider.h b/src/plugins/baremetal/defaultgdbserverprovider.h
index 82b7e78160..8beb9b7b77 100644
--- a/src/plugins/baremetal/defaultgdbserverprovider.h
+++ b/src/plugins/baremetal/defaultgdbserverprovider.h
@@ -38,32 +38,11 @@ class DefaultGdbServerProviderFactory;
class DefaultGdbServerProvider final : public GdbServerProvider
{
public:
- QString typeDisplayName() const final;
-
- QVariantMap toMap() const final;
- bool fromMap(const QVariantMap &data) final;
-
- bool operator==(const GdbServerProvider &) const final;
-
GdbServerProviderConfigWidget *configurationWidget() final;
GdbServerProvider *clone() const final;
- QString channel() const final;
-
- bool isValid() const final;
-
- QString host() const;
- void setHost(const QString &host);
-
- quint16 port() const;
- void setPort(const quint16 &port);
-
private:
explicit DefaultGdbServerProvider();
- explicit DefaultGdbServerProvider(const DefaultGdbServerProvider &);
-
- QString m_host = QLatin1String("localhost");
- quint16 m_port = 3333;
friend class DefaultGdbServerProviderConfigWidget;
friend class DefaultGdbServerProviderFactory;
diff --git a/src/plugins/baremetal/gdbserverprovider.cpp b/src/plugins/baremetal/gdbserverprovider.cpp
index 520e8fb30f..a916146c38 100644
--- a/src/plugins/baremetal/gdbserverprovider.cpp
+++ b/src/plugins/baremetal/gdbserverprovider.cpp
@@ -49,6 +49,9 @@ const char initCommandsKeyC[] = "BareMetal.GdbServerProvider.InitCommands";
const char resetCommandsKeyC[] = "BareMetal.GdbServerProvider.ResetCommands";
const char useExtendedRemoteKeyC[] = "BareMetal.GdbServerProvider.UseExtendedRemote";
+const char hostKeySuffixC[] = ".Host";
+const char portKeySuffixC[] = ".Port";
+
static QString createId(const QString &id)
{
QString newId = id.left(id.indexOf(QLatin1Char(':')));
@@ -128,6 +131,11 @@ bool GdbServerProvider::useExtendedRemote() const
return m_useExtendedRemote;
}
+QString GdbServerProvider::typeDisplayName() const
+{
+ return m_typeDisplayName;
+}
+
void GdbServerProvider::setUseExtendedRemote(bool useExtendedRemote)
{
m_useExtendedRemote = useExtendedRemote;
@@ -143,6 +151,22 @@ void GdbServerProvider::setResetCommands(const QString &cmds)
m_resetCommands = cmds;
}
+void GdbServerProvider::setChannel(const QUrl &channel)
+{
+ m_channel = channel;
+}
+
+void GdbServerProvider::setDefaultChannel(const QString &host, int port)
+{
+ m_channel.setHost(host);
+ m_channel.setPort(port);
+}
+
+QUrl GdbServerProvider::channel() const
+{
+ return m_channel;
+}
+
Utils::CommandLine GdbServerProvider::command() const
{
return {};
@@ -158,12 +182,21 @@ bool GdbServerProvider::operator==(const GdbServerProvider &other) const
// We ignore displayname
return thisId == otherId
+ && m_channel == other.m_channel
&& m_startupMode == other.m_startupMode
&& m_initCommands == other.m_initCommands
&& m_resetCommands == other.m_resetCommands
&& m_useExtendedRemote == other.m_useExtendedRemote;
}
+QString GdbServerProvider::channelString() const
+{
+ // Just return as "host:port" form.
+ if (m_channel.port() <= 0)
+ return m_channel.host();
+ return m_channel.host() + ':' + QString::number(m_channel.port());
+}
+
QVariantMap GdbServerProvider::toMap() const
{
return {
@@ -173,12 +206,14 @@ QVariantMap GdbServerProvider::toMap() const
{QLatin1String(initCommandsKeyC), m_initCommands},
{QLatin1String(resetCommandsKeyC), m_resetCommands},
{QLatin1String(useExtendedRemoteKeyC), m_useExtendedRemote},
+ {m_settingsBase + hostKeySuffixC, m_channel.host()},
+ {m_settingsBase + portKeySuffixC, m_channel.port()},
};
}
bool GdbServerProvider::isValid() const
{
- return !channel().isNull();
+ return !channelString().isEmpty();
}
bool GdbServerProvider::canStartupMode(StartupMode m) const
@@ -211,9 +246,22 @@ bool GdbServerProvider::fromMap(const QVariantMap &data)
m_initCommands = data.value(QLatin1String(initCommandsKeyC)).toString();
m_resetCommands = data.value(QLatin1String(resetCommandsKeyC)).toString();
m_useExtendedRemote = data.value(QLatin1String(useExtendedRemoteKeyC)).toBool();
+ m_channel.setHost(data.value(m_settingsBase + hostKeySuffixC).toString());
+ m_channel.setPort(data.value(m_settingsBase + portKeySuffixC).toInt());
+
return true;
}
+void GdbServerProvider::setTypeDisplayName(const QString &typeDisplayName)
+{
+ m_typeDisplayName = typeDisplayName;
+}
+
+void GdbServerProvider::setSettingsKeyBase(const QString &settingsBase)
+{
+ m_settingsBase = settingsBase;
+}
+
// GdbServerProviderFactory
QString GdbServerProviderFactory::id() const
@@ -410,26 +458,19 @@ HostWidget::HostWidget(QWidget *parent)
this, &HostWidget::dataChanged);
}
-void HostWidget::setHost(const QString &host)
-{
- const QSignalBlocker blocker(this);
- m_hostLineEdit->setText(host);
-}
-
-QString HostWidget::host() const
-{
- return m_hostLineEdit->text();
-}
-
-void HostWidget::setPort(const quint16 &port)
+void HostWidget::setChannel(const QUrl &channel)
{
const QSignalBlocker blocker(this);
- m_portSpinBox->setValue(port);
+ m_hostLineEdit->setText(channel.host());
+ m_portSpinBox->setValue(channel.port());
}
-quint16 HostWidget::port() const
+QUrl HostWidget::channel() const
{
- return m_portSpinBox->value();
+ QUrl url;
+ url.setHost(m_hostLineEdit->text());
+ url.setPort(m_portSpinBox->value());
+ return url;
}
} // namespace Internal
diff --git a/src/plugins/baremetal/gdbserverprovider.h b/src/plugins/baremetal/gdbserverprovider.h
index 8d91408a2e..5a6bc246a5 100644
--- a/src/plugins/baremetal/gdbserverprovider.h
+++ b/src/plugins/baremetal/gdbserverprovider.h
@@ -72,14 +72,13 @@ public:
QString initCommands() const;
QString resetCommands() const;
bool useExtendedRemote() const;
+ QString typeDisplayName() const;
virtual bool operator==(const GdbServerProvider &) const;
- virtual QString typeDisplayName() const = 0;
-
virtual GdbServerProviderConfigWidget *configurationWidget() = 0;
- virtual QString channel() const = 0;
+ virtual QString channelString() const;
virtual GdbServerProvider *clone() const = 0;
virtual QVariantMap toMap() const;
@@ -92,6 +91,10 @@ public:
void registerDevice(BareMetalDevice *);
void unregisterDevice(BareMetalDevice *);
+ QUrl channel() const;
+ void setChannel(const QUrl &channelString);
+ void setDefaultChannel(const QString &host, int port);
+
protected:
explicit GdbServerProvider(const QString &id);
explicit GdbServerProvider(const GdbServerProvider &);
@@ -100,6 +103,8 @@ protected:
void setInitCommands(const QString &);
void setResetCommands(const QString &);
void setUseExtendedRemote(bool);
+ void setSettingsKeyBase(const QString &settingsBase);
+ void setTypeDisplayName(const QString &typeDisplayName);
void providerUpdated();
@@ -107,7 +112,10 @@ protected:
private:
QString m_id;
+ QString m_settingsBase;
mutable QString m_displayName;
+ QString m_typeDisplayName;
+ QUrl m_channel;
StartupMode m_startupMode = NoStartup;
QString m_initCommands;
QString m_resetCommands;
@@ -195,10 +203,8 @@ class HostWidget final : public QWidget
public:
explicit HostWidget(QWidget *parent = nullptr);
- void setHost(const QString &host);
- QString host() const;
- void setPort(const quint16 &port);
- quint16 port() const;
+ void setChannel(const QUrl &host);
+ QUrl channel() const;
signals:
void dataChanged();
diff --git a/src/plugins/baremetal/gdbserverproviderchooser.cpp b/src/plugins/baremetal/gdbserverproviderchooser.cpp
index 764a9ee0cd..768c2d205f 100644
--- a/src/plugins/baremetal/gdbserverproviderchooser.cpp
+++ b/src/plugins/baremetal/gdbserverproviderchooser.cpp
@@ -87,7 +87,7 @@ void GdbServerProviderChooser::manageButtonClicked()
void GdbServerProviderChooser::currentIndexChanged(int index)
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
emit providerChanged();
}
diff --git a/src/plugins/baremetal/gdbserverproviderssettingspage.cpp b/src/plugins/baremetal/gdbserverproviderssettingspage.cpp
index b538ebce33..fb78ef713e 100644
--- a/src/plugins/baremetal/gdbserverproviderssettingspage.cpp
+++ b/src/plugins/baremetal/gdbserverproviderssettingspage.cpp
@@ -406,8 +406,7 @@ QModelIndex GdbServerProvidersSettingsWidget::currentIndex() const
}
-GdbServerProvidersSettingsPage::GdbServerProvidersSettingsPage(QObject *parent)
- : Core::IOptionsPage(parent)
+GdbServerProvidersSettingsPage::GdbServerProvidersSettingsPage()
{
setId(Constants::GDB_PROVIDERS_SETTINGS_ID);
setDisplayName(tr("Bare Metal"));
diff --git a/src/plugins/baremetal/gdbserverproviderssettingspage.h b/src/plugins/baremetal/gdbserverproviderssettingspage.h
index a68515526e..c41389b307 100644
--- a/src/plugins/baremetal/gdbserverproviderssettingspage.h
+++ b/src/plugins/baremetal/gdbserverproviderssettingspage.h
@@ -87,7 +87,7 @@ class GdbServerProvidersSettingsPage final : public Core::IOptionsPage
Q_OBJECT
public:
- explicit GdbServerProvidersSettingsPage(QObject *parent = nullptr);
+ GdbServerProvidersSettingsPage();
private:
QWidget *widget() final;
diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp
index c0684f008c..75dbee8cb5 100644
--- a/src/plugins/baremetal/iarewtoolchain.cpp
+++ b/src/plugins/baremetal/iarewtoolchain.cpp
@@ -71,8 +71,10 @@ static QString cppLanguageOption(const FilePath &compiler)
const QString baseName = compiler.toFileInfo().baseName();
if (baseName == "iccarm")
return QString("--c++");
- if (baseName == "icc8051" || baseName == "iccavr")
+ if (baseName == "icc8051" || baseName == "iccavr"
+ || baseName == "iccstm8" || baseName == "icc430") {
return QString("--ec++");
+ }
return {};
}
@@ -95,17 +97,16 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const Core::Id lang
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
- QStringList arguments;
- arguments.push_back(fakeIn.fileName());
+ CommandLine cmd(compiler, {fakeIn.fileName()});
if (languageId == ProjectExplorer::Constants::CXX_LANGUAGE_ID)
- arguments.push_back(cppLanguageOption(compiler));
- arguments.push_back("--predef_macros");
- arguments.push_back(outpath);
+ cmd.addArg(cppLanguageOption(compiler));
+ cmd.addArg("--predef_macros");
+ cmd.addArg(outpath);
- const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(), arguments);
+ const SynchronousProcessResponse response = cpp.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished
|| response.exitCode != 0) {
- qWarning() << response.exitMessage(compiler.toString(), 10);
+ qWarning() << response.exitMessage(cmd.toUserOutput(), 10);
return {};
}
@@ -141,16 +142,14 @@ static HeaderPaths dumpHeaderPaths(const FilePath &compiler, const Core::Id lang
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
- QStringList arguments;
- arguments.push_back(fakeIn.fileName());
+ CommandLine cmd(compiler, {fakeIn.fileName()});
if (languageId == ProjectExplorer::Constants::CXX_LANGUAGE_ID)
- arguments.push_back(cppLanguageOption(compiler));
- arguments.push_back("--preinclude");
- arguments.push_back(".");
+ cmd.addArg(cppLanguageOption(compiler));
+ cmd.addArg("--preinclude");
+ cmd.addArg(".");
// Note: Response should retutn an error, just don't check on errors.
- const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(),
- arguments);
+ const SynchronousProcessResponse response = cpp.runBlocking(cmd);
HeaderPaths headerPaths;
@@ -192,6 +191,10 @@ static Abi::Architecture guessArchitecture(const Macros &macros)
return Abi::Architecture::Mcs51Architecture;
if (macro.key == "__ICCAVR__")
return Abi::Architecture::AvrArchitecture;
+ if (macro.key == "__ICCSTM8__")
+ return Abi::Architecture::Stm8Architecture;
+ if (macro.key == "__ICC430__")
+ return Abi::Architecture::Msp430Architecture;
}
return Abi::Architecture::UnknownArchitecture;
}
@@ -208,10 +211,13 @@ static unsigned char guessWordWidth(const Macros &macros)
static Abi::BinaryFormat guessFormat(Abi::Architecture arch)
{
- if (arch == Abi::Architecture::ArmArchitecture)
+ if (arch == Abi::Architecture::ArmArchitecture
+ || arch == Abi::Architecture::Stm8Architecture) {
return Abi::BinaryFormat::ElfFormat;
+ }
if (arch == Abi::Architecture::Mcs51Architecture
- || arch == Abi::Architecture::AvrArchitecture) {
+ || arch == Abi::Architecture::AvrArchitecture
+ || arch == Abi::Architecture::Msp430Architecture) {
return Abi::BinaryFormat::UbrofFormat;
}
return Abi::BinaryFormat::UnknownFormat;
@@ -237,11 +243,8 @@ static QString buildDisplayName(Abi::Architecture arch, Core::Id language,
IarToolChain::IarToolChain() :
ToolChain(Constants::IAREW_TOOLCHAIN_TYPEID)
-{ }
-
-QString IarToolChain::typeDisplayName() const
{
- return Internal::IarToolChainFactory::tr("IAREW");
+ setTypeDisplayName(Internal::IarToolChainFactory::tr("IAREW"));
}
void IarToolChain::setTargetAbi(const Abi &abi)
@@ -300,11 +303,12 @@ Utils::LanguageExtensions IarToolChain::languageExtensions(const QStringList &)
WarningFlags IarToolChain::warningFlags(const QStringList &cxxflags) const
{
- Q_UNUSED(cxxflags);
+ Q_UNUSED(cxxflags)
return WarningFlags::Default;
}
-ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &) const
{
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
@@ -328,9 +332,10 @@ ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner
}
HeaderPaths IarToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
- const FilePath &fileName) const
+ const FilePath &fileName,
+ const Environment &env) const
{
- return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
+ return createBuiltInHeaderPathsRunner(env)(cxxFlags, fileName.toString(), "");
}
void IarToolChain::addToEnvironment(Environment &env) const
@@ -430,6 +435,8 @@ QList<ToolChain *> IarToolChainFactory::autoDetect(const QList<ToolChain *> &alr
{{"EWARM"}, {"\\arm\\bin\\iccarm.exe"}},
{{"EWAVR"}, {"\\avr\\bin\\iccavr.exe"}},
{{"EW8051"}, {"\\8051\\bin\\icc8051.exe"}},
+ {{"EWSTM8"}, {"\\stm8\\bin\\iccstm8.exe"}},
+ {{"EW430"}, {"\\430\\bin\\icc430.exe"}},
};
QSettings registry(kRegistryNode, QSettings::NativeFormat);
@@ -447,7 +454,7 @@ QList<ToolChain *> IarToolChainFactory::autoDetect(const QList<ToolChain *> &alr
if (!compilerPath.isEmpty()) {
// Build full compiler path.
compilerPath += entry.subExePath;
- const FileName fn = FileName::fromString(compilerPath);
+ const FilePath fn = FilePath::fromString(compilerPath);
if (compilerExists(fn)) {
// Note: threeLevelKey is a guessed toolchain version.
candidates.push_back({fn, threeLevelKey});
diff --git a/src/plugins/baremetal/iarewtoolchain.h b/src/plugins/baremetal/iarewtoolchain.h
index 019c9e7185..0ad3dd6ddc 100644
--- a/src/plugins/baremetal/iarewtoolchain.h
+++ b/src/plugins/baremetal/iarewtoolchain.h
@@ -52,8 +52,6 @@ class IarToolChain final : public ProjectExplorer::ToolChain
Q_DECLARE_TR_FUNCTIONS(IarToolChain)
public:
- QString typeDisplayName() const final;
-
void setTargetAbi(const ProjectExplorer::Abi &abi);
ProjectExplorer::Abi targetAbi() const final;
@@ -65,9 +63,10 @@ public:
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const final;
ProjectExplorer::WarningFlags warningFlags(const QStringList &cxxflags) const final;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const final;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(const Utils::Environment &) const final;
ProjectExplorer::HeaderPaths builtInHeaderPaths(const QStringList &cxxFlags,
- const Utils::FilePath &) const final;
+ const Utils::FilePath &,
+ const Utils::Environment &env) const final;
void addToEnvironment(Utils::Environment &env) const final;
ProjectExplorer::IOutputParser *outputParser() const final;
diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp
index 303efa3440..eb6afe8e0e 100644
--- a/src/plugins/baremetal/keiltoolchain.cpp
+++ b/src/plugins/baremetal/keiltoolchain.cpp
@@ -102,13 +102,12 @@ static Macros dumpC51PredefinedMacros(const FilePath &compiler, const QStringLis
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
- QStringList arguments;
- arguments.push_back(fakeIn.fileName());
+ const CommandLine cmd(compiler, {fakeIn.fileName()});
- const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(), arguments);
+ const SynchronousProcessResponse response = cpp.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished
|| response.exitCode != 0) {
- qWarning() << response.exitMessage(compiler.toString(), 10);
+ qWarning() << response.exitMessage(cmd.toUserOutput(), 10);
return {};
}
@@ -131,11 +130,9 @@ static Macros dumpArmPredefinedMacros(const FilePath &compiler, const QStringLis
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
- QStringList arguments;
- arguments.push_back("-E");
- arguments.push_back("--list-macros");
+ const CommandLine cmd(compiler, {"-E", "--list-macros"});
- const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(), arguments);
+ const SynchronousProcessResponse response = cpp.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished
|| response.exitCode != 0) {
qWarning() << response.exitMessage(compiler.toString(), 10);
@@ -241,11 +238,8 @@ static QString buildDisplayName(Abi::Architecture arch, Core::Id language,
KeilToolchain::KeilToolchain() :
ToolChain(Constants::KEIL_TOOLCHAIN_TYPEID)
-{ }
-
-QString KeilToolchain::typeDisplayName() const
{
- return Internal::KeilToolchainFactory::tr("KEIL");
+ setTypeDisplayName(Internal::KeilToolchainFactory::tr("KEIL"));
}
void KeilToolchain::setTargetAbi(const Abi &abi)
@@ -300,11 +294,12 @@ Utils::LanguageExtensions KeilToolchain::languageExtensions(const QStringList &)
WarningFlags KeilToolchain::warningFlags(const QStringList &cxxflags) const
{
- Q_UNUSED(cxxflags);
+ Q_UNUSED(cxxflags)
return WarningFlags::Default;
}
-ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunner(
+ const Environment &) const
{
const Utils::FilePath compilerCommand = m_compilerCommand;
@@ -323,9 +318,10 @@ ToolChain::BuiltInHeaderPathsRunner KeilToolchain::createBuiltInHeaderPathsRunne
}
HeaderPaths KeilToolchain::builtInHeaderPaths(const QStringList &cxxFlags,
- const FilePath &fileName) const
+ const FilePath &fileName,
+ const Environment &env) const
{
- return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
+ return createBuiltInHeaderPathsRunner(env)(cxxFlags, fileName.toString(), "");
}
void KeilToolchain::addToEnvironment(Environment &env) const
diff --git a/src/plugins/baremetal/keiltoolchain.h b/src/plugins/baremetal/keiltoolchain.h
index 5ccf9e05ff..b3ea5717b6 100644
--- a/src/plugins/baremetal/keiltoolchain.h
+++ b/src/plugins/baremetal/keiltoolchain.h
@@ -52,8 +52,6 @@ class KeilToolchain final : public ProjectExplorer::ToolChain
Q_DECLARE_TR_FUNCTIONS(KeilToolchain)
public:
- QString typeDisplayName() const final;
-
void setTargetAbi(const ProjectExplorer::Abi &abi);
ProjectExplorer::Abi targetAbi() const final;
@@ -65,9 +63,11 @@ public:
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const final;
ProjectExplorer::WarningFlags warningFlags(const QStringList &cxxflags) const final;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const final;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &) const final;
ProjectExplorer::HeaderPaths builtInHeaderPaths(const QStringList &cxxFlags,
- const Utils::FilePath &) const final;
+ const Utils::FilePath &,
+ const Utils::Environment &env) const final;
void addToEnvironment(Utils::Environment &env) const final;
ProjectExplorer::IOutputParser *outputParser() const final;
diff --git a/src/plugins/baremetal/openocdgdbserverprovider.cpp b/src/plugins/baremetal/openocdgdbserverprovider.cpp
index b7044defe0..04b1b88cc5 100644
--- a/src/plugins/baremetal/openocdgdbserverprovider.cpp
+++ b/src/plugins/baremetal/openocdgdbserverprovider.cpp
@@ -46,8 +46,6 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
-const char hostKeyC[] = "BareMetal.OpenOcdGdbServerProvider.Host";
-const char portKeyC[] = "BareMetal.OpenOcdGdbServerProvider.Port";
const char executableFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ExecutableFile";
const char rootScriptsDirKeyC[] = "BareMetal.OpenOcdGdbServerProvider.RootScriptsDir";
const char configurationFileKeyC[] = "BareMetal.OpenOcdGdbServerProvider.ConfigurationPath";
@@ -60,11 +58,11 @@ OpenOcdGdbServerProvider::OpenOcdGdbServerProvider()
{
setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands());
+ setDefaultChannel("localhost", 3333);
+ setSettingsKeyBase("BareMetal.OpenOcdGdbServerProvider");
+ setTypeDisplayName(OpenOcdGdbServerProviderFactory::tr("OpenOCD"));
}
-OpenOcdGdbServerProvider::OpenOcdGdbServerProvider(
- const OpenOcdGdbServerProvider &other) = default;
-
QString OpenOcdGdbServerProvider::defaultInitCommands()
{
return QLatin1String("set remote hardware-breakpoint-limit 6\n"
@@ -79,19 +77,14 @@ QString OpenOcdGdbServerProvider::defaultResetCommands()
return QLatin1String("monitor reset halt\n");
}
-QString OpenOcdGdbServerProvider::typeDisplayName() const
-{
- return OpenOcdGdbServerProviderFactory::tr("OpenOCD");
-}
-
-QString OpenOcdGdbServerProvider::channel() const
+QString OpenOcdGdbServerProvider::channelString() const
{
switch (startupMode()) {
case NoStartup:
// fallback
case StartupOnNetwork:
// Just return as "host:port" form.
- return m_host + QLatin1Char(':') + QString::number(m_port);
+ return GdbServerProvider::channelString();
case StartupOnPipe: {
// In the pipe mode need to add quotes to each item of arguments;
// otherwise running will be stuck.
@@ -112,13 +105,13 @@ QString OpenOcdGdbServerProvider::channel() const
CommandLine OpenOcdGdbServerProvider::command() const
{
- CommandLine cmd{m_executableFile, {}};
+ CommandLine cmd{m_executableFile};
cmd.addArg("-c");
if (startupMode() == StartupOnPipe)
cmd.addArg("gdb_port pipe");
else
- cmd.addArg("gdb_port " + QString::number(m_port));
+ cmd.addArg("gdb_port " + QString::number(channel().port()));
if (!m_rootScriptsDir.isEmpty())
cmd.addArgs({"-s", m_rootScriptsDir});
@@ -127,7 +120,7 @@ CommandLine OpenOcdGdbServerProvider::command() const
cmd.addArgs({"-f", m_configurationFile});
if (!m_additionalArguments.isEmpty())
- cmd.addArgs(m_additionalArguments);
+ cmd.addArgs(m_additionalArguments, CommandLine::Raw);
return cmd;
}
@@ -145,7 +138,7 @@ bool OpenOcdGdbServerProvider::isValid() const
const StartupMode m = startupMode();
if (m == NoStartup || m == StartupOnNetwork) {
- if (m_host.isEmpty())
+ if (channel().host().isEmpty())
return false;
}
@@ -165,8 +158,6 @@ GdbServerProvider *OpenOcdGdbServerProvider::clone() const
QVariantMap OpenOcdGdbServerProvider::toMap() const
{
QVariantMap data = GdbServerProvider::toMap();
- data.insert(QLatin1String(hostKeyC), m_host);
- data.insert(QLatin1String(portKeyC), m_port);
data.insert(QLatin1String(executableFileKeyC), m_executableFile.toVariant());
data.insert(QLatin1String(rootScriptsDirKeyC), m_rootScriptsDir);
data.insert(QLatin1String(configurationFileKeyC), m_configurationFile);
@@ -179,8 +170,6 @@ bool OpenOcdGdbServerProvider::fromMap(const QVariantMap &data)
if (!GdbServerProvider::fromMap(data))
return false;
- m_host = data.value(QLatin1String(hostKeyC)).toString();
- m_port = data.value(QLatin1String(portKeyC)).toInt();
m_executableFile = FilePath::fromVariant(data.value(QLatin1String(executableFileKeyC)));
m_rootScriptsDir = data.value(QLatin1String(rootScriptsDirKeyC)).toString();
m_configurationFile = data.value(QLatin1String(configurationFileKeyC)).toString();
@@ -194,9 +183,7 @@ bool OpenOcdGdbServerProvider::operator==(const GdbServerProvider &other) const
return false;
const auto p = static_cast<const OpenOcdGdbServerProvider *>(&other);
- return m_host == p->m_host
- && m_port == p->m_port
- && m_executableFile == p->m_executableFile
+ return m_executableFile == p->m_executableFile
&& m_rootScriptsDir == p->m_rootScriptsDir
&& m_configurationFile == p->m_configurationFile
&& m_additionalArguments == p->m_additionalArguments;
@@ -320,8 +307,7 @@ void OpenOcdGdbServerProviderConfigWidget::applyImpl()
const auto p = static_cast<OpenOcdGdbServerProvider *>(provider());
Q_ASSERT(p);
- p->m_host = m_hostWidget->host();
- p->m_port = m_hostWidget->port();
+ p->setChannel(m_hostWidget->channel());
p->m_executableFile = m_executableFileChooser->fileName();
p->m_rootScriptsDir = m_rootScriptsDirChooser->fileName().toString();
p->m_configurationFile = m_configurationFileChooser->fileName().toString();
@@ -342,8 +328,7 @@ void OpenOcdGdbServerProviderConfigWidget::setFromProvider()
const QSignalBlocker blocker(this);
startupModeChanged();
- m_hostWidget->setHost(p->m_host);
- m_hostWidget->setPort(p->m_port);
+ m_hostWidget->setChannel(p->channel());
m_executableFileChooser->setFileName(p->m_executableFile);
m_rootScriptsDirChooser->setFileName(Utils::FilePath::fromString(p->m_rootScriptsDir));
m_configurationFileChooser->setFileName(Utils::FilePath::fromString(p->m_configurationFile));
diff --git a/src/plugins/baremetal/openocdgdbserverprovider.h b/src/plugins/baremetal/openocdgdbserverprovider.h
index 229b12bf61..ceb5329c37 100644
--- a/src/plugins/baremetal/openocdgdbserverprovider.h
+++ b/src/plugins/baremetal/openocdgdbserverprovider.h
@@ -40,8 +40,6 @@ class OpenOcdGdbServerProviderFactory;
class OpenOcdGdbServerProvider final : public GdbServerProvider
{
public:
- QString typeDisplayName() const final;
-
QVariantMap toMap() const final;
bool fromMap(const QVariantMap &data) final;
@@ -50,7 +48,7 @@ public:
GdbServerProviderConfigWidget *configurationWidget() final;
GdbServerProvider *clone() const final;
- QString channel() const final;
+ QString channelString() const final;
Utils::CommandLine command() const final;
bool canStartupMode(StartupMode mode) const final;
@@ -58,13 +56,10 @@ public:
private:
explicit OpenOcdGdbServerProvider();
- explicit OpenOcdGdbServerProvider(const OpenOcdGdbServerProvider &);
static QString defaultInitCommands();
static QString defaultResetCommands();
- QString m_host = QLatin1String("localhost");
- quint16 m_port = 3333;
Utils::FilePath m_executableFile = Utils::FilePath::fromString("openocd");
QString m_rootScriptsDir;
QString m_configurationFile;
diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp
index b839a68fe8..199d8ef0aa 100644
--- a/src/plugins/baremetal/sdcctoolchain.cpp
+++ b/src/plugins/baremetal/sdcctoolchain.cpp
@@ -72,6 +72,8 @@ static QString compilerTargetFlag(const Abi &abi)
switch (abi.architecture()) {
case Abi::Architecture::Mcs51Architecture:
return QString("-mmcs51");
+ case Abi::Architecture::Stm8Architecture:
+ return QString("-mstm8");
default:
return {};
}
@@ -92,13 +94,9 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const QStringList &
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
- QStringList arguments;
- arguments.push_back(compilerTargetFlag(abi));
- arguments.push_back("-dM");
- arguments.push_back("-E");
- arguments.push_back(fakeIn.fileName());
+ const CommandLine cmd(compiler, {compilerTargetFlag(abi), "-dM", "-E", fakeIn.fileName()});
- const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(), arguments);
+ const SynchronousProcessResponse response = cpp.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished
|| response.exitCode != 0) {
qWarning() << response.exitMessage(compiler.toString(), 10);
@@ -119,11 +117,9 @@ static HeaderPaths dumpHeaderPaths(const FilePath &compiler, const QStringList &
cpp.setEnvironment(env);
cpp.setTimeoutS(10);
- QStringList arguments;
- arguments.push_back(compilerTargetFlag(abi));
- arguments.push_back("--print-search-dirs");
+ const CommandLine cmd(compiler, {compilerTargetFlag(abi), "--print-search-dirs"});
- const SynchronousProcessResponse response = cpp.runBlocking(compiler.toString(), arguments);
+ const SynchronousProcessResponse response = cpp.runBlocking(cmd);
if (response.result != SynchronousProcessResponse::Finished
|| response.exitCode != 0) {
qWarning() << response.exitMessage(compiler.toString(), 10);
@@ -175,6 +171,8 @@ static Abi::Architecture guessArchitecture(const Macros &macros)
for (const Macro &macro : macros) {
if (macro.key == "__SDCC_mcs51")
return Abi::Architecture::Mcs51Architecture;
+ if (macro.key == "__SDCC_stm8")
+ return Abi::Architecture::Stm8Architecture;
}
return Abi::Architecture::UnknownArchitecture;
}
@@ -218,11 +216,8 @@ static Utils::FilePath compilerPathFromEnvironment(const QString &compilerName)
SdccToolChain::SdccToolChain() :
ToolChain(Constants::SDCC_TOOLCHAIN_TYPEID)
-{ }
-
-QString SdccToolChain::typeDisplayName() const
{
- return Internal::SdccToolChainFactory::tr("SDCC");
+ setTypeDisplayName(Internal::SdccToolChainFactory::tr("SDCC"));
}
void SdccToolChain::setTargetAbi(const Abi &abi)
@@ -279,38 +274,29 @@ Utils::LanguageExtensions SdccToolChain::languageExtensions(const QStringList &)
WarningFlags SdccToolChain::warningFlags(const QStringList &cxxflags) const
{
- Q_UNUSED(cxxflags);
+ Q_UNUSED(cxxflags)
return WarningFlags::Default;
}
-ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &) const
{
Environment env = Environment::systemEnvironment();
addToEnvironment(env);
const Utils::FilePath compilerCommand = m_compilerCommand;
- const Core::Id languageId = language();
const Abi abi = m_targetAbi;
- HeaderPathsCache headerPaths = headerPathsCache();
-
- return [env, compilerCommand, headerPaths, languageId, abi](const QStringList &flags,
- const QString &fileName,
- const QString &) {
- Q_UNUSED(flags)
- Q_UNUSED(fileName)
-
- const HeaderPaths paths = dumpHeaderPaths(compilerCommand, env.toStringList(), abi);
- headerPaths->insert({}, paths);
-
- return paths;
+ return [env, compilerCommand, abi](const QStringList &, const QString &, const QString &) {
+ return dumpHeaderPaths(compilerCommand, env.toStringList(), abi);
};
}
HeaderPaths SdccToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
- const FilePath &fileName) const
+ const FilePath &fileName,
+ const Environment &env) const
{
- return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
+ return createBuiltInHeaderPathsRunner(env)(cxxFlags, fileName.toString(), "");
}
void SdccToolChain::addToEnvironment(Environment &env) const
@@ -461,21 +447,41 @@ QList<ToolChain *> SdccToolChainFactory::autoDetectToolchain(
const Candidate &candidate, Core::Id language) const
{
const auto env = Environment::systemEnvironment();
- const Macros macros = dumpPredefinedMacros(candidate.compilerPath, env.toStringList(), {});
- if (macros.isEmpty())
- return {};
- const Abi abi = guessAbi(macros);
-
- const auto tc = new SdccToolChain;
- tc->setDetection(ToolChain::AutoDetection);
- tc->setLanguage(language);
- tc->setCompilerCommand(candidate.compilerPath);
- tc->setTargetAbi(abi);
- tc->setDisplayName(buildDisplayName(abi.architecture(), language, candidate.compilerVersion));
-
- const auto languageVersion = ToolChain::languageVersion(language, macros);
- tc->predefinedMacrosCache()->insert({}, {macros, languageVersion});
- return {tc};
+
+ // Table of supported ABI's by SDCC compiler.
+ const Abi knownAbis[] = {
+ {Abi::Mcs51Architecture},
+ {Abi::Stm8Architecture}
+ };
+
+ QList<ToolChain *> tcs;
+
+ // Probe each ABI from the table, because the SDCC compiler
+ // can be compiled with or without the specified architecture.
+ for (const auto &knownAbi : knownAbis) {
+ const Macros macros = dumpPredefinedMacros(candidate.compilerPath,
+ env.toStringList(), knownAbi);
+ if (macros.isEmpty())
+ continue;
+ const Abi abi = guessAbi(macros);
+ if (knownAbi.architecture() != abi.architecture())
+ continue;
+
+ const auto tc = new SdccToolChain;
+ tc->setDetection(ToolChain::AutoDetection);
+ tc->setLanguage(language);
+ tc->setCompilerCommand(candidate.compilerPath);
+ tc->setTargetAbi(abi);
+ tc->setDisplayName(buildDisplayName(abi.architecture(), language,
+ candidate.compilerVersion));
+
+ const auto languageVersion = ToolChain::languageVersion(language, macros);
+ tc->predefinedMacrosCache()->insert({}, {macros, languageVersion});
+
+ tcs.push_back(tc);
+ }
+
+ return tcs;
}
// SdccToolChainConfigWidget
diff --git a/src/plugins/baremetal/sdcctoolchain.h b/src/plugins/baremetal/sdcctoolchain.h
index 15ed599524..58fd92e0d5 100644
--- a/src/plugins/baremetal/sdcctoolchain.h
+++ b/src/plugins/baremetal/sdcctoolchain.h
@@ -52,8 +52,6 @@ class SdccToolChain final : public ProjectExplorer::ToolChain
Q_DECLARE_TR_FUNCTIONS(SdccToolChain)
public:
- QString typeDisplayName() const final;
-
void setTargetAbi(const ProjectExplorer::Abi &abi);
ProjectExplorer::Abi targetAbi() const final;
@@ -65,9 +63,11 @@ public:
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const final;
ProjectExplorer::WarningFlags warningFlags(const QStringList &cxxflags) const final;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const final;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &) const final;
ProjectExplorer::HeaderPaths builtInHeaderPaths(const QStringList &cxxFlags,
- const Utils::FilePath &) const final;
+ const Utils::FilePath &,
+ const Utils::Environment &env) const final;
void addToEnvironment(Utils::Environment &env) const final;
ProjectExplorer::IOutputParser *outputParser() const final;
diff --git a/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp b/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp
index 552f890c80..35e83322e3 100644
--- a/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp
+++ b/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp
@@ -47,8 +47,6 @@ using namespace Utils;
namespace BareMetal {
namespace Internal {
-const char hostKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.Host";
-const char portKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.Port";
const char executableFileKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExecutableFile";
const char verboseLevelKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.VerboseLevel";
const char extendedModeKeyC[] = "BareMetal.StLinkUtilGdbServerProvider.ExtendedMode";
@@ -62,13 +60,14 @@ StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider()
{
setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands());
+ setDefaultChannel("localhost", 4242);
+ setSettingsKeyBase("BareMetal.StLinkUtilGdbServerProvider");
+ setTypeDisplayName(StLinkUtilGdbServerProviderFactory::tr("ST-LINK Utility"));
}
StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider(
const StLinkUtilGdbServerProvider &other)
: GdbServerProvider(other)
- , m_host(other.m_host)
- , m_port(other.m_port)
, m_executableFile(other.m_executableFile)
, m_verboseLevel(0)
, m_extendedMode(false)
@@ -87,19 +86,14 @@ QString StLinkUtilGdbServerProvider::defaultResetCommands()
return {};
}
-QString StLinkUtilGdbServerProvider::typeDisplayName() const
-{
- return StLinkUtilGdbServerProviderFactory::tr("ST-LINK Utility");
-}
-
-QString StLinkUtilGdbServerProvider::channel() const
+QString StLinkUtilGdbServerProvider::channelString() const
{
switch (startupMode()) {
case NoStartup:
// fallback
case StartupOnNetwork:
// Just return as "host:port" form.
- return m_host + QLatin1Char(':') + QString::number(m_port);
+ return GdbServerProvider::channelString();
case StartupOnPipe:
// Unsupported mode
return {};
@@ -119,7 +113,7 @@ CommandLine StLinkUtilGdbServerProvider::command() const
cmd.addArg("--no-reset");
cmd.addArg("--stlink_version=" + QString::number(m_transport));
- cmd.addArg("--listen_port=" + QString::number(m_port));
+ cmd.addArg("--listen_port=" + QString::number(channel().port()));
cmd.addArg("--verbose=" + QString::number(m_verboseLevel));
return cmd;
@@ -138,7 +132,7 @@ bool StLinkUtilGdbServerProvider::isValid() const
const StartupMode m = startupMode();
if (m == NoStartup || m == StartupOnNetwork) {
- if (m_host.isEmpty())
+ if (channel().host().isEmpty())
return false;
}
@@ -158,8 +152,6 @@ GdbServerProvider *StLinkUtilGdbServerProvider::clone() const
QVariantMap StLinkUtilGdbServerProvider::toMap() const
{
QVariantMap data = GdbServerProvider::toMap();
- data.insert(QLatin1String(hostKeyC), m_host);
- data.insert(QLatin1String(portKeyC), m_port);
data.insert(QLatin1String(executableFileKeyC), m_executableFile.toVariant());
data.insert(QLatin1String(verboseLevelKeyC), m_verboseLevel);
data.insert(QLatin1String(extendedModeKeyC), m_extendedMode);
@@ -173,9 +165,7 @@ bool StLinkUtilGdbServerProvider::fromMap(const QVariantMap &data)
if (!GdbServerProvider::fromMap(data))
return false;
- m_host = data.value(QLatin1String(hostKeyC)).toString();
- m_port = data.value(QLatin1String(portKeyC)).toInt();
- m_executableFile = FileName::fromVariant(data.value(QLatin1String(executableFileKeyC)));
+ m_executableFile = FilePath::fromVariant(data.value(QLatin1String(executableFileKeyC)));
m_verboseLevel = data.value(QLatin1String(verboseLevelKeyC)).toInt();
m_extendedMode = data.value(QLatin1String(extendedModeKeyC)).toBool();
m_resetBoard = data.value(QLatin1String(resetBoardKeyC)).toBool();
@@ -190,9 +180,7 @@ bool StLinkUtilGdbServerProvider::operator==(const GdbServerProvider &other) con
return false;
const auto p = static_cast<const StLinkUtilGdbServerProvider *>(&other);
- return m_host == p->m_host
- && m_port == p->m_port
- && m_executableFile == p->m_executableFile
+ return m_executableFile == p->m_executableFile
&& m_verboseLevel == p->m_verboseLevel
&& m_extendedMode == p->m_extendedMode
&& m_resetBoard == p->m_resetBoard
@@ -329,8 +317,7 @@ void StLinkUtilGdbServerProviderConfigWidget::applyImpl()
const auto p = static_cast<StLinkUtilGdbServerProvider *>(provider());
Q_ASSERT(p);
- p->m_host = m_hostWidget->host();
- p->m_port = m_hostWidget->port();
+ p->setChannel(m_hostWidget->channel());
p->m_executableFile = m_executableFileChooser->fileName();
p->m_verboseLevel = m_verboseLevelSpinBox->value();
p->m_extendedMode = m_extendedModeCheckBox->isChecked();
@@ -387,8 +374,7 @@ void StLinkUtilGdbServerProviderConfigWidget::setFromProvider()
const QSignalBlocker blocker(this);
startupModeChanged();
- m_hostWidget->setHost(p->m_host);
- m_hostWidget->setPort(p->m_port);
+ m_hostWidget->setChannel(p->channel());
m_executableFileChooser->setFileName(p->m_executableFile);
m_verboseLevelSpinBox->setValue(p->m_verboseLevel);
m_extendedModeCheckBox->setChecked(p->m_extendedMode);
diff --git a/src/plugins/baremetal/stlinkutilgdbserverprovider.h b/src/plugins/baremetal/stlinkutilgdbserverprovider.h
index 18b75ad405..5416cb5b8b 100644
--- a/src/plugins/baremetal/stlinkutilgdbserverprovider.h
+++ b/src/plugins/baremetal/stlinkutilgdbserverprovider.h
@@ -45,7 +45,6 @@ class StLinkUtilGdbServerProvider final : public GdbServerProvider
{
public:
enum TransportLayer { ScsiOverUsb = 1, RawUsb = 2 };
- QString typeDisplayName() const final;
QVariantMap toMap() const final;
bool fromMap(const QVariantMap &data) final;
@@ -55,7 +54,7 @@ public:
GdbServerProviderConfigWidget *configurationWidget() final;
GdbServerProvider *clone() const final;
- QString channel() const final;
+ QString channelString() const final;
Utils::CommandLine command() const final;
bool canStartupMode(StartupMode mode) const final;
@@ -68,8 +67,6 @@ private:
static QString defaultInitCommands();
static QString defaultResetCommands();
- QString m_host = QLatin1String("localhost");
- quint16 m_port = 4242;
Utils::FilePath m_executableFile = Utils::FilePath::fromString("st-util");
int m_verboseLevel = 0; // 0..99
bool m_extendedMode = false; // Listening for connections after disconnect
diff --git a/src/plugins/bazaar/bazaarclient.cpp b/src/plugins/bazaar/bazaarclient.cpp
index a60c7f331e..896ef54bf1 100644
--- a/src/plugins/bazaar/bazaarclient.cpp
+++ b/src/plugins/bazaar/bazaarclient.cpp
@@ -180,7 +180,7 @@ VcsBaseEditorWidget *BazaarClient::annotate(
bool BazaarClient::isVcsDirectory(const FilePath &fileName) const
{
- return fileName.toFileInfo().isDir()
+ return fileName.isDir()
&& !fileName.fileName().compare(Constants::BAZAARREPO, HostOsInfo::fileNameCaseSensitivity());
}
diff --git a/src/plugins/bazaar/bazaarcontrol.cpp b/src/plugins/bazaar/bazaarcontrol.cpp
index 7b38aa971c..e420723b62 100644
--- a/src/plugins/bazaar/bazaarcontrol.cpp
+++ b/src/plugins/bazaar/bazaarcontrol.cpp
@@ -150,7 +150,7 @@ Core::ShellCommand *BazaarControl::createInitialCheckoutCommand(const QString &u
QProcessEnvironment env = m_bazaarClient->processEnvironment();
env.insert(QLatin1String("BZR_PROGRESS_BAR"), QLatin1String("text"));
auto command = new VcsBase::VcsCommand(baseDirectory.toString(), env);
- command->addJob(m_bazaarClient->vcsBinary(), args, -1);
+ command->addJob({m_bazaarClient->vcsBinary(), args}, -1);
return command;
}
diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp
index a35b2ede62..c2990c9232 100644
--- a/src/plugins/bazaar/bazaarplugin.cpp
+++ b/src/plugins/bazaar/bazaarplugin.cpp
@@ -145,8 +145,8 @@ BazaarPlugin::~BazaarPlugin()
bool BazaarPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
Context context(Constants::BAZAAR_CONTEXT);
diff --git a/src/plugins/beautifier/abstractsettings.cpp b/src/plugins/beautifier/abstractsettings.cpp
index c7c091df90..ab3a880afe 100644
--- a/src/plugins/beautifier/abstractsettings.cpp
+++ b/src/plugins/beautifier/abstractsettings.cpp
@@ -121,9 +121,9 @@ QString AbstractSettings::styleFileName(const QString &key) const
return m_styleDir.absoluteFilePath(key + m_ending);
}
-QString AbstractSettings::command() const
+Utils::FilePath AbstractSettings::command() const
{
- return m_command;
+ return Utils::FilePath::fromString(m_command);
}
void AbstractSettings::setCommand(const QString &command)
diff --git a/src/plugins/beautifier/abstractsettings.h b/src/plugins/beautifier/abstractsettings.h
index 3e168c1283..ae61bde267 100644
--- a/src/plugins/beautifier/abstractsettings.h
+++ b/src/plugins/beautifier/abstractsettings.h
@@ -36,6 +36,7 @@
#include <QVector>
namespace Core { class IDocument; }
+namespace Utils { class FilePath; }
namespace Beautifier {
namespace Internal {
@@ -64,7 +65,7 @@ public:
void replaceStyle(const QString &oldKey, const QString &newKey, const QString &value);
virtual QString styleFileName(const QString &key) const;
- QString command() const;
+ Utils::FilePath command() const;
void setCommand(const QString &command);
int version() const;
virtual void updateVersion();
diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp
index 2788214fee..bb9059652c 100644
--- a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp
+++ b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp
@@ -41,8 +41,9 @@
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <cppeditor/cppeditorconstants.h>
-#include <projectexplorer/projecttree.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/projecttree.h>
#include <texteditor/formattexteditor.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
@@ -103,10 +104,9 @@ QString ArtisticStyle::configurationFile() const
if (m_settings.useOtherFiles()) {
if (const ProjectExplorer::Project *project
= ProjectExplorer::ProjectTree::currentProject()) {
- const Utils::FilePathList files = project->files(ProjectExplorer::Project::AllFiles);
- for (const Utils::FilePath &file : files) {
- if (!file.endsWith(".astylerc"))
- continue;
+ const Utils::FilePathList astyleRcfiles = project->files(
+ [](const ProjectExplorer::Node *n) { return n->filePath().endsWith(".astylerc"); });
+ for (const Utils::FilePath &file : astyleRcfiles) {
const QFileInfo fi = file.toFileInfo();
if (fi.isReadable())
return file.toString();
@@ -147,7 +147,7 @@ bool ArtisticStyle::isApplicable(const Core::IDocument *document) const
Command ArtisticStyle::command(const QString &cfgFile) const
{
Command command;
- command.setExecutable(m_settings.command());
+ command.setExecutable(m_settings.command().toString());
command.addOption("-q");
command.addOption("--options=" + cfgFile);
diff --git a/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp b/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp
index 97410fadac..01deb00b4d 100644
--- a/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp
+++ b/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp
@@ -39,11 +39,8 @@ namespace Beautifier {
namespace Internal {
namespace ArtisticStyle {
-ArtisticStyleOptionsPageWidget::ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings,
- QWidget *parent) :
- QWidget(parent),
- ui(new Ui::ArtisticStyleOptionsPage),
- m_settings(settings)
+ArtisticStyleOptionsPageWidget::ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings)
+ : ui(new Ui::ArtisticStyleOptionsPage), m_settings(settings)
{
ui->setupUi(this);
ui->useHomeFile->setText(ui->useHomeFile->text().replace(
@@ -65,7 +62,7 @@ ArtisticStyleOptionsPageWidget::~ArtisticStyleOptionsPageWidget()
void ArtisticStyleOptionsPageWidget::restore()
{
- ui->command->setPath(m_settings->command());
+ ui->command->setFileName(m_settings->command());
ui->mime->setText(m_settings->supportedMimeTypesAsString());
ui->useOtherFiles->setChecked(m_settings->useOtherFiles());
ui->useSpecificConfigFile->setChecked(m_settings->useSpecificConfigFile());
diff --git a/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.h b/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.h
index fe8f604dc3..e1e9141bcb 100644
--- a/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.h
+++ b/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.h
@@ -43,8 +43,7 @@ class ArtisticStyleOptionsPageWidget : public QWidget
Q_OBJECT
public:
- explicit ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings,
- QWidget *parent = nullptr);
+ explicit ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings);
~ArtisticStyleOptionsPageWidget() override;
void restore();
void apply();
diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp
index 41ba9270aa..981dd5983b 100644
--- a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp
+++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp
@@ -82,11 +82,10 @@ static int parseVersion(const QString &text)
return 0;
}
-static int updateVersionHelper(const QString &command)
+static int updateVersionHelper(const Utils::FilePath &command)
{
Utils::SynchronousProcess process;
- Utils::SynchronousProcessResponse response
- = process.runBlocking(command, QStringList("--version"));
+ Utils::SynchronousProcessResponse response = process.runBlocking({command, {"--version"}});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return 0;
@@ -182,8 +181,7 @@ void ArtisticStyleSettings::createDocumentationFile() const
{
Utils::SynchronousProcess process;
process.setTimeoutS(2);
- Utils::SynchronousProcessResponse response
- = process.runBlocking(command(), QStringList("-h"));
+ Utils::SynchronousProcessResponse response = process.runBlocking({command(), {"-h"}});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp
index 6e4cb079f2..598d5a2388 100644
--- a/src/plugins/beautifier/beautifierplugin.cpp
+++ b/src/plugins/beautifier/beautifierplugin.cpp
@@ -43,6 +43,7 @@
#include <coreplugin/messagemanager.h>
#include <cppeditor/cppeditorconstants.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <texteditor/formattexteditor.h>
#include <texteditor/textdocument.h>
@@ -50,13 +51,13 @@
#include <texteditor/texteditor.h>
#include <texteditor/texteditorconstants.h>
#include <utils/algorithm.h>
-#include <utils/textutils.h>
#include <utils/fileutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <utils/synchronousprocess.h>
#include <utils/temporarydirectory.h>
+#include <utils/textutils.h>
#include <QDir>
#include <QFileInfo>
@@ -161,7 +162,12 @@ void BeautifierPluginPrivate::autoFormatOnSave(Core::IDocument *document)
// Check if file is contained in the current project (if wished)
if (m_generalSettings->autoFormatOnlyCurrentProject()) {
const ProjectExplorer::Project *pro = ProjectExplorer::ProjectTree::currentProject();
- if (!pro || !pro->files(ProjectExplorer::Project::SourceFiles).contains(document->filePath())) {
+ if (!pro
+ || pro->files([document](const ProjectExplorer::Node *n) {
+ return ProjectExplorer::Project::SourceFiles(n)
+ && n->filePath() == document->filePath();
+ })
+ .isEmpty()) {
return;
}
}
diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp
index a6f7f8e198..6cb1b63139 100644
--- a/src/plugins/beautifier/clangformat/clangformat.cpp
+++ b/src/plugins/beautifier/clangformat/clangformat.cpp
@@ -167,7 +167,7 @@ void ClangFormat::disableFormattingSelectedText()
Command ClangFormat::command() const
{
Command command;
- command.setExecutable(m_settings.command());
+ command.setExecutable(m_settings.command().toString());
command.setProcessing(Command::PipeProcessing);
if (m_settings.usePredefinedStyle()) {
diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
index 970fb4ea56..9c04198418 100644
--- a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
+++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
@@ -70,7 +70,7 @@ ClangFormatOptionsPageWidget::~ClangFormatOptionsPageWidget()
void ClangFormatOptionsPageWidget::restore()
{
- ui->command->setPath(m_settings->command());
+ ui->command->setFileName(m_settings->command());
ui->mime->setText(m_settings->supportedMimeTypesAsString());
const int predefinedStyleIndex = ui->predefinedStyle->findText(m_settings->predefinedStyle());
if (predefinedStyleIndex != -1)
diff --git a/src/plugins/beautifier/configurationdialog.cpp b/src/plugins/beautifier/configurationdialog.cpp
index 48fcd18483..7d84c73023 100644
--- a/src/plugins/beautifier/configurationdialog.cpp
+++ b/src/plugins/beautifier/configurationdialog.cpp
@@ -62,7 +62,7 @@ ConfigurationDialog::ConfigurationDialog(QWidget *parent) :
QPalette pal;
pal.setColor(QPalette::Base, tf.background().color());
pal.setColor(QPalette::Text, tf.foreground().color());
- pal.setColor(QPalette::Foreground, tf.foreground().color());
+ pal.setColor(QPalette::WindowText, tf.foreground().color());
if (selectionFormat.background().style() != Qt::NoBrush)
pal.setColor(QPalette::Highlight, selectionFormat.background().color());
pal.setBrush(QPalette::HighlightedText, selectionFormat.foreground());
diff --git a/src/plugins/beautifier/generaloptionspage.cpp b/src/plugins/beautifier/generaloptionspage.cpp
index c2bec70740..ae832f0c98 100644
--- a/src/plugins/beautifier/generaloptionspage.cpp
+++ b/src/plugins/beautifier/generaloptionspage.cpp
@@ -37,8 +37,7 @@ namespace Beautifier {
namespace Internal {
GeneralOptionsPageWidget::GeneralOptionsPageWidget(const QSharedPointer<GeneralSettings> &settings,
- const QStringList &toolIds, QWidget *parent) :
- QWidget(parent),
+ const QStringList &toolIds) :
ui(new Ui::GeneralOptionsPage),
m_settings(settings)
{
diff --git a/src/plugins/beautifier/generaloptionspage.h b/src/plugins/beautifier/generaloptionspage.h
index 61f7e84d77..b6335f68ad 100644
--- a/src/plugins/beautifier/generaloptionspage.h
+++ b/src/plugins/beautifier/generaloptionspage.h
@@ -44,7 +44,7 @@ class GeneralOptionsPageWidget : public QWidget
public:
explicit GeneralOptionsPageWidget(const QSharedPointer<GeneralSettings> &settings,
- const QStringList &toolIds, QWidget *parent = nullptr);
+ const QStringList &toolIds);
~GeneralOptionsPageWidget() override;
void restore();
void apply(bool *autoFormatChanged);
diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp
index f6a36eadc0..65ee86d9f7 100644
--- a/src/plugins/beautifier/uncrustify/uncrustify.cpp
+++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp
@@ -41,8 +41,9 @@
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <cppeditor/cppeditorconstants.h>
-#include <projectexplorer/projecttree.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/projecttree.h>
#include <texteditor/formattexteditor.h>
#include <texteditor/texteditor.h>
#include <utils/fileutils.h>
@@ -144,10 +145,9 @@ QString Uncrustify::configurationFile() const
if (m_settings.useOtherFiles()) {
if (const ProjectExplorer::Project *project
= ProjectExplorer::ProjectTree::currentProject()) {
- const Utils::FilePathList files = project->files(ProjectExplorer::Project::AllFiles);
+ const Utils::FilePathList files = project->files(
+ [](const ProjectExplorer::Node *n) { return n->filePath().endsWith("cfg"); });
for (const Utils::FilePath &file : files) {
- if (!file.endsWith("cfg"))
- continue;
const QFileInfo fi = file.toFileInfo();
if (fi.isReadable() && fi.fileName() == "uncrustify.cfg")
return file.toString();
@@ -184,7 +184,7 @@ bool Uncrustify::isApplicable(const Core::IDocument *document) const
Command Uncrustify::command(const QString &cfgFile, bool fragment) const
{
Command command;
- command.setExecutable(m_settings.command());
+ command.setExecutable(m_settings.command().toString());
command.setProcessing(Command::PipeProcessing);
if (m_settings.version() >= 62) {
command.addOption("--assume");
diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp
index 1e5dc0c57c..2fe042daa3 100644
--- a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp
+++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp
@@ -68,7 +68,7 @@ UncrustifyOptionsPageWidget::~UncrustifyOptionsPageWidget()
void UncrustifyOptionsPageWidget::restore()
{
- ui->command->setPath(m_settings->command());
+ ui->command->setFileName(m_settings->command());
ui->mime->setText(m_settings->supportedMimeTypesAsString());
ui->useOtherFiles->setChecked(m_settings->useOtherFiles());
ui->useHomeFile->setChecked(m_settings->useHomeFile());
diff --git a/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp b/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp
index 7d7954ceb7..d92c64a80d 100644
--- a/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp
+++ b/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp
@@ -152,7 +152,7 @@ void UncrustifySettings::createDocumentationFile() const
Utils::SynchronousProcess process;
process.setTimeoutS(2);
Utils::SynchronousProcessResponse response
- = process.runBlocking(command(), QStringList("--show-config"));
+ = process.runBlocking({command(), {"--show-config"}});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
@@ -230,7 +230,7 @@ void UncrustifySettings::updateVersion()
m_versionProcess.kill();
m_versionProcess.waitForFinished();
}
- m_versionProcess.start(command(), {"--version"});
+ m_versionProcess.start(command().toString(), {"--version"});
}
void UncrustifySettings::parseVersionProcessResult(int exitCode, QProcess::ExitStatus exitStatus)
diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp
index 9fbba5c7f8..b6bc79d23a 100644
--- a/src/plugins/bineditor/bineditorplugin.cpp
+++ b/src/plugins/bineditor/bineditorplugin.cpp
@@ -368,7 +368,6 @@ public:
auto l = new QHBoxLayout;
auto w = new QWidget;
- l->setMargin(0);
l->setContentsMargins(0, 0, 5, 0);
l->addStretch(1);
l->addWidget(m_addressEdit);
diff --git a/src/plugins/bineditor/bineditorwidget.cpp b/src/plugins/bineditor/bineditorwidget.cpp
index 2d17786453..561b133925 100644
--- a/src/plugins/bineditor/bineditorwidget.cpp
+++ b/src/plugins/bineditor/bineditorwidget.cpp
@@ -140,7 +140,7 @@ BinEditorWidget::BinEditorWidget(QWidget *parent)
: QAbstractScrollArea(parent), d(new BinEditorWidgetPrivate(this))
{
m_bytesPerLine = 16;
- m_ieditor = 0;
+ m_ieditor = nullptr;
m_baseAddr = 0;
m_blockSize = 4096;
m_size = 0;
diff --git a/src/plugins/bookmarks/bookmarkfilter.cpp b/src/plugins/bookmarks/bookmarkfilter.cpp
index a148e69955..0c74ceafeb 100644
--- a/src/plugins/bookmarks/bookmarkfilter.cpp
+++ b/src/plugins/bookmarks/bookmarkfilter.cpp
@@ -46,7 +46,7 @@ BookmarkFilter::BookmarkFilter(BookmarkManager *manager)
QList<LocatorFilterEntry> BookmarkFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry)
{
- Q_UNUSED(future);
+ Q_UNUSED(future)
if (m_manager->rowCount() == 0)
return QList<LocatorFilterEntry>();
@@ -120,9 +120,9 @@ QList<LocatorFilterEntry> BookmarkFilter::matchesFor(QFutureInterface<LocatorFil
void BookmarkFilter::accept(LocatorFilterEntry selection, QString *newText,
int *selectionStart, int *selectionLength) const
{
- Q_UNUSED(newText);
- Q_UNUSED(selectionStart);
- Q_UNUSED(selectionLength);
+ Q_UNUSED(newText)
+ Q_UNUSED(selectionStart)
+ Q_UNUSED(selectionLength)
if (const Bookmark *bookmark = m_manager->bookmarkForIndex(
selection.internalData.toModelIndex())) {
m_manager->gotoBookmark(bookmark);
@@ -131,5 +131,5 @@ void BookmarkFilter::accept(LocatorFilterEntry selection, QString *newText,
void BookmarkFilter::refresh(QFutureInterface<void> &future)
{
- Q_UNUSED(future);
+ Q_UNUSED(future)
}
diff --git a/src/plugins/boot2qt/Boot2Qt.json.in b/src/plugins/boot2qt/Boot2Qt.json.in
new file mode 100644
index 0000000000..a459d6b298
--- /dev/null
+++ b/src/plugins/boot2qt/Boot2Qt.json.in
@@ -0,0 +1,22 @@
+{
+ \"Name\" : \"Boot2Qt\",
+ \"Version\" : \"$$QTCREATOR_VERSION\",
+ \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
+ \"Revision\" : \"$$QTC_PLUGIN_REVISION\",
+ \"DisabledByDefault\" : true,
+ \"Vendor\" : \"The Qt Company Ltd\",
+ \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
+ \"License\" : [ \"Commercial Usage\",
+ \"\",
+ \"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt 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.\",
+ \"\",
+ \"GNU General Public License Usage\",
+ \"\",
+ \"Alternatively, this plugin 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 plugin. 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.\"
+],
+
+ \"Category\" : \"Device Support\",
+ \"Description\" : \"Support for the Boot2Qt Device access using the Qt Debug Bridge.\",
+ \"Url\" : \"http://www.qt.io\",
+ $$dependencyList
+}
diff --git a/src/plugins/boot2qt/CMakeLists.txt b/src/plugins/boot2qt/CMakeLists.txt
new file mode 100644
index 0000000000..c557459698
--- /dev/null
+++ b/src/plugins/boot2qt/CMakeLists.txt
@@ -0,0 +1,31 @@
+add_qtc_plugin(Boot2Qt
+ DEPENDS Qt5::Network QtcSsh
+ PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport RemoteLinux
+ SOURCES
+ qdb.qrc
+ qdb_global.h
+ qdbconstants.h
+ qdbdeployconfigurationfactory.cpp qdbdeployconfigurationfactory.h
+ qdbdeploystepfactory.cpp qdbdeploystepfactory.h
+ qdbdevice.cpp qdbdevice.h
+ qdbdevicedebugsupport.cpp qdbdevicedebugsupport.h
+ qdbmakedefaultappservice.cpp qdbmakedefaultappservice.h
+ qdbmakedefaultappstep.cpp qdbmakedefaultappstep.h
+ qdbplugin.cpp qdbplugin.h
+ qdbqtversion.cpp qdbqtversion.h
+ qdbrunconfiguration.cpp qdbrunconfiguration.h
+ qdbstopapplicationservice.cpp qdbstopapplicationservice.h
+ qdbstopapplicationstep.cpp qdbstopapplicationstep.h
+ qdbutils.cpp qdbutils.h
+)
+
+extend_qtc_plugin(Boot2Qt
+ SOURCES_PREFIX device-detection
+ SOURCES
+ devicedetector.cpp devicedetector.h
+ hostmessages.cpp hostmessages.h
+ qdbdevicetracker.cpp qdbdevicetracker.h
+ qdbmessagetracker.cpp qdbmessagetracker.h
+ qdbwatcher.cpp qdbwatcher.h
+)
+
diff --git a/src/plugins/boot2qt/boot2qt.pro b/src/plugins/boot2qt/boot2qt.pro
new file mode 100644
index 0000000000..8c5f51e504
--- /dev/null
+++ b/src/plugins/boot2qt/boot2qt.pro
@@ -0,0 +1,40 @@
+DEFINES += BOOT2QT_LIBRARY
+QT += network
+
+include(../../qtcreatorplugin.pri)
+include(boot2qt_dependencies.pri)
+
+include(device-detection/device-detection.pri)
+
+HEADERS += \
+ qdbutils.h \
+ qdbdevice.h \
+ qdbqtversion.h \
+ qdbdeployconfigurationfactory.h \
+ qdbrunconfiguration.h \
+ qdbmakedefaultappstep.h \
+ qdbmakedefaultappservice.h \
+ qdbstopapplicationstep.h \
+ qdbstopapplicationservice.h \
+ qdbdeploystepfactory.h \
+ qdbdevicedebugsupport.h \
+ qdbconstants.h \
+ qdb_global.h \
+ qdbplugin.h
+
+SOURCES += \
+ qdbutils.cpp \
+ qdbdevice.cpp \
+ qdbqtversion.cpp \
+ qdbdeployconfigurationfactory.cpp \
+ qdbrunconfiguration.cpp \
+ qdbmakedefaultappstep.cpp \
+ qdbmakedefaultappservice.cpp \
+ qdbstopapplicationstep.cpp \
+ qdbstopapplicationservice.cpp \
+ qdbdeploystepfactory.cpp \
+ qdbdevicedebugsupport.cpp \
+ qdbplugin.cpp \
+
+RESOURCES += \
+ qdb.qrc
diff --git a/src/plugins/boot2qt/boot2qt.qbs b/src/plugins/boot2qt/boot2qt.qbs
new file mode 100644
index 0000000000..ac6a33f279
--- /dev/null
+++ b/src/plugins/boot2qt/boot2qt.qbs
@@ -0,0 +1,65 @@
+import qbs
+
+QtcPlugin {
+ name: "Boot2Qt"
+
+ Depends { name: "Core" }
+ Depends { name: "Debugger" }
+ Depends { name: "ProjectExplorer" }
+ Depends { name: "QmlDebug" }
+ Depends { name: "QtSupport" }
+ Depends { name: "RemoteLinux" }
+ Depends { name: "Utils" }
+
+ cpp.defines: base.concat("BOOT2QT_LIBRARY")
+
+ Group {
+ name: "General"
+ files: [
+ "qdb.qrc",
+ "qdbutils.cpp",
+ "qdbutils.h",
+ "qdbconstants.h",
+ "qdb_global.h",
+ "qdbdeployconfigurationfactory.cpp",
+ "qdbdeployconfigurationfactory.h",
+ "qdbdeploystepfactory.cpp",
+ "qdbdeploystepfactory.h",
+ "qdbdevice.cpp",
+ "qdbdevice.h",
+ "qdbdevicedebugsupport.cpp",
+ "qdbdevicedebugsupport.h",
+ "qdbmakedefaultappservice.cpp",
+ "qdbmakedefaultappservice.h",
+ "qdbmakedefaultappstep.cpp",
+ "qdbmakedefaultappstep.h",
+ "qdbplugin.cpp",
+ "qdbplugin.h",
+ "qdbstopapplicationservice.cpp",
+ "qdbstopapplicationservice.h",
+ "qdbstopapplicationstep.cpp",
+ "qdbstopapplicationstep.h",
+ "qdbqtversion.cpp",
+ "qdbqtversion.h",
+ "qdbrunconfiguration.cpp",
+ "qdbrunconfiguration.h",
+ ]
+ }
+
+ Group {
+ name: "Device Detection"
+ prefix: "device-detection/"
+ files: [
+ "devicedetector.cpp",
+ "devicedetector.h",
+ "hostmessages.cpp",
+ "hostmessages.h",
+ "qdbdevicetracker.cpp",
+ "qdbdevicetracker.h",
+ "qdbwatcher.h",
+ "qdbwatcher.cpp",
+ "qdbmessagetracker.cpp",
+ "qdbmessagetracker.h",
+ ]
+ }
+}
diff --git a/src/plugins/boot2qt/boot2qt_dependencies.pri b/src/plugins/boot2qt/boot2qt_dependencies.pri
new file mode 100644
index 0000000000..ea2f583ed9
--- /dev/null
+++ b/src/plugins/boot2qt/boot2qt_dependencies.pri
@@ -0,0 +1,8 @@
+QTC_PLUGIN_NAME = Boot2Qt
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ debugger \
+ projectexplorer \
+ qtsupport \
+ remotelinux
+
diff --git a/src/plugins/boot2qt/device-detection/device-detection.pri b/src/plugins/boot2qt/device-detection/device-detection.pri
new file mode 100644
index 0000000000..6ba0c35152
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/device-detection.pri
@@ -0,0 +1,13 @@
+HEADERS += \
+ $$PWD/devicedetector.h \
+ $$PWD/hostmessages.h \
+ $$PWD/qdbdevicetracker.h \
+ $$PWD/qdbmessagetracker.h \
+ $$PWD/qdbwatcher.h \
+
+SOURCES += \
+ $$PWD/devicedetector.cpp \
+ $$PWD/hostmessages.cpp \
+ $$PWD/qdbdevicetracker.cpp \
+ $$PWD/qdbmessagetracker.cpp \
+ $$PWD/qdbwatcher.cpp \
diff --git a/src/plugins/boot2qt/device-detection/devicedetector.cpp b/src/plugins/boot2qt/device-detection/devicedetector.cpp
new file mode 100644
index 0000000000..89dbb60e2f
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/devicedetector.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "devicedetector.h"
+
+#include "../qdbutils.h"
+#include "../qdbconstants.h"
+#include "../qdbdevice.h"
+
+#include <projectexplorer/devicesupport/devicemanager.h>
+#include <utils/qtcassert.h>
+
+#include <QHash>
+#include <QObject>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+static bool isAutodetectedQdbDevice(const IDevice::ConstPtr &device)
+{
+ return device
+ && device->type() == Qdb::Constants::QdbLinuxOsType
+ && device->isAutoDetected();
+}
+
+DeviceDetector::DeviceDetector()
+{
+}
+
+DeviceDetector::~DeviceDetector()
+{
+ stop();
+}
+
+void DeviceDetector::start()
+{
+ QTC_ASSERT(m_state == Inactive, return);
+
+ connect(&m_deviceTracker, &QdbDeviceTracker::deviceEvent,
+ this, &DeviceDetector::handleDeviceEvent);
+ connect(&m_deviceTracker, &QdbDeviceTracker::trackerError,
+ this, &DeviceDetector::handleTrackerError);
+
+ resetDevices();
+ m_state = WaitingForDeviceUpdates;
+ m_deviceTracker.start();
+ m_messageTracker.start();
+}
+
+void DeviceDetector::stop()
+{
+ m_messageTracker.stop();
+
+ switch (m_state) {
+ case WaitingForDeviceUpdates:
+ m_deviceTracker.stop();
+ resetDevices();
+ break;
+ case Inactive:
+ break;
+ }
+ m_state = Inactive;
+}
+
+void DeviceDetector::handleDeviceEvent(QdbDeviceTracker::DeviceEventType eventType,
+ const QMap<QString, QString> &info)
+{
+ const QString serial = info.value("serial");
+ if (serial.isEmpty()) {
+ showMessage("Error: Did not get a serial number in a device event from QDB", false);
+ return;
+ }
+
+ const Core::Id deviceId = Constants::QdbHardwareDevicePrefix.withSuffix(':' + serial);
+ const auto messagePrefix = tr("Device \"%1\" %2").arg(serial);
+ DeviceManager * const dm = DeviceManager::instance();
+
+ if (eventType == QdbDeviceTracker::NewDevice) {
+ const QString name = tr("Qt Debug Bridge device %1").arg(serial);
+ QdbDevice::Ptr device = QdbDevice::create();
+ device->setupId(IDevice::AutoDetected, deviceId);
+ device->setDisplayName(name);
+ device->setType(Qdb::Constants::QdbLinuxOsType);
+ device->setMachineType(IDevice::Hardware);
+
+ const QString ipAddress = info["ipAddress"];
+ device->setupDefaultNetworkSettings(ipAddress);
+
+ IDevice::DeviceState state;
+ if (ipAddress.isEmpty())
+ state = IDevice::DeviceConnected;
+ else
+ state = IDevice::DeviceReadyToUse;
+ device->setDeviceState(state);
+
+ dm->addDevice(device);
+
+ if (state == IDevice::DeviceConnected)
+ showMessage(messagePrefix.arg("connected, waiting for IP"), false);
+ else
+ showMessage(messagePrefix.arg("is ready to use at ").append(ipAddress), false);
+ } else if (eventType == QdbDeviceTracker::DisconnectedDevice) {
+ dm->setDeviceState(deviceId, IDevice::DeviceDisconnected);
+ showMessage(messagePrefix.arg("disconnected"), false);
+ }
+}
+
+void DeviceDetector::handleTrackerError(const QString &errorMessage)
+{
+ showMessage(tr("Device detection error: %1").arg(errorMessage), true);
+ stop();
+}
+
+void DeviceDetector::resetDevices()
+{
+ DeviceManager * const dm = DeviceManager::instance();
+ for (int i = 0; i < dm->deviceCount(); ++i) {
+ const IDevice::ConstPtr device = dm->deviceAt(i);
+ if (isAutodetectedQdbDevice(device))
+ dm->setDeviceState(device->id(), IDevice::DeviceDisconnected);
+ }
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/clangtools/clangtidyclazyruncontrol.h b/src/plugins/boot2qt/device-detection/devicedetector.h
index b0dfafef6a..c5c85c30da 100644
--- a/src/plugins/clangtools/clangtidyclazyruncontrol.h
+++ b/src/plugins/boot2qt/device-detection/devicedetector.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,30 +25,36 @@
#pragma once
-#include "clangtoolruncontrol.h"
+#include "../qdbdevice.h"
+#include "qdbdevicetracker.h"
+#include "qdbmessagetracker.h"
-#include <cpptools/clangdiagnosticconfig.h>
-
-namespace ClangTools {
+namespace Qdb {
namespace Internal {
-class ClangTidyClazyRunControl final : public ClangToolRunControl
+class DeviceDetector : public QObject
{
Q_OBJECT
public:
- ClangTidyClazyRunControl(ProjectExplorer::RunControl *runControl,
- ProjectExplorer::Target *target,
- const CppTools::ClangDiagnosticConfig &diagnosticConfig,
- const FileInfos &fileInfos);
+ DeviceDetector();
+ ~DeviceDetector();
-protected:
- ClangToolRunner *createRunner() final;
- ClangTool *tool() final;
+ void start();
+ void stop();
private:
- CppTools::ClangDiagnosticConfig m_diagnosticConfig;
+ void handleDeviceEvent(QdbDeviceTracker::DeviceEventType eventType,
+ const QMap<QString, QString> &info);
+ void handleTrackerError(const QString &errorMessage);
+ void resetDevices();
+
+ enum State { Inactive, WaitingForDeviceUpdates };
+
+ State m_state = Inactive;
+ QdbDeviceTracker m_deviceTracker;
+ QdbMessageTracker m_messageTracker;
};
} // namespace Internal
-} // namespace ClangTools
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/hostmessages.cpp b/src/plugins/boot2qt/device-detection/hostmessages.cpp
new file mode 100644
index 0000000000..a5ff0e4168
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/hostmessages.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "hostmessages.h"
+
+#include <utils/qtcassert.h>
+
+const QString responseField = "response";
+const QString requestField = "request";
+const QString versionField = "_version";
+
+void setVersionField(QJsonObject &obj)
+{
+ obj[versionField] = qdbHostMessageVersion;
+}
+
+bool checkHostMessageVersion(const QJsonObject &obj)
+{
+ return obj[versionField].toInt() == qdbHostMessageVersion;
+}
+
+QByteArray createRequest(const RequestType &type)
+{
+ QJsonObject obj;
+ setVersionField(obj);
+ obj[requestField] = requestTypeString(type);
+ return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n');
+}
+
+RequestType requestType(const QJsonObject &obj)
+{
+ const auto fieldValue = obj[requestField];
+ if (fieldValue == requestTypeString(RequestType::Devices))
+ return RequestType::Devices;
+ if (fieldValue == requestTypeString(RequestType::WatchDevices))
+ return RequestType::WatchDevices;
+ if (fieldValue == requestTypeString(RequestType::StopServer))
+ return RequestType::StopServer;
+ if (fieldValue == requestTypeString(RequestType::Messages))
+ return RequestType::Messages;
+ if (fieldValue == requestTypeString(RequestType::WatchMessages))
+ return RequestType::WatchMessages;
+ if (fieldValue == requestTypeString(RequestType::MessagesAndClear))
+ return RequestType::MessagesAndClear;
+
+ return RequestType::Unknown;
+}
+
+QString requestTypeString(const RequestType &type)
+{
+ switch (type) {
+ case RequestType::Devices:
+ return QStringLiteral("devices");
+ case RequestType::WatchDevices:
+ return QStringLiteral("watch-devices");
+ case RequestType::StopServer:
+ return QStringLiteral("stop-server");
+ case RequestType::Messages:
+ return QStringLiteral("messages");
+ case RequestType::WatchMessages:
+ return QStringLiteral("watch-messages");
+ case RequestType::MessagesAndClear:
+ return QStringLiteral("messages-and-clear");
+ case RequestType::Unknown:
+ break;
+ }
+ QTC_ASSERT(false, return QString());
+}
+
+QJsonObject initializeResponse(const ResponseType &type)
+{
+ QJsonObject obj;
+ setVersionField(obj);
+ obj[responseField] = responseTypeString(type);
+ return obj;
+}
+
+ResponseType responseType(const QJsonObject &obj)
+{
+ const auto fieldValue = obj[responseField];
+ if (fieldValue == responseTypeString(ResponseType::Devices))
+ return ResponseType::Devices;
+ if (fieldValue == responseTypeString(ResponseType::NewDevice))
+ return ResponseType::NewDevice;
+ if (fieldValue == responseTypeString(ResponseType::DisconnectedDevice))
+ return ResponseType::DisconnectedDevice;
+ if (fieldValue == responseTypeString(ResponseType::Stopping))
+ return ResponseType::Stopping;
+ if (fieldValue == responseTypeString(ResponseType::Messages))
+ return ResponseType::Messages;
+ if (fieldValue == responseTypeString(ResponseType::InvalidRequest))
+ return ResponseType::InvalidRequest;
+ if (fieldValue == responseTypeString(ResponseType::UnsupportedVersion))
+ return ResponseType::UnsupportedVersion;
+
+ return ResponseType::Unknown;
+}
+
+QString responseTypeString(const ResponseType &type)
+{
+ switch (type) {
+ case ResponseType::Devices:
+ return QStringLiteral("devices");
+ case ResponseType::NewDevice:
+ return QStringLiteral("new-device");
+ case ResponseType::DisconnectedDevice:
+ return QStringLiteral("disconnected-device");
+ case ResponseType::Stopping:
+ return QStringLiteral("stopping");
+ case ResponseType::Messages:
+ return QStringLiteral("messages");
+ case ResponseType::InvalidRequest:
+ return QStringLiteral("invalid-request");
+ case ResponseType::UnsupportedVersion:
+ return QStringLiteral("unsupported-version");
+ case ResponseType::Unknown:
+ break;
+ }
+ QTC_ASSERT(false, return QString());
+}
+
+QByteArray serialiseResponse(const QJsonObject &obj)
+{
+ return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n');
+}
diff --git a/src/plugins/boot2qt/device-detection/hostmessages.h b/src/plugins/boot2qt/device-detection/hostmessages.h
new file mode 100644
index 0000000000..5191d2c058
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/hostmessages.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qjsondocument.h>
+#include <QtCore/qjsonobject.h>
+
+const int qdbHostMessageVersion = 1;
+bool checkHostMessageVersion(const QJsonObject &obj);
+
+enum class RequestType
+{
+ Unknown = 0,
+ Devices,
+ WatchDevices,
+ StopServer,
+ WatchMessages,
+ Messages,
+ MessagesAndClear,
+};
+
+QByteArray createRequest(const RequestType &type);
+RequestType requestType(const QJsonObject &obj);
+QString requestTypeString(const RequestType &type);
+
+enum class ResponseType
+{
+ Unknown = 0,
+ Devices,
+ NewDevice,
+ DisconnectedDevice,
+ Stopping,
+ InvalidRequest,
+ UnsupportedVersion,
+ Messages,
+};
+
+QJsonObject initializeResponse(const ResponseType &type);
+ResponseType responseType(const QJsonObject &obj);
+QString responseTypeString(const ResponseType &type);
+QByteArray serialiseResponse(const QJsonObject &obj);
diff --git a/src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp b/src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp
new file mode 100644
index 0000000000..8ec5ec655a
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevicetracker.h"
+#include "qdbwatcher.h"
+
+#include "../qdbutils.h"
+#include "hostmessages.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+
+namespace Qdb {
+namespace Internal {
+
+QdbDeviceTracker::QdbDeviceTracker(QObject *parent)
+ : QObject(parent)
+{
+ m_qdbWatcher = new QdbWatcher(this);
+ connect(m_qdbWatcher, &QdbWatcher::incomingMessage, this, &QdbDeviceTracker::handleWatchMessage);
+ connect(m_qdbWatcher, &QdbWatcher::watcherError, this, &QdbDeviceTracker::trackerError);
+}
+void QdbDeviceTracker::start()
+{
+ m_qdbWatcher->start(RequestType::WatchDevices);
+}
+
+void QdbDeviceTracker::stop()
+{
+ m_qdbWatcher->stop();
+}
+
+void QdbDeviceTracker::handleWatchMessage(const QJsonDocument &document)
+{
+ const auto type = responseType(document.object());
+ if (type != ResponseType::NewDevice && type != ResponseType::DisconnectedDevice) {
+ stop();
+ const QString message =
+ tr("Shutting down device discovery due to unexpected response: %1");
+ emit trackerError(message.arg(QString::fromUtf8(document.toJson())));
+ return;
+ }
+
+ DeviceEventType eventType = type == ResponseType::NewDevice ? NewDevice
+ : DisconnectedDevice;
+ QVariantMap variantInfo = document.object().toVariantMap();
+ QMap<QString, QString> info;
+
+ switch (eventType) {
+ case NewDevice:
+ {
+ const QVariantMap deviceInfo = variantInfo["device"].value<QVariantMap>();
+ for (auto iter = deviceInfo.begin(); iter != deviceInfo.end(); ++iter)
+ info[iter.key()] = iter.value().toString();
+ }
+ break;
+ case DisconnectedDevice:
+ info["serial"] = variantInfo["serial"].toString();
+ break;
+ }
+ emit deviceEvent(eventType, info);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbdevicetracker.h b/src/plugins/boot2qt/device-detection/qdbdevicetracker.h
new file mode 100644
index 0000000000..85cf9ee8fc
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbdevicetracker.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+#include <QObject>
+#include <QMap>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbWatcher;
+
+class QdbDeviceTracker : public QObject
+{
+ Q_OBJECT
+public:
+ QdbDeviceTracker(QObject *parent = nullptr);
+
+ enum DeviceEventType
+ {
+ NewDevice,
+ DisconnectedDevice
+ };
+
+ void start();
+ void stop();
+
+signals:
+ void deviceEvent(DeviceEventType eventType, QMap<QString, QString> info);
+ void trackerError(QString errorMessage);
+
+private:
+ void handleWatchMessage(const QJsonDocument &document);
+
+ QdbWatcher *m_qdbWatcher = nullptr;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp b/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
new file mode 100644
index 0000000000..3e9bc558d0
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbmessagetracker.h"
+#include "qdbwatcher.h"
+
+#include "../qdbutils.h"
+#include "hostmessages.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+
+namespace Qdb {
+namespace Internal {
+
+QdbMessageTracker::QdbMessageTracker(QObject *parent)
+ : QObject(parent)
+{
+ m_qdbWatcher = new QdbWatcher(this);
+ connect(m_qdbWatcher, &QdbWatcher::incomingMessage, this, &QdbMessageTracker::handleWatchMessage);
+ // Errors are not handled because showing the messages is just a helpful addition for the users
+ // but not critical.
+}
+
+void QdbMessageTracker::start()
+{
+ m_qdbWatcher->start(RequestType::WatchMessages);
+}
+
+void QdbMessageTracker::stop()
+{
+ m_qdbWatcher->stop();
+}
+
+void QdbMessageTracker::handleWatchMessage(const QJsonDocument &document)
+{
+ const auto type = responseType(document.object());
+ if (type != ResponseType::Messages) {
+ stop();
+ const QString message =
+ tr("Shutting down message reception due to unexpected response: %1");
+ emit trackerError(message.arg(QString::fromUtf8(document.toJson())));
+ return;
+ }
+
+ for (const auto &i : document.object().value(QLatin1String("messages")).toArray()) {
+ // There is an additional interger field "type" available allowing future
+ // filtering and handling messages regarding of their type.
+ const auto message = i.toObject().value(QLatin1String("text")).toString();
+
+ // In case the issues reported from qdb server are permanent the messages
+ // will reappear every second annoying the user. A cache will check
+ // if the message was already displayed.
+ for (auto i = m_messageCache.firstIndex(); i < m_messageCache.lastIndex(); ++i) {
+ if (m_messageCache.at(i) == message)
+ return;
+ }
+
+ m_messageCache.append(message);
+ showMessage(tr("Qdb message: %1").arg(message), true);
+ }
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbmessagetracker.h b/src/plugins/boot2qt/device-detection/qdbmessagetracker.h
new file mode 100644
index 0000000000..499b0dd55b
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbmessagetracker.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+#include <QObject>
+#include <QContiguousCache>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbWatcher;
+
+class QdbMessageTracker : public QObject
+{
+ Q_OBJECT
+public:
+ QdbMessageTracker(QObject *parent = nullptr);
+
+ void start();
+ void stop();
+
+signals:
+ void trackerError(QString errorMessage);
+
+private:
+ void handleWatchMessage(const QJsonDocument &document);
+
+ QdbWatcher *m_qdbWatcher = nullptr;
+ QContiguousCache<QString> m_messageCache = QContiguousCache<QString>(10);
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbwatcher.cpp b/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
new file mode 100644
index 0000000000..e5a9b5c2ef
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbwatcher.h"
+
+#include "../qdbutils.h"
+#include "hostmessages.h"
+
+#include <utils/fileutils.h>
+
+#include <QFile>
+#include <QProcess>
+#include <QTimer>
+
+namespace Qdb {
+namespace Internal {
+
+const int startupDelay = 500; // time in ms to wait for host server startup before retrying
+const QString qdbSocketName = "qdb.socket";
+
+QMutex QdbWatcher::s_startMutex;
+bool QdbWatcher::s_startedServer = false;
+
+QdbWatcher::QdbWatcher(QObject *parent)
+ : QObject(parent)
+ , m_requestType(RequestType::Unknown)
+{
+}
+
+QdbWatcher::~QdbWatcher()
+{
+ stop();
+}
+
+void QdbWatcher::start(RequestType requestType)
+{
+ m_requestType = requestType;
+ startPrivate();
+}
+
+void QdbWatcher::startPrivate()
+{
+ m_socket = std::unique_ptr<QLocalSocket>(new QLocalSocket());
+ connect(m_socket.get(), &QLocalSocket::connected,
+ this, &QdbWatcher::handleWatchConnection);
+ connect(m_socket.get(), static_cast<void (QLocalSocket::*)
+ (QLocalSocket::LocalSocketError)>(&QLocalSocket::error),
+ this, &QdbWatcher::handleWatchError);
+ m_socket->connectToServer(qdbSocketName);
+}
+
+void QdbWatcher::stop()
+{
+ m_shuttingDown = true;
+ if (m_socket)
+ m_socket->disconnectFromServer();
+}
+
+void QdbWatcher::handleWatchConnection()
+{
+ m_retried = false;
+ {
+ QMutexLocker lock(&s_startMutex);
+ s_startedServer = false;
+ }
+ connect(m_socket.get(), &QIODevice::readyRead, this, &QdbWatcher::handleWatchMessage);
+ m_socket->write(createRequest(m_requestType));
+}
+
+void QdbWatcher::handleWatchError(QLocalSocket::LocalSocketError error)
+{
+ if (m_shuttingDown)
+ return;
+
+ if (error == QLocalSocket::PeerClosedError) {
+ retry();
+ return;
+ }
+
+ if (error != QLocalSocket::ServerNotFoundError
+ && error != QLocalSocket::ConnectionRefusedError) {
+ stop();
+ emit watcherError(tr("Unexpected QLocalSocket error: %1")
+ .arg(m_socket->errorString()));
+ return;
+ }
+
+ if (m_retried) {
+ stop();
+ emit watcherError(tr("Could not connect to QDB host server even after trying to start it"));
+ return;
+ }
+ retry();
+}
+
+void QdbWatcher::handleWatchMessage()
+{
+ while (m_socket->bytesAvailable() > 0) {
+ const QByteArray responseBytes = m_socket->readLine();
+ const auto document = QJsonDocument::fromJson(responseBytes);
+ if (document.isNull()) {
+ const QString message =
+ tr("Invalid JSON response received from QDB server: %1");
+ emit watcherError(message.arg(QString::fromUtf8(responseBytes)));
+ return;
+ }
+ emit incomingMessage(document);
+ }
+}
+
+void QdbWatcher::forkHostServer()
+{
+ Utils::FilePath qdbFilePath = findTool(QdbTool::Qdb);
+ QFile executable(qdbFilePath.toString());
+ if (!executable.exists()) {
+ const QString message = tr("Could not find QDB host server executable. "
+ "You can set the location with environment variable %1.")
+ .arg(QLatin1String(overridingEnvironmentVariable(QdbTool::Qdb)));
+ showMessage(message, true);
+ return;
+ }
+ if (QProcess::startDetached(qdbFilePath.toString(), {"server"}))
+ showMessage(tr("QDB host server started"), false);
+ else
+ showMessage(tr("Could not start QDB host server in %1").arg(qdbFilePath.toString()), true);
+}
+
+void QdbWatcher::retry()
+{
+ m_retried = true;
+ {
+ QMutexLocker lock(&s_startMutex);
+ if (!s_startedServer) {
+ showMessage(tr("Starting QDB host server"), false);
+ forkHostServer();
+ s_startedServer = true;
+ }
+ }
+ QTimer::singleShot(startupDelay, this, &QdbWatcher::startPrivate);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbwatcher.h b/src/plugins/boot2qt/device-detection/qdbwatcher.h
new file mode 100644
index 0000000000..713c18e997
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbwatcher.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QLocalSocket>
+#include <QMutex>
+#include <QObject>
+
+#include <memory>
+
+enum class RequestType;
+QT_BEGIN_NAMESPACE
+class QJsonDocument;
+QT_END_NAMESPACE
+
+namespace Qdb {
+namespace Internal {
+
+class QdbWatcher : public QObject
+{
+ Q_OBJECT
+public:
+ QdbWatcher(QObject *parent = nullptr);
+ virtual ~QdbWatcher();
+ void stop();
+ void start(RequestType requestType);
+
+signals:
+ void incomingMessage(const QJsonDocument &);
+ void watcherError(const QString &);
+
+private:
+ void startPrivate();
+
+private:
+ void handleWatchConnection();
+ void handleWatchError(QLocalSocket::LocalSocketError error);
+ void handleWatchMessage();
+ static void forkHostServer();
+ void retry();
+
+ static QMutex s_startMutex;
+ static bool s_startedServer;
+
+ std::unique_ptr<QLocalSocket> m_socket = nullptr;
+ bool m_shuttingDown = false;
+ bool m_retried = false;
+ RequestType m_requestType;
+};
+
+} // namespace Internal
+} // namespace Qdb
+
diff --git a/src/plugins/boot2qt/images/qdbdevice.png b/src/plugins/boot2qt/images/qdbdevice.png
new file mode 100644
index 0000000000..760dde9777
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevice.png
Binary files differ
diff --git a/src/plugins/boot2qt/images/qdbdevice@2x.png b/src/plugins/boot2qt/images/qdbdevice@2x.png
new file mode 100644
index 0000000000..62ffbdad02
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevice@2x.png
Binary files differ
diff --git a/src/plugins/boot2qt/images/qdbdevicesmall.png b/src/plugins/boot2qt/images/qdbdevicesmall.png
new file mode 100644
index 0000000000..d15d6de6ca
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevicesmall.png
Binary files differ
diff --git a/src/plugins/boot2qt/images/qdbdevicesmall@2x.png b/src/plugins/boot2qt/images/qdbdevicesmall@2x.png
new file mode 100644
index 0000000000..38409af9ee
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevicesmall@2x.png
Binary files differ
diff --git a/src/plugins/boot2qt/qdb.qrc b/src/plugins/boot2qt/qdb.qrc
new file mode 100644
index 0000000000..2855671b05
--- /dev/null
+++ b/src/plugins/boot2qt/qdb.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/qdb">
+ <file>images/qdbdevice.png</file>
+ <file>images/qdbdevice@2x.png</file>
+ <file>images/qdbdevicesmall.png</file>
+ <file>images/qdbdevicesmall@2x.png</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/boot2qt/qdb_global.h b/src/plugins/boot2qt/qdb_global.h
new file mode 100644
index 0000000000..e17acae85f
--- /dev/null
+++ b/src/plugins/boot2qt/qdb_global.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtGlobal>
+
+#if defined(BOOT2QT_LIBRARY)
+# define QDBPLUGINSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define QDBPLUGINSHARED_EXPORT Q_DECL_IMPORT
+#endif
diff --git a/src/plugins/boot2qt/qdbconstants.h b/src/plugins/boot2qt/qdbconstants.h
new file mode 100644
index 0000000000..9d9093f4a1
--- /dev/null
+++ b/src/plugins/boot2qt/qdbconstants.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <coreplugin/id.h>
+
+namespace Qdb {
+namespace Constants {
+
+const char QdbLinuxOsType[] = "QdbLinuxOsType";
+
+const char QdbDeployConfigurationId[] = "Qt4ProjectManager.Qdb.QdbDeployConfiguration";
+
+const Core::Id QdbHardwareDevicePrefix = "QdbHardwareDevice";
+const char AppcontrollerFilepath[] = "/usr/bin/appcontroller";
+const char QdbRunConfigurationPrefix[] = "QdbLinuxRunConfiguration:";
+
+} // namespace Constants
+
+namespace Internal {
+enum VmState { VmReady, VmNotReady, VmShutDown };
+}
+
+} // namespace Qdb
diff --git a/src/plugins/android/androidgdbserverkitinformation.h b/src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp
index db4f349344..c033b6b101 100644
--- a/src/plugins/android/androidgdbserverkitinformation.h
+++ b/src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,31 +23,38 @@
**
****************************************************************************/
-#pragma once
+#include "qdbdeployconfigurationfactory.h"
+#include "qdbconstants.h"
+#include "qdbstopapplicationstep.h"
+
+#include <projectexplorer/deploymentdataview.h>
#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
-namespace Android {
-namespace Internal {
+#include <remotelinux/remotelinuxcheckforfreediskspacestep.h>
+#include <remotelinux/genericdirectuploadstep.h>
+#include <remotelinux/remotelinuxdeployconfiguration.h>
-class AndroidGdbServerKitAspect : public ProjectExplorer::KitAspect
-{
- Q_OBJECT
-public:
- AndroidGdbServerKitAspect();
+using namespace ProjectExplorer;
+using namespace RemoteLinux;
- void setup(ProjectExplorer::Kit *) override;
- ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *) const override;
- bool isApplicableToKit(const ProjectExplorer::Kit *k) const override;
- ItemList toUserOutput(const ProjectExplorer::Kit *) const override;
+namespace Qdb {
+namespace Internal {
- ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *) const override;
+QdbDeployConfigurationFactory::QdbDeployConfigurationFactory()
+{
+ setConfigBaseId(Constants::QdbDeployConfigurationId);
+ addSupportedTargetDeviceType(Constants::QdbLinuxOsType);
+ setDefaultDisplayName(QCoreApplication::translate("Qdb::Internal::QdbDeployConfiguration",
+ "Deploy to Boot2Qt target"));
+ setUseDeploymentDataView();
- static Core::Id id();
- static Utils::FilePath gdbServer(const ProjectExplorer::Kit *kit);
- static void setGdbSever(ProjectExplorer::Kit *kit, const Utils::FilePath &gdbServerCommand);
- static Utils::FilePath autoDetect(const ProjectExplorer::Kit *kit);
-};
+ addInitialStep(RemoteLinuxCheckForFreeDiskSpaceStep::stepId());
+ addInitialStep(QdbStopApplicationStep::stepId());
+ addInitialStep(GenericDirectUploadStep::stepId());
+}
} // namespace Internal
-} // namespace Android
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeployconfigurationfactory.h b/src/plugins/boot2qt/qdbdeployconfigurationfactory.h
new file mode 100644
index 0000000000..90fd93f239
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeployconfigurationfactory.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/deployconfiguration.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory
+{
+public:
+ QdbDeployConfigurationFactory();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/cpptools/cppkitinfo.cpp b/src/plugins/boot2qt/qdbdeploystepfactory.cpp
index e57a4dbd73..a39b3e5b86 100644
--- a/src/plugins/cpptools/cppkitinfo.cpp
+++ b/src/plugins/boot2qt/qdbdeploystepfactory.cpp
@@ -23,42 +23,34 @@
**
****************************************************************************/
-#include "cppkitinfo.h"
+#include "qdbdeploystepfactory.h"
-#include <projectexplorer/kit.h>
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/kitmanager.h>
-#include <projectexplorer/project.h>
+#include "qdbconstants.h"
+#include "qdbmakedefaultappstep.h"
+#include "qdbstopapplicationstep.h"
+
+#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtkitinformation.h>
-
-namespace CppTools {
-
-using namespace ProjectExplorer;
+namespace Qdb {
+namespace Internal {
-KitInfo::KitInfo(Project *project)
+QdbMakeDefaultAppStepFactory::QdbMakeDefaultAppStepFactory()
{
- // Kit
- if (Target *target = project->activeTarget())
- kit = target->kit();
- else
- kit = KitManager::defaultKit();
-
- // Toolchains
- if (kit) {
- cToolChain = ToolChainKitAspect::toolChain(kit, Constants::C_LANGUAGE_ID);
- cxxToolChain = ToolChainKitAspect::toolChain(kit, Constants::CXX_LANGUAGE_ID);
- }
-
- // Sysroot
- sysRootPath = ProjectExplorer::SysRootKitAspect::sysRoot(kit).toString();
+ registerStep<QdbMakeDefaultAppStep>(QdbMakeDefaultAppStep::stepId());
+ setDisplayName(QdbMakeDefaultAppStep::stepDisplayName());
+ setSupportedDeviceType(Constants::QdbLinuxOsType);
+ setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
}
-bool KitInfo::isValid() const
+QdbStopApplicationStepFactory::QdbStopApplicationStepFactory()
{
- return kit;
+ registerStep<QdbStopApplicationStep>(QdbStopApplicationStep::stepId());
+ setDisplayName(QdbStopApplicationStep::stepDisplayName());
+ setSupportedDeviceType(Constants::QdbLinuxOsType);
+ setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
}
-} // namespace CppTools
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeploystepfactory.h b/src/plugins/boot2qt/qdbdeploystepfactory.h
new file mode 100644
index 0000000000..fada4a8478
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeploystepfactory.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/buildstep.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppStepFactory : public ProjectExplorer::BuildStepFactory
+{
+public:
+ QdbMakeDefaultAppStepFactory();
+};
+
+class QdbStopApplicationStepFactory : public ProjectExplorer::BuildStepFactory
+{
+public:
+ QdbStopApplicationStepFactory();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevice.cpp b/src/plugins/boot2qt/qdbdevice.cpp
new file mode 100644
index 0000000000..c6e388878d
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevice.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevice.h"
+
+#include "qdbutils.h"
+#include "qdbconstants.h"
+#include "qdbdevicedebugsupport.h"
+
+#include <coreplugin/icore.h>
+
+#include <projectexplorer/applicationlauncher.h>
+#include <projectexplorer/devicesupport/idevice.h>
+#include <projectexplorer/runcontrol.h>
+
+#include <remotelinux/linuxdeviceprocess.h>
+
+#include <ssh/sshconnection.h>
+
+#include <utils/portlist.h>
+#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+
+#include <QFormLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QWizard>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDeviceProcess : public RemoteLinux::LinuxDeviceProcess
+{
+public:
+ QdbDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent)
+ : RemoteLinux::LinuxDeviceProcess(device, parent)
+ {
+ }
+
+ void terminate() override
+ {
+ ProjectExplorer::Runnable r;
+ r.executable = FilePath::fromString(Constants::AppcontrollerFilepath);
+ r.commandLineArguments = QStringLiteral("--stop");
+
+ (new ApplicationLauncher(this))->start(r, device());
+ }
+};
+
+
+class DeviceApplicationObserver : public ApplicationLauncher
+{
+public:
+ DeviceApplicationObserver(const IDevice::ConstPtr &device, const CommandLine &command)
+ {
+ connect(&m_appRunner, &ApplicationLauncher::remoteStdout, this,
+ &DeviceApplicationObserver::handleStdout);
+ connect(&m_appRunner, &ApplicationLauncher::remoteStderr, this,
+ &DeviceApplicationObserver::handleStderr);
+ connect(&m_appRunner, &ApplicationLauncher::reportError, this,
+ &DeviceApplicationObserver::handleError);
+ connect(&m_appRunner, &ApplicationLauncher::finished, this,
+ &DeviceApplicationObserver::handleFinished);
+
+ QTC_ASSERT(device, return);
+ m_deviceName = device->displayName();
+
+ Runnable r;
+ r.setCommandLine(command);
+ m_appRunner.start(r, device);
+ showMessage(QdbDevice::tr("Starting command '%1' on device '%2'.")
+ .arg(command.toUserOutput(), m_deviceName));
+ }
+
+private:
+ void handleStdout(const QString &data) { m_stdout += data; }
+ void handleStderr(const QString &data) { m_stderr += data; }
+ void handleError(const QString &message) { m_error = message; }
+
+ void handleFinished(bool success)
+ {
+ if (success && (m_stdout.contains("fail") || m_stdout.contains("error")
+ || m_stdout.contains("not found"))) {
+ // FIXME: Needed in a post-adb world?
+ success = false; // adb does not forward exit codes and all stderr goes to stdout.
+ }
+ if (!success) {
+ QString errorString;
+ if (!m_error.isEmpty()) {
+ errorString = QdbDevice::tr("Command failed on device '%1': %2")
+ .arg(m_deviceName, m_error);
+ } else {
+ errorString = QdbDevice::tr("Command failed on device '%1'.").arg(m_deviceName);
+ }
+ showMessage(errorString, true);
+ if (!m_stdout.isEmpty())
+ showMessage(QdbDevice::tr("stdout was: '%1'").arg(m_stdout));
+ if (!m_stderr.isEmpty())
+ showMessage(QdbDevice::tr("stderr was: '%1'").arg(m_stderr));
+ } else {
+ showMessage(QdbDevice::tr("Commands on device '%1' finished successfully.")
+ .arg(m_deviceName));
+ }
+ deleteLater();
+ }
+
+ QString m_stdout;
+ QString m_stderr;
+ ProjectExplorer::ApplicationLauncher m_appRunner;
+ QString m_deviceName;
+ QString m_error;
+};
+
+
+// QdbDevice
+
+QdbDevice::QdbDevice()
+{
+ setDisplayType(tr("Boot2Qt Device"));
+
+ addDeviceAction({tr("Reboot Device"), [](const IDevice::Ptr &device, QWidget *) {
+ (void) new DeviceApplicationObserver(device, CommandLine{"reboot"});
+ }});
+
+ addDeviceAction({tr("Restore Default App"), [](const IDevice::Ptr &device, QWidget *) {
+ (void) new DeviceApplicationObserver(device, CommandLine{"appcontroller", {"--remove-default"}});
+ }});
+}
+
+ProjectExplorer::IDeviceWidget *QdbDevice::createWidget()
+{
+ ProjectExplorer::IDeviceWidget *w = RemoteLinux::LinuxDevice::createWidget();
+
+ return w;
+}
+
+ProjectExplorer::DeviceProcess *QdbDevice::createProcess(QObject *parent) const
+{
+ return new QdbDeviceProcess(sharedFromThis(), parent);
+}
+
+void QdbDevice::setSerialNumber(const QString &serial)
+{
+ m_serialNumber = serial;
+}
+
+QString QdbDevice::serialNumber() const
+{
+ return m_serialNumber;
+}
+
+void QdbDevice::fromMap(const QVariantMap &map)
+{
+ ProjectExplorer::IDevice::fromMap(map);
+ setSerialNumber(map.value("Qdb.SerialNumber").toString());
+}
+
+QVariantMap QdbDevice::toMap() const
+{
+ QVariantMap map = ProjectExplorer::IDevice::toMap();
+ map.insert("Qdb.SerialNumber", serialNumber());
+ return map;
+}
+
+void QdbDevice::setupDefaultNetworkSettings(const QString &host)
+{
+ setFreePorts(Utils::PortList::fromString("10000-10100"));
+
+ QSsh::SshConnectionParameters parameters = sshParameters();
+ parameters.setHost(host);
+ parameters.setUserName("root");
+ parameters.setPort(22);
+ parameters.timeout = 10;
+ parameters.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypeAll;
+ setSshParameters(parameters);
+}
+
+// QdbDeviceWizard
+
+class QdbSettingsPage : public QWizardPage
+{
+public:
+ QdbSettingsPage()
+ {
+ setWindowTitle(QdbDevice::tr("WizardPage"));
+ setTitle(QdbDevice::tr("Device Settings"));
+
+ nameLineEdit = new QLineEdit(this);
+ nameLineEdit->setPlaceholderText(QdbDevice::tr("A short, free-text description"));
+
+ addressLineEdit = new QLineEdit(this);
+ addressLineEdit->setPlaceholderText(QdbDevice::tr("Host name or IP address"));
+
+ auto usbWarningLabel = new QLabel(this);
+ usbWarningLabel->setText(QString("<html><head/><body><it><b>%1</it><p>%2</p></body></html>")
+ .arg("Note:")
+ .arg("Do not use this wizard for devices connected via USB.<br/>"
+ "Those will be auto-detected.</p>"
+ "<p>The connectivity to the device is tested after finishing."));
+
+ auto formLayout = new QFormLayout(this);
+ formLayout->addRow(QdbDevice::tr("Device name:"), nameLineEdit);
+ formLayout->addRow(QdbDevice::tr("Device address:"), addressLineEdit);
+ formLayout->addRow(usbWarningLabel);
+
+ connect(nameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged);
+ connect(addressLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged);
+ }
+
+ QString deviceName() const { return nameLineEdit->text().trimmed(); }
+ QString deviceAddress() const { return addressLineEdit->text().trimmed(); }
+
+private:
+ bool isComplete() const final {
+ return !deviceName().isEmpty() && !deviceAddress().isEmpty();
+ }
+
+ QLineEdit *nameLineEdit;
+ QLineEdit *addressLineEdit;
+
+};
+
+class QdbDeviceWizard : public QWizard
+{
+public:
+ QdbDeviceWizard(QWidget *parent)
+ : QWizard(parent)
+ {
+ setWindowTitle(QdbDeviceWizard::tr("Boot2Qt Network Device Setup"));
+ settingsPage.setCommitPage(true);
+
+ enum { SettingsPageId };
+
+ setPage(SettingsPageId, &settingsPage);
+ }
+
+ ProjectExplorer::IDevice::Ptr device()
+ {
+ QdbDevice::Ptr device = QdbDevice::create();
+
+ device->setDisplayName(settingsPage.deviceName());
+ device->setupId(ProjectExplorer::IDevice::ManuallyAdded, Core::Id());
+ device->setType(Constants::QdbLinuxOsType);
+ device->setMachineType(ProjectExplorer::IDevice::Hardware);
+
+ device->setupDefaultNetworkSettings(settingsPage.deviceAddress());
+
+ return device;
+ }
+
+private:
+ QdbSettingsPage settingsPage;
+};
+
+
+// Device factory
+
+QdbLinuxDeviceFactory::QdbLinuxDeviceFactory()
+ : IDeviceFactory(Constants::QdbLinuxOsType)
+{
+ setDisplayName(tr("Boot2Qt Device"));
+ setCombinedIcon(":/qdb/images/qdbdevicesmall.png", ":/qdb/images/qdbdevice.png");
+ setCanCreate(true);
+ setConstructionFunction(&QdbDevice::create);
+}
+
+IDevice::Ptr QdbLinuxDeviceFactory::create() const
+{
+ QdbDeviceWizard wizard(Core::ICore::mainWindow());
+
+ if (wizard.exec() != QDialog::Accepted)
+ return IDevice::Ptr();
+ return wizard.device();
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevice.h b/src/plugins/boot2qt/qdbdevice.h
new file mode 100644
index 0000000000..a0f6f9338f
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevice.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "qdbconstants.h"
+#include <projectexplorer/kit.h>
+#include <remotelinux/linuxdevice.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDevice : public RemoteLinux::LinuxDevice
+{
+public:
+ typedef QSharedPointer<QdbDevice> Ptr;
+ typedef QSharedPointer<const QdbDevice> ConstPtr;
+
+ static Ptr create() { return Ptr(new QdbDevice); }
+
+ ProjectExplorer::IDeviceWidget *createWidget() final;
+
+ ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const final;
+
+ void setSerialNumber(const QString &serial);
+ QString serialNumber() const;
+
+ void fromMap(const QVariantMap &map) final;
+ QVariantMap toMap() const final;
+
+ void setupDefaultNetworkSettings(const QString &host);
+
+private:
+ QdbDevice();
+
+ QString m_serialNumber;
+};
+
+class QdbLinuxDeviceFactory : public ProjectExplorer::IDeviceFactory
+{
+ Q_OBJECT
+public:
+ QdbLinuxDeviceFactory();
+
+private:
+ ProjectExplorer::IDevice::Ptr create() const final;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevicedebugsupport.cpp b/src/plugins/boot2qt/qdbdevicedebugsupport.cpp
new file mode 100644
index 0000000000..7ed2cd9643
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicedebugsupport.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevicedebugsupport.h"
+
+#include "qdbconstants.h"
+#include "qdbdevice.h"
+#include "qdbrunconfiguration.h"
+
+#include <debugger/debuggerruncontrol.h>
+
+#include <ssh/sshconnection.h>
+
+#include <utils/algorithm.h>
+#include <utils/url.h>
+
+using namespace Debugger;
+using namespace ProjectExplorer;
+using namespace Utils;
+using namespace Qdb::Internal;
+
+namespace Qdb {
+
+class QdbDeviceInferiorRunner : public RunWorker
+{
+public:
+ QdbDeviceInferiorRunner(RunControl *runControl,
+ bool usePerf, bool useGdbServer, bool useQmlServer,
+ QmlDebug::QmlDebugServicesPreset qmlServices)
+ : RunWorker(runControl),
+ m_usePerf(usePerf), m_useGdbServer(useGdbServer), m_useQmlServer(useQmlServer),
+ m_qmlServices(qmlServices)
+ {
+ setId("QdbDebuggeeRunner");
+
+ connect(&m_launcher, &ApplicationLauncher::remoteProcessStarted,
+ this, &RunWorker::reportStarted);
+ connect(&m_launcher, &ApplicationLauncher::finished,
+ this, &RunWorker::reportStopped);
+ connect(&m_launcher, &ApplicationLauncher::appendMessage,
+ this, &RunWorker::appendMessage);
+ connect(&m_launcher, &ApplicationLauncher::remoteStdout,
+ this, [this](const QString &out) { appendMessage(out, StdOutFormat); });
+ connect(&m_launcher, &ApplicationLauncher::remoteStderr,
+ this, [this](const QString &out) { appendMessage(out, StdErrFormat); });
+
+ m_portsGatherer = new GdbServerPortsGatherer(runControl);
+ m_portsGatherer->setUseGdbServer(useGdbServer || usePerf);
+ m_portsGatherer->setUseQmlServer(useQmlServer);
+ addStartDependency(m_portsGatherer);
+ }
+
+ QUrl perfServer() const { return m_portsGatherer->gdbServer(); }
+ QUrl gdbServer() const { return m_portsGatherer->gdbServer(); }
+ QUrl qmlServer() const { return m_portsGatherer->qmlServer(); }
+
+ void start() override
+ {
+ const int perfPort = m_portsGatherer->gdbServer().port();
+ const int gdbServerPort = m_portsGatherer->gdbServer().port();
+ const int qmlServerPort = m_portsGatherer->qmlServer().port();
+
+ int lowerPort = 0;
+ int upperPort = 0;
+
+ Runnable r = runnable();
+
+ QString args;
+ if (m_useGdbServer) {
+ args.append(" --debug-gdb");
+ lowerPort = upperPort = gdbServerPort;
+ }
+ if (m_useQmlServer) {
+ args.append(" --debug-qml --qml-debug-services ");
+ args.append(QmlDebug::qmlDebugServices(m_qmlServices));
+ lowerPort = upperPort = qmlServerPort;
+ }
+ if (m_useGdbServer && m_useQmlServer) {
+ if (gdbServerPort + 1 != qmlServerPort) {
+ reportFailure("Need adjacent free ports for combined C++/QML debugging");
+ return;
+ }
+ lowerPort = gdbServerPort;
+ upperPort = qmlServerPort;
+ }
+ if (m_usePerf) {
+ QVariantMap settingsData = runControl()->settingsData("Analyzer.Perf.Settings");
+ QVariant perfRecordArgs = settingsData.value("Analyzer.Perf.RecordArguments");
+ QString args = Utils::transform(perfRecordArgs.toStringList(), [](QString arg) {
+ return arg.replace(',', ",,");
+ }).join(',');
+ args.append(QString(" --profile-perf %1").arg(args));
+ lowerPort = upperPort = perfPort;
+ }
+ args.append(QString(" --port-range %1-%2 ").arg(lowerPort).arg(upperPort));
+ args.append(r.executable.toString());
+ args.append(" ");
+ args.append(r.commandLineArguments);
+
+ r.commandLineArguments = args;
+ r.executable = FilePath::fromString(Constants::AppcontrollerFilepath);
+
+ m_launcher.start(r, device());
+ }
+
+ void stop() override { m_launcher.stop(); }
+
+private:
+ Debugger::GdbServerPortsGatherer *m_portsGatherer = nullptr;
+ bool m_usePerf;
+ bool m_useGdbServer;
+ bool m_useQmlServer;
+ QmlDebug::QmlDebugServicesPreset m_qmlServices;
+ ApplicationLauncher m_launcher;
+};
+
+
+// QdbDeviceDebugSupport
+
+QdbDeviceDebugSupport::QdbDeviceDebugSupport(RunControl *runControl)
+ : Debugger::DebuggerRunTool(runControl)
+{
+ setId("QdbDeviceDebugSupport");
+
+ m_debuggee = new QdbDeviceInferiorRunner(runControl, false, isCppDebugging(), isQmlDebugging(),
+ QmlDebug::QmlDebuggerServices);
+ addStartDependency(m_debuggee);
+
+ m_debuggee->addStopDependency(this);
+}
+
+void QdbDeviceDebugSupport::start()
+{
+ setStartMode(Debugger::AttachToRemoteServer);
+ setCloseMode(KillAndExitMonitorAtClose);
+ setRemoteChannel(m_debuggee->gdbServer());
+ setQmlServer(m_debuggee->qmlServer());
+ setUseContinueInsteadOfRun(true);
+ setContinueAfterAttach(true);
+ addSolibSearchDir("%{sysroot}/system/lib");
+
+ DebuggerRunTool::start();
+}
+
+void QdbDeviceDebugSupport::stop()
+{
+ // Do nothing unusual. The launcher will die as result of (gdb) kill.
+ DebuggerRunTool::stop();
+}
+
+
+// QdbDeviceQmlProfilerSupport
+
+QdbDeviceQmlToolingSupport::QdbDeviceQmlToolingSupport(RunControl *runControl)
+ : RunWorker(runControl)
+{
+ setId("QdbDeviceQmlToolingSupport");
+
+ QmlDebug::QmlDebugServicesPreset services = QmlDebug::servicesForRunMode(runControl->runMode());
+ m_runner = new QdbDeviceInferiorRunner(runControl, false, false, true, services);
+ addStartDependency(m_runner);
+ addStopDependency(m_runner);
+
+ m_worker = runControl->createWorker(QmlDebug::runnerIdForRunMode(runControl->runMode()));
+ m_worker->addStartDependency(this);
+ addStopDependency(m_worker);
+}
+
+void QdbDeviceQmlToolingSupport::start()
+{
+ m_worker->recordData("QmlServerUrl", m_runner->qmlServer());
+ reportStarted();
+}
+
+// QdbDevicePerfProfilerSupport
+
+QdbDevicePerfProfilerSupport::QdbDevicePerfProfilerSupport(RunControl *runControl)
+ : RunWorker(runControl)
+{
+ setId("QdbDevicePerfProfilerSupport");
+
+ m_profilee = new QdbDeviceInferiorRunner(runControl, true, false, false,
+ QmlDebug::NoQmlDebugServices);
+ addStartDependency(m_profilee);
+ addStopDependency(m_profilee);
+}
+
+void QdbDevicePerfProfilerSupport::start()
+{
+ runControl()->setProperty("PerfConnection", m_profilee->perfServer());
+ reportStarted();
+}
+
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevicedebugsupport.h b/src/plugins/boot2qt/qdbdevicedebugsupport.h
new file mode 100644
index 0000000000..8ed779d370
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicedebugsupport.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <debugger/debuggerruncontrol.h>
+#include <qmldebug/qmldebugcommandlinearguments.h>
+
+namespace Qdb {
+
+class QdbDeviceInferiorRunner;
+
+class QdbDeviceDebugSupport : public Debugger::DebuggerRunTool
+{
+public:
+ QdbDeviceDebugSupport(ProjectExplorer::RunControl *runControl);
+
+private:
+ void start();
+ void stop();
+
+ QdbDeviceInferiorRunner *m_debuggee = nullptr;
+};
+
+class QdbDeviceQmlToolingSupport : public ProjectExplorer::RunWorker
+{
+public:
+ QdbDeviceQmlToolingSupport(ProjectExplorer::RunControl *runControl);
+
+private:
+ void start() override;
+
+ QdbDeviceInferiorRunner *m_runner = nullptr;
+ ProjectExplorer::RunWorker *m_worker = nullptr;
+};
+
+class QdbDevicePerfProfilerSupport : public ProjectExplorer::RunWorker
+{
+public:
+ QdbDevicePerfProfilerSupport(ProjectExplorer::RunControl *runControl);
+
+private:
+ void start() override;
+
+ QdbDeviceInferiorRunner *m_profilee = nullptr;
+};
+
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbmakedefaultappservice.cpp b/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
new file mode 100644
index 0000000000..fc7212b910
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbmakedefaultappservice.h"
+
+#include "qdbconstants.h"
+#include "qdbrunconfiguration.h"
+
+#include <ssh/sshremoteprocessrunner.h>
+#include <projectexplorer/target.h>
+#include <projectexplorer/runconfigurationaspects.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppServicePrivate
+{
+public:
+ bool makeDefault;
+ QSsh::SshRemoteProcessRunner *processRunner;
+};
+
+QdbMakeDefaultAppService::QdbMakeDefaultAppService(QObject *parent)
+ : AbstractRemoteLinuxDeployService(parent),
+ d(new QdbMakeDefaultAppServicePrivate)
+{
+ d->processRunner = 0;
+ d->makeDefault = true;
+}
+
+QdbMakeDefaultAppService::~QdbMakeDefaultAppService()
+{
+ cleanup();
+ delete d;
+}
+
+void QdbMakeDefaultAppService::setMakeDefault(bool makeDefault)
+{
+ d->makeDefault = makeDefault;
+}
+
+void QdbMakeDefaultAppService::handleStdErr()
+{
+ emit stdErrData(QString::fromUtf8(d->processRunner->readAllStandardError()));
+}
+
+void QdbMakeDefaultAppService::handleProcessFinished(const QString &error)
+{
+ if (!error.isEmpty()) {
+ emit errorMessage(tr("Remote process failed: %1").arg(error));
+ stopDeployment();
+ return;
+ }
+
+ QByteArray processOutput = d->processRunner->readAllStandardOutput();
+
+ if (d->makeDefault)
+ emit progressMessage(tr("Application made as the default one."));
+ else
+ emit progressMessage(tr("Reset the default application."));
+
+ stopDeployment();
+}
+
+void QdbMakeDefaultAppService::doDeploy()
+{
+ d->processRunner = new QSsh::SshRemoteProcessRunner;
+ connect(d->processRunner, &QSsh::SshRemoteProcessRunner::processClosed,
+ this, &QdbMakeDefaultAppService::handleProcessFinished);
+ connect(d->processRunner, &QSsh::SshRemoteProcessRunner::readyReadStandardError,
+ this, &QdbMakeDefaultAppService::handleStdErr);
+
+ QString remoteExe;
+
+ if (ProjectExplorer::RunConfiguration *rc = target()->activeRunConfiguration()) {
+ if (auto exeAspect = rc->aspect<ProjectExplorer::ExecutableAspect>())
+ remoteExe = exeAspect->executable().toString();
+ }
+
+ QString command = Constants::AppcontrollerFilepath;
+ command += d->makeDefault && !remoteExe.isEmpty() ? QStringLiteral(" --make-default ") + remoteExe
+ : QStringLiteral(" --remove-default");
+
+ d->processRunner->run(command, deviceConfiguration()->sshParameters());
+}
+
+void QdbMakeDefaultAppService::stopDeployment()
+{
+ cleanup();
+ handleDeploymentDone();
+}
+
+void QdbMakeDefaultAppService::cleanup()
+{
+ if (d->processRunner) {
+ disconnect(d->processRunner, 0, this, 0);
+ d->processRunner->cancel();
+ delete d->processRunner;
+ d->processRunner = 0;
+ }
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/boot2qt/qdbmakedefaultappservice.h
index 27bfb430b1..4e900a0bb6 100644
--- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h
+++ b/src/plugins/boot2qt/qdbmakedefaultappservice.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,34 +25,36 @@
#pragma once
-#include <projectexplorer/runconfiguration.h>
+#include <remotelinux/abstractremotelinuxdeployservice.h>
-#include <utils/fileutils.h>
-
-namespace QmakeProjectManager {
+namespace Qdb {
namespace Internal {
-class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration
+class QdbMakeDefaultAppServicePrivate;
+
+class QdbMakeDefaultAppService : public RemoteLinux::AbstractRemoteLinuxDeployService
{
Q_OBJECT
-
public:
- DesktopQmakeRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
+ QdbMakeDefaultAppService(QObject *parent = 0);
+ ~QdbMakeDefaultAppService();
+ void setMakeDefault(bool makeDefault);
private:
- void updateTargetInformation();
- bool fromMap(const QVariantMap &map) final;
- void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &info) final;
+ void handleStdErr();
+ void handleProcessFinished(const QString &error);
- QString defaultDisplayName();
- Utils::FilePath proFilePath() const;
-};
+ bool isDeploymentNecessary() const { return true; }
+ void doDeviceSetup() { handleDeviceSetupDone(true); }
+ void stopDeviceSetup() { handleDeviceSetupDone(false); }
-class DesktopQmakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
-{
-public:
- DesktopQmakeRunConfigurationFactory();
+ void doDeploy();
+ void stopDeployment();
+
+ void cleanup();
+
+ QdbMakeDefaultAppServicePrivate * const d;
};
} // namespace Internal
-} // namespace QmakeProjectManager
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp
new file mode 100644
index 0000000000..5ddb9fa6c7
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbmakedefaultappstep.h"
+
+#include "qdbmakedefaultappservice.h"
+
+#include <projectexplorer/runconfigurationaspects.h>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+QdbMakeDefaultAppStep::QdbMakeDefaultAppStep(BuildStepList *bsl)
+ : AbstractRemoteLinuxDeployStep(bsl, stepId())
+{
+ setDefaultDisplayName(stepDisplayName());
+
+ auto service = createDeployService<QdbMakeDefaultAppService>();
+
+ auto selection = addAspect<BaseSelectionAspect>();
+ selection->setSettingsKey("QdbMakeDefaultDeployStep.MakeDefault");
+ selection->addOption(tr("Set this application to start by default"));
+ selection->addOption(tr("Reset default application"));
+
+ setInternalInitializer([service, selection] {
+ service->setMakeDefault(selection->value() == 0);
+ return service->isDeploymentPossible();
+ });
+}
+
+Core::Id QdbMakeDefaultAppStep::stepId()
+{
+ return "Qdb.MakeDefaultAppStep";
+}
+
+QString QdbMakeDefaultAppStep::stepDisplayName()
+{
+ return QStringLiteral("Change default application");
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.h b/src/plugins/boot2qt/qdbmakedefaultappstep.h
new file mode 100644
index 0000000000..ffaf0dcab6
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappstep.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeploystep.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppStep : public RemoteLinux::AbstractRemoteLinuxDeployStep
+{
+ Q_OBJECT
+
+public:
+ explicit QdbMakeDefaultAppStep(ProjectExplorer::BuildStepList *bsl);
+
+ static Core::Id stepId();
+ static QString stepDisplayName();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbplugin.cpp b/src/plugins/boot2qt/qdbplugin.cpp
new file mode 100644
index 0000000000..8a07dbba6c
--- /dev/null
+++ b/src/plugins/boot2qt/qdbplugin.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbplugin.h"
+
+#include "device-detection/devicedetector.h"
+#include "qdbdeployconfigurationfactory.h"
+#include "qdbdeploystepfactory.h"
+#include "qdbdevicedebugsupport.h"
+#include "qdbqtversion.h"
+#include "qdbrunconfiguration.h"
+#include "qdbutils.h"
+
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+
+#include <projectexplorer/devicesupport/devicemanager.h>
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/target.h>
+
+#include <qtsupport/qtversionfactory.h>
+
+#include <remotelinux/remotelinuxcheckforfreediskspacestep.h>
+#include <remotelinux/genericdirectuploadstep.h>
+
+#include <utils/hostosinfo.h>
+#include <utils/fileutils.h>
+
+#include <QAction>
+#include <QFileInfo>
+#include <QProcess>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+static Utils::FilePath flashWizardFilePath()
+{
+ return findTool(QdbTool::FlashingWizard);
+}
+
+static void startFlashingWizard()
+{
+ const QString filePath = flashWizardFilePath().toUserOutput();
+ if (Utils::HostOsInfo::isWindowsHost()) {
+ if (QProcess::startDetached(QLatin1String("explorer.exe"), {filePath}))
+ return;
+ } else if (QProcess::startDetached(filePath)) {
+ return;
+ }
+ const QString message =
+ QCoreApplication::translate("Qdb", "Flash wizard \"%1\" failed to start.");
+ showMessage(message.arg(filePath), true);
+}
+
+static bool isFlashActionDisabled()
+{
+ QSettings * const settings = Core::ICore::settings();
+ settings->beginGroup(settingsGroupKey());
+ bool disabled = settings->value("flashActionDisabled", false).toBool();
+ settings->endGroup();
+ return disabled;
+}
+
+void registerFlashAction(QObject *parentForAction)
+{
+ if (isFlashActionDisabled())
+ return;
+ const Utils::FilePath fileName = flashWizardFilePath();
+ if (!fileName.exists()) {
+ const QString message =
+ QCoreApplication::translate("Qdb", "Flash wizard executable \"%1\" not found.");
+ showMessage(message.arg(fileName.toString()));
+ return;
+ }
+
+ const char flashActionId[] = "Qdb.FlashAction";
+ if (Core::ActionManager::command(flashActionId))
+ return; // The action has already been registered.
+
+ Core::ActionContainer *toolsContainer =
+ Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
+ toolsContainer->insertGroup(Core::Constants::G_TOOLS_OPTIONS,
+ flashActionId);
+
+ Core::Context globalContext(Core::Constants::C_GLOBAL);
+
+ const QString actionText = QCoreApplication::translate("Qdb", "Flash Boot to Qt Device");
+ QAction *flashAction = new QAction(actionText, parentForAction);
+ Core::Command *flashCommand = Core::ActionManager::registerAction(flashAction,
+ flashActionId,
+ globalContext);
+ QObject::connect(flashAction, &QAction::triggered, startFlashingWizard);
+ toolsContainer->addAction(flashCommand, flashActionId);
+}
+
+class QdbQtVersionFactory : public QtSupport::QtVersionFactory
+{
+public:
+ QdbQtVersionFactory()
+ {
+ setQtVersionCreator([] { return new QdbQtVersion; });
+ setSupportedType("Qdb.EmbeddedLinuxQt");
+ setPriority(99);
+ setRestrictionChecker([](const SetupData &setup) {
+ return setup.platforms.contains("boot2qt");
+ });
+ }
+};
+
+class QdbDeviceRunSupport : public SimpleTargetRunner
+{
+public:
+ QdbDeviceRunSupport(RunControl *runControl)
+ : SimpleTargetRunner(runControl)
+ {
+ setStarter([this, runControl] {
+ Runnable r = runControl->runnable();
+ r.commandLineArguments = r.executable.toString() + ' ' + r.commandLineArguments;
+ r.executable = Utils::FilePath::fromString(Constants::AppcontrollerFilepath);
+ doStart(r, runControl->device());
+ });
+ }
+};
+
+template <class Step>
+class QdbDeployStepFactory : public ProjectExplorer::BuildStepFactory
+{
+public:
+ QdbDeployStepFactory()
+ {
+ registerStep<Step>(Step::stepId());
+ setDisplayName(Step::displayName());
+ setSupportedConfiguration(Constants::QdbDeployConfigurationId);
+ setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
+ }
+};
+
+class QdbPluginPrivate : public QObject
+{
+public:
+ void setupDeviceDetection();
+
+ QdbLinuxDeviceFactory m_qdbDeviceFactory;
+ QdbQtVersionFactory m_qtVersionFactory;
+ QdbDeployConfigurationFactory m_deployConfigFactory;
+ QdbRunConfigurationFactory m_runConfigFactory;
+ QdbStopApplicationStepFactory m_stopApplicationStepFactory;
+ QdbMakeDefaultAppStepFactory m_makeDefaultAppStepFactory;
+
+ QdbDeployStepFactory<RemoteLinux::RemoteLinuxCheckForFreeDiskSpaceStep>
+ m_checkForFreeDiskSpaceStepFactory;
+ QdbDeployStepFactory<RemoteLinux::GenericDirectUploadStep>
+ m_directUploadStepFactory;
+
+ const QList<Core::Id> supportedRunConfigs {
+ m_runConfigFactory.id(),
+ "QmlProjectManager.QmlRunConfiguration"
+ };
+
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<QdbDeviceRunSupport>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ supportedRunConfigs,
+ {Qdb::Constants::QdbLinuxOsType}
+ };
+ RunWorkerFactory debugWorkerFactory{
+ RunWorkerFactory::make<QdbDeviceDebugSupport>(),
+ {ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ supportedRunConfigs,
+ {Qdb::Constants::QdbLinuxOsType}
+ };
+ RunWorkerFactory qmlToolWorkerFactory{
+ RunWorkerFactory::make<QdbDeviceQmlToolingSupport>(),
+ {ProjectExplorer::Constants::QML_PROFILER_RUN_MODE,
+ ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE},
+ supportedRunConfigs,
+ {Qdb::Constants::QdbLinuxOsType}
+ };
+ RunWorkerFactory perfRecorderFactory{
+ RunWorkerFactory::make<QdbDevicePerfProfilerSupport>(),
+ {"PerfRecorder"},
+ {},
+ {Qdb::Constants::QdbLinuxOsType}
+ };
+
+ DeviceDetector m_deviceDetector;
+};
+
+QdbPlugin::~QdbPlugin()
+{
+ delete d;
+}
+
+bool QdbPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ d = new QdbPluginPrivate;
+
+ registerFlashAction(this);
+
+ return true;
+}
+
+void QdbPlugin::extensionsInitialized()
+{
+ DeviceManager * const dm = DeviceManager::instance();
+ if (dm->isLoaded()) {
+ d->setupDeviceDetection();
+ } else {
+ connect(dm, &DeviceManager::devicesLoaded,
+ d, &QdbPluginPrivate::setupDeviceDetection);
+ }
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag QdbPlugin::aboutToShutdown()
+{
+ d->m_deviceDetector.stop();
+
+ return SynchronousShutdown;
+}
+
+void QdbPluginPrivate::setupDeviceDetection()
+{
+ m_deviceDetector.start();
+}
+
+} // Internal
+} // Qdb
diff --git a/src/plugins/boot2qt/qdbplugin.h b/src/plugins/boot2qt/qdbplugin.h
new file mode 100644
index 0000000000..2f1611fa60
--- /dev/null
+++ b/src/plugins/boot2qt/qdbplugin.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <extensionsystem/iplugin.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Boot2Qt.json")
+
+public:
+ QdbPlugin() = default;
+ ~QdbPlugin() final;
+
+private:
+ bool initialize(const QStringList &arguments, QString *errorString) final;
+ void extensionsInitialized() final;
+ ShutdownFlag aboutToShutdown() final;
+
+ class QdbPluginPrivate *d = nullptr;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/clangtools/clangtoolsbasicsettings.cpp b/src/plugins/boot2qt/qdbqtversion.cpp
index bf1d533700..ea62199106 100644
--- a/src/plugins/clangtools/clangtoolsbasicsettings.cpp
+++ b/src/plugins/boot2qt/qdbqtversion.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,30 +23,25 @@
**
****************************************************************************/
-#include "clangtoolsbasicsettings.h"
-#include "ui_clangtoolsbasicsettings.h"
+#include "qdbqtversion.h"
-#include "clangtoolsutils.h"
+#include "qdbconstants.h"
-namespace ClangTools {
+#include <coreplugin/id.h>
+
+namespace Qdb {
namespace Internal {
-ClangToolsBasicSettings::ClangToolsBasicSettings(QWidget *parent)
- : QWidget(parent)
- , m_ui(new Ui::ClangToolsBasicSettings)
+QString QdbQtVersion::description() const
{
- m_ui->setupUi(this);
+ return QCoreApplication::translate("QtVersion", "Boot2Qt", "Qt version is used for Boot2Qt development");
}
-ClangToolsBasicSettings::~ClangToolsBasicSettings()
+QSet<Core::Id> QdbQtVersion::targetDeviceTypes() const
{
- delete m_ui;
-}
+ return {Core::Id(Constants::QdbLinuxOsType)};
-Ui::ClangToolsBasicSettings *ClangToolsBasicSettings::ui()
-{
- return m_ui;
}
} // namespace Internal
-} // namespace ClangTools
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbqtversion.h b/src/plugins/boot2qt/qdbqtversion.h
new file mode 100644
index 0000000000..ac95a70701
--- /dev/null
+++ b/src/plugins/boot2qt/qdbqtversion.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <qtsupport/baseqtversion.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbQtVersion : public QtSupport::BaseQtVersion
+{
+public:
+ QdbQtVersion() = default;
+ ~QdbQtVersion() = default;
+
+ QString description() const final;
+ QSet<Core::Id> targetDeviceTypes() const final;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbrunconfiguration.cpp b/src/plugins/boot2qt/qdbrunconfiguration.cpp
new file mode 100644
index 0000000000..d1abe58229
--- /dev/null
+++ b/src/plugins/boot2qt/qdbrunconfiguration.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbrunconfiguration.h"
+
+#include "qdbconstants.h"
+
+#include <projectexplorer/buildtargetinfo.h>
+#include <projectexplorer/deploymentdata.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/runconfigurationaspects.h>
+#include <projectexplorer/target.h>
+
+#include <remotelinux/remotelinuxenvironmentaspect.h>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Qdb {
+namespace Internal {
+
+// FullCommandLineAspect
+
+FullCommandLineAspect::FullCommandLineAspect(RunConfiguration *rc)
+{
+ setLabelText(QdbRunConfiguration::tr("Full command line:"));
+
+ auto exeAspect = rc->aspect<ExecutableAspect>();
+ auto argumentsAspect = rc->aspect<ArgumentsAspect>();
+
+ auto updateCommandLine = [this, rc, exeAspect, argumentsAspect] {
+ const QString usedExecutable = exeAspect->executable().toString();
+ const QString args = argumentsAspect->arguments(rc->macroExpander());
+ setValue(QString(Constants::AppcontrollerFilepath)
+ + ' ' + usedExecutable + ' ' + args);
+ };
+
+ connect(argumentsAspect, &ArgumentsAspect::argumentsChanged, this, updateCommandLine);
+ connect(exeAspect, &ExecutableAspect::changed, this, updateCommandLine);
+ updateCommandLine();
+}
+
+// QdbRunConfiguration
+
+QdbRunConfiguration::QdbRunConfiguration(Target *target, Core::Id id)
+ : RunConfiguration(target, id)
+{
+ auto exeAspect = addAspect<ExecutableAspect>();
+ exeAspect->setSettingsKey("QdbRunConfig.RemoteExecutable");
+ exeAspect->setLabelText(tr("Executable on device:"));
+ exeAspect->setExecutablePathStyle(OsTypeLinux);
+ exeAspect->setPlaceHolderText(tr("Remote path not set"));
+ exeAspect->makeOverridable("QdbRunConfig.AlternateRemoteExecutable",
+ "QdbRunCofig.UseAlternateRemoteExecutable");
+
+ auto symbolsAspect = addAspect<SymbolFileAspect>();
+ symbolsAspect->setSettingsKey("QdbRunConfig.LocalExecutable");
+ symbolsAspect->setLabelText(tr("Executable on host:"));
+ symbolsAspect->setDisplayStyle(SymbolFileAspect::LabelDisplay);
+
+ addAspect<RemoteLinux::RemoteLinuxEnvironmentAspect>(target);
+ addAspect<ArgumentsAspect>();
+ addAspect<WorkingDirectoryAspect>();
+ addAspect<FullCommandLineAspect>(this);
+
+ connect(target, &Target::deploymentDataChanged,
+ this, &QdbRunConfiguration::updateTargetInformation);
+ connect(target, &Target::applicationTargetsChanged,
+ this, &QdbRunConfiguration::updateTargetInformation);
+ connect(target, &Target::kitChanged,
+ this, &QdbRunConfiguration::updateTargetInformation);
+ connect(target->project(), &Project::parsingFinished,
+ this, &QdbRunConfiguration::updateTargetInformation);
+
+ setDefaultDisplayName(tr("Run on Boot2Qt Device"));
+}
+
+ProjectExplorer::RunConfiguration::ConfigurationState QdbRunConfiguration::ensureConfigured(QString *errorMessage)
+{
+ QString remoteExecutable = aspect<ExecutableAspect>()->executable().toString();
+ if (remoteExecutable.isEmpty()) {
+ if (errorMessage) {
+ *errorMessage = tr("The remote executable must be set "
+ "in order to run on a Boot2Qt device.");
+ }
+ return UnConfigured;
+ }
+ return Configured;
+}
+
+void QdbRunConfiguration::updateTargetInformation()
+{
+ const BuildTargetInfo bti = buildTargetInfo();
+ const FilePath localExecutable = bti.targetFilePath;
+ const DeployableFile depFile = target()->deploymentData().deployableForLocalFile(localExecutable);
+
+ aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(depFile.remoteFilePath()));
+ aspect<SymbolFileAspect>()->setFilePath(localExecutable);
+}
+
+QString QdbRunConfiguration::defaultDisplayName() const
+{
+ return RunConfigurationFactory::decoratedTargetName(buildKey(), target());
+}
+
+// QdbRunConfigurationFactory
+
+QdbRunConfigurationFactory::QdbRunConfigurationFactory()
+{
+ registerRunConfiguration<QdbRunConfiguration>(Qdb::Constants::QdbRunConfigurationPrefix);
+ addSupportedTargetDeviceType(Constants::QdbLinuxOsType);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/boot2qt/qdbrunconfiguration.h
index 934f676624..0099c63b5e 100644
--- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
+++ b/src/plugins/boot2qt/qdbrunconfiguration.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,36 +25,38 @@
#pragma once
-#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/runconfigurationaspects.h>
-#include <QHash>
-#include <QPair>
-#include <QStringList>
-
-namespace QbsProjectManager {
+namespace Qdb {
namespace Internal {
-class QbsRunConfiguration : public ProjectExplorer::RunConfiguration
+class FullCommandLineAspect : public ProjectExplorer::BaseStringAspect
{
Q_OBJECT
public:
- QbsRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
+ explicit FullCommandLineAspect(ProjectExplorer::RunConfiguration *rc);
+};
-private:
- Utils::FilePath executableToRun(const ProjectExplorer::BuildTargetInfo &targetInfo) const;
- QVariantMap toMap() const final;
- bool fromMap(const QVariantMap &map) final;
- void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci) final;
+class QdbRunConfiguration : public ProjectExplorer::RunConfiguration
+{
+ Q_OBJECT
+public:
+ QdbRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
+
+ ConfigurationState ensureConfigured(QString *errorMessage) override;
+
+private:
void updateTargetInformation();
+ QString defaultDisplayName() const;
};
-class QbsRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
+class QdbRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
{
public:
- QbsRunConfigurationFactory();
+ QdbRunConfigurationFactory();
};
} // namespace Internal
-} // namespace QbsProjectManager
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationservice.cpp b/src/plugins/boot2qt/qdbstopapplicationservice.cpp
new file mode 100644
index 0000000000..e0a683cc61
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationservice.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbstopapplicationservice.h"
+
+#include "qdbconstants.h"
+
+#include <projectexplorer/applicationlauncher.h>
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/target.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationServicePrivate
+{
+public:
+ ProjectExplorer::ApplicationLauncher applicationLauncher;
+ QString errorOutput;
+};
+
+QdbStopApplicationService::QdbStopApplicationService(QObject *parent)
+ : AbstractRemoteLinuxDeployService(parent),
+ d(new QdbStopApplicationServicePrivate)
+{
+
+}
+
+QdbStopApplicationService::~QdbStopApplicationService()
+{
+ cleanup();
+ delete d;
+}
+
+void QdbStopApplicationService::handleProcessFinished(bool success)
+{
+ const auto failureMessage = tr("Could not check and possibly stop running application.");
+ if (!success) {
+ emit errorMessage(failureMessage);
+ stopDeployment();
+ return;
+ }
+
+ if (d->errorOutput.contains("Could not connect: Connection refused")) {
+ emit progressMessage(tr("Checked that there is no running application."));
+ } else if (!d->errorOutput.isEmpty()) {
+ emit stdErrData(d->errorOutput);
+ emit errorMessage(failureMessage);
+ } else {
+ emit progressMessage(tr("Stopped the running application."));
+ }
+
+ stopDeployment();
+}
+
+void QdbStopApplicationService::handleStderr(const QString &output)
+{
+ d->errorOutput.append(output);
+}
+
+void QdbStopApplicationService::handleStdout(const QString &output)
+{
+ emit stdOutData(output);
+}
+
+void QdbStopApplicationService::doDeploy()
+{
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::reportError,
+ this, &QdbStopApplicationService::stdErrData);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::remoteStderr,
+ this, &QdbStopApplicationService::handleStderr);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::remoteStdout,
+ this, &QdbStopApplicationService::handleStdout);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::finished,
+ this, &QdbStopApplicationService::handleProcessFinished);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::reportProgress,
+ this, &QdbStopApplicationService::stdOutData);
+
+ ProjectExplorer::Runnable runnable;
+ runnable.executable = Utils::FilePath::fromString(Constants::AppcontrollerFilepath);
+ runnable.commandLineArguments = QStringLiteral("--stop");
+ runnable.workingDirectory = QStringLiteral("/usr/bin");
+
+ d->applicationLauncher.start(runnable,
+ ProjectExplorer::DeviceKitAspect::device(target()->kit()));
+}
+
+void QdbStopApplicationService::stopDeployment()
+{
+ cleanup();
+ handleDeploymentDone();
+}
+
+void QdbStopApplicationService::cleanup()
+{
+ d->applicationLauncher.disconnect(this);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationservice.h b/src/plugins/boot2qt/qdbstopapplicationservice.h
new file mode 100644
index 0000000000..9e925ade4e
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationservice.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeployservice.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationServicePrivate;
+
+class QdbStopApplicationService : public RemoteLinux::AbstractRemoteLinuxDeployService
+{
+ Q_OBJECT
+public:
+ QdbStopApplicationService(QObject *parent = 0);
+ ~QdbStopApplicationService();
+
+private:
+ void handleProcessFinished(bool success);
+ void handleStderr(const QString &output);
+ void handleStdout(const QString &output);
+
+ bool isDeploymentNecessary() const final { return true; }
+ void doDeviceSetup() final { handleDeviceSetupDone(true); }
+ void stopDeviceSetup() final { handleDeviceSetupDone(false); }
+
+ void doDeploy() final;
+ void stopDeployment() final;
+
+ void cleanup();
+
+ QdbStopApplicationServicePrivate * const d;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.cpp b/src/plugins/boot2qt/qdbstopapplicationstep.cpp
new file mode 100644
index 0000000000..0005a01712
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationstep.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbstopapplicationstep.h"
+
+#include "qdbstopapplicationservice.h"
+
+namespace Qdb {
+namespace Internal {
+
+QdbStopApplicationStep::QdbStopApplicationStep(ProjectExplorer::BuildStepList *bsl)
+ : AbstractRemoteLinuxDeployStep(bsl, stepId())
+{
+ auto service = createDeployService<QdbStopApplicationService>();
+
+ setDefaultDisplayName(stepDisplayName());
+ setWidgetExpandedByDefault(false);
+
+ setInternalInitializer([service] { return service->isDeploymentPossible(); });
+}
+
+Core::Id QdbStopApplicationStep::stepId()
+{
+ return "Qdb.StopApplicationStep";
+}
+
+QString QdbStopApplicationStep::stepDisplayName()
+{
+ return tr("Stop already running application");
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.h b/src/plugins/boot2qt/qdbstopapplicationstep.h
new file mode 100644
index 0000000000..2d1fcf69c9
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationstep.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeploystep.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationStep : public RemoteLinux::AbstractRemoteLinuxDeployStep
+{
+ Q_OBJECT
+public:
+ explicit QdbStopApplicationStep(ProjectExplorer::BuildStepList *bsl);
+
+ static Core::Id stepId();
+ static QString stepDisplayName();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbutils.cpp b/src/plugins/boot2qt/qdbutils.cpp
new file mode 100644
index 0000000000..b4880fa28c
--- /dev/null
+++ b/src/plugins/boot2qt/qdbutils.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbutils.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/messagemanager.h>
+#include <utils/hostosinfo.h>
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+
+#include <QDir>
+
+namespace Qdb {
+namespace Internal {
+
+static QString executableBaseName(QdbTool tool)
+{
+ switch (tool) {
+ case QdbTool::FlashingWizard:
+ return QLatin1String("b2qt-flashing-wizard");
+ case QdbTool::Qdb:
+ return QLatin1String("qdb");
+ }
+ QTC_CHECK(false);
+ return QString();
+}
+
+Utils::FilePath findTool(QdbTool tool)
+{
+ QString filePath = QString::fromLocal8Bit(qgetenv(overridingEnvironmentVariable(tool)));
+
+ if (filePath.isEmpty()) {
+ QSettings * const settings = Core::ICore::settings();
+ settings->beginGroup(settingsGroupKey());
+ filePath = settings->value(settingsKey(tool)).toString();
+ settings->endGroup();
+ }
+
+ if (filePath.isEmpty()) {
+ filePath = Utils::HostOsInfo::withExecutableSuffix(
+ QCoreApplication::applicationDirPath()
+#ifdef Q_OS_MACOS
+ + QLatin1String("/../../../Tools/b2qt/")
+#else
+ + QLatin1String("/../../b2qt/")
+#endif
+ + executableBaseName(tool));
+ }
+
+ return Utils::FilePath::fromString(QDir::cleanPath(filePath));
+}
+
+const char *overridingEnvironmentVariable(QdbTool tool)
+{
+ switch (tool) {
+ case QdbTool::FlashingWizard:
+ return "BOOT2QT_FLASHWIZARD_FILEPATH";
+ case QdbTool::Qdb:
+ return "BOOT2QT_QDB_FILEPATH";
+ }
+ QTC_ASSERT(false, return "");
+}
+
+void showMessage(const QString &message, bool important)
+{
+ const QString fullMessage = QCoreApplication::translate("Boot2Qt", "Boot2Qt: %1").arg(message);
+ const Core::MessageManager::PrintToOutputPaneFlags flags = important
+ ? Core::MessageManager::ModeSwitch : Core::MessageManager::Silent;
+ Core::MessageManager::write(fullMessage, flags);
+}
+
+QString settingsGroupKey()
+{
+ return QLatin1String("Boot2Qt");
+}
+
+QString settingsKey(QdbTool tool)
+{
+ switch (tool) {
+ case QdbTool::FlashingWizard:
+ return QLatin1String("flashingWizardFilePath");
+ case QdbTool::Qdb:
+ return QLatin1String("qdbFilePath");
+ }
+ QTC_ASSERT(false, return QString());
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbutils.h b/src/plugins/boot2qt/qdbutils.h
new file mode 100644
index 0000000000..feafdbab57
--- /dev/null
+++ b/src/plugins/boot2qt/qdbutils.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/fileutils.h>
+
+#include <qglobal.h>
+
+namespace Qdb {
+namespace Internal {
+
+enum class QdbTool {
+ FlashingWizard,
+ Qdb
+};
+
+Utils::FilePath findTool(QdbTool tool);
+const char *overridingEnvironmentVariable(QdbTool tool);
+void showMessage(const QString &message, bool important = false);
+QString settingsGroupKey();
+QString settingsKey(QdbTool tool);
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/clangcodemodel/clangassistproposalmodel.cpp b/src/plugins/clangcodemodel/clangassistproposalmodel.cpp
index 6e535fb04a..9f682ff6eb 100644
--- a/src/plugins/clangcodemodel/clangassistproposalmodel.cpp
+++ b/src/plugins/clangcodemodel/clangassistproposalmodel.cpp
@@ -52,9 +52,9 @@ void ClangAssistProposalModel::sort(const QString &/*prefix*/)
auto currentItemsCompare = [](AssistProposalItemInterface *first,
AssistProposalItemInterface *second) {
- if (first->prefixMatch() != second->prefixMatch()) {
- return static_cast<int>(first->prefixMatch())
- < static_cast<int>(second->prefixMatch());
+ if (first->proposalMatch() != second->proposalMatch()) {
+ return static_cast<int>(first->proposalMatch())
+ < static_cast<int>(second->proposalMatch());
}
return false;
};
diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp
index 34e3136830..bfba1329a9 100644
--- a/src/plugins/clangcodemodel/clangbackendreceiver.cpp
+++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp
@@ -86,15 +86,18 @@ void BackendReceiver::addExpectedCompletionsMessage(
void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget)
{
- QMutableHashIterator<quint64, ClangCompletionAssistProcessor *> it(m_assistProcessorsTable);
- while (it.hasNext()) {
- it.next();
+ QList<quint64> toRemove;
+ for (auto it = m_assistProcessorsTable.cbegin(), end = m_assistProcessorsTable.cend();
+ it != end; ++it)
+ {
ClangCompletionAssistProcessor *assistProcessor = it.value();
if (assistProcessor->textEditorWidget() == textEditorWidget) {
delete assistProcessor;
- it.remove();
+ toRemove.append(it.key());
}
}
+ for (quint64 item : toRemove)
+ m_assistProcessorsTable.remove(item);
}
QFuture<CppTools::CursorInfo> BackendReceiver::addExpectedReferencesMessage(
@@ -219,7 +222,7 @@ CppTools::CursorInfo::Range toCursorInfoRange(const SourceRangeContainer &source
{
const SourceLocationContainer &start = sourceRange.start;
const SourceLocationContainer &end = sourceRange.end;
- const unsigned length = end.column - start.column;
+ const int length = end.column - start.column;
return {start.line, start.column, length};
}
@@ -249,10 +252,10 @@ CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message)
const SourceLocationContainer &start = range.start;
const SourceLocationContainer &end = range.end;
- result.startLine = static_cast<int>(start.line);
- result.startColumn = static_cast<int>(start.column);
- result.endLine = static_cast<int>(end.line);
- result.endColumn = static_cast<int>(end.column);
+ result.startLine = start.line;
+ result.startColumn = start.column;
+ result.endLine = end.line;
+ result.endColumn = end.column;
result.fileName = start.filePath;
result.isResultOnlyForFallBack = message.result.isResultOnlyForFallBack;
diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
index 6c5ae3cb4b..51aaa6ba7a 100644
--- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
+++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
@@ -60,9 +60,8 @@ static void addProjectPanelWidget()
auto panelFactory = new ProjectExplorer::ProjectPanelFactory();
panelFactory->setPriority(60);
panelFactory->setDisplayName(ClangProjectSettingsWidget::tr("Clang Code Model"));
- panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) {
- return new ClangProjectSettingsWidget(project);
- });
+ panelFactory->setCreateWidgetFunction(
+ [&](ProjectExplorer::Project *project) { return new ClangProjectSettingsWidget(project); });
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
}
@@ -96,8 +95,8 @@ ClangCodeModelPlugin::~ClangCodeModelPlugin()
bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
ProjectExplorer::TaskHub::addCategory(Constants::TASK_CATEGORY_DIAGNOSTICS,
tr("Clang Code Model"));
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
index 6f1397c487..09f5ee9507 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
@@ -189,7 +189,7 @@ CodeCompletions ClangCompletionAssistProcessor::applyCompletionFixIt(const CodeC
ClangFixItOperation fixItOperation(Utf8String(), completion.requiredFixIts);
fixItOperation.perform();
- const int fixItLength = static_cast<int>(fixIt.range.end.column - fixIt.range.start.column);
+ const int fixItLength = fixIt.range.end.column - fixIt.range.start.column;
const QString fixItText = fixIt.text.toString();
m_positionForProposal += fixItText.length() - fixItLength;
diff --git a/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp b/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp
index cd90c29fb4..20d4cf707a 100644
--- a/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp
+++ b/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp
@@ -75,7 +75,7 @@ static Core::LocatorFilterEntry makeEntry(Core::ILocatorFilter *filter,
{
const ClangBackEnd::ExtraInfo &extraInfo = info.extraInfo;
QString displayName = extraInfo.token;
- ::Utils::LineColumn lineColumn(static_cast<int>(info.line), static_cast<int>(info.column));
+ ::Utils::LineColumn lineColumn(info.line, info.column);
Core::LocatorFilterEntry entry(filter, displayName, QVariant::fromValue(lineColumn));
QString extra;
ClangBackEnd::HighlightingType mainType = info.types.mainHighlightingType;
diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
index 5151279a28..fe77b0156c 100644
--- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
+++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp
@@ -36,7 +36,6 @@
#include <QApplication>
#include <QDesktopServices>
-#include <QDesktopWidget>
#include <QFileInfo>
#include <QHash>
#include <QLabel>
diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
index 8fd2508315..627299c64e 100644
--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp
@@ -637,7 +637,6 @@ ClangEditorDocumentProcessor::creatorForHeaderErrorDiagnosticWidget(
return [firstHeaderErrorDiagnostic]() {
auto vbox = new QVBoxLayout;
- vbox->setMargin(0);
vbox->setContentsMargins(10, 0, 0, 2);
vbox->setSpacing(2);
diff --git a/src/plugins/clangcodemodel/clangfixitoperation.cpp b/src/plugins/clangcodemodel/clangfixitoperation.cpp
index a7170dc881..5f325f8ceb 100644
--- a/src/plugins/clangcodemodel/clangfixitoperation.cpp
+++ b/src/plugins/clangcodemodel/clangfixitoperation.cpp
@@ -35,7 +35,6 @@ namespace ClangCodeModel {
namespace Internal {
using FileToFixits = QMap<QString, QVector<ClangBackEnd::FixItContainer>>;
-using FileToFixitsIterator = QMapIterator<QString, QVector<ClangBackEnd::FixItContainer>>;
using RefactoringFilePtr = QSharedPointer<TextEditor::RefactoringFile>;
ClangFixItOperation::ClangFixItOperation(
@@ -75,9 +74,7 @@ void ClangFixItOperation::perform()
const TextEditor::RefactoringChanges refactoringChanges;
const FileToFixits fileToFixIts = fixitsPerFile(fixItContainers);
- FileToFixitsIterator i(fileToFixIts);
- while (i.hasNext()) {
- i.next();
+ for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) {
const QString filePath = i.key();
const QVector<ClangBackEnd::FixItContainer> fixits = i.value();
diff --git a/src/plugins/clangcodemodel/clangfixitoperationsextractor.cpp b/src/plugins/clangcodemodel/clangfixitoperationsextractor.cpp
index 981a679a9b..72d52cb81b 100644
--- a/src/plugins/clangcodemodel/clangfixitoperationsextractor.cpp
+++ b/src/plugins/clangcodemodel/clangfixitoperationsextractor.cpp
@@ -63,7 +63,7 @@ bool hasFixItAt(const QVector<ClangBackEnd::FixItContainer> &fixits,
{
const auto isFixitForLocation = [filePath, line] (const ClangBackEnd::FixItContainer &fixit) {
const ClangBackEnd::SourceLocationContainer &location = fixit.range.start;
- return location.filePath == filePath && location.line == uint(line);
+ return location.filePath == filePath && location.line == line;
};
return Utils::anyOf(fixits, isFixitForLocation);
diff --git a/src/plugins/clangcodemodel/clangfollowsymbol.cpp b/src/plugins/clangcodemodel/clangfollowsymbol.cpp
index e03a2b904c..58adcacee2 100644
--- a/src/plugins/clangcodemodel/clangfollowsymbol.cpp
+++ b/src/plugins/clangcodemodel/clangfollowsymbol.cpp
@@ -43,8 +43,8 @@ namespace Internal {
// Returns invalid Mark if it is not found at (line, column)
static bool findMark(const QVector<ClangBackEnd::TokenInfoContainer> &marks,
- uint line,
- uint column,
+ int line,
+ int column,
ClangBackEnd::TokenInfoContainer &mark)
{
mark = Utils::findOrDefault(marks,
diff --git a/src/plugins/clangcodemodel/clanghighlightingresultreporter.h b/src/plugins/clangcodemodel/clanghighlightingresultreporter.h
index 2c6e7a89a8..b3755fd264 100644
--- a/src/plugins/clangcodemodel/clanghighlightingresultreporter.h
+++ b/src/plugins/clangcodemodel/clanghighlightingresultreporter.h
@@ -65,7 +65,7 @@ private:
int m_chunkSize = 100;
bool m_flushRequested = false;
- unsigned m_flushLine = 0;
+ int m_flushLine = 0;
};
} // namespace Internal
diff --git a/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h b/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h
index 6a88a1fd22..c8de24a0d0 100644
--- a/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h
+++ b/src/plugins/clangcodemodel/clangisdiagnosticrelatedtolocation.h
@@ -31,8 +31,8 @@ namespace ClangCodeModel {
namespace Internal {
static bool isWithinRange(const ClangBackEnd::SourceRangeContainer &range,
- uint line,
- uint column)
+ int line,
+ int column)
{
const ClangBackEnd::SourceLocationContainer &startLocation = range.start;
const ClangBackEnd::SourceLocationContainer &endLocation = range.end;
@@ -44,8 +44,8 @@ static bool isWithinRange(const ClangBackEnd::SourceRangeContainer &range,
}
static bool isWithinOneRange(const QVector<ClangBackEnd::SourceRangeContainer> &ranges,
- uint line,
- uint column)
+ int line,
+ int column)
{
for (const ClangBackEnd::SourceRangeContainer &range : ranges) {
if (isWithinRange(range, line, column))
@@ -57,8 +57,8 @@ static bool isWithinOneRange(const QVector<ClangBackEnd::SourceRangeContainer> &
bool isDiagnosticRelatedToLocation(const ClangBackEnd::DiagnosticContainer &diagnostic,
const QVector<ClangBackEnd::SourceRangeContainer> &additionalRanges,
- uint line,
- uint column)
+ int line,
+ int column)
{
const ClangBackEnd::SourceLocationContainer &location = diagnostic.location;
diff --git a/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp b/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp
index c3ca95c6a0..25d22bb1c1 100644
--- a/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp
+++ b/src/plugins/clangcodemodel/test/clangbatchfileprocessor.cpp
@@ -235,7 +235,7 @@ bool OpenProjectCommand::run()
QTC_ASSERT(openProjectSucceeded, return false);
Project *project = openProjectSucceeded.project();
- project->configureAsExampleProject({});
+ project->configureAsExampleProject();
return CppTools::Tests::TestCase::waitUntilCppModelManagerIsAwareOf(project, timeOutInMs());
}
diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
index 4307e8b96f..fe533f5931 100644
--- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
+++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp
@@ -243,7 +243,7 @@ CppTools::ProjectPart::Ptr createProjectPart(const QStringList &files,
projectPart->projectFile = QLatin1String("myproject.project");
foreach (const QString &file, files)
projectPart->files.append(ProjectFile(file, ProjectFile::classify(file)));
- projectPart->qtVersion = ProjectPart::NoQt;
+ projectPart->qtVersion = ::Utils::QtVersion::None;
projectPart->projectMacros = macros;
return projectPart;
diff --git a/src/plugins/clangformat/clangformatplugin.cpp b/src/plugins/clangformat/clangformatplugin.cpp
index 1f3ea8d475..4e2b8c6c83 100644
--- a/src/plugins/clangformat/clangformatplugin.cpp
+++ b/src/plugins/clangformat/clangformatplugin.cpp
@@ -107,8 +107,8 @@ static void replaceCppCodeStyle()
bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorString)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorString);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
replaceCppCodeStyle();
@@ -136,7 +136,7 @@ bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorS
const QString fileName = openClangFormatConfigAction->data().toString();
if (!fileName.isEmpty()) {
const QString clangFormatConfigPath = configForFile(
- Utils::FileName::fromString(fileName));
+ Utils::FilePath::fromString(fileName));
Core::EditorManager::openEditor(clangFormatConfigPath);
}
});
diff --git a/src/plugins/clangpchmanager/CMakeLists.txt b/src/plugins/clangpchmanager/CMakeLists.txt
index 6b36a88060..a012d090c9 100644
--- a/src/plugins/clangpchmanager/CMakeLists.txt
+++ b/src/plugins/clangpchmanager/CMakeLists.txt
@@ -4,12 +4,17 @@ add_qtc_plugin(ClangPchManager
DEFINES CLANGPCHMANAGER_LIB
PLUGIN_DEPENDS Core CppTools
SOURCES
+ clangindexingprojectsettings.cpp clangindexingprojectsettings.h
+ clangindexingprojectsettingswidget.cpp clangindexingprojectsettingswidget.h clangindexingprojectsettingswidget.ui
+ clangindexingsettingsmanager.cpp clangindexingsettingsmanager.h
clangpchmanager_global.h
clangpchmanagerplugin.cpp clangpchmanagerplugin.h
pchmanagerclient.cpp pchmanagerclient.h
pchmanagerconnectionclient.cpp pchmanagerconnectionclient.h
pchmanagernotifierinterface.cpp pchmanagernotifierinterface.h
pchmanagerprojectupdater.cpp pchmanagerprojectupdater.h
+ preprocessormacrocollector.cpp preprocessormacrocollector.h
+ preprocessormacrowidget.cpp preprocessormacrowidget.h
progressmanager.h
progressmanagerinterface.h
projectupdater.cpp projectupdater.h
diff --git a/src/plugins/clangpchmanager/clangindexingprojectsettings.cpp b/src/plugins/clangpchmanager/clangindexingprojectsettings.cpp
new file mode 100644
index 0000000000..722c7767be
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangindexingprojectsettings.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangindexingprojectsettings.h"
+
+#include <projectexplorer/project.h>
+
+namespace ClangPchManager {
+
+namespace {
+Utils::NameValueItems fromQVariantMap(const QVariantMap &variantMap,
+ Utils::NameValueItem::Operation operation)
+{
+ Utils::NameValueItems nameValueItems;
+ nameValueItems.reserve(variantMap.size());
+
+ auto end = variantMap.end();
+
+ for (auto iterator = variantMap.cbegin(); iterator != end; ++iterator) // QMap iterators are broken
+ nameValueItems.push_back({iterator.key(), iterator.value().toString(), operation});
+
+ return nameValueItems;
+}
+
+} // namespace
+
+ClangIndexingProjectSettings::ClangIndexingProjectSettings(ProjectExplorer::Project *project)
+ : m_project(project)
+{}
+
+void ClangIndexingProjectSettings::saveMacros(const Utils::NameValueItems &items)
+{
+ QVariantMap unsets;
+ QVariantMap sets;
+
+ for (const Utils::NameValueItem &item : items) {
+ using Operation = Utils::NameValueItem::Operation;
+ switch (item.operation) {
+ case Operation::SetEnabled:
+ sets[item.name] = item.value;
+ break;
+ case Operation::Unset:
+ unsets[item.name] = item.value;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (sets.size())
+ m_project->setNamedSettings("set_indexing_macro", sets);
+ else
+ m_project->setNamedSettings("set_indexing_macro", {});
+
+ if (unsets.size())
+ m_project->setNamedSettings("unset_indexing_macro", unsets);
+ else
+ m_project->setNamedSettings("unset_indexing_macro", {});
+}
+
+Utils::NameValueItems ClangIndexingProjectSettings::readMacros() const
+{
+ QVariant unsets = m_project->namedSettings("unset_indexing_macro");
+
+ Utils::NameValueItems items = fromQVariantMap(unsets.toMap(), Utils::NameValueItem::Unset);
+
+ QVariant sets = m_project->namedSettings("set_indexing_macro");
+
+ items += fromQVariantMap(sets.toMap(), Utils::NameValueItem::SetEnabled);
+
+ return items;
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/clangindexingprojectsettings.h b/src/plugins/clangpchmanager/clangindexingprojectsettings.h
new file mode 100644
index 0000000000..7571034a28
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangindexingprojectsettings.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangpchmanager_global.h"
+
+#include <utils/namevalueitem.h>
+
+namespace ProjectExplorer {
+class Project;
+}
+
+namespace ClangPchManager {
+
+class CLANGPCHMANAGER_EXPORT ClangIndexingProjectSettings
+{
+public:
+ ClangIndexingProjectSettings(ProjectExplorer::Project *project);
+
+ Utils::NameValueItems readMacros() const;
+ void saveMacros(const Utils::NameValueItems &items);
+
+private:
+ ProjectExplorer::Project *m_project;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.cpp b/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.cpp
new file mode 100644
index 0000000000..fc791fe652
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangindexingprojectsettingswidget.h"
+#include "ui_clangindexingprojectsettingswidget.h"
+
+#include <cpptools/cppmodelmanager.h>
+#include <projectexplorer/project.h>
+
+#include "pchmanagerprojectupdater.h"
+#include "preprocessormacrocollector.h"
+#include "preprocessormacrowidget.h"
+#include "qtcreatorprojectupdater.h"
+
+namespace ClangPchManager {
+ClangIndexingProjectSettingsWidget::ClangIndexingProjectSettingsWidget(
+ ClangIndexingProjectSettings *settings,
+ ProjectExplorer::Project *project,
+ QtCreatorProjectUpdater<PchManagerProjectUpdater> &projectUpdater)
+ : ui(new Ui::ClangIndexingProjectSettingsWidget)
+ , m_project(project)
+ , m_projectUpdater(projectUpdater)
+{
+ ui->setupUi(this);
+ ui->preprocessorMacrosWidget->setSettings(settings);
+ connect(ui->reindexButton, &QPushButton::clicked, this, &ClangIndexingProjectSettingsWidget::reindex);
+}
+
+ClangIndexingProjectSettingsWidget::~ClangIndexingProjectSettingsWidget()
+{
+ delete ui;
+}
+
+void ClangIndexingProjectSettingsWidget::onProjectPartsUpdated(ProjectExplorer::Project *project)
+{
+ const CppTools::ProjectInfo projectInfo = CppTools::CppModelManager::instance()->projectInfo(
+ project);
+
+ PreprocessorMacroCollector collector;
+
+ for (auto projectPart : projectInfo.projectParts())
+ collector.add(projectPart->projectMacros);
+
+ ui->preprocessorMacrosWidget->setBasePreprocessorMacros(collector.macros());
+}
+
+void ClangIndexingProjectSettingsWidget::reindex()
+{
+ m_projectUpdater.projectPartsUpdated(m_project);
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.h b/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.h
new file mode 100644
index 0000000000..2a3b4293b5
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QWidget>
+
+namespace ProjectExplorer {
+class Project;
+}
+
+namespace Ui {
+class ClangIndexingProjectSettingsWidget;
+}
+
+namespace ClangPchManager {
+
+template<typename T>
+class QtCreatorProjectUpdater;
+class PchManagerProjectUpdater;
+
+class ClangIndexingProjectSettings;
+
+class ClangIndexingProjectSettingsWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ClangIndexingProjectSettingsWidget(
+ ClangIndexingProjectSettings *settings,
+ ProjectExplorer::Project *project,
+ QtCreatorProjectUpdater<PchManagerProjectUpdater> &projectUpdater);
+ ~ClangIndexingProjectSettingsWidget();
+
+ void onProjectPartsUpdated(ProjectExplorer::Project *project);
+ void reindex();
+
+private:
+ Ui::ClangIndexingProjectSettingsWidget *ui;
+ ProjectExplorer::Project *m_project;
+ QtCreatorProjectUpdater<PchManagerProjectUpdater> &m_projectUpdater;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.ui b/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.ui
new file mode 100644
index 0000000000..b10fd91bee
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangindexingprojectsettingswidget.ui
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ClangIndexingProjectSettingsWidget</class>
+ <widget class="QWidget" name="ClangIndexingProjectSettingsWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QPushButton" name="reindexButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reindex</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="ClangPchManager::PreprocessorMacroWidget" name="preprocessorMacrosWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ClangPchManager::PreprocessorMacroWidget</class>
+ <extends>QWidget</extends>
+ <header>preprocessormacrowidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/clangpchmanager/clangindexingsettingsmanager.cpp b/src/plugins/clangpchmanager/clangindexingsettingsmanager.cpp
new file mode 100644
index 0000000000..786581d73d
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangindexingsettingsmanager.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "clangindexingsettingsmanager.h"
+
+#include "clangindexingprojectsettings.h"
+
+namespace ClangPchManager {
+
+ClangIndexingSettingsManager::ClangIndexingSettingsManager() = default;
+
+ClangIndexingSettingsManager::~ClangIndexingSettingsManager() = default;
+
+ClangIndexingProjectSettings *ClangIndexingSettingsManager::settings(ProjectExplorer::Project *project)
+{
+ auto &setting = m_settings[project];
+
+ if (!setting)
+ setting = std::make_unique<ClangIndexingProjectSettings>(project);
+
+ return setting.get();
+}
+
+void ClangIndexingSettingsManager::remove(ProjectExplorer::Project *project)
+{
+ m_settings.erase(project);
+}
+
+bool ClangIndexingSettingsManager::hasSettings(ProjectExplorer::Project *project) const
+{
+ return m_settings.find(project) != m_settings.end();
+}
+} // namespace ClangPchManager
diff --git a/src/plugins/projectexplorer/deploymentdatamodel.h b/src/plugins/clangpchmanager/clangindexingsettingsmanager.h
index a2437cb4bc..72f501f35b 100644
--- a/src/plugins/projectexplorer/deploymentdatamodel.h
+++ b/src/plugins/clangpchmanager/clangindexingsettingsmanager.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,28 +25,35 @@
#pragma once
-#include "deploymentdata.h"
-#include "projectexplorer_export.h"
+#include "clangpchmanager_global.h"
-#include <QAbstractTableModel>
+#include <map>
+#include <memory>
namespace ProjectExplorer {
+class Project;
+}
-class PROJECTEXPLORER_EXPORT DeploymentDataModel : public QAbstractTableModel
+namespace ClangPchManager {
+
+class ClangIndexingProjectSettings;
+
+class CLANGPCHMANAGER_EXPORT ClangIndexingSettingsManager
{
- Q_OBJECT
public:
- explicit DeploymentDataModel(QObject *parent = nullptr);
+ ClangIndexingSettingsManager();
+ ~ClangIndexingSettingsManager();
- void setDeploymentData(const DeploymentData &deploymentData);
+ ClangIndexingSettingsManager(const ClangIndexingSettingsManager &) = delete;
+ ClangIndexingSettingsManager &operator=(const ClangIndexingSettingsManager &) = delete;
-private:
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ ClangIndexingProjectSettings *settings(ProjectExplorer::Project *project);
+ void remove(ProjectExplorer::Project *project);
- DeploymentData m_deploymentData;
+ bool hasSettings(ProjectExplorer::Project *project) const;
+
+private:
+ std::map<ProjectExplorer::Project *, std::unique_ptr<ClangIndexingProjectSettings>> m_settings;
};
-} // namespace ProjectExplorer
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/clangpchmanager-source.pri b/src/plugins/clangpchmanager/clangpchmanager-source.pri
index c0eb7ba90a..a74d61313c 100644
--- a/src/plugins/clangpchmanager/clangpchmanager-source.pri
+++ b/src/plugins/clangpchmanager/clangpchmanager-source.pri
@@ -7,18 +7,24 @@ shared|dll {
INCLUDEPATH += $$PWD
HEADERS += \
+ $$PWD/clangindexingprojectsettings.h \
+ $$PWD/clangindexingsettingsmanager.h \
$$PWD/pchmanagerclient.h \
$$PWD/pchmanagernotifierinterface.h \
$$PWD/pchmanagerconnectionclient.h \
$$PWD/clangpchmanager_global.h \
+ $$PWD/preprocessormacrocollector.h \
$$PWD/projectupdater.h \
$$PWD/pchmanagerprojectupdater.h \
$$PWD/progressmanager.h \
$$PWD/progressmanagerinterface.h
SOURCES += \
+ $$PWD/clangindexingprojectsettings.cpp \
+ $$PWD/clangindexingsettingsmanager.cpp \
$$PWD/pchmanagerclient.cpp \
$$PWD/pchmanagernotifierinterface.cpp \
$$PWD/pchmanagerconnectionclient.cpp \
+ $$PWD/preprocessormacrocollector.cpp \
$$PWD/projectupdater.cpp \
$$PWD/pchmanagerprojectupdater.cpp
diff --git a/src/plugins/clangpchmanager/clangpchmanager.pro b/src/plugins/clangpchmanager/clangpchmanager.pro
index e222ffd3d4..b0bc548c20 100644
--- a/src/plugins/clangpchmanager/clangpchmanager.pro
+++ b/src/plugins/clangpchmanager/clangpchmanager.pro
@@ -12,8 +12,15 @@ win32 {
HEADERS += \
$$PWD/clangpchmanagerplugin.h \
+ clangindexingprojectsettingswidget.h \
+ preprocessormacrowidget.h \
qtcreatorprojectupdater.h
SOURCES += \
$$PWD/clangpchmanagerplugin.cpp \
+ clangindexingprojectsettingswidget.cpp \
+ preprocessormacrowidget.cpp \
qtcreatorprojectupdater.cpp
+
+FORMS += \
+ clangindexingprojectsettingswidget.ui
diff --git a/src/plugins/clangpchmanager/clangpchmanager.qbs b/src/plugins/clangpchmanager/clangpchmanager.qbs
index 8c22188633..a49e642e6f 100644
--- a/src/plugins/clangpchmanager/clangpchmanager.qbs
+++ b/src/plugins/clangpchmanager/clangpchmanager.qbs
@@ -19,6 +19,13 @@ QtcPlugin {
cpp.includePaths: ["."]
files: [
+ "clangindexingprojectsettings.cpp",
+ "clangindexingprojectsettings.h",
+ "clangindexingprojectsettingswidget.cpp",
+ "clangindexingprojectsettingswidget.h",
+ "clangindexingprojectsettingswidget.ui",
+ "clangindexingsettingsmanager.cpp",
+ "clangindexingsettingsmanager.h",
"clangpchmanagerplugin.cpp",
"clangpchmanagerplugin.h",
"clangpchmanager_global.h",
@@ -30,6 +37,10 @@ QtcPlugin {
"pchmanagerconnectionclient.h",
"pchmanagerprojectupdater.cpp",
"pchmanagerprojectupdater.h",
+ "preprocessormacrocollector.cpp",
+ "preprocessormacrocollector.h",
+ "preprocessormacrowidget.cpp",
+ "preprocessormacrowidget.h",
"projectupdater.cpp",
"projectupdater.h",
"qtcreatorprojectupdater.cpp",
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
index c50a4db7b9..606e12b98e 100644
--- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
@@ -25,8 +25,10 @@
#include "clangpchmanagerplugin.h"
-#include "pchmanagerconnectionclient.h"
+#include "clangindexingprojectsettingswidget.h"
+#include "clangindexingsettingsmanager.h"
#include "pchmanagerclient.h"
+#include "pchmanagerconnectionclient.h"
#include "progressmanager.h"
#include "qtcreatorprojectupdater.h"
@@ -38,12 +40,14 @@
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <extensionsystem/pluginmanager.h>
+#include <projectexplorer/projectpanelfactory.h>
#include <utils/hostosinfo.h>
#include <QFutureInterface>
#include <chrono>
+#include <map>
using namespace std::chrono_literals;
@@ -58,6 +62,29 @@ QString backendProcessPath()
+ QStringLiteral(QTC_HOST_EXE_SUFFIX);
}
+void addIndexingProjectPaneWidget(ClangIndexingSettingsManager &settingsManager,
+ QtCreatorProjectUpdater<PchManagerProjectUpdater> &projectUpdater)
+{
+ auto factory = new ProjectExplorer::ProjectPanelFactory;
+ factory->setPriority(120);
+ factory->setDisplayName(ClangIndexingProjectSettingsWidget::tr("Clang Indexing"));
+ factory->setCreateWidgetFunction([&](ProjectExplorer::Project *project) {
+ auto widget = new ClangIndexingProjectSettingsWidget(settingsManager.settings(project),
+ project,
+ projectUpdater);
+
+ widget->onProjectPartsUpdated(project);
+
+ QObject::connect(CppTools::CppModelManager::instance(),
+ &CppTools::CppModelManager::projectPartsUpdated,
+ widget,
+ &ClangIndexingProjectSettingsWidget::onProjectPartsUpdated);
+
+ return widget;
+ });
+ ProjectExplorer::ProjectPanelFactory::registerFactory(factory);
+}
+
} // anonymous namespace
class ClangPchManagerPluginData
@@ -83,10 +110,12 @@ public:
ClangBackEnd::ProjectPartsStorage<Sqlite::Database> projectPartsStorage{database};
PchManagerClient pchManagerClient{pchCreationProgressManager, dependencyCreationProgressManager};
PchManagerConnectionClient connectionClient{&pchManagerClient};
- QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(),
- pchManagerClient,
- filePathCache,
- projectPartsStorage};
+ ClangIndexingSettingsManager settingsManager;
+ QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdater{connectionClient.serverProxy(),
+ pchManagerClient,
+ filePathCache,
+ projectPartsStorage,
+ settingsManager};
};
std::unique_ptr<ClangPchManagerPluginData> ClangPchManagerPlugin::d;
@@ -102,6 +131,8 @@ bool ClangPchManagerPlugin::initialize(const QStringList & /*arguments*/, QStrin
startBackend();
+ addIndexingProjectPaneWidget(d->settingsManager, d->projectUpdater);
+
return true;
}
@@ -133,4 +164,9 @@ PchManagerClient &ClangPchManagerPlugin::pchManagerClient()
return d->pchManagerClient;
}
+ClangIndexingSettingsManager &ClangPchManagerPlugin::settingsManager()
+{
+ return d->settingsManager;
+}
+
} // namespace ClangRefactoring
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.h b/src/plugins/clangpchmanager/clangpchmanagerplugin.h
index 60c7d2b266..f472b769b4 100644
--- a/src/plugins/clangpchmanager/clangpchmanagerplugin.h
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.h
@@ -33,6 +33,7 @@
namespace ClangPchManager {
+class ClangIndexingSettingsManager;
class ClangPchManagerPluginData;
class PchManagerClient;
@@ -50,6 +51,7 @@ public:
ShutdownFlag aboutToShutdown();
static PchManagerClient &pchManagerClient();
+ static ClangIndexingSettingsManager &settingsManager();
private:
void startBackend();
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.h b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
index fd1b98eab4..8d41e56476 100644
--- a/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
@@ -35,8 +35,9 @@ public:
PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
PchManagerClient &client,
ClangBackEnd::FilePathCachingInterface &filePathCache,
- ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
- : ProjectUpdater(server, filePathCache, projectPartsStorage)
+ ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
+ ClangIndexingSettingsManager &settingsManager)
+ : ProjectUpdater(server, filePathCache, projectPartsStorage, settingsManager)
, m_client(client)
{}
diff --git a/src/plugins/clangpchmanager/preprocessormacrocollector.cpp b/src/plugins/clangpchmanager/preprocessormacrocollector.cpp
new file mode 100644
index 0000000000..03b38daeff
--- /dev/null
+++ b/src/plugins/clangpchmanager/preprocessormacrocollector.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "preprocessormacrocollector.h"
+
+namespace ClangPchManager {
+
+namespace {
+PreprocessorMacros toSortedMacros(const ProjectExplorer::Macros &macros)
+{
+ PreprocessorMacros sortedMacros;
+ sortedMacros.reserve(macros.size());
+
+ for (const ProjectExplorer::Macro &macro : macros)
+ if (macro.type == ProjectExplorer::MacroType::Define)
+ sortedMacros.push_back({QString::fromUtf8(macro.key), QString::fromUtf8(macro.value)});
+
+ std::sort(sortedMacros.begin(), sortedMacros.end());
+
+ return sortedMacros;
+}
+} // namespace
+
+void PreprocessorMacroCollector::add(const ProjectExplorer::Macros &macros)
+{
+ PreprocessorMacros sortedMacros = toSortedMacros(macros);
+ std::sort(sortedMacros.begin(), sortedMacros.end());
+
+ PreprocessorMacros mergedMacros;
+ mergedMacros.reserve(sortedMacros.size() + m_macros.size());
+
+ std::set_union(m_macros.begin(),
+ m_macros.end(),
+ sortedMacros.begin(),
+ sortedMacros.end(),
+ std::back_inserter(mergedMacros));
+
+ m_macros = mergedMacros;
+}
+
+const PreprocessorMacros &PreprocessorMacroCollector::macros() const
+{
+ return m_macros;
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/preprocessormacrocollector.h b/src/plugins/clangpchmanager/preprocessormacrocollector.h
new file mode 100644
index 0000000000..2de2553df3
--- /dev/null
+++ b/src/plugins/clangpchmanager/preprocessormacrocollector.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QString>
+#include <QVector>
+
+#include <projectexplorer/projectmacro.h>
+
+#include <utility>
+
+namespace ClangPchManager {
+
+using PreprocessorMacro = std::pair<QString, QString>;
+using PreprocessorMacros = QVector<PreprocessorMacro>;
+
+class PreprocessorMacroCollector
+{
+public:
+ void add(const ProjectExplorer::Macros &macros);
+
+ const PreprocessorMacros &macros() const;
+
+private:
+ PreprocessorMacros m_macros;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/preprocessormacrowidget.cpp b/src/plugins/clangpchmanager/preprocessormacrowidget.cpp
new file mode 100644
index 0000000000..8ebe45bef8
--- /dev/null
+++ b/src/plugins/clangpchmanager/preprocessormacrowidget.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "preprocessormacrowidget.h"
+#include "clangindexingprojectsettings.h"
+
+#include <utils/detailswidget.h>
+#include <utils/headerviewstretcher.h>
+#include <utils/itemviews.h>
+#include <utils/namevaluedictionary.h>
+#include <utils/namevalueitem.h>
+#include <utils/namevaluemodel.h>
+#include <utils/namevaluesdialog.h>
+#include <utils/namevaluevalidator.h>
+
+#include <coreplugin/find/itemviewfind.h>
+
+#include <QLineEdit>
+#include <QStyledItemDelegate>
+#include <QVBoxLayout>
+
+namespace ClangPchManager {
+
+class ProcessorMacroDelegate : public QStyledItemDelegate
+{
+public:
+ ProcessorMacroDelegate(Utils::NameValueModel *model, QTreeView *view)
+ : QStyledItemDelegate(view)
+ , m_model(model)
+ , m_view(view)
+ {}
+
+ QWidget *createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override
+ {
+ QWidget *w = QStyledItemDelegate::createEditor(parent, option, index);
+ if (index.column() != 0)
+ return w;
+
+ if (auto edit = qobject_cast<QLineEdit *>(w))
+ edit->setValidator(new Utils::NameValueValidator(
+ edit, m_model, m_view, index, PreprocessorMacroWidget::tr("Macro already exists.")));
+ return w;
+ }
+
+private:
+ Utils::NameValueModel *m_model;
+ QTreeView *m_view;
+};
+
+PreprocessorMacroWidget::PreprocessorMacroWidget(QWidget *parent) : QWidget(parent)
+{
+ m_model = std::make_unique<Utils::NameValueModel>();
+ connect(m_model.get(),
+ &Utils::NameValueModel::userChangesChanged,
+ this,
+ &PreprocessorMacroWidget::userChangesChanged);
+ connect(m_model.get(),
+ &QAbstractItemModel::modelReset,
+ this,
+ &PreprocessorMacroWidget::invalidateCurrentIndex);
+
+ connect(m_model.get(), &Utils::NameValueModel::focusIndex, this, &PreprocessorMacroWidget::focusIndex);
+
+ auto vbox = new QVBoxLayout(this);
+ vbox->setContentsMargins(0, 0, 0, 0);
+
+ m_detailsContainer = new Utils::DetailsWidget(this);
+
+ auto details = new QWidget(m_detailsContainer);
+ m_detailsContainer->setWidget(details);
+ details->setVisible(false);
+
+ auto vbox2 = new QVBoxLayout(details);
+ vbox2->setContentsMargins(0, 0, 0, 0);
+
+ auto horizontalLayout = new QHBoxLayout;
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
+ auto tree = new Utils::TreeView(this);
+ connect(tree, &QAbstractItemView::activated, tree, [tree](const QModelIndex &idx) {
+ tree->edit(idx);
+ });
+ m_preprocessorMacrosView = tree;
+ m_preprocessorMacrosView->setModel(m_model.get());
+ m_preprocessorMacrosView->setItemDelegate(
+ new ProcessorMacroDelegate(m_model.get(), m_preprocessorMacrosView));
+ m_preprocessorMacrosView->setMinimumHeight(400);
+ m_preprocessorMacrosView->setRootIsDecorated(false);
+ m_preprocessorMacrosView->setUniformRowHeights(true);
+ new Utils::HeaderViewStretcher(m_preprocessorMacrosView->header(), 1);
+ m_preprocessorMacrosView->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_preprocessorMacrosView->setSelectionBehavior(QAbstractItemView::SelectItems);
+ m_preprocessorMacrosView->setFrameShape(QFrame::NoFrame);
+ QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_preprocessorMacrosView,
+ Core::ItemViewFind::LightColored);
+ findWrapper->setFrameStyle(QFrame::StyledPanel);
+ horizontalLayout->addWidget(findWrapper);
+
+ auto buttonLayout = new QVBoxLayout();
+
+ m_editButton = new QPushButton(this);
+ m_editButton->setText(tr("Ed&it"));
+ buttonLayout->addWidget(m_editButton);
+
+ m_addButton = new QPushButton(this);
+ m_addButton->setText(tr("&Add"));
+ buttonLayout->addWidget(m_addButton);
+
+ m_resetButton = new QPushButton(this);
+ m_resetButton->setEnabled(false);
+ m_resetButton->setText(tr("&Reset"));
+ buttonLayout->addWidget(m_resetButton);
+
+ m_unsetButton = new QPushButton(this);
+ m_unsetButton->setEnabled(false);
+ m_unsetButton->setText(tr("&Unset"));
+ buttonLayout->addWidget(m_unsetButton);
+
+ buttonLayout->addStretch();
+
+ horizontalLayout->addLayout(buttonLayout);
+ vbox2->addLayout(horizontalLayout);
+
+ vbox->addWidget(m_detailsContainer);
+
+ connect(m_model.get(),
+ &QAbstractItemModel::dataChanged,
+ this,
+ &PreprocessorMacroWidget::updateButtons);
+
+ connect(m_editButton, &QAbstractButton::clicked, this, &PreprocessorMacroWidget::editButtonClicked);
+ connect(m_addButton, &QAbstractButton::clicked, this, &PreprocessorMacroWidget::addButtonClicked);
+ connect(m_resetButton, &QAbstractButton::clicked, this, &PreprocessorMacroWidget::removeButtonClicked);
+ connect(m_unsetButton, &QAbstractButton::clicked, this, &PreprocessorMacroWidget::unsetButtonClicked);
+ connect(m_preprocessorMacrosView->selectionModel(),
+ &QItemSelectionModel::currentChanged,
+ this,
+ &PreprocessorMacroWidget::currentIndexChanged);
+ connect(m_detailsContainer,
+ &Utils::DetailsWidget::linkActivated,
+ this,
+ &PreprocessorMacroWidget::linkActivated);
+ connect(m_model.get(),
+ &Utils::NameValueModel::userChangesChanged,
+ this,
+ &PreprocessorMacroWidget::updateSummaryText);
+ connect(m_model.get(),
+ &Utils::NameValueModel::userChangesChanged,
+ this,
+ &PreprocessorMacroWidget::saveSettings);
+}
+
+void PreprocessorMacroWidget::setBasePreprocessorMacros(const PreprocessorMacros &macros)
+{
+ m_model->setUserChanges(m_settings->readMacros());
+ m_model->setBaseNameValueDictionary(Utils::NameValueDictionary{macros});
+}
+
+void PreprocessorMacroWidget::setSettings(ClangIndexingProjectSettings *settings)
+{
+ m_settings = settings;
+}
+
+PreprocessorMacroWidget::~PreprocessorMacroWidget() = default;
+
+void PreprocessorMacroWidget::updateButtons()
+{
+ currentIndexChanged(m_preprocessorMacrosView->currentIndex());
+}
+
+void PreprocessorMacroWidget::focusIndex(const QModelIndex &index)
+{
+ m_preprocessorMacrosView->setCurrentIndex(index);
+ m_preprocessorMacrosView->setFocus();
+
+ m_preprocessorMacrosView->scrollTo(index, QAbstractItemView::PositionAtTop);
+}
+
+void PreprocessorMacroWidget::invalidateCurrentIndex()
+{
+ currentIndexChanged(QModelIndex());
+}
+
+void PreprocessorMacroWidget::editButtonClicked()
+{
+ m_preprocessorMacrosView->edit(m_preprocessorMacrosView->currentIndex());
+}
+
+void PreprocessorMacroWidget::addButtonClicked()
+{
+ QModelIndex index = m_model->addVariable();
+ m_preprocessorMacrosView->setCurrentIndex(index);
+ m_preprocessorMacrosView->edit(index);
+}
+
+void PreprocessorMacroWidget::removeButtonClicked()
+{
+ const QString &name = m_model->indexToVariable(m_preprocessorMacrosView->currentIndex());
+ m_model->resetVariable(name);
+}
+
+void PreprocessorMacroWidget::unsetButtonClicked()
+{
+ const QString &name = m_model->indexToVariable(m_preprocessorMacrosView->currentIndex());
+ if (!m_model->canReset(name))
+ m_model->resetVariable(name);
+ else
+ m_model->unsetVariable(name);
+}
+
+void PreprocessorMacroWidget::currentIndexChanged(const QModelIndex &current)
+{
+ if (current.isValid()) {
+ m_editButton->setEnabled(true);
+ const QString &name = m_model->indexToVariable(current);
+ bool modified = m_model->canReset(name) && m_model->changes(name);
+ bool unset = m_model->isUnset(name);
+ m_resetButton->setEnabled(modified || unset);
+ m_unsetButton->setEnabled(!unset);
+ } else {
+ m_editButton->setEnabled(false);
+ m_resetButton->setEnabled(false);
+ m_unsetButton->setEnabled(false);
+ }
+}
+
+void PreprocessorMacroWidget::linkActivated(const QString &link)
+{
+ m_detailsContainer->setState(Utils::DetailsWidget::Expanded);
+ QModelIndex idx = m_model->variableToIndex(link);
+ focusIndex(idx);
+}
+
+void PreprocessorMacroWidget::updateSummaryText()
+{
+ Utils::NameValueItems items = m_model->userChanges();
+ Utils::NameValueItem::sort(&items);
+
+ QString text;
+ for (const Utils::EnvironmentItem &item : items) {
+ if (item.name != Utils::NameValueModel::tr("<VARIABLE>")) {
+ text.append(QLatin1String("<br>"));
+ if (item.operation == Utils::NameValueItem::Unset)
+ text.append(tr("Unset <a href=\"%1\"><b>%1</b></a>").arg(item.name.toHtmlEscaped()));
+ else
+ text.append(tr("Set <a href=\"%1\"><b>%1</b></a> to <b>%2</b>")
+ .arg(item.name.toHtmlEscaped(), item.value.toHtmlEscaped()));
+ }
+ }
+
+ m_detailsContainer->setSummaryText(text);
+}
+
+void PreprocessorMacroWidget::saveSettings()
+{
+ m_settings->saveMacros(m_model->userChanges());
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/preprocessormacrowidget.h b/src/plugins/clangpchmanager/preprocessormacrowidget.h
new file mode 100644
index 0000000000..0c4c01545c
--- /dev/null
+++ b/src/plugins/clangpchmanager/preprocessormacrowidget.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QPushButton>
+#include <QTreeView>
+
+#include <memory>
+
+namespace Utils {
+class DetailsWidget;
+class NameValueModel;
+} // namespace Utils
+
+namespace ClangPchManager {
+class ClangIndexingProjectSettings;
+using PreprocessorMacro = std::pair<QString, QString>;
+using PreprocessorMacros = QVector<PreprocessorMacro>;
+
+class PreprocessorMacroWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PreprocessorMacroWidget(QWidget *parent = nullptr);
+ ~PreprocessorMacroWidget() override;
+ void setBasePreprocessorMacros(const PreprocessorMacros &macros);
+ void setSettings(ClangIndexingProjectSettings *settings);
+
+signals:
+ void userChangesChanged();
+
+private:
+ void updateButtons();
+ void focusIndex(const QModelIndex &index);
+ void invalidateCurrentIndex();
+ void editButtonClicked();
+ void addButtonClicked();
+ void removeButtonClicked();
+ void unsetButtonClicked();
+ void currentIndexChanged(const QModelIndex &current);
+ void linkActivated(const QString &link);
+ void updateSummaryText();
+ void saveSettings();
+
+private:
+ std::unique_ptr<Utils::NameValueModel> m_model;
+ Utils::DetailsWidget *m_detailsContainer;
+ QTreeView *m_preprocessorMacrosView;
+ QPushButton *m_editButton;
+ QPushButton *m_addButton;
+ QPushButton *m_resetButton;
+ QPushButton *m_unsetButton;
+ ClangIndexingProjectSettings *m_settings = {};
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
index 3d340aea88..e006357e0c 100644
--- a/src/plugins/clangpchmanager/projectupdater.cpp
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -27,6 +27,8 @@
#include "pchmanagerclient.h"
+#include <clangindexingprojectsettings.h>
+#include <clangindexingsettingsmanager.h>
#include <filepathid.h>
#include <pchmanagerserverinterface.h>
#include <removegeneratedfilesmessage.h>
@@ -42,9 +44,13 @@
#include <projectexplorer/buildconfiguration.h>
#include <utils/algorithm.h>
+#include <utils/namevalueitem.h>
+
+#include <QDirIterator>
#include <algorithm>
#include <functional>
+#include <iostream>
namespace ClangPchManager {
@@ -64,8 +70,12 @@ public:
void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
Utils::SmallStringVector &&toolChainArguments)
{
- m_server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{
- toProjectPartContainers(projectParts), std::move(toolChainArguments)});
+ addProjectFilesToFilePathCache(projectParts);
+ fetchProjectPartIds(projectParts);
+
+ m_server.updateProjectParts(
+ ClangBackEnd::UpdateProjectPartsMessage{toProjectPartContainers(projectParts),
+ std::move(toolChainArguments)});
}
void ProjectUpdater::removeProjectParts(ClangBackEnd::ProjectPartIds projectPartIds)
@@ -175,9 +185,63 @@ void cleanupMacros(ClangBackEnd::CompilerMacros &macros)
macros.erase(newEnd, macros.end());
}
+
+void updateWithSettings(ClangBackEnd::CompilerMacros &macros,
+ Utils::NameValueItems &&settingsItems,
+ int &index)
+{
+ std::sort(settingsItems.begin(), settingsItems.end(), [](const auto &first, const auto &second) {
+ return std::tie(first.operation, first.name, first.value)
+ < std::tie(first.operation, second.name, second.value);
+ });
+
+ auto point = std::partition_point(settingsItems.begin(), settingsItems.end(), [](const auto &entry) {
+ return entry.operation == Utils::NameValueItem::SetEnabled;
+ });
+
+ std::transform(
+ settingsItems.begin(),
+ point,
+ std::back_inserter(macros),
+ [&](const Utils::NameValueItem &settingsMacro) {
+ return ClangBackEnd::CompilerMacro{settingsMacro.name, settingsMacro.value, ++index};
+ });
+
+ std::sort(macros.begin(), macros.end(), [](const auto &first, const auto &second) {
+ return std::tie(first.key, first.value) < std::tie(second.key, second.value);
+ });
+
+ ClangBackEnd::CompilerMacros result;
+ result.reserve(macros.size());
+
+ ClangBackEnd::CompilerMacros convertedSettingsMacros;
+ convertedSettingsMacros.resize(std::distance(point, settingsItems.end()));
+ std::transform(
+ point,
+ settingsItems.end(),
+ std::back_inserter(convertedSettingsMacros),
+ [&](const Utils::NameValueItem &settingsMacro) {
+ return ClangBackEnd::CompilerMacro{settingsMacro.name, settingsMacro.value, ++index};
+ });
+
+ std::set_difference(macros.begin(),
+ macros.end(),
+ convertedSettingsMacros.begin(),
+ convertedSettingsMacros.end(),
+ std::back_inserter(result),
+ [](const ClangBackEnd::CompilerMacro &first,
+ const ClangBackEnd::CompilerMacro &second) {
+ return std::tie(first.key, first.value)
+ < std::tie(second.key, second.value);
+ });
+
+ macros = std::move(result);
+}
+
} // namespace
-ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectExplorer::Macros &projectMacros)
+ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(
+ const ProjectExplorer::Macros &projectMacros, Utils::NameValueItems &&settingsMacros)
{
int index = 0;
auto macros = Utils::transform<ClangBackEnd::CompilerMacros>(
@@ -186,6 +250,7 @@ ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectE
});
cleanupMacros(macros);
+ updateWithSettings(macros, std::move(settingsMacros), index);
std::sort(macros.begin(), macros.end());
@@ -286,14 +351,17 @@ ClangBackEnd::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
- const QByteArray projectPartName = projectPart->id().toUtf8();
+ ClangBackEnd::ProjectPartId projectPartId = m_projectPartIdCache.stringId(
+ Utils::PathString{projectPart->id()}, [&](Utils::SmallStringView projectPartName) {
+ return m_projectPartsStorage.fetchProjectPartId(projectPartName);
+ });
- ClangBackEnd::ProjectPartId projectPartId = m_projectPartsStorage.fetchProjectPartId(
- projectPartName);
+ ClangIndexingProjectSettings *settings = m_settingsManager.settings(projectPart->project);
return ClangBackEnd::ProjectPartContainer(projectPartId,
Utils::SmallStringVector(arguments),
- createCompilerMacros(projectPart->projectMacros),
+ createCompilerMacros(projectPart->projectMacros,
+ settings->readMacros()),
std::move(includeSearchPaths.system),
std::move(includeSearchPaths.project),
std::move(headerAndSources.headers),
@@ -351,24 +419,63 @@ ClangBackEnd::FilePaths ProjectUpdater::createExcludedPaths(
QString ProjectUpdater::fetchProjectPartName(ClangBackEnd::ProjectPartId projectPartId) const
{
- return m_projectPartsStorage.fetchProjectPartName(projectPartId).toQString();
+ return QString(m_projectPartIdCache.string(projectPartId.projectPathId,
+ [&](ClangBackEnd::ProjectPartId projectPartId) {
+ return m_projectPartsStorage.fetchProjectPartName(
+ projectPartId);
+ }));
}
ClangBackEnd::ProjectPartIds ProjectUpdater::toProjectPartIds(
- const QStringList &projectPartNames) const
+ const QStringList &projectPartNamesAsQString) const
{
ClangBackEnd::ProjectPartIds projectPartIds;
projectPartIds.reserve(projectPartIds.size());
- std::transform(projectPartNames.begin(),
- projectPartNames.end(),
- std::back_inserter(projectPartIds),
- [&](const QString &projectPartName) {
- return m_projectPartsStorage.fetchProjectPartId(
- Utils::SmallString{projectPartName});
- });
+ auto projectPartNames = Utils::transform<std::vector<Utils::PathString>>(
+ projectPartNamesAsQString, [&](const QString &projectPartName) { return projectPartName; });
+
+ return m_projectPartIdCache.stringIds(projectPartNames, [&](Utils::SmallStringView projectPartName) {
+ return m_projectPartsStorage.fetchProjectPartId(projectPartName);
+ });
+}
+
+void ProjectUpdater::addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts)
+{
+ ClangBackEnd::FilePaths filePaths;
+ filePaths.reserve(10000);
+
+ for (CppTools::ProjectPart *projectPart : projectParts) {
+ for (const CppTools::ProjectFile &file : projectPart->files)
+ if (file.active)
+ filePaths.emplace_back(file.path);
+ }
- return projectPartIds;
+ m_filePathCache.addFilePaths(filePaths);
}
+void ProjectUpdater::fetchProjectPartIds(const std::vector<CppTools::ProjectPart *> &projectParts)
+{
+ std::unique_ptr<Sqlite::DeferredTransaction> transaction;
+
+ auto projectPartNames = Utils::transform<std::vector<Utils::PathString>>(
+ projectParts, [](CppTools::ProjectPart *projectPart) { return projectPart->id(); });
+
+ auto projectPartNameViews = Utils::transform<std::vector<Utils::SmallStringView>>(
+ projectPartNames,
+ [](const Utils::PathString &projectPartName) { return projectPartName.toStringView(); });
+
+ m_projectPartIdCache
+ .addStrings(std::move(projectPartNameViews), [&](Utils::SmallStringView projectPartName) {
+ if (!transaction)
+ transaction = std::make_unique<Sqlite::DeferredTransaction>(
+ m_projectPartsStorage.transactionBackend());
+ return m_projectPartsStorage.fetchProjectPartIdUnguarded(projectPartName);
+ });
+
+ if (transaction)
+ transaction->commit();
+
+} // namespace ClangPchManager
+
} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.h b/src/plugins/clangpchmanager/projectupdater.h
index 044b86f637..16d662004f 100644
--- a/src/plugins/clangpchmanager/projectupdater.h
+++ b/src/plugins/clangpchmanager/projectupdater.h
@@ -34,9 +34,13 @@
#include <includesearchpath.h>
#include <projectpartcontainer.h>
#include <projectpartsstorageinterface.h>
+#include <projectpartstoragestructs.h>
+#include <stringcache.h>
#include <projectexplorer/headerpath.h>
+#include <utils/environmentfwd.h>
+
namespace ProjectExplorer {
class Macro;
using Macros = QVector<Macro>;
@@ -59,9 +63,19 @@ namespace ClangPchManager {
class HeaderAndSources;
class PchManagerClient;
+class ClangIndexingSettingsManager;
+class ClangIndexingProjectSettings;
class CLANGPCHMANAGER_EXPORT ProjectUpdater
{
+ using StringCache = ClangBackEnd::StringCache<Utils::PathString,
+ Utils::SmallStringView,
+ ClangBackEnd::ProjectPartId,
+ ClangBackEnd::NonLockingMutex,
+ decltype(&Utils::reverseCompare),
+ Utils::reverseCompare,
+ ClangBackEnd::Internal::ProjectPartNameId>;
+
public:
struct SystemAndProjectIncludeSearchPaths
{
@@ -71,11 +85,15 @@ public:
ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
ClangBackEnd::FilePathCachingInterface &filePathCache,
- ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
- : m_server(server)
- , m_filePathCache(filePathCache)
+ ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
+ ClangIndexingSettingsManager &settingsManager)
+ : m_filePathCache(filePathCache)
+ , m_server(server)
, m_projectPartsStorage(projectPartsStorage)
- {}
+ , m_settingsManager(settingsManager)
+ {
+ m_projectPartIdCache.populate(m_projectPartsStorage.fetchAllProjectPartNamesAndIds());
+ }
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
Utils::SmallStringVector &&toolChainArguments);
@@ -98,8 +116,8 @@ public:
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
const CppTools::ProjectFile &projectFile) const;
static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
- static ClangBackEnd::CompilerMacros createCompilerMacros(
- const ProjectExplorer::Macros &projectMacros);
+ static ClangBackEnd::CompilerMacros createCompilerMacros(const ProjectExplorer::Macros &projectMacros,
+ Utils::NameValueItems &&settingsMacros);
static SystemAndProjectIncludeSearchPaths createIncludeSearchPaths(
const CppTools::ProjectPart &projectPart);
static ClangBackEnd::FilePaths createExcludedPaths(
@@ -109,12 +127,19 @@ public:
ClangBackEnd::ProjectPartIds toProjectPartIds(const QStringList &projectPartNames) const;
+ void addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts);
+ void fetchProjectPartIds(const std::vector<CppTools::ProjectPart *> &projectParts);
+
+protected:
+ ClangBackEnd::FilePathCachingInterface &m_filePathCache;
+
private:
ClangBackEnd::GeneratedFiles m_generatedFiles;
ClangBackEnd::FilePaths m_excludedPaths;
ClangBackEnd::ProjectManagementServerInterface &m_server;
- ClangBackEnd::FilePathCachingInterface &m_filePathCache;
ClangBackEnd::ProjectPartsStorageInterface &m_projectPartsStorage;
+ ClangIndexingSettingsManager &m_settingsManager;
+ mutable StringCache m_projectPartIdCache;
};
} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
index 5331e2ef05..9a3b1498cc 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
@@ -29,6 +29,8 @@
#include <projectexplorer/project.h>
+#include <filepathcachinginterface.h>
+
namespace ClangPchManager {
namespace Internal {
@@ -38,16 +40,21 @@ CppTools::CppModelManager *cppModelManager()
return CppTools::CppModelManager::instance();
}
-std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
+std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
+ ClangBackEnd::FilePathCachingInterface &filePathCache)
{
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
generatedFiles.reserve(std::size_t(abstractEditors.size()));
- auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
- return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
- Utils::SmallString::fromQByteArray(abstractEditor->contents()),
- {});
+ auto toFileContainer = [&](const CppTools::AbstractEditorSupport *abstractEditor) {
+ ClangBackEnd::FilePath filePath(abstractEditor->fileName());
+ ClangBackEnd::FilePathId filePathId = filePathCache.filePathId(filePath);
+ return ClangBackEnd::V2::FileContainer(std::move(filePath),
+ filePathId,
+ Utils::SmallString::fromQByteArray(
+ abstractEditor->contents()),
+ {});
};
std::transform(abstractEditors.begin(),
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
index 1cdef70b79..1cada833e7 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
@@ -32,6 +32,8 @@
#include <filecontainerv2.h>
+#include <utils/algorithm.h>
+
#include <QObject>
namespace ProjectExplorer {
@@ -46,7 +48,8 @@ namespace ClangPchManager {
namespace Internal {
CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
-CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles();
+CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
+ ClangBackEnd::FilePathCachingInterface &filePathCache);
CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
}
@@ -59,8 +62,9 @@ public:
QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
ClientType &client,
ClangBackEnd::FilePathCachingInterface &filePathCache,
- ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
- : ProjectUpdaterType(server, client, filePathCache, projectPartsStorage)
+ ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
+ ClangIndexingSettingsManager &settingsManager)
+ : ProjectUpdaterType(server, client, filePathCache, projectPartsStorage, settingsManager)
{
connectToCppModelManager();
}
@@ -74,7 +78,6 @@ public:
void projectPartsUpdated(ProjectExplorer::Project *project)
{
-
ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project), {}); // TODO add support for toolchainarguments
}
@@ -83,9 +86,13 @@ public:
ProjectUpdaterType::removeProjectParts(projectPartIds);
}
- void abstractEditorUpdated(const QString &filePath, const QByteArray &contents)
+ void abstractEditorUpdated(const QString &qFilePath, const QByteArray &contents)
{
- ProjectUpdaterType::updateGeneratedFiles({{ClangBackEnd::FilePath{filePath}, contents}});
+ ClangBackEnd::FilePath filePath{qFilePath};
+ ClangBackEnd::FilePathId filePathId = ProjectUpdaterType::m_filePathCache.filePathId(
+ filePath);
+
+ ProjectUpdaterType::updateGeneratedFiles({{std::move(filePath), filePathId, contents}});
}
void abstractEditorRemoved(const QString &filePath)
@@ -98,6 +105,14 @@ protected:
const Utils::FilePath &,
const Utils::FilePathList &targets) override
{
+ auto filePaths = Utils::transform<ClangBackEnd::FilePaths>(targets,
+ [](const Utils::FilePath &filePath) {
+ return ClangBackEnd::FilePath{
+ filePath.toString()};
+ });
+
+ ProjectUpdater::m_filePathCache.addFilePaths(filePaths);
+
for (const Utils::FilePath &target : targets)
abstractEditorUpdated(target.toString(), {});
}
@@ -105,7 +120,8 @@ protected:
private:
void connectToCppModelManager()
{
- ProjectUpdaterType::updateGeneratedFiles(Internal::createGeneratedFiles());
+ ProjectUpdaterType::updateGeneratedFiles(
+ Internal::createGeneratedFiles(ProjectUpdaterType::m_filePathCache));
QObject::connect(Internal::cppModelManager(),
&CppTools::CppModelManager::projectPartsUpdated,
diff --git a/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp b/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp
index 3e60919e32..cb9d64fe42 100644
--- a/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp
+++ b/src/plugins/clangrefactoring/clangqueryhoverhandler.cpp
@@ -53,8 +53,8 @@ void ClangQueryHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorW
int line = textCursor.blockNumber() + 1;
int column = textCursor.columnNumber() + 1;
- Messages messages = m_highligher->messagesForLineAndColumn(uint(line), uint(column));
- Contexts contexts = m_highligher->contextsForLineAndColumn(uint(line), uint(column));
+ Messages messages = m_highligher->messagesForLineAndColumn(line, column);
+ Contexts contexts = m_highligher->contextsForLineAndColumn(line, column);
if (!messages.empty())
setToolTip(QString("%1: %2").arg(QString(messages[0].errorTypeText())).arg(QString(messages[0].arguments.join(", "))));
diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
index 46a18376dd..f60aaff6e8 100644
--- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
+++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.cpp
@@ -82,10 +82,9 @@ void ClangQueryProjectsFindFilter::requestSourceRangesAndDiagnostics(const QStri
{
const QString filePath = temporaryFile.fileName();
- ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(queryText,
- {ClangBackEnd::FilePath(filePath),
- exampleContent,
- {"cc", "-std=c++1z", toNative(filePath)}});
+ ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage message(
+ queryText,
+ {ClangBackEnd::FilePath(filePath), 1, exampleContent, {"cc", "-std=c++1z", toNative(filePath)}});
m_server.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message));
}
@@ -119,7 +118,7 @@ bool ClangQueryProjectsFindFilter::showSearchTermInput() const
Core::FindFlags ClangQueryProjectsFindFilter::supportedFindFlags() const
{
- return 0;
+ return nullptr;
}
void ClangQueryProjectsFindFilter::setProjectParts(const std::vector<CppTools::ProjectPart::Ptr> &projectParts)
@@ -204,10 +203,9 @@ void appendSource(std::vector<ClangBackEnd::V2::FileContainer> &sources,
if (!unsavedContentContains(sourceFilePath, unsavedContent) && !isCHeader(projectFile.kind)) {
sources.emplace_back(ClangBackEnd::FilePath(projectFile.path),
+ -1,
"",
- createCommandLine(projectPart.data(),
- projectFile.path,
- projectFile.kind));
+ createCommandLine(projectPart.data(), projectFile.path, projectFile.kind));
}
}
diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h
index c8558e5286..2d36caed2e 100644
--- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h
+++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.h
@@ -62,7 +62,7 @@ public:
bool isEnabled() const override;
void requestSourceRangesAndDiagnostics(const QString &queryText, const QString &exampleContent);
SearchHandle *find(const QString &queryText);
- void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override;
+ void findAll(const QString &queryText, Core::FindFlags findFlags = nullptr) override;
bool showSearchTermInput() const override;
Core::FindFlags supportedFindFlags() const override;
diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
index d33e4e2b88..4f7d34d800 100644
--- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
+++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
@@ -42,8 +42,8 @@
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
-#include <extensionsystem/pluginmanager.h>
#include <cpptools/cpptoolsconstants.h>
+#include <extensionsystem/pluginmanager.h>
#include <refactoringdatabaseinitializer.h>
#include <filepathcaching.h>
@@ -99,16 +99,13 @@ public:
QtCreatorRefactoringProjectUpdater projectUpdate{connectionClient.serverProxy(),
ClangPchManagerPlugin::pchManagerClient(),
filePathCache,
- projectPartsStorage};
+ projectPartsStorage,
+ ClangPchManagerPlugin::settingsManager()};
};
-ClangRefactoringPlugin::ClangRefactoringPlugin()
-{
-}
+ClangRefactoringPlugin::ClangRefactoringPlugin() = default;
-ClangRefactoringPlugin::~ClangRefactoringPlugin()
-{
-}
+ClangRefactoringPlugin::~ClangRefactoringPlugin() = default;
static bool useClangFilters()
{
@@ -126,8 +123,8 @@ bool ClangRefactoringPlugin::initialize(const QStringList & /*arguments*/, QStri
connectBackend();
startBackend();
- CppTools::CppModelManager::addRefactoringEngine(
- CppTools::RefactoringEngineType::ClangRefactoring, &refactoringEngine());
+ CppTools::CppModelManager::addRefactoringEngine(CppTools::RefactoringEngineType::ClangRefactoring,
+ &refactoringEngine());
initializeFilters();
diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp
index 05c378b196..e3dc7ee4e8 100644
--- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp
+++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.cpp
@@ -108,10 +108,12 @@ std::vector<ClangBackEnd::V2::FileContainer> createUnsavedContents()
std::vector<ClangBackEnd::V2::FileContainer> unsavedContents;
unsavedContents.reserve(std::size_t(abstractEditors.size()));
- auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
- return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
- Utils::SmallString::fromQByteArray(abstractEditor->contents()),
- {});
+ auto toFileContainer = [](const CppTools::AbstractEditorSupport *abstractEditor) {
+ return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
+ -1,
+ Utils::SmallString::fromQByteArray(
+ abstractEditor->contents()),
+ {});
};
std::transform(abstractEditors.begin(),
diff --git a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h
index aa53cd6fd7..23825c6228 100644
--- a/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h
+++ b/src/plugins/clangrefactoring/qtcreatorclangqueryfindfilter.h
@@ -40,7 +40,7 @@ public:
SearchInterface &m_searchInterface,
RefactoringClient &m_refactoringClient);
- void findAll(const QString &queryText, Core::FindFlags findFlags = 0) override;
+ void findAll(const QString &queryText, Core::FindFlags findFlags = nullptr) override;
void handleQueryOrExampleTextChanged();
diff --git a/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.cpp b/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.cpp
index dea3ccfeec..415186d555 100644
--- a/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.cpp
+++ b/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.cpp
@@ -37,16 +37,21 @@ CppTools::CppModelManager *cppModelManager()
return CppTools::CppModelManager::instance();
}
-std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
+std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
+ ClangBackEnd::FilePathCachingInterface &filePathCache)
{
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
generatedFiles.reserve(std::size_t(abstractEditors.size()));
- auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
- return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
- Utils::SmallString::fromQByteArray(abstractEditor->contents()),
- {});
+ auto toFileContainer = [&](const CppTools::AbstractEditorSupport *abstractEditor) {
+ ClangBackEnd::FilePath filePath{abstractEditor->fileName()};
+ ClangBackEnd::FilePathId filePathId = filePathCache.filePathId(filePath);
+ return ClangBackEnd::V2::FileContainer(std::move(filePath),
+ filePathId,
+ Utils::SmallString::fromQByteArray(
+ abstractEditor->contents()),
+ {});
};
std::transform(abstractEditors.begin(),
@@ -64,19 +69,24 @@ QtCreatorRefactoringProjectUpdater::QtCreatorRefactoringProjectUpdater(
ClangBackEnd::ProjectManagementServerInterface &server,
ClangPchManager::PchManagerClient &pchManagerClient,
ClangBackEnd::FilePathCachingInterface &filePathCache,
- ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
+ ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
+ ClangPchManager::ClangIndexingSettingsManager &settingsManager)
: RefactoringProjectUpdater(server,
pchManagerClient,
*cppModelManager(),
filePathCache,
- projectPartsStorage)
+ projectPartsStorage,
+ settingsManager)
{
connectToCppModelManager();
}
-void QtCreatorRefactoringProjectUpdater::abstractEditorUpdated(const QString &filePath, const QByteArray &contents)
+void QtCreatorRefactoringProjectUpdater::abstractEditorUpdated(const QString &qFilePath,
+ const QByteArray &contents)
{
- RefactoringProjectUpdater::updateGeneratedFiles({{ClangBackEnd::FilePath{filePath}, contents}});
+ ClangBackEnd::FilePath filePath{qFilePath};
+ ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(filePath);
+ RefactoringProjectUpdater::updateGeneratedFiles({{std::move(filePath), filePathId, contents}});
}
void QtCreatorRefactoringProjectUpdater::abstractEditorRemoved(const QString &filePath)
@@ -86,7 +96,7 @@ void QtCreatorRefactoringProjectUpdater::abstractEditorRemoved(const QString &fi
void QtCreatorRefactoringProjectUpdater::connectToCppModelManager()
{
- RefactoringProjectUpdater::updateGeneratedFiles(createGeneratedFiles());
+ RefactoringProjectUpdater::updateGeneratedFiles(createGeneratedFiles(m_filePathCache));
QObject::connect(cppModelManager(),
&CppTools::CppModelManager::abstractEditorSupportContentsUpdated,
diff --git a/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.h b/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.h
index 85d635a3af..7fd16afa16 100644
--- a/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.h
+++ b/src/plugins/clangrefactoring/qtcreatorrefactoringprojectupdater.h
@@ -32,11 +32,11 @@ namespace ClangRefactoring {
class QtCreatorRefactoringProjectUpdater final : public RefactoringProjectUpdater
{
public:
- QtCreatorRefactoringProjectUpdater(
- ClangBackEnd::ProjectManagementServerInterface &server,
- ClangPchManager::PchManagerClient &pchManagerClient,
- ClangBackEnd::FilePathCachingInterface &filePathCache,
- ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage);
+ QtCreatorRefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+ ClangPchManager::PchManagerClient &pchManagerClient,
+ ClangBackEnd::FilePathCachingInterface &filePathCache,
+ ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
+ ClangPchManager::ClangIndexingSettingsManager &settingsManager);
private:
void abstractEditorUpdated(const QString &filePath, const QByteArray &contents);
diff --git a/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp b/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp
index 3cc4a96a44..f4fe42d193 100644
--- a/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp
+++ b/src/plugins/clangrefactoring/qtcreatorsearchhandle.cpp
@@ -35,7 +35,7 @@ QtCreatorSearchHandle::QtCreatorSearchHandle(Core::SearchResult *searchResult)
: searchResult(searchResult)
{
auto title = QCoreApplication::translate("QtCreatorSearchHandle", "Clang Query");
- Core::ProgressManager::addTask(promise.future(), title, "clang query", 0);
+ Core::ProgressManager::addTask(promise.future(), title, "clang query", nullptr);
}
void QtCreatorSearchHandle::addResult(const QString &fileName,
diff --git a/src/plugins/clangrefactoring/querysqlitestatementfactory.h b/src/plugins/clangrefactoring/querysqlitestatementfactory.h
index 14fc27149d..65d8289579 100644
--- a/src/plugins/clangrefactoring/querysqlitestatementfactory.h
+++ b/src/plugins/clangrefactoring/querysqlitestatementfactory.h
@@ -47,7 +47,20 @@ public:
ReadStatement selectSourceUsagesForSymbolLocation{
"SELECT directoryPath || '/' || sourceName, line, column "
"FROM locations NATURAL JOIN sources NATURAL JOIN directories "
- "WHERE symbolId = (SELECT symbolId FROM locations WHERE sourceId=? AND line=? AND column=?)",
+ "WHERE symbolId = (SELECT symbolId FROM locations WHERE sourceId=? AND line=? AND "
+ "column=?)",
+ database};
+ ReadStatement selectSourceUsagesOrderedForSymbolLocation{
+ "SELECT directoryPath || '/' || sourceName, line, column "
+ "FROM locations NATURAL JOIN sources NATURAL JOIN directories "
+ "WHERE symbolId = (SELECT symbolId FROM locations WHERE sourceId=? AND line=? AND "
+ "column=?) ORDER BY locationKind LIMIT 2",
+ database};
+ ReadStatement selectSourceUsagesByLocationKindForSymbolLocation{
+ "SELECT directoryPath || '/' || sourceName, line, column "
+ "FROM locations NATURAL JOIN sources NATURAL JOIN directories "
+ "WHERE symbolId = (SELECT symbolId FROM locations WHERE sourceId=? AND line=? AND "
+ "column=?) AND locationKind = ?",
database};
ReadStatement selectSymbolsForKindAndStartsWith{
"SELECT symbolId, symbolName, signature FROM symbols WHERE symbolKind = ? AND symbolName LIKE ?",
diff --git a/src/plugins/clangrefactoring/refactoringengine.cpp b/src/plugins/clangrefactoring/refactoringengine.cpp
index cc9121331d..6b5546cc88 100644
--- a/src/plugins/clangrefactoring/refactoringengine.cpp
+++ b/src/plugins/clangrefactoring/refactoringengine.cpp
@@ -68,7 +68,8 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &,
CppTools::Usages RefactoringEngine::locationsAt(const CppTools::CursorInEditor &data) const
{
- CppTools::Usages usages;
+ if (data.cursor().isNull())
+ return {};
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
Utils::OptionalLineColumn lineColumn = Utils::Text::convertPosition(cursor.document(),
@@ -78,10 +79,30 @@ CppTools::Usages RefactoringEngine::locationsAt(const CppTools::CursorInEditor &
const QByteArray filePath = data.filePath().toString().toUtf8();
const ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(ClangBackEnd::FilePathView(filePath));
- usages = m_symbolQuery.sourceUsagesAt(filePathId, lineColumn->line, lineColumn->column);
+ return m_symbolQuery.sourceUsagesAt(filePathId, lineColumn->line, lineColumn->column);
}
- return usages;
+ return {};
+}
+
+CppTools::Usages RefactoringEngine::declarationAt(const CppTools::CursorInEditor &data) const
+{
+ if (data.cursor().isNull())
+ return {};
+
+ QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
+ Utils::OptionalLineColumn lineColumn = Utils::Text::convertPosition(cursor.document(),
+ cursor.position());
+
+ if (lineColumn) {
+ const QByteArray filePath = data.filePath().toString().toUtf8();
+ const ClangBackEnd::FilePathId filePathId = m_filePathCache.filePathId(
+ ClangBackEnd::FilePathView(filePath));
+
+ return m_symbolQuery.declarationsAt(filePathId, lineColumn->line, lineColumn->column);
+ }
+
+ return {};
}
void RefactoringEngine::globalRename(const CppTools::CursorInEditor &data,
@@ -104,16 +125,13 @@ void RefactoringEngine::globalFollowSymbol(const CppTools::CursorInEditor &data,
CppTools::SymbolFinder *,
bool) const
{
- // TODO: replace that with specific followSymbol query
- const CppTools::Usages usages = locationsAt(data);
+ const CppTools::Usages usages = declarationAt(data);
CppTools::Usage usage = Utils::findOrDefault(usages, [&data](const CppTools::Usage &usage) {
- // We've already searched in the current file, skip it.
- if (usage.path == data.filePath().toString())
- return false;
- return true;
+ return usage.path != data.filePath().toString();
+
});
- processLinkCallback(Link(usage.path, usage.line, usage.column));
+ processLinkCallback(Link(usage.path, usage.line, usage.column - 1));
}
bool RefactoringEngine::isRefactoringEngineAvailable() const
diff --git a/src/plugins/clangrefactoring/refactoringengine.h b/src/plugins/clangrefactoring/refactoringengine.h
index 739b545310..4dfef3ba0c 100644
--- a/src/plugins/clangrefactoring/refactoringengine.h
+++ b/src/plugins/clangrefactoring/refactoringengine.h
@@ -74,6 +74,7 @@ public:
private:
CppTools::Usages locationsAt(const CppTools::CursorInEditor &data) const;
+ CppTools::Usages declarationAt(const CppTools::CursorInEditor &data) const;
ClangBackEnd::RefactoringServerInterface &m_server;
ClangBackEnd::RefactoringClientInterface &m_client;
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.h b/src/plugins/clangrefactoring/refactoringprojectupdater.h
index 0986e35cb0..01e96cb0a4 100644
--- a/src/plugins/clangrefactoring/refactoringprojectupdater.h
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.h
@@ -40,8 +40,9 @@ public:
ClangPchManager::PchManagerClient &pchManagerClient,
CppTools::CppModelManagerInterface &cppModelManager,
ClangBackEnd::FilePathCachingInterface &filePathCache,
- ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage)
- : ClangPchManager::ProjectUpdater(server, filePathCache, projectPartsStorage)
+ ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
+ ClangPchManager::ClangIndexingSettingsManager &settingsManager)
+ : ClangPchManager::ProjectUpdater(server, filePathCache, projectPartsStorage, settingsManager)
, ClangPchManager::PchManagerNotifierInterface(pchManagerClient)
, m_cppModelManager(cppModelManager)
{
diff --git a/src/plugins/clangrefactoring/symbolquery.h b/src/plugins/clangrefactoring/symbolquery.h
index b5a46ab7e6..2468369c82 100644
--- a/src/plugins/clangrefactoring/symbolquery.h
+++ b/src/plugins/clangrefactoring/symbolquery.h
@@ -75,6 +75,36 @@ public:
utf8Column);
}
+ CppTools::Usages sourceUsagesAtByLocationKind(ClangBackEnd::FilePathId filePathId,
+ int line,
+ int utf8Column,
+ ClangBackEnd::SourceLocationKind kind) const override
+ {
+ ReadStatement &locationsStatement = m_statementFactory.selectSourceUsagesByLocationKindForSymbolLocation;
+
+ const std::size_t reserveSize = 128;
+
+ return locationsStatement.template values<CppTools::Usage, 3>(reserveSize,
+ filePathId.filePathId,
+ line,
+ utf8Column,
+ int(kind));
+ }
+
+ CppTools::Usages declarationsAt(ClangBackEnd::FilePathId filePathId,
+ int line,
+ int utf8Column) const override
+ {
+ ReadStatement &locationsStatement = m_statementFactory.selectSourceUsagesOrderedForSymbolLocation;
+
+ const std::size_t reserveSize = 128;
+
+ return locationsStatement.template values<CppTools::Usage, 3>(reserveSize,
+ filePathId.filePathId,
+ line,
+ utf8Column);
+ }
+
Symbols symbolsWithOneSymbolKinds(ClangBackEnd::SymbolKind symbolKind,
Utils::SmallStringView searchTerm) const
{
diff --git a/src/plugins/clangrefactoring/symbolqueryinterface.h b/src/plugins/clangrefactoring/symbolqueryinterface.h
index 568d26568f..6ea6c97304 100644
--- a/src/plugins/clangrefactoring/symbolqueryinterface.h
+++ b/src/plugins/clangrefactoring/symbolqueryinterface.h
@@ -46,10 +46,17 @@ public:
virtual CppTools::Usages sourceUsagesAt(ClangBackEnd::FilePathId filePathId,
int line,
int utf8Column) const = 0;
+ virtual CppTools::Usages sourceUsagesAtByLocationKind(ClangBackEnd::FilePathId filePathId,
+ int line,
+ int utf8Column,
+ ClangBackEnd::SourceLocationKind) const = 0;
virtual Symbols symbols(const ClangBackEnd::SymbolKinds &symbolKinds,
Utils::SmallStringView searchTerm) const = 0;
virtual Utils::optional<SourceLocation> locationForSymbolId(SymbolId symbolId,
ClangBackEnd::SourceLocationKind kind) const = 0;
+ virtual CppTools::Usages declarationsAt(ClangBackEnd::FilePathId filePathId,
+ int line,
+ int utf8Column) const = 0;
protected:
~SymbolQueryInterface() = default;
diff --git a/src/plugins/clangtools/CMakeLists.txt b/src/plugins/clangtools/CMakeLists.txt
index 9e767418f0..93195bdfb9 100644
--- a/src/plugins/clangtools/CMakeLists.txt
+++ b/src/plugins/clangtools/CMakeLists.txt
@@ -2,24 +2,23 @@ if (WITH_TESTS)
set(TST_COMPONENT QmakeProjectManager)
endif()
+find_package(yaml-cpp QUIET MODULE)
+
add_qtc_plugin(ClangTools
- CONDITION TARGET libclang
- DEPENDS ClangSupport libclang
+ CONDITION TARGET libclang AND TARGET yaml-cpp
+ DEPENDS ClangSupport libclang yaml-cpp
PLUGIN_DEPENDS Core Debugger CppTools ${TST_COMPONENT}
INCLUDES ${CLANG_INCLUDE_DIRS}
SOURCES
clangfileinfo.h
clangfixitsrefactoringchanges.cpp clangfixitsrefactoringchanges.h
clangselectablefilesdialog.cpp clangselectablefilesdialog.h clangselectablefilesdialog.ui
- clangtidyclazyruncontrol.cpp clangtidyclazyruncontrol.h
clangtidyclazyrunner.cpp clangtidyclazyrunner.h
clangtidyclazytool.cpp clangtidyclazytool.h
clangtool.cpp clangtool.h
clangtoolruncontrol.cpp clangtoolruncontrol.h
clangtoolrunner.cpp clangtoolrunner.h
clangtools_global.h
- clangtoolsbasicsettings.cpp clangtoolsbasicsettings.h clangtoolsbasicsettings.ui
- clangtoolsconfigwidget.cpp clangtoolsconfigwidget.h clangtoolsconfigwidget.ui
clangtoolsconstants.h
clangtoolsdiagnostic.cpp clangtoolsdiagnostic.h
clangtoolsdiagnosticmodel.cpp clangtoolsdiagnosticmodel.h
@@ -30,6 +29,7 @@ add_qtc_plugin(ClangTools
clangtoolsprojectsettingswidget.cpp clangtoolsprojectsettingswidget.h clangtoolsprojectsettingswidget.ui
clangtoolssettings.cpp clangtoolssettings.h
clangtoolsutils.cpp clangtoolsutils.h
+ settingswidget.cpp settingswidget.h settingswidget.ui
)
extend_qtc_plugin(ClangTools
diff --git a/src/plugins/clangtools/clangselectablefilesdialog.cpp b/src/plugins/clangtools/clangselectablefilesdialog.cpp
index c6ad76ff0a..c9fce5552f 100644
--- a/src/plugins/clangtools/clangselectablefilesdialog.cpp
+++ b/src/plugins/clangtools/clangselectablefilesdialog.cpp
@@ -24,8 +24,8 @@
****************************************************************************/
#include "clangselectablefilesdialog.h"
+
#include "ui_clangselectablefilesdialog.h"
-#include "ui_clangtoolsbasicsettings.h"
#include "clangtoolsprojectsettings.h"
#include "clangtoolssettings.h"
@@ -292,57 +292,36 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
m_ui->buttons->setStandardButtons(QDialogButtonBox::Cancel);
m_ui->buttons->addButton(m_analyzeButton, QDialogButtonBox::AcceptRole);
- CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticConfigsSelectionWidget
- = m_ui->clangToolsBasicSettings->ui()->clangDiagnosticConfigsSelectionWidget;
- QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis;
- buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
+ CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticWidget = m_ui->diagnosticWidget;
ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project);
m_customDiagnosticConfig = diagnosticConfiguration(settings);
- m_buildBeforeAnalysis = settings->buildBeforeAnalysis();
if (settings->useGlobalSettings()) {
m_ui->globalOrCustom->setCurrentIndex(GlobalSettings);
- m_ui->clangToolsBasicSettings->setEnabled(false);
- diagnosticConfigsSelectionWidget->refresh(
- ClangToolsSettings::instance()->savedDiagnosticConfigId());
- buildBeforeAnalysis->setCheckState(
- ClangToolsSettings::instance()->savedBuildBeforeAnalysis()
- ? Qt::Checked : Qt::Unchecked);
+ diagnosticWidget->refresh(ClangToolsSettings::instance()->savedDiagnosticConfigId());
+ diagnosticWidget->setEnabled(false);
} else {
m_ui->globalOrCustom->setCurrentIndex(CustomSettings);
- m_ui->clangToolsBasicSettings->setEnabled(true);
- diagnosticConfigsSelectionWidget->refresh(m_customDiagnosticConfig);
- buildBeforeAnalysis->setCheckState(m_buildBeforeAnalysis ? Qt::Checked : Qt::Unchecked);
+ diagnosticWidget->refresh(m_customDiagnosticConfig);
+ diagnosticWidget->setEnabled(true);
}
connect(m_ui->globalOrCustom,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[=](int index){
- m_ui->clangToolsBasicSettings->setEnabled(index == CustomSettings);
- if (index == CustomSettings) {
- diagnosticConfigsSelectionWidget->refresh(m_customDiagnosticConfig);
- buildBeforeAnalysis->setCheckState(m_buildBeforeAnalysis ? Qt::Checked : Qt::Unchecked);
- } else {
- diagnosticConfigsSelectionWidget->refresh(
- ClangToolsSettings::instance()->savedDiagnosticConfigId());
- buildBeforeAnalysis->setCheckState(
- ClangToolsSettings::instance()->savedBuildBeforeAnalysis()
- ? Qt::Checked : Qt::Unchecked);
- }
+ diagnosticWidget->setEnabled(index == CustomSettings);
+ if (index == CustomSettings)
+ diagnosticWidget->refresh(m_customDiagnosticConfig);
+ else
+ diagnosticWidget->refresh(ClangToolsSettings::instance()->savedDiagnosticConfigId());
});
- connect(diagnosticConfigsSelectionWidget,
+ connect(diagnosticWidget,
&ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
[this](const Core::Id &currentConfigId) {
if (m_ui->globalOrCustom->currentIndex() == CustomSettings)
m_customDiagnosticConfig = currentConfigId;
});
- connect(buildBeforeAnalysis, &QCheckBox::toggled, [this](bool checked) {
- if (!checked)
- showHintAboutBuildBeforeAnalysis();
- if (m_ui->globalOrCustom->currentIndex() == CustomSettings)
- m_buildBeforeAnalysis = checked;
- });
// Restore selection
if (settings->selectedDirs().isEmpty() && settings->selectedFiles().isEmpty())
@@ -358,9 +337,9 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed,
this, [=]() {
if (m_ui->globalOrCustom->currentIndex() == CustomSettings) {
- diagnosticConfigsSelectionWidget->refresh(m_customDiagnosticConfig);
+ diagnosticWidget->refresh(m_customDiagnosticConfig);
} else {
- diagnosticConfigsSelectionWidget->refresh(
+ diagnosticWidget->refresh(
ClangToolsSettings::instance()->savedDiagnosticConfigId());
}
});
@@ -377,12 +356,11 @@ void SelectableFilesDialog::accept()
{
ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project);
- // Save diagnostic configuration and flag to build before analysis
+ // Save diagnostic configuration
settings->setUseGlobalSettings(m_ui->globalOrCustom->currentIndex() == GlobalSettings);
settings->setDiagnosticConfig(m_customDiagnosticConfig);
- settings->setBuildBeforeAnalysis(m_buildBeforeAnalysis);
- // Save selection
+ // Save file selection
QSet<FilePath> checkedDirs;
QSet<FilePath> checkedFiles;
m_filesModel->minimalSelection(checkedDirs, checkedFiles);
diff --git a/src/plugins/clangtools/clangselectablefilesdialog.h b/src/plugins/clangtools/clangselectablefilesdialog.h
index 39dc1fcbed..e639d06199 100644
--- a/src/plugins/clangtools/clangselectablefilesdialog.h
+++ b/src/plugins/clangtools/clangselectablefilesdialog.h
@@ -65,7 +65,6 @@ private:
Core::Id m_customDiagnosticConfig;
ProjectExplorer::Project *m_project;
QPushButton *m_analyzeButton = nullptr;
- bool m_buildBeforeAnalysis = true;
};
} // namespace Internal
diff --git a/src/plugins/clangtools/clangselectablefilesdialog.ui b/src/plugins/clangtools/clangselectablefilesdialog.ui
index 2fe10139a3..267b36364a 100644
--- a/src/plugins/clangtools/clangselectablefilesdialog.ui
+++ b/src/plugins/clangtools/clangselectablefilesdialog.ui
@@ -19,7 +19,7 @@
<property name="title">
<string>General</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@@ -52,7 +52,7 @@
</layout>
</item>
<item>
- <widget class="ClangTools::Internal::ClangToolsBasicSettings" name="clangToolsBasicSettings" native="true"/>
+ <widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="diagnosticWidget" native="true"/>
</item>
</layout>
</widget>
@@ -87,9 +87,9 @@
</widget>
<customwidgets>
<customwidget>
- <class>ClangTools::Internal::ClangToolsBasicSettings</class>
+ <class>CppTools::ClangDiagnosticConfigsSelectionWidget</class>
<extends>QWidget</extends>
- <header>clangtools/clangtoolsbasicsettings.h</header>
+ <header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
diff --git a/src/plugins/clangtools/clangtidyclazyruncontrol.cpp b/src/plugins/clangtools/clangtidyclazyruncontrol.cpp
deleted file mode 100644
index 3d7d63a84a..0000000000
--- a/src/plugins/clangtools/clangtidyclazyruncontrol.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "clangtidyclazyruncontrol.h"
-
-#include "clangtidyclazyrunner.h"
-#include "clangtidyclazytool.h"
-
-using namespace ProjectExplorer;
-
-namespace ClangTools {
-namespace Internal {
-
-ClangTidyClazyRunControl::ClangTidyClazyRunControl(
- RunControl *runControl,
- Target *target,
- const CppTools::ClangDiagnosticConfig &diagnosticConfig,
- const FileInfos &fileInfos)
- : ClangToolRunControl(runControl, target, fileInfos)
- , m_diagnosticConfig(diagnosticConfig)
-{
- setId("ClangTidyClazyRunner");
- init();
-}
-
-ClangToolRunner *ClangTidyClazyRunControl::createRunner()
-{
- QTC_ASSERT(!m_clangExecutable.isEmpty(), return nullptr);
-
- auto runner = new ClangTidyClazyRunner(m_diagnosticConfig,
- m_clangExecutable,
- m_temporaryDir.path(),
- m_environment,
- this);
- connect(runner, &ClangTidyClazyRunner::finishedWithSuccess,
- this, &ClangTidyClazyRunControl::onRunnerFinishedWithSuccess);
- connect(runner, &ClangTidyClazyRunner::finishedWithFailure,
- this, &ClangTidyClazyRunControl::onRunnerFinishedWithFailure);
- return runner;
-}
-
-ClangTool *ClangTidyClazyRunControl::tool()
-{
- return ClangTidyClazyTool::instance();
-}
-
-} // namespace Internal
-} // namespace ClangTools
-
diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp
index 2bb0caf3aa..21238a9f1c 100644
--- a/src/plugins/clangtools/clangtidyclazyrunner.cpp
+++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp
@@ -26,6 +26,9 @@
#include "clangtidyclazyrunner.h"
#include "clangtoolssettings.h"
+#include "clangtoolsutils.h"
+
+#include <coreplugin/icore.h>
#include <cpptools/compileroptionsbuilder.h>
#include <cpptools/cppcodemodelsettings.h>
@@ -40,50 +43,25 @@
static Q_LOGGING_CATEGORY(LOG, "qtc.clangtools.runner", QtWarningMsg)
+using namespace CppTools;
+
namespace ClangTools {
namespace Internal {
-ClangTidyClazyRunner::ClangTidyClazyRunner(const CppTools::ClangDiagnosticConfig &diagnosticConfig,
- const QString &clangExecutable,
- const QString &clangLogFileDir,
- const Utils::Environment &environment,
- QObject *parent)
- : ClangToolRunner(clangExecutable,
- clangLogFileDir,
- environment,
- tr("Clang-Tidy and Clazy"),
- parent)
- , m_diagnosticConfig(diagnosticConfig)
+static QStringList serializeDiagnosticsArguments(const QStringList &baseOptions,
+ const QString &outputFilePath)
{
+ const QStringList serializeArgs{"-serialize-diagnostics", outputFilePath};
+ if (baseOptions.contains("--driver-mode=cl"))
+ return clangArgsForCl(serializeArgs);
+ return serializeArgs;
}
-QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringList &options)
+static QStringList clazyPluginArguments(const ClangDiagnosticConfig diagnosticConfig)
{
- using namespace CppTools;
QStringList arguments;
- if (LOG().isDebugEnabled())
- arguments << QLatin1String("-v");
-
- const QStringList serializeArgs{"-serialize-diagnostics", m_logFile};
- if (options.contains("--driver-mode=cl"))
- arguments << clangArgsForCl(serializeArgs);
- else
- arguments << serializeArgs;
-
- arguments << ClangDiagnosticConfigsModel::globalDiagnosticOptions()
- << m_diagnosticConfig.clangOptions();
-
- const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode();
- if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) {
- arguments << XclangArgs({"-add-plugin", "clang-tidy"});
- if (tidyMode != ClangDiagnosticConfig::TidyMode::File) {
- const QString tidyChecks = m_diagnosticConfig.clangTidyChecks();
- arguments << XclangArgs({"-plugin-arg-clang-tidy", "-checks=" + tidyChecks});
- }
- }
-
- const QString clazyChecks = m_diagnosticConfig.clazyChecks();
+ const QString clazyChecks = diagnosticConfig.clazyChecks();
if (!clazyChecks.isEmpty()) {
arguments << XclangArgs({"-add-plugin",
"clazy",
@@ -92,12 +70,96 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis
"-plugin-arg-clazy",
"no-autowrite-fixits",
"-plugin-arg-clazy",
- m_diagnosticConfig.clazyChecks()});
+ diagnosticConfig.clazyChecks()});
}
- arguments << options << QDir::toNativeSeparators(filePath());
return arguments;
}
+static QStringList tidyChecksArguments(const ClangDiagnosticConfig diagnosticConfig)
+{
+ const ClangDiagnosticConfig::TidyMode tidyMode = diagnosticConfig.clangTidyMode();
+ if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) {
+ if (tidyMode != ClangDiagnosticConfig::TidyMode::File)
+ return {"-checks=" + diagnosticConfig.clangTidyChecks()};
+ }
+
+ return {};
+}
+
+static QStringList clazyChecksArguments(const ClangDiagnosticConfig diagnosticConfig)
+{
+ const QString clazyChecks = diagnosticConfig.clazyChecks();
+ if (!clazyChecks.isEmpty())
+ return {"-checks=" + diagnosticConfig.clazyChecks()};
+ return {};
+}
+
+static QStringList mainToolArguments(const QString &mainFilePath, const QString &outputFilePath)
+{
+ return {
+ "-export-fixes=" + outputFilePath,
+ QDir::toNativeSeparators(mainFilePath),
+ };
+}
+
+static QStringList clangArguments(const ClangDiagnosticConfig &diagnosticConfig,
+ const QStringList &baseOptions)
+{
+ QStringList arguments;
+ arguments << ClangDiagnosticConfigsModel::globalDiagnosticOptions()
+ << diagnosticConfig.clangOptions()
+ << baseOptions;
+
+ if (LOG().isDebugEnabled())
+ arguments << QLatin1String("-v");
+
+ return arguments;
+}
+
+ClangTidyRunner::ClangTidyRunner(const ClangDiagnosticConfig &config, QObject *parent)
+ : ClangToolRunner(parent)
+{
+ setName(tr("Clang-Tidy"));
+ setOutputFileFormat(OutputFileFormat::Yaml);
+ setExecutable(clangTidyExecutable());
+ setArgsCreator([this, config](const QStringList &baseOptions) {
+ return QStringList()
+ << tidyChecksArguments(config)
+ << mainToolArguments(fileToAnalyze(), outputFilePath())
+ << "--"
+ << clangArguments(config, baseOptions);
+ });
+}
+
+ClazyStandaloneRunner::ClazyStandaloneRunner(const ClangDiagnosticConfig &config, QObject *parent)
+ : ClangToolRunner(parent)
+{
+ setName(tr("Clazy"));
+ setOutputFileFormat(OutputFileFormat::Yaml);
+ setExecutable(clazyStandaloneExecutable());
+ setArgsCreator([this, config](const QStringList &baseOptions) {
+ return QStringList()
+ << clazyChecksArguments(config)
+ << mainToolArguments(fileToAnalyze(), outputFilePath())
+ << "--"
+ << clangArguments(config, baseOptions);
+ });
+}
+
+ClazyPluginRunner::ClazyPluginRunner(const ClangDiagnosticConfig &config, QObject *parent)
+ : ClangToolRunner(parent)
+{
+ setName(tr("Clazy"));
+ setOutputFileFormat(OutputFileFormat::Serialized);
+ setExecutable(Core::ICore::clangExecutable(CLANG_BINDIR));
+ setArgsCreator([this, config](const QStringList &baseOptions) {
+ return serializeDiagnosticsArguments(baseOptions, outputFilePath())
+ << clazyPluginArguments(config)
+ << clangArguments(config, baseOptions)
+ << QDir::toNativeSeparators(fileToAnalyze());
+ });
+}
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtidyclazyrunner.h b/src/plugins/clangtools/clangtidyclazyrunner.h
index 507ac2977d..72cd7a155c 100644
--- a/src/plugins/clangtools/clangtidyclazyrunner.h
+++ b/src/plugins/clangtools/clangtidyclazyrunner.h
@@ -32,22 +32,28 @@
namespace ClangTools {
namespace Internal {
-class ClangTidyClazyRunner final : public ClangToolRunner
+class ClangTidyRunner final : public ClangToolRunner
{
Q_OBJECT
public:
- ClangTidyClazyRunner(const CppTools::ClangDiagnosticConfig &diagnosticConfig,
- const QString &clangExecutable,
- const QString &clangLogFileDir,
- const Utils::Environment &environment,
- QObject *parent = nullptr);
+ ClangTidyRunner(const CppTools::ClangDiagnosticConfig &config, QObject *parent = nullptr);
+};
+
+class ClazyStandaloneRunner final : public ClangToolRunner
+{
+ Q_OBJECT
+
+public:
+ ClazyStandaloneRunner(const CppTools::ClangDiagnosticConfig &config, QObject *parent = nullptr);
+};
-protected:
- QStringList constructCommandLineArguments(const QStringList &options) final;
+class ClazyPluginRunner final : public ClangToolRunner
+{
+ Q_OBJECT
-private:
- const CppTools::ClangDiagnosticConfig m_diagnosticConfig;
+public:
+ ClazyPluginRunner(const CppTools::ClangDiagnosticConfig &config, QObject *parent = nullptr);
};
} // namespace Internal
diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp
index ec743c9794..85be64da49 100644
--- a/src/plugins/clangtools/clangtidyclazytool.cpp
+++ b/src/plugins/clangtools/clangtidyclazytool.cpp
@@ -27,16 +27,18 @@
#include "clangfixitsrefactoringchanges.h"
#include "clangselectablefilesdialog.h"
+#include "clangtoolruncontrol.h"
#include "clangtoolsconstants.h"
#include "clangtoolsdiagnosticmodel.h"
#include "clangtoolslogfilereader.h"
-#include "clangtidyclazyruncontrol.h"
#include "clangtoolsdiagnosticview.h"
#include "clangtoolsprojectsettings.h"
#include "clangtoolssettings.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/messagebox.h>
#include <cpptools/clangdiagnosticconfigsmodel.h>
#include <cpptools/cppcodemodelsettings.h>
@@ -55,6 +57,7 @@
#include <utils/utilsicons.h>
#include <QAction>
+#include <QFileDialog>
#include <QToolButton>
using namespace Core;
@@ -249,6 +252,13 @@ ClangTidyClazyTool::ClangTidyClazyTool()
connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goNext);
m_goNext = action;
+ // Load diagnostics from file
+ action = new QAction(this);
+ action->setIcon(Utils::Icons::OPENFILE_TOOLBAR.icon());
+ action->setToolTip(tr("Load Diagnostics from YAML Files exported with \"-export-fixes\"."));
+ connect(action, &QAction::triggered, this, &ClangTidyClazyTool::loadDiagnosticsFromFiles);
+ m_loadExported = action;
+
// Clear data
action = new QAction(this);
action->setDisabled(true);
@@ -317,14 +327,22 @@ ClangTidyClazyTool::ClangTidyClazyTool()
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "ClangTidyClazy.Action"),
Debugger::Constants::G_ANALYZER_TOOLS);
- QObject::connect(action, &QAction::triggered, this, [this]() { startTool(true); });
+ QObject::connect(action, &QAction::triggered, this, [this]() {
+ startTool(ClangTidyClazyTool::FileSelection::AskUser);
+ });
QObject::connect(m_startAction, &QAction::triggered, action, &QAction::triggered);
QObject::connect(m_startAction, &QAction::changed, action, [action, this] {
action->setEnabled(m_startAction->isEnabled());
});
+ QObject::connect(m_startOnCurrentFileAction, &QAction::triggered, this, [this] {
+ startTool(ClangTidyClazyTool::FileSelection::CurrentFile);
+ });
+
m_perspective.addToolBarAction(m_startAction);
+ m_perspective.addToolBarAction(m_startOnCurrentFileAction);
m_perspective.addToolBarAction(m_stopAction);
+ m_perspective.addToolBarAction(m_loadExported);
m_perspective.addToolBarAction(m_clear);
m_perspective.addToolBarAction(m_goBack);
m_perspective.addToolBarAction(m_goNext);
@@ -362,23 +380,26 @@ static ClangDiagnosticConfig getDiagnosticConfig(Project *project)
return configsModel.configWithId(diagnosticConfigId);
}
-void ClangTidyClazyTool::startTool(bool askUserForFileSelection)
+void ClangTidyClazyTool::startTool(FileSelection fileSelection)
{
+ Project *project = SessionManager::startupProject();
+ QTC_ASSERT(project, return);
+ QTC_ASSERT(project->activeTarget(), return);
+
auto runControl = new RunControl(Constants::CLANGTIDYCLAZY_RUN_MODE);
runControl->setDisplayName(tr("Clang-Tidy and Clazy"));
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
+ runControl->setTarget(project->activeTarget());
- Project *project = SessionManager::startupProject();
- QTC_ASSERT(project, return);
-
- const FileInfos fileInfos = collectFileInfos(project, askUserForFileSelection);
+ const FileInfos fileInfos = collectFileInfos(project, fileSelection);
if (fileInfos.empty())
return;
- auto clangTool = new ClangTidyClazyRunControl(runControl,
- project->activeTarget(),
- getDiagnosticConfig(project),
- fileInfos);
+ const bool preventBuild = fileSelection == FileSelection::CurrentFile;
+ auto clangTool = new ClangToolRunWorker(runControl,
+ getDiagnosticConfig(project),
+ fileInfos,
+ preventBuild);
m_stopAction->disconnect();
connect(m_stopAction, &QAction::triggered, runControl, [runControl] {
@@ -412,28 +433,77 @@ void ClangTidyClazyTool::startTool(bool askUserForFileSelection)
void ClangTidyClazyTool::updateRunActions()
{
if (m_toolBusy) {
- m_startAction->setEnabled(false);
QString tooltipText = tr("Clang-Tidy and Clazy are still running.");
+
+ m_startAction->setEnabled(false);
m_startAction->setToolTip(tooltipText);
+
+ m_startOnCurrentFileAction->setEnabled(false);
+ m_startOnCurrentFileAction->setToolTip(tooltipText);
+
m_stopAction->setEnabled(true);
+ m_loadExported->setEnabled(false);
m_clear->setEnabled(false);
} else {
- QString toolTip = tr("Start Clang-Tidy and Clazy.");
+ QString toolTipStart = m_startAction->text();
+ QString toolTipStartOnCurrentFile = m_startOnCurrentFileAction->text();
+
Project *project = SessionManager::startupProject();
Target *target = project ? project->activeTarget() : nullptr;
const Core::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID;
bool canRun = target && project->projectLanguages().contains(cxx)
&& ToolChainKitAspect::toolChain(target->kit(), cxx);
if (!canRun)
- toolTip = tr("This is not a C++ project.");
+ toolTipStart = toolTipStartOnCurrentFile = tr("This is not a C/C++ project.");
- m_startAction->setToolTip(toolTip);
m_startAction->setEnabled(canRun);
+ m_startAction->setToolTip(toolTipStart);
+
+ m_startOnCurrentFileAction->setEnabled(canRun);
+ m_startOnCurrentFileAction->setToolTip(toolTipStartOnCurrentFile);
+
m_stopAction->setEnabled(false);
+ m_loadExported->setEnabled(true);
m_clear->setEnabled(m_diagnosticModel->diagnostics().count());
}
}
+void ClangTidyClazyTool::loadDiagnosticsFromFiles()
+{
+ // Ask user for files
+ const QStringList filePaths
+ = QFileDialog::getOpenFileNames(Core::ICore::mainWindow(),
+ tr("Select YAML Files with Diagnostics"),
+ QDir::homePath(),
+ tr("YAML Files (*.yml *.yaml);;All Files (*)"));
+ if (filePaths.isEmpty())
+ return;
+
+ // Load files
+ Diagnostics diagnostics;
+ QString errors;
+ for (const QString &filePath : filePaths) {
+ QString currentError;
+ diagnostics << readExportedDiagnostics(Utils::FilePath::fromString(filePath),
+ {},
+ &currentError);
+
+ if (!currentError.isEmpty()) {
+ if (!errors.isEmpty())
+ errors.append("\n");
+ errors.append(currentError);
+ }
+ }
+
+ // Show errors
+ if (!errors.isEmpty())
+ AsynchronousMessageBox::critical(tr("Error Loading Diagnostics"), errors);
+
+ // Show imported
+ m_diagnosticModel->clear();
+ onNewDiagnosticsAvailable(diagnostics);
+}
+
void ClangTidyClazyTool::handleStateUpdate()
{
QTC_ASSERT(m_goBack, return);
@@ -445,8 +515,11 @@ void ClangTidyClazyTool::handleStateUpdate()
const int issuesVisible = m_diagnosticFilterModel->rowCount();
m_goBack->setEnabled(issuesVisible > 1);
m_goNext->setEnabled(issuesVisible > 1);
+ m_clear->setEnabled(issuesFound > 0);
m_expandCollapse->setEnabled(issuesVisible);
+ m_loadExported->setEnabled(!m_running);
+
QString message;
if (m_running) {
if (issuesFound)
@@ -463,15 +536,28 @@ void ClangTidyClazyTool::handleStateUpdate()
Debugger::showPermanentStatusMessage(message);
}
-QList<Diagnostic> ClangTidyClazyTool::read(const QString &filePath,
- const QSet<Utils::FilePath> &projectFiles,
- const QString &logFilePath,
- QString *errorMessage) const
+Diagnostics ClangTidyClazyTool::read(OutputFileFormat outputFileFormat,
+ const QString &logFilePath,
+ const QString &mainFilePath,
+ const QSet<Utils::FilePath> &projectFiles,
+ QString *errorMessage) const
{
- return readSerializedDiagnostics(filePath, projectFiles, logFilePath, errorMessage);
+ const auto acceptFromFilePath = [projectFiles](const Utils::FilePath &filePath) {
+ return projectFiles.contains(filePath);
+ };
+
+ if (outputFileFormat == OutputFileFormat::Yaml) {
+ return readExportedDiagnostics(Utils::FilePath::fromString(logFilePath),
+ acceptFromFilePath,
+ errorMessage);
+ }
+ return readSerializedDiagnostics(Utils::FilePath::fromString(logFilePath),
+ Utils::FilePath::fromString(mainFilePath),
+ acceptFromFilePath,
+ errorMessage);
}
-void ClangTidyClazyTool::onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics)
+void ClangTidyClazyTool::onNewDiagnosticsAvailable(const Diagnostics &diagnostics)
{
ClangTool::onNewDiagnosticsAvailable(diagnostics);
if (!m_diagnosticFilterModel->filterRegExp().pattern().isEmpty())
diff --git a/src/plugins/clangtools/clangtidyclazytool.h b/src/plugins/clangtools/clangtidyclazytool.h
index 1783290538..be96438117 100644
--- a/src/plugins/clangtools/clangtidyclazytool.h
+++ b/src/plugins/clangtools/clangtidyclazytool.h
@@ -51,19 +51,21 @@ public:
static ClangTidyClazyTool *instance();
- void startTool(bool askUserForFileSelection) final;
+ void startTool(FileSelection fileSelection) final;
- QList<Diagnostic> read(const QString &filePath,
- const QSet<Utils::FilePath> &projectFiles,
- const QString &logFilePath,
- QString *errorMessage) const final;
+ Diagnostics read(OutputFileFormat outputFileFormat,
+ const QString &logFilePath,
+ const QString &mainFilePath,
+ const QSet<Utils::FilePath> &projectFiles,
+ QString *errorMessage) const final;
- void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics) override;
+ void onNewDiagnosticsAvailable(const Diagnostics &diagnostics) override;
private:
void handleStateUpdate() final;
void updateRunActions();
+ void loadDiagnosticsFromFiles();
DiagnosticFilterModel *m_diagnosticFilterModel = nullptr;
@@ -72,6 +74,7 @@ private:
QAction *m_goBack = nullptr;
QAction *m_goNext = nullptr;
+ QAction *m_loadExported = nullptr;
QAction *m_clear = nullptr;
QAction *m_expandCollapse = nullptr;
diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp
index 10295ed28b..a2ffb83c7b 100644
--- a/src/plugins/clangtools/clangtool.cpp
+++ b/src/plugins/clangtools/clangtool.cpp
@@ -34,6 +34,7 @@
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <cpptools/cppmodelmanager.h>
@@ -97,7 +98,27 @@ ClangTool::ClangTool(const QString &name)
{
m_diagnosticModel = new ClangToolsDiagnosticModel(this);
- m_startAction = Debugger::createStartAction();
+ const Utils::Icon RUN_FILE_OVERLAY(
+ {{":/utils/images/run_file.png", Utils::Theme::IconsBaseColor}});
+
+ const Utils::Icon RUN_SELECTED_OVERLAY(
+ {{":/utils/images/runselected_boxes.png", Utils::Theme::BackgroundColorDark},
+ {":/utils/images/runselected_tickmarks.png", Utils::Theme::IconsBaseColor}});
+
+ auto action = new QAction(tr("Analyze Project..."), this);
+ Utils::Icon runSelectedIcon = Utils::Icons::RUN_SMALL_TOOLBAR;
+ for (const Utils::IconMaskAndColor &maskAndColor : RUN_SELECTED_OVERLAY)
+ runSelectedIcon.append(maskAndColor);
+ action->setIcon(runSelectedIcon.icon());
+ m_startAction = action;
+
+ action = new QAction(tr("Analyze Current File"), this);
+ Utils::Icon runFileIcon = Utils::Icons::RUN_SMALL_TOOLBAR;
+ for (const Utils::IconMaskAndColor &maskAndColor : RUN_FILE_OVERLAY)
+ runFileIcon.append(maskAndColor);
+ action->setIcon(runFileIcon.icon());
+ m_startOnCurrentFileAction = action;
+
m_stopAction = Debugger::createStopAction();
}
@@ -106,21 +127,38 @@ ClangTool::~ClangTool()
delete m_diagnosticView;
}
-FileInfos ClangTool::collectFileInfos(Project *project, bool askUserForFileSelection) const
+FileInfos ClangTool::collectFileInfos(Project *project, FileSelection fileSelection) const
{
auto projectInfo = CppTools::CppModelManager::instance()->projectInfo(project);
QTC_ASSERT(projectInfo.isValid(), return FileInfos());
const FileInfos allFileInfos = sortedFileInfos(projectInfo.projectParts());
- if (askUserForFileSelection) {
+ if (fileSelection == FileSelection::AllFiles)
+ return allFileInfos;
+
+ if (fileSelection == FileSelection::AskUser) {
SelectableFilesDialog dialog(projectInfo, allFileInfos);
if (dialog.exec() == QDialog::Rejected)
return FileInfos();
return dialog.filteredFileInfos();
- } else {
- return allFileInfos;
}
+
+ if (fileSelection == FileSelection::CurrentFile) {
+ if (const IDocument *document = EditorManager::currentDocument()) {
+ const Utils::FilePath filePath = document->filePath();
+ if (!filePath.isEmpty()) {
+ const FileInfo fileInfo = Utils::findOrDefault(allFileInfos,
+ [&](const FileInfo &fi) {
+ return fi.file == filePath;
+ });
+ if (!fileInfo.file.isEmpty())
+ return {fileInfo};
+ }
+ }
+ }
+
+ return {};
}
const QString &ClangTool::name() const
@@ -144,7 +182,7 @@ QSet<Diagnostic> ClangTool::diagnostics() const
});
}
-void ClangTool::onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics)
+void ClangTool::onNewDiagnosticsAvailable(const Diagnostics &diagnostics)
{
QTC_ASSERT(m_diagnosticModel, return);
m_diagnosticModel->addDiagnostics(diagnostics);
diff --git a/src/plugins/clangtools/clangtool.h b/src/plugins/clangtools/clangtool.h
index 1d94719759..c0b1565260 100644
--- a/src/plugins/clangtools/clangtool.h
+++ b/src/plugins/clangtools/clangtool.h
@@ -26,6 +26,8 @@
#pragma once
#include "clangfileinfo.h"
+#include "clangtoolsdiagnostic.h"
+#include "clangtoolslogfilereader.h"
#include <projectexplorer/runconfiguration.h>
#include <cpptools/projectinfo.h>
@@ -47,22 +49,31 @@ public:
ClangTool(const QString &name);
~ClangTool() override;
- virtual void startTool(bool askUserForFileSelection) = 0;
+ enum class FileSelection {
+ AllFiles,
+ CurrentFile,
+ AskUser,
+ };
+ virtual void startTool(FileSelection fileSelection) = 0;
- virtual QList<Diagnostic> read(const QString &filePath,
- const QSet<Utils::FilePath> &projectFiles,
- const QString &logFilePath,
- QString *errorMessage) const = 0;
+ virtual Diagnostics read(OutputFileFormat outputFileFormat,
+ const QString &logFilePath,
+ const QString &mainFilePath,
+ const QSet<Utils::FilePath> &projectFiles,
+ QString *errorMessage) const = 0;
FileInfos collectFileInfos(ProjectExplorer::Project *project,
- bool askUserForFileSelection) const;
+ FileSelection fileSelection) const;
// For testing.
QSet<Diagnostic> diagnostics() const;
const QString &name() const;
- virtual void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics);
+ virtual void onNewDiagnosticsAvailable(const Diagnostics &diagnostics);
+
+ QAction *startAction() const { return m_startAction; }
+ QAction *startOnCurrentFileAction() const { return m_startOnCurrentFileAction; }
signals:
void finished(bool success); // For testing.
@@ -77,6 +88,7 @@ protected:
QPointer<Debugger::DetailedErrorView> m_diagnosticView;
QAction *m_startAction = nullptr;
+ QAction *m_startOnCurrentFileAction = nullptr;
QAction *m_stopAction = nullptr;
bool m_running = false;
bool m_toolBusy = false;
diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp
index 6467293417..da8e9f053c 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.cpp
+++ b/src/plugins/clangtools/clangtoolruncontrol.cpp
@@ -25,12 +25,12 @@
#include "clangtoolruncontrol.h"
+#include "clangtidyclazyrunner.h"
+#include "clangtidyclazytool.h"
#include "clangtool.h"
#include "clangtoolslogfilereader.h"
-#include "clangtoolsprojectsettings.h"
#include "clangtoolssettings.h"
#include "clangtoolsutils.h"
-#include "clangtoolrunner.h"
#include <debugger/analyzer/analyzerconstants.h>
@@ -81,8 +81,7 @@ static QStringList splitArgs(QString &argsString)
return result;
}
-template<size_t Size>
-static QStringList extraOptions(const char(&environment)[Size])
+static QStringList extraOptions(const char *environment)
{
if (!qEnvironmentVariableIsSet(environment))
return QStringList();
@@ -90,7 +89,8 @@ static QStringList extraOptions(const char(&environment)[Size])
return splitArgs(arguments);
}
-static QStringList extraClangToolsPrependOptions() {
+static QStringList extraClangToolsPrependOptions()
+{
constexpr char csaPrependOptions[] = "QTC_CLANG_CSA_CMD_PREPEND";
constexpr char toolsPrependOptions[] = "QTC_CLANG_TOOLS_CMD_PREPEND";
static const QStringList options = extraOptions(csaPrependOptions)
@@ -100,7 +100,8 @@ static QStringList extraClangToolsPrependOptions() {
return options;
}
-static QStringList extraClangToolsAppendOptions() {
+static QStringList extraClangToolsAppendOptions()
+{
constexpr char csaAppendOptions[] = "QTC_CLANG_CSA_CMD_APPEND";
constexpr char toolsAppendOptions[] = "QTC_CLANG_TOOLS_CMD_APPEND";
static const QStringList options = extraOptions(csaAppendOptions)
@@ -113,29 +114,26 @@ static QStringList extraClangToolsAppendOptions() {
namespace ClangTools {
namespace Internal {
+static ClangTool *tool()
+{
+ return ClangTidyClazyTool::instance();
+}
+
class ProjectBuilder : public RunWorker
{
public:
- ProjectBuilder(RunControl *runControl, Project *project, ClangToolRunControl *parent)
- : RunWorker(runControl), m_project(project), m_parent(parent)
+ ProjectBuilder(RunControl *runControl)
+ : RunWorker(runControl)
{
setId("ProjectBuilder");
}
- void setEnabled(bool enabled) { m_enabled = enabled; }
-
bool success() const { return m_success; }
private:
void start() final
{
- if (!m_enabled) {
- ProjectExplorerPlugin::saveModifiedFiles();
- onBuildFinished(true);
- return;
- }
-
- Target *target = m_project->activeTarget();
+ Target *target = runControl()->target();
QTC_ASSERT(target, reportFailure(); return);
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
@@ -143,14 +141,14 @@ private:
buildType = buildConfig->buildType();
if (buildType == BuildConfiguration::Release) {
- const QString wrongMode = ClangToolRunControl::tr("Release");
- const QString toolName = m_parent->tool()->name();
- const QString title = ClangToolRunControl::tr("Run %1 in %2 Mode?").arg(toolName, wrongMode);
- const QString problem = ClangToolRunControl::tr(
+ const QString wrongMode = ClangToolRunWorker::tr("Release");
+ const QString toolName = tool()->name();
+ const QString title = ClangToolRunWorker::tr("Run %1 in %2 Mode?").arg(toolName, wrongMode);
+ const QString problem = ClangToolRunWorker::tr(
"You are trying to run the tool \"%1\" on an application in %2 mode. The tool is "
"designed to be used in Debug mode since enabled assertions can reduce the number of "
"false positives.").arg(toolName, wrongMode);
- const QString question = ClangToolRunControl::tr(
+ const QString question = ClangToolRunWorker::tr(
"Do you want to continue and run the tool in %1 mode?").arg(wrongMode);
const QString message = QString("<html><head/><body>"
"<p>%1</p>"
@@ -168,7 +166,7 @@ private:
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &ProjectBuilder::onBuildFinished, Qt::QueuedConnection);
- ProjectExplorerPlugin::buildProject(m_project);
+ ProjectExplorerPlugin::buildProject(target->project());
}
void onBuildFinished(bool success)
@@ -180,9 +178,6 @@ private:
}
private:
- QPointer<Project> m_project;
- ClangToolRunControl *m_parent;
- bool m_enabled = true;
bool m_success = false;
};
@@ -207,7 +202,7 @@ static AnalyzeUnits toAnalyzeUnits(const FileInfos &fileInfos)
return unitsToAnalyze;
}
-AnalyzeUnits ClangToolRunControl::unitsToAnalyze()
+AnalyzeUnits ClangToolRunWorker::unitsToAnalyze()
{
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
@@ -216,79 +211,82 @@ AnalyzeUnits ClangToolRunControl::unitsToAnalyze()
static QDebug operator<<(QDebug debug, const Utils::Environment &environment)
{
- foreach (const QString &entry, environment.toStringList())
+ for (const QString &entry : environment.toStringList())
debug << "\n " << entry;
return debug;
}
static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
{
- foreach (const AnalyzeUnit &unit, analyzeUnits)
+ for (const AnalyzeUnit &unit : analyzeUnits)
debug << "\n " << unit.file;
return debug;
}
-ClangToolRunControl::ClangToolRunControl(RunControl *runControl,
- Target *target,
- const FileInfos &fileInfos)
+ClangToolRunWorker::ClangToolRunWorker(RunControl *runControl,
+ const ClangDiagnosticConfig &diagnosticConfig,
+ const FileInfos &fileInfos,
+ bool preventBuild)
: RunWorker(runControl)
- , m_projectBuilder(new ProjectBuilder(runControl, target->project(), this))
- , m_clangExecutable(Core::ICore::clangExecutable(CLANG_BINDIR))
, m_temporaryDir("clangtools-XXXXXX")
- , m_target(target)
+ , m_diagnosticConfig(diagnosticConfig)
, m_fileInfos(fileInfos)
{
- addStartDependency(m_projectBuilder);
-
- ClangToolsProjectSettings *projectSettings = ClangToolsProjectSettingsManager::getSettings(
- target->project());
- if (projectSettings->useGlobalSettings())
- m_projectBuilder->setEnabled(ClangToolsSettings::instance()->savedBuildBeforeAnalysis());
- else
- m_projectBuilder->setEnabled(projectSettings->buildBeforeAnalysis());
-}
-
-void ClangToolRunControl::init()
-{
+ setId("ClangTidyClazyRunner");
setSupportsReRunning(false);
- m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(
- m_target->project());
- BuildConfiguration *buildConfiguration = m_target->activeBuildConfiguration();
+ if (!preventBuild && ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) {
+ m_projectBuilder = new ProjectBuilder(runControl);
+ addStartDependency(m_projectBuilder);
+ }
+
+ Target *target = runControl->target();
+ m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(target->project());
+
+ BuildConfiguration *buildConfiguration = target->activeBuildConfiguration();
QTC_ASSERT(buildConfiguration, return);
m_environment = buildConfiguration->environment();
- ToolChain *toolChain = ToolChainKitAspect::toolChain(m_target->kit(),
- ProjectExplorer::Constants::CXX_LANGUAGE_ID);
+ ToolChain *toolChain = ToolChainKitAspect::toolChain(target->kit(),
+ ProjectExplorer::Constants::CXX_LANGUAGE_ID);
QTC_ASSERT(toolChain, return);
m_targetTriple = toolChain->originalTargetTriple();
m_toolChainType = toolChain->typeId();
}
-void ClangToolRunControl::start()
+QList<RunnerCreator> ClangToolRunWorker::runnerCreators()
+{
+ QList<RunnerCreator> creators;
+
+ if (m_diagnosticConfig.clangTidyMode() != CppTools::ClangDiagnosticConfig::TidyMode::Disabled)
+ creators << [this]() { return createRunner<ClangTidyRunner>(); };
+
+ if (!m_diagnosticConfig.clazyChecks().isEmpty()) {
+ if (!qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty())
+ creators << [this]() { return createRunner<ClazyStandaloneRunner>(); };
+ else
+ creators << [this]() { return createRunner<ClazyPluginRunner>(); };
+ }
+
+ return creators;
+}
+
+void ClangToolRunWorker::start()
{
TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID);
+ ProjectExplorerPlugin::saveModifiedFiles();
if (ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) {
- QTC_ASSERT(m_projectBuilder, return;);
- if (!m_projectBuilder->success()) {
+ if (m_projectBuilder && !m_projectBuilder->success()) {
reportFailure();
return;
}
}
const QString &toolName = tool()->name();
- if (m_clangExecutable.isEmpty()) {
- const QString errorMessage = tr("%1: Can't find clang executable, stop.").arg(toolName);
- appendMessage(errorMessage, Utils::ErrorMessageFormat);
- TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
- TaskHub::requestPopup();
- reportFailure();
- return;
- }
-
- m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(m_target->project());
- m_projectFiles = Utils::toSet(m_target->project()->files(Project::AllFiles));
+ Project *project = runControl()->project();
+ m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(project);
+ m_projectFiles = Utils::toSet(project->files(Project::AllFiles));
// Some projects provides CompilerCallData once a build is finished,
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
@@ -318,10 +316,15 @@ void ClangToolRunControl::start()
// Collect files
const AnalyzeUnits unitsToProcess = unitsToAnalyze();
qCDebug(LOG) << "Files to process:" << unitsToProcess;
- m_unitsToProcess = unitsToProcess;
- m_initialFilesToProcessSize = m_unitsToProcess.count();
- m_filesAnalyzed = 0;
- m_filesNotAnalyzed = 0;
+
+ m_queue.clear();
+ for (const AnalyzeUnit &unit : unitsToProcess) {
+ for (const RunnerCreator &creator : runnerCreators())
+ m_queue << QueueItem{unit, creator};
+ }
+ m_initialQueueSize = m_queue.count();
+ m_filesAnalyzed.clear();
+ m_filesNotAnalyzed.clear();
// Set up progress information
using namespace Core;
@@ -331,8 +334,8 @@ void ClangToolRunControl::start()
toolName.toStdString().c_str());
futureProgress->setKeepOnFinish(FutureProgress::HideOnFinish);
connect(futureProgress, &FutureProgress::canceled,
- this, &ClangToolRunControl::onProgressCanceled);
- m_progress.setProgressRange(0, m_initialFilesToProcessSize);
+ this, &ClangToolRunWorker::onProgressCanceled);
+ m_progress.setProgressRange(0, m_initialQueueSize);
m_progress.reportStarted();
// Start process(es)
@@ -342,75 +345,91 @@ void ClangToolRunControl::start()
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
m_success = true;
- if (m_unitsToProcess.isEmpty()) {
+ if (m_queue.isEmpty()) {
finalize();
return;
}
reportStarted();
- while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty())
+ while (m_runners.size() < parallelRuns && !m_queue.isEmpty())
analyzeNextFile();
}
-void ClangToolRunControl::stop()
+void ClangToolRunWorker::stop()
{
- QSetIterator<ClangToolRunner *> i(m_runners);
- while (i.hasNext()) {
- ClangToolRunner *runner = i.next();
+ for (ClangToolRunner *runner : m_runners) {
QObject::disconnect(runner, nullptr, this, nullptr);
delete runner;
}
m_projectFiles.clear();
m_runners.clear();
- m_unitsToProcess.clear();
+ m_queue.clear();
m_progress.reportFinished();
reportStopped();
}
-void ClangToolRunControl::analyzeNextFile()
+void ClangToolRunWorker::analyzeNextFile()
{
if (m_progress.isFinished())
return; // The previous call already reported that we are finished.
- if (m_unitsToProcess.isEmpty()) {
+ if (m_queue.isEmpty()) {
if (m_runners.isEmpty())
finalize();
return;
}
- const AnalyzeUnit unit = m_unitsToProcess.takeFirst();
+ const QueueItem queueItem = m_queue.takeFirst();
+ const AnalyzeUnit unit = queueItem.unit;
qCDebug(LOG) << "analyzeNextFile:" << unit.file;
- ClangToolRunner *runner = createRunner();
+ ClangToolRunner *runner = queueItem.runnerCreator();
m_runners.insert(runner);
+
+ const QString executable = runner->executable();
+ if (!isFileExecutable(executable)) {
+ const QString errorMessage = tr("%1: Invalid executable \"%2\", stop.")
+ .arg(runner->name(), executable);
+ TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
+ TaskHub::requestPopup();
+ reportFailure(errorMessage);
+ stop();
+ return;
+ }
+
QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
- appendMessage(tr("Analyzing \"%1\".").arg(
- Utils::FilePath::fromString(unit.file).toUserOutput()),
+ appendMessage(tr("Analyzing \"%1\" [%2].")
+ .arg(FilePath::fromString(unit.file).toUserOutput(), runner->name()),
Utils::StdOutFormat);
}
-void ClangToolRunControl::onRunnerFinishedWithSuccess(const QString &filePath)
+void ClangToolRunWorker::onRunnerFinishedWithSuccess(const QString &filePath)
{
- const QString logFilePath = qobject_cast<ClangToolRunner *>(sender())->logFilePath();
- qCDebug(LOG) << "onRunnerFinishedWithSuccess:" << logFilePath;
+ auto runner = qobject_cast<ClangToolRunner *>(sender());
+ const QString outputFilePath = runner->outputFilePath();
+ qCDebug(LOG) << "onRunnerFinishedWithSuccess:" << outputFilePath;
QString errorMessage;
- const QList<Diagnostic> diagnostics = tool()->read(filePath,
- m_projectFiles,
- logFilePath,
- &errorMessage);
- QFile::remove(logFilePath); // Clean-up.
+ const Diagnostics diagnostics = tool()->read(runner->outputFileFormat(),
+ outputFilePath,
+ filePath,
+ m_projectFiles,
+ &errorMessage);
+ QFile::remove(outputFilePath); // Clean-up.
if (!errorMessage.isEmpty()) {
+ m_filesAnalyzed.remove(filePath);
+ m_filesNotAnalyzed.insert(filePath);
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
- const QString filePath = qobject_cast<ClangToolRunner *>(sender())->filePath();
+ const QString filePath = qobject_cast<ClangToolRunner *>(sender())->fileToAnalyze();
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
Utils::StdErrFormat);
} else {
- ++m_filesAnalyzed;
+ if (!m_filesNotAnalyzed.contains(filePath))
+ m_filesAnalyzed.insert(filePath);
if (!diagnostics.isEmpty())
tool()->onNewDiagnosticsAvailable(diagnostics);
}
@@ -418,30 +437,31 @@ void ClangToolRunControl::onRunnerFinishedWithSuccess(const QString &filePath)
handleFinished();
}
-void ClangToolRunControl::onRunnerFinishedWithFailure(const QString &errorMessage,
+void ClangToolRunWorker::onRunnerFinishedWithFailure(const QString &errorMessage,
const QString &errorDetails)
{
qCDebug(LOG).noquote() << "onRunnerFinishedWithFailure:"
<< errorMessage << '\n' << errorDetails;
auto *toolRunner = qobject_cast<ClangToolRunner *>(sender());
- const QString filePath = toolRunner->filePath();
- const QString logFilePath = toolRunner->logFilePath();
+ const QString fileToAnalyze = toolRunner->fileToAnalyze();
+ const QString outputFilePath = toolRunner->outputFilePath();
// Even in the error case the log file was created, so clean it up here, too.
- QFile::remove(logFilePath);
+ QFile::remove(outputFilePath);
- const QString message = tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage);
-
- ++m_filesNotAnalyzed;
+ m_filesAnalyzed.remove(fileToAnalyze);
+ m_filesNotAnalyzed.insert(fileToAnalyze);
m_success = false;
+
+ const QString message = tr("Failed to analyze \"%1\": %2").arg(fileToAnalyze, errorMessage);
appendMessage(message, Utils::StdErrFormat);
appendMessage(errorDetails, Utils::StdErrFormat);
TaskHub::addTask(Task::Error, message, Debugger::Constants::ANALYZERTASK_ID);
handleFinished();
}
-void ClangToolRunControl::handleFinished()
+void ClangToolRunWorker::handleFinished()
{
m_runners.remove(qobject_cast<ClangToolRunner *>(sender()));
updateProgressValue();
@@ -449,31 +469,33 @@ void ClangToolRunControl::handleFinished()
analyzeNextFile();
}
-void ClangToolRunControl::onProgressCanceled()
+void ClangToolRunWorker::onProgressCanceled()
{
m_progress.reportCanceled();
runControl()->initiateStop();
}
-void ClangToolRunControl::updateProgressValue()
+void ClangToolRunWorker::updateProgressValue()
{
- m_progress.setProgressValue(m_initialFilesToProcessSize - m_unitsToProcess.size());
+ m_progress.setProgressValue(m_initialQueueSize - m_queue.size());
}
-void ClangToolRunControl::finalize()
+void ClangToolRunWorker::finalize()
{
const QString toolName = tool()->name();
appendMessage(tr("%1 finished: "
"Processed %2 files successfully, %3 failed.")
- .arg(toolName).arg(m_filesAnalyzed).arg(m_filesNotAnalyzed),
+ .arg(toolName)
+ .arg(m_filesAnalyzed.size())
+ .arg(m_filesNotAnalyzed.size()),
Utils::NormalMessageFormat);
- if (m_filesNotAnalyzed != 0) {
+ if (m_filesNotAnalyzed.size() != 0) {
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
- if (m_target && !m_target->activeBuildConfiguration()->buildDirectory().exists()
- && !ClangToolsProjectSettingsManager::getSettings(m_target->project())
- ->buildBeforeAnalysis()) {
+ Target *target = runControl()->target();
+ if (target && !target->activeBuildConfiguration()->buildDirectory().exists()
+ && !ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) {
msg = tr("%1: You might need to build the project to generate or update source "
"files. To build automatically, enable \"Build the project before starting "
"analysis\".")
@@ -488,5 +510,17 @@ void ClangToolRunControl::finalize()
runControl()->initiateStop();
}
+template<class T>
+ClangToolRunner *ClangToolRunWorker::createRunner()
+{
+ auto runner = new T(m_diagnosticConfig, this);
+ runner->init(m_temporaryDir.path(), m_environment);
+ connect(runner, &ClangToolRunner::finishedWithSuccess,
+ this, &ClangToolRunWorker::onRunnerFinishedWithSuccess);
+ connect(runner, &ClangToolRunner::finishedWithFailure,
+ this, &ClangToolRunWorker::onRunnerFinishedWithFailure);
+ return runner;
+}
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolruncontrol.h b/src/plugins/clangtools/clangtoolruncontrol.h
index 2027d9513b..842350a7f4 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.h
+++ b/src/plugins/clangtools/clangtoolruncontrol.h
@@ -27,20 +27,20 @@
#include "clangfileinfo.h"
-#include <projectexplorer/runcontrol.h>
+#include <cpptools/clangdiagnosticconfig.h>
#include <cpptools/projectinfo.h>
+#include <projectexplorer/runcontrol.h>
#include <utils/environment.h>
#include <utils/temporarydirectory.h>
#include <QFutureInterface>
+#include <QSet>
#include <QStringList>
namespace ClangTools {
namespace Internal {
-class ClangTool;
class ClangToolRunner;
-class Diagnostic;
class ProjectBuilder;
struct AnalyzeUnit {
@@ -52,24 +52,27 @@ struct AnalyzeUnit {
};
using AnalyzeUnits = QList<AnalyzeUnit>;
-class ClangToolRunControl : public ProjectExplorer::RunWorker
+using RunnerCreator = std::function<ClangToolRunner*()>;
+
+struct QueueItem {
+ AnalyzeUnit unit;
+ RunnerCreator runnerCreator;
+};
+using QueueItems = QList<QueueItem>;
+
+class ClangToolRunWorker : public ProjectExplorer::RunWorker
{
Q_OBJECT
public:
- ClangToolRunControl(ProjectExplorer::RunControl *runControl,
- ProjectExplorer::Target *target,
- const FileInfos &fileInfos);
+ ClangToolRunWorker(ProjectExplorer::RunControl *runControl,
+ const CppTools::ClangDiagnosticConfig &diagnosticConfig,
+ const FileInfos &fileInfos,
+ bool preventBuild);
bool success() const { return m_success; } // For testing.
- virtual ClangTool *tool() = 0;
-
protected:
- void init();
-
- virtual ClangToolRunner *createRunner() = 0;
-
void onRunnerFinishedWithSuccess(const QString &filePath);
void onRunnerFinishedWithFailure(const QString &errorMessage, const QString &errorDetails);
@@ -77,6 +80,9 @@ private:
void start() final;
void stop() final;
+ QList<RunnerCreator> runnerCreators();
+ template <class T> ClangToolRunner *createRunner();
+
AnalyzeUnits unitsToAnalyze();
void analyzeNextFile();
@@ -88,13 +94,12 @@ private:
void finalize();
protected:
- ProjectBuilder *m_projectBuilder;
+ ProjectBuilder *m_projectBuilder = nullptr;
Utils::Environment m_environment;
- QString m_clangExecutable;
Utils::TemporaryDirectory m_temporaryDir;
private:
- QPointer<ProjectExplorer::Target> m_target;
+ CppTools::ClangDiagnosticConfig m_diagnosticConfig;
FileInfos m_fileInfos;
CppTools::ProjectInfo m_projectInfoBeforeBuild;
@@ -103,12 +108,12 @@ private:
Core::Id m_toolChainType;
QFutureInterface<void> m_progress;
- AnalyzeUnits m_unitsToProcess;
+ QueueItems m_queue;
QSet<Utils::FilePath> m_projectFiles;
QSet<ClangToolRunner *> m_runners;
- int m_initialFilesToProcessSize = 0;
- int m_filesAnalyzed = 0;
- int m_filesNotAnalyzed = 0;
+ int m_initialQueueSize = 0;
+ QSet<QString> m_filesAnalyzed;
+ QSet<QString> m_filesNotAnalyzed;
bool m_success = false;
};
diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp
index c02d59a7da..0a63e8731b 100644
--- a/src/plugins/clangtools/clangtoolrunner.cpp
+++ b/src/plugins/clangtools/clangtoolrunner.cpp
@@ -53,28 +53,20 @@ static QString finishedDueToCrash(const QString &name)
return ClangToolRunner::tr("%1 crashed.").arg(name);
}
-QString finishedWithBadExitCode(const QString &name, int exitCode)
+static QString finishedWithBadExitCode(const QString &name, int exitCode)
{
return ClangToolRunner::tr("%1 finished with exit code: %2.").arg(name).arg(exitCode);
}
-ClangToolRunner::ClangToolRunner(const QString &clangExecutable,
- const QString &clangLogFileDir,
- const Utils::Environment &environment,
- const QString &name,
- QObject *parent)
- : QObject(parent)
- , m_clangExecutable(QDir::toNativeSeparators(clangExecutable))
- , m_clangLogFileDir(clangLogFileDir)
- , m_name(name)
+void ClangToolRunner::init(const QString &outputDirPath,
+ const Utils::Environment &environment)
{
- QTC_CHECK(!m_clangExecutable.isEmpty());
- QTC_CHECK(!m_clangLogFileDir.isEmpty());
+ m_outputDirPath = outputDirPath;
+ QTC_CHECK(!m_outputDirPath.isEmpty());
m_process.setProcessChannelMode(QProcess::MergedChannels);
m_process.setProcessEnvironment(environment.toProcessEnvironment());
- m_process.setWorkingDirectory(m_clangLogFileDir); // Current clang-cl puts log file into working dir.
- connect(&m_process, &QProcess::started, this, &ClangToolRunner::onProcessStarted);
+ m_process.setWorkingDirectory(m_outputDirPath); // Current clang-cl puts log file into working dir.
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &ClangToolRunner::onProcessFinished);
connect(&m_process, &QProcess::errorOccurred, this, &ClangToolRunner::onProcessError);
@@ -86,43 +78,54 @@ ClangToolRunner::~ClangToolRunner()
Utils::SynchronousProcess::stopProcess(m_process);
}
-bool ClangToolRunner::run(const QString &filePath, const QStringList &compilerOptions)
+static QString createOutputFilePath(const QString &dirPath, const QString &fileToAnalyze)
{
- QTC_ASSERT(!m_clangExecutable.isEmpty(), return false);
+ const QString fileName = QFileInfo(fileToAnalyze).fileName();
+ const QString fileTemplate = dirPath
+ + QLatin1String("/report-") + fileName + QLatin1String("-XXXXXX");
+
+ Utils::TemporaryFile temporaryFile("clangtools");
+ temporaryFile.setAutoRemove(false);
+ temporaryFile.setFileTemplate(fileTemplate);
+ if (temporaryFile.open()) {
+ temporaryFile.close();
+ return temporaryFile.fileName();
+ }
+ return QString();
+}
+
+bool ClangToolRunner::run(const QString &fileToAnalyze, const QStringList &compilerOptions)
+{
+ QTC_ASSERT(!m_executable.isEmpty(), return false);
QTC_CHECK(!compilerOptions.contains(QLatin1String("-o")));
- QTC_CHECK(!compilerOptions.contains(filePath));
+ QTC_CHECK(!compilerOptions.contains(fileToAnalyze));
- m_filePath = filePath;
+ m_fileToAnalyze = fileToAnalyze;
m_processOutput.clear();
- m_logFile = createLogFile(filePath);
- QTC_ASSERT(!m_logFile.isEmpty(), return false);
- const QStringList arguments = constructCommandLineArguments(compilerOptions);
- m_commandLine = Utils::QtcProcess::joinArgs(QStringList(m_clangExecutable) + arguments);
+ m_outputFilePath = createOutputFilePath(m_outputDirPath, fileToAnalyze);
+ QTC_ASSERT(!m_outputFilePath.isEmpty(), return false);
+ const QStringList arguments = m_argsCreator(compilerOptions);
+ m_commandLine = Utils::QtcProcess::joinArgs(QStringList(m_executable) + arguments);
qCDebug(LOG).noquote() << "Starting" << m_commandLine;
- m_process.start(m_clangExecutable, arguments);
+ m_process.start(m_executable, arguments);
return true;
}
-void ClangToolRunner::onProcessStarted()
-{
- emit started();
-}
-
void ClangToolRunner::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
if (exitStatus == QProcess::NormalExit) {
if (exitCode == 0) {
qCDebug(LOG).noquote() << "Output:\n" << Utils::SynchronousProcess::normalizeNewlines(
QString::fromLocal8Bit(m_processOutput));
- emit finishedWithSuccess(m_filePath);
+ emit finishedWithSuccess(m_fileToAnalyze);
} else {
emit finishedWithFailure(finishedWithBadExitCode(m_name, exitCode),
- processCommandlineAndOutput());
+ commandlineAndOutput());
}
} else { // == QProcess::CrashExit
- emit finishedWithFailure(finishedDueToCrash(m_name), processCommandlineAndOutput());
+ emit finishedWithFailure(finishedDueToCrash(m_name), commandlineAndOutput());
}
}
@@ -131,7 +134,7 @@ void ClangToolRunner::onProcessError(QProcess::ProcessError error)
if (error == QProcess::Crashed)
return; // handled by slot of finished()
- emit finishedWithFailure(generalProcessError(m_name), processCommandlineAndOutput());
+ emit finishedWithFailure(generalProcessError(m_name), commandlineAndOutput());
}
void ClangToolRunner::onProcessOutput()
@@ -139,31 +142,14 @@ void ClangToolRunner::onProcessOutput()
m_processOutput.append(m_process.readAll());
}
-QString ClangToolRunner::createLogFile(const QString &filePath) const
-{
- const QString fileName = QFileInfo(filePath).fileName();
- const QString fileTemplate = m_clangLogFileDir
- + QLatin1String("/report-") + fileName + QLatin1String("-XXXXXX");
-
- Utils::TemporaryFile temporaryFile("clangtools");
- temporaryFile.setAutoRemove(false);
- temporaryFile.setFileTemplate(fileTemplate);
- if (temporaryFile.open()) {
- temporaryFile.close();
- return temporaryFile.fileName();
- }
- return QString();
-}
-
-QString ClangToolRunner::processCommandlineAndOutput() const
+QString ClangToolRunner::commandlineAndOutput() const
{
return tr("Command line: %1\n"
- "Process Error: %2\n"
- "Output:\n%3")
- .arg(m_commandLine,
- QString::number(m_process.error()),
- Utils::SynchronousProcess::normalizeNewlines(
- QString::fromLocal8Bit(m_processOutput)));
+ "Process Error: %2\n"
+ "Output:\n%3")
+ .arg(m_commandLine,
+ QString::number(m_process.error()),
+ Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(m_processOutput)));
}
} // namespace Internal
diff --git a/src/plugins/clangtools/clangtoolrunner.h b/src/plugins/clangtools/clangtoolrunner.h
index b0d0b605cc..575876ff6c 100644
--- a/src/plugins/clangtools/clangtoolrunner.h
+++ b/src/plugins/clangtools/clangtoolrunner.h
@@ -25,65 +25,69 @@
#pragma once
+#include "clangtoolslogfilereader.h"
+
#include <QString>
#include <QProcess>
+#include <memory>
+
namespace Utils { class Environment; }
namespace ClangTools {
namespace Internal {
-QString finishedWithBadExitCode(const QString &name, int exitCode); // exposed for tests
+using ArgsCreator = std::function<QStringList(const QStringList &baseOptions)>;
class ClangToolRunner : public QObject
{
Q_OBJECT
public:
- ClangToolRunner(const QString &clangExecutable,
- const QString &clangLogFileDir,
- const Utils::Environment &environment,
- const QString &name,
- QObject *parent = nullptr);
+ ClangToolRunner(QObject *parent = nullptr) : QObject(parent) {}
~ClangToolRunner() override;
+ void init(const QString &outputDirPath, const Utils::Environment &environment);
+ void setName(const QString &name) { m_name = name; }
+ void setExecutable(const QString &executable) { m_executable = executable; }
+ void setArgsCreator(const ArgsCreator &argsCreator) { m_argsCreator = argsCreator; }
+ void setOutputFileFormat(const OutputFileFormat &format) { m_outputFileFormat = format; }
+
+ QString name() const { return m_name; }
+ QString executable() const { return m_executable; }
+ OutputFileFormat outputFileFormat() const { return m_outputFileFormat; }
+ QString fileToAnalyze() const { return m_fileToAnalyze; }
+ QString outputFilePath() const { return m_outputFilePath; }
+
// compilerOptions is expected to contain everything except:
- // (1) filePath, that is the file to analyze
+ // (1) file to analyze
// (2) -o output-file
- bool run(const QString &filePath, const QStringList &compilerOptions = QStringList());
-
- QString filePath() const { return m_filePath; }
- QString logFilePath() const { return m_logFile; }
+ bool run(const QString &fileToAnalyze, const QStringList &compilerOptions = QStringList());
signals:
- void started();
- void finishedWithSuccess(const QString &filePath);
+ void finishedWithSuccess(const QString &fileToAnalyze);
void finishedWithFailure(const QString &errorMessage, const QString &errorDetails);
-protected:
- virtual QStringList constructCommandLineArguments(const QStringList &options) = 0;
-
- virtual void onProcessOutput();
-
private:
- void onProcessStarted();
+ void onProcessOutput();
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onProcessError(QProcess::ProcessError error);
- QString createLogFile(const QString &filePath) const;
- QString processCommandlineAndOutput() const;
+ QString commandlineAndOutput() const;
-protected:
- QString m_logFile;
+private:
+ QString m_outputDirPath;
QProcess m_process;
QByteArray m_processOutput;
-private:
- QString m_clangExecutable;
- QString m_clangLogFileDir;
- QString m_filePath;
+ QString m_name;
+ QString m_executable;
+ ArgsCreator m_argsCreator;
+ OutputFileFormat m_outputFileFormat = OutputFileFormat::Yaml;
+
+ QString m_fileToAnalyze;
+ QString m_outputFilePath;
QString m_commandLine;
- const QString m_name;
};
} // namespace Internal
diff --git a/src/plugins/clangtools/clangtools.pro b/src/plugins/clangtools/clangtools.pro
index f0611a6c85..a089f1edb7 100644
--- a/src/plugins/clangtools/clangtools.pro
+++ b/src/plugins/clangtools/clangtools.pro
@@ -1,6 +1,5 @@
include(../../qtcreatorplugin.pri)
include(../../shared/clang/clang_installation.pri)
-
include(../../shared/clang/clang_defines.pri)
requires(!isEmpty(LLVM_VERSION))
@@ -8,18 +7,24 @@ requires(!isEmpty(LLVM_VERSION))
LIBS += $$LIBCLANG_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH
+include(../../shared/yaml-cpp/yaml-cpp_installation.pri)
+isEmpty(EXTERNAL_YAML_CPP_FOUND) {
+ DEFINES += YAML_CPP_DLL
+} else {
+ LIBS += $$EXTERNAL_YAML_CPP_LIBS
+ QMAKE_CXXFLAGS += $$EXTERNAL_YAML_CPP_CXXFLAGS
+}
+
SOURCES += \
clangfixitsrefactoringchanges.cpp \
clangselectablefilesdialog.cpp \
clangtoolsdiagnosticview.cpp \
clangtoolsprojectsettingswidget.cpp \
- clangtidyclazyruncontrol.cpp \
clangtidyclazyrunner.cpp \
clangtidyclazytool.cpp \
clangtool.cpp \
clangtoolruncontrol.cpp \
clangtoolrunner.cpp \
- clangtoolsbasicsettings.cpp \
clangtoolsdiagnostic.cpp \
clangtoolsdiagnosticmodel.cpp \
clangtoolslogfilereader.cpp \
@@ -27,7 +32,7 @@ SOURCES += \
clangtoolsprojectsettings.cpp \
clangtoolssettings.cpp \
clangtoolsutils.cpp \
- clangtoolsconfigwidget.cpp
+ settingswidget.cpp \
HEADERS += \
clangfileinfo.h \
@@ -35,14 +40,12 @@ HEADERS += \
clangselectablefilesdialog.h \
clangtoolsdiagnosticview.h \
clangtoolsprojectsettingswidget.h \
- clangtidyclazyruncontrol.h \
clangtidyclazyrunner.h \
clangtidyclazytool.h \
clangtool.h \
clangtoolruncontrol.h \
clangtoolrunner.h \
clangtools_global.h \
- clangtoolsbasicsettings.h \
clangtoolsconstants.h \
clangtoolsdiagnostic.h \
clangtoolsdiagnosticmodel.h \
@@ -51,13 +54,12 @@ HEADERS += \
clangtoolsprojectsettings.h \
clangtoolssettings.h \
clangtoolsutils.h \
- clangtoolsconfigwidget.h
+ settingswidget.h \
FORMS += \
- clangtoolsprojectsettingswidget.ui \
- clangtoolsconfigwidget.ui \
clangselectablefilesdialog.ui \
- clangtoolsbasicsettings.ui
+ clangtoolsprojectsettingswidget.ui \
+ settingswidget.ui \
equals(TEST, 1) {
HEADERS += \
diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs
index c7c34dd583..32146f87c0 100644
--- a/src/plugins/clangtools/clangtools.qbs
+++ b/src/plugins/clangtools/clangtools.qbs
@@ -13,6 +13,7 @@ QtcPlugin {
Depends { name: "Utils" }
Depends { name: "libclang"; required: false }
+ Depends { name: "yaml-cpp" }
Depends { name: "clang_defines" }
Depends { name: "Qt.widgets" }
@@ -36,8 +37,6 @@ QtcPlugin {
"clangselectablefilesdialog.cpp",
"clangselectablefilesdialog.h",
"clangselectablefilesdialog.ui",
- "clangtidyclazyruncontrol.cpp",
- "clangtidyclazyruncontrol.h",
"clangtidyclazyrunner.cpp",
"clangtidyclazyrunner.h",
"clangtidyclazytool.cpp",
@@ -49,12 +48,6 @@ QtcPlugin {
"clangtoolrunner.cpp",
"clangtoolrunner.h",
"clangtools_global.h",
- "clangtoolsbasicsettings.cpp",
- "clangtoolsbasicsettings.h",
- "clangtoolsbasicsettings.ui",
- "clangtoolsconfigwidget.cpp",
- "clangtoolsconfigwidget.h",
- "clangtoolsconfigwidget.ui",
"clangtoolsconstants.h",
"clangtoolsdiagnostic.cpp",
"clangtoolsdiagnostic.h",
@@ -75,6 +68,9 @@ QtcPlugin {
"clangtoolsutils.h",
"clangtoolsplugin.cpp",
"clangtoolsplugin.h",
+ "settingswidget.cpp",
+ "settingswidget.h",
+ "settingswidget.ui",
]
Group {
diff --git a/src/plugins/clangtools/clangtools_dependencies.pri b/src/plugins/clangtools/clangtools_dependencies.pri
index 7dff1d4688..943ca17936 100644
--- a/src/plugins/clangtools/clangtools_dependencies.pri
+++ b/src/plugins/clangtools/clangtools_dependencies.pri
@@ -2,6 +2,10 @@ QTC_PLUGIN_NAME = ClangTools
QTC_LIB_DEPENDS += \
extensionsystem \
utils
+
+include(../../shared/yaml-cpp/yaml-cpp_installation.pri)
+isEmpty(EXTERNAL_YAML_CPP_FOUND): QTC_LIB_DEPENDS += yaml-cpp
+
QTC_PLUGIN_DEPENDS += \
debugger \
cpptools
diff --git a/src/plugins/clangtools/clangtools_global.h b/src/plugins/clangtools/clangtools_global.h
index 159526ec64..0b47c30a25 100644
--- a/src/plugins/clangtools/clangtools_global.h
+++ b/src/plugins/clangtools/clangtools_global.h
@@ -29,6 +29,8 @@
#if defined(CLANGTOOLS_LIBRARY)
# define CLANGTOOLS_EXPORT Q_DECL_EXPORT
+#elif defined(CLANGTOOLS_STATIC_LIBRARY)
+# define CLANGTOOLS_EXPORT
#else
# define CLANGTOOLS_EXPORT Q_DECL_IMPORT
#endif
diff --git a/src/plugins/clangtools/clangtoolsbasicsettings.ui b/src/plugins/clangtools/clangtoolsbasicsettings.ui
deleted file mode 100644
index ccdba126bd..0000000000
--- a/src/plugins/clangtools/clangtoolsbasicsettings.ui
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ClangTools::Internal::ClangToolsBasicSettings</class>
- <widget class="QWidget" name="ClangTools::Internal::ClangToolsBasicSettings">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>300</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QCheckBox" name="buildBeforeAnalysis">
- <property name="text">
- <string>Build the project before analysis</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="clangDiagnosticConfigsSelectionWidget" native="true"/>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>CppTools::ClangDiagnosticConfigsSelectionWidget</class>
- <extends>QWidget</extends>
- <header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/clangtools/clangtoolsconfigwidget.cpp b/src/plugins/clangtools/clangtoolsconfigwidget.cpp
deleted file mode 100644
index b634875f97..0000000000
--- a/src/plugins/clangtools/clangtoolsconfigwidget.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "clangtoolsconfigwidget.h"
-#include "ui_clangtoolsbasicsettings.h"
-#include "ui_clangtoolsconfigwidget.h"
-
-#include "clangtoolsutils.h"
-
-#include <cpptools/clangdiagnosticconfigswidget.h>
-#include <cpptools/cppcodemodelsettings.h>
-#include <cpptools/cpptoolsreuse.h>
-
-#include <QDir>
-#include <QThread>
-
-namespace ClangTools {
-namespace Internal {
-
-ClangToolsConfigWidget::ClangToolsConfigWidget(
- ClangToolsSettings *settings,
- QWidget *parent)
- : QWidget(parent)
- , m_ui(new Ui::ClangToolsConfigWidget)
- , m_settings(settings)
-{
- m_ui->setupUi(this);
-
- m_ui->simultaneousProccessesSpinBox->setValue(settings->savedSimultaneousProcesses());
- m_ui->simultaneousProccessesSpinBox->setMinimum(1);
- m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
- connect(m_ui->simultaneousProccessesSpinBox,
- QOverload<int>::of(&QSpinBox::valueChanged),
- [settings](int count) { settings->setSimultaneousProcesses(count); });
-
- QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis;
- buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
- buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis()
- ? Qt::Checked : Qt::Unchecked);
- connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) {
- if (!checked)
- showHintAboutBuildBeforeAnalysis();
- settings->setBuildBeforeAnalysis(checked);
- });
-
- CppTools::ClangDiagnosticConfigsSelectionWidget *clangDiagnosticConfigsSelectionWidget
- = m_ui->clangToolsBasicSettings->ui()->clangDiagnosticConfigsSelectionWidget;
- clangDiagnosticConfigsSelectionWidget->refresh(settings->savedDiagnosticConfigId());
-
- connect(clangDiagnosticConfigsSelectionWidget,
- &CppTools::ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
- this, [this](const Core::Id &currentConfigId) {
- m_settings->setDiagnosticConfigId(currentConfigId);
- });
-
- connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed,
- this, [=]() {
- // Settings were applied so apply also the current selection if possible.
- clangDiagnosticConfigsSelectionWidget->refresh(m_settings->diagnosticConfigId());
- m_settings->writeSettings();
- });
-}
-
-ClangToolsConfigWidget::~ClangToolsConfigWidget() = default;
-
-} // namespace Internal
-} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsconstants.h b/src/plugins/clangtools/clangtoolsconstants.h
index 6bfe64ca87..f19ffc068a 100644
--- a/src/plugins/clangtools/clangtoolsconstants.h
+++ b/src/plugins/clangtools/clangtoolsconstants.h
@@ -28,9 +28,15 @@
namespace ClangTools {
namespace Constants {
+const char RUN_ON_PROJECT[] = "ClangTools.RunOnProject";
+const char RUN_ON_CURRENT_FILE[] = "ClangTools.RunOnCurrentFile";
+
const char SETTINGS_PAGE_ID[] = "Analyzer.ClangTools.Settings";
const char SETTINGS_ID[] = "ClangTools";
const char CLANGTIDYCLAZY_RUN_MODE[] = "ClangTidyClazy.RunMode";
+const char CLANG_TIDY_EXECUTABLE_NAME[] = "clang-tidy";
+const char CLAZY_STANDALONE_EXECUTABLE_NAME[] = "clazy-standalone";
+
} // Constants
} // ClangTools
diff --git a/src/plugins/clangtools/clangtoolsdiagnostic.cpp b/src/plugins/clangtools/clangtoolsdiagnostic.cpp
index cb1f4ead62..5e850659bf 100644
--- a/src/plugins/clangtools/clangtoolsdiagnostic.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnostic.cpp
@@ -33,6 +33,15 @@ bool ExplainingStep::isValid() const
return location.isValid() && !ranges.isEmpty() && !message.isEmpty();
}
+bool operator==(const ExplainingStep &lhs, const ExplainingStep &rhs)
+{
+ return lhs.message == rhs.message
+ && lhs.location == rhs.location
+ && lhs.ranges == rhs.ranges
+ && lhs.isFixIt == rhs.isFixIt
+ ;
+}
+
bool Diagnostic::isValid() const
{
return !description.isEmpty();
@@ -46,5 +55,16 @@ quint32 qHash(const Diagnostic &diagnostic)
^ diagnostic.location.column;
}
+bool operator==(const Diagnostic &lhs, const Diagnostic &rhs)
+{
+ return lhs.description == rhs.description
+ && lhs.category == rhs.category
+ && lhs.type == rhs.type
+ && lhs.location == rhs.location
+ && lhs.explainingSteps == rhs.explainingSteps
+ && lhs.hasFixits == rhs.hasFixits
+ ;
+}
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsdiagnostic.h b/src/plugins/clangtools/clangtoolsdiagnostic.h
index eb16803638..99df078fdc 100644
--- a/src/plugins/clangtools/clangtoolsdiagnostic.h
+++ b/src/plugins/clangtools/clangtoolsdiagnostic.h
@@ -44,10 +44,8 @@ public:
}
QString message;
- QString extendedMessage;
Debugger::DiagnosticLocation location;
QVector<Debugger::DiagnosticLocation> ranges;
- int depth = 0;
bool isFixIt = false;
};
@@ -59,13 +57,15 @@ public:
QString description;
QString category;
QString type;
- QString issueContextKind;
- QString issueContext;
Debugger::DiagnosticLocation location;
QVector<ExplainingStep> explainingSteps;
bool hasFixits = false;
};
+bool operator==(const Diagnostic &lhs, const Diagnostic &rhs);
+
+using Diagnostics = QList<Diagnostic>;
+
quint32 qHash(const Diagnostic &diagnostic);
} // namespace Internal
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
index ea6ec38fa3..6ac802d973 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
@@ -92,8 +92,6 @@ QDebug operator<<(QDebug debug, const Diagnostic &d)
{
return debug << "category:" << d.category
<< "type:" << d.type
- << "context:" << d.issueContext
- << "contextKind:" << d.issueContextKind
<< "hasFixits:" << d.hasFixits
<< "explainingSteps:" << d.explainingSteps.size()
<< "location:" << d.location
@@ -101,7 +99,7 @@ QDebug operator<<(QDebug debug, const Diagnostic &d)
;
}
-void ClangToolsDiagnosticModel::addDiagnostics(const QList<Diagnostic> &diagnostics)
+void ClangToolsDiagnosticModel::addDiagnostics(const Diagnostics &diagnostics)
{
const auto onFixitStatusChanged = [this](FixitStatus newStatus) {
if (newStatus == FixitStatus::Scheduled)
@@ -233,13 +231,6 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic, Fixit
diagnostic.description.toHtmlEscaped());
}
- if (!diagnostic.issueContext.isEmpty() && !diagnostic.issueContextKind.isEmpty()) {
- lines << qMakePair(
- QCoreApplication::translate("ClangTools::Diagnostic", "Context:"),
- diagnostic.issueContextKind.toHtmlEscaped() + QLatin1Char(' ')
- + diagnostic.issueContext.toHtmlEscaped());
- }
-
lines << qMakePair(
QCoreApplication::translate("ClangTools::Diagnostic", "Location:"),
createFullLocationString(diagnostic.location));
@@ -266,9 +257,6 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic, Fixit
static QString createExplainingStepToolTipString(const ExplainingStep &step)
{
- if (step.message == step.extendedMessage)
- return createFullLocationString(step.location);
-
using StringPair = QPair<QString, QString>;
QList<StringPair> lines;
@@ -277,11 +265,6 @@ static QString createExplainingStepToolTipString(const ExplainingStep &step)
QCoreApplication::translate("ClangTools::ExplainingStep", "Message:"),
step.message.toHtmlEscaped());
}
- if (!step.extendedMessage.isEmpty()) {
- lines << qMakePair(
- QCoreApplication::translate("ClangTools::ExplainingStep", "Extended message:"),
- step.extendedMessage.toHtmlEscaped());
- }
lines << qMakePair(
QCoreApplication::translate("ClangTools::ExplainingStep", "Location:"),
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
index e5a97fea29..3ac1df0d0c 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
@@ -113,7 +113,7 @@ class ClangToolsDiagnosticModel : public ClangToolsDiagnosticModelBase
public:
ClangToolsDiagnosticModel(QObject *parent = nullptr);
- void addDiagnostics(const QList<Diagnostic> &diagnostics);
+ void addDiagnostics(const Diagnostics &diagnostics);
QSet<Diagnostic> diagnostics() const;
enum ItemRole {
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp
index e59b1f22f3..4408a597b7 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp
@@ -210,8 +210,7 @@ void DiagnosticView::suppressCurrentDiagnostic()
= filePath.relativeChildPath(project->projectDirectory());
if (!relativeFilePath.isEmpty())
filePath = relativeFilePath;
- const SuppressedDiagnostic supDiag(filePath, diag.description, diag.issueContextKind,
- diag.issueContext, diag.explainingSteps.count());
+ const SuppressedDiagnostic supDiag(filePath, diag.description, diag.explainingSteps.count());
ClangToolsProjectSettingsManager::getSettings(project)->addSuppressedDiagnostic(supDiag);
} else {
filterModel->addSuppressedDiagnostic(SuppressedDiagnostic(diag));
diff --git a/src/plugins/clangtools/clangtoolslogfilereader.cpp b/src/plugins/clangtools/clangtoolslogfilereader.cpp
index 76c38f44be..59ea741c25 100644
--- a/src/plugins/clangtools/clangtoolslogfilereader.cpp
+++ b/src/plugins/clangtools/clangtoolslogfilereader.cpp
@@ -29,9 +29,9 @@
#include <QDebug>
#include <QDir>
-#include <QObject>
#include <QFile>
#include <QFileInfo>
+#include <QObject>
#include <QRegularExpression>
#include <QXmlStreamReader>
@@ -39,9 +39,12 @@
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
+#include <utils/textutils.h>
#include <clang-c/Index.h>
+#include <yaml-cpp/yaml.h>
+
namespace ClangTools {
namespace Internal {
@@ -122,7 +125,7 @@ static ExplainingStep buildFixIt(const CXDiagnostic cxDiagnostic, unsigned index
}
static Diagnostic buildDiagnostic(const CXDiagnostic cxDiagnostic,
- const QSet<Utils::FilePath> &projectFiles,
+ const AcceptDiagsFromFilePath &acceptFromFilePath,
const QString &nativeFilePath)
{
Diagnostic diagnostic;
@@ -136,7 +139,7 @@ static Diagnostic buildDiagnostic(const CXDiagnostic cxDiagnostic,
diagnostic.location = diagLocationFromSourceLocation(cxLocation);
const auto diagnosticFilePath = Utils::FilePath::fromString(diagnostic.location.filePath);
- if (!projectFiles.contains(diagnosticFilePath))
+ if (acceptFromFilePath && !acceptFromFilePath(diagnosticFilePath))
return diagnostic;
// TODO: Introduce CppTools::ProjectFile::isGenerated to filter these out properly
@@ -182,15 +185,15 @@ static Diagnostic buildDiagnostic(const CXDiagnostic cxDiagnostic,
return diagnostic;
}
-static QList<Diagnostic> readSerializedDiagnostics_helper(const QString &filePath,
- const QSet<Utils::FilePath> &projectFiles,
- const QString &logFilePath)
+static Diagnostics readSerializedDiagnostics_helper(const Utils::FilePath &logFilePath,
+ const Utils::FilePath &mainFilePath,
+ const AcceptDiagsFromFilePath &acceptFromFilePath)
{
- QList<Diagnostic> list;
+ Diagnostics list;
CXLoadDiag_Error error;
CXString errorString;
- CXDiagnosticSet diagnostics = clang_loadDiagnostics(logFilePath.toStdString().c_str(),
+ CXDiagnosticSet diagnostics = clang_loadDiagnostics(logFilePath.toString().toStdString().c_str(),
&error,
&errorString);
if (error != CXLoadDiag_None || !diagnostics)
@@ -200,13 +203,13 @@ static QList<Diagnostic> readSerializedDiagnostics_helper(const QString &filePat
clang_disposeDiagnosticSet(diagnostics);
});
- const QString nativeFilePath = QDir::toNativeSeparators(filePath);
+ const QString nativeFilePath = QDir::toNativeSeparators(mainFilePath.toString());
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
CXDiagnostic cxDiagnostic = clang_getDiagnosticInSet(diagnostics, i);
Utils::ExecuteOnDestruction cleanUpDiagnostic([&]() {
clang_disposeDiagnostic(cxDiagnostic);
});
- const Diagnostic diagnostic = buildDiagnostic(cxDiagnostic, projectFiles, nativeFilePath);
+ const Diagnostic diagnostic = buildDiagnostic(cxDiagnostic, acceptFromFilePath, nativeFilePath);
if (!diagnostic.isValid())
continue;
@@ -216,30 +219,265 @@ static QList<Diagnostic> readSerializedDiagnostics_helper(const QString &filePat
return list;
}
-static bool checkFilePath(const QString &filePath, QString *errorMessage)
+static bool checkFilePath(const Utils::FilePath &filePath, QString *errorMessage)
{
- QFileInfo fi(filePath);
+ QFileInfo fi(filePath.toFileInfo());
if (!fi.exists() || !fi.isReadable()) {
if (errorMessage) {
*errorMessage
= QString(QT_TRANSLATE_NOOP("LogFileReader",
"File \"%1\" does not exist or is not readable."))
- .arg(filePath);
+ .arg(filePath.toUserOutput());
}
return false;
}
return true;
}
-QList<Diagnostic> readSerializedDiagnostics(const QString &filePath,
- const QSet<Utils::FilePath> &projectFiles,
- const QString &logFilePath,
- QString *errorMessage)
+Diagnostics readSerializedDiagnostics(const Utils::FilePath &logFilePath,
+ const Utils::FilePath &mainFilePath,
+ const AcceptDiagsFromFilePath &acceptFromFilePath,
+ QString *errorMessage)
+{
+ if (!checkFilePath(logFilePath, errorMessage))
+ return {};
+
+ return readSerializedDiagnostics_helper(logFilePath, mainFilePath, acceptFromFilePath);
+}
+
+Utils::optional<LineColumnInfo> byteOffsetInUtf8TextToLineColumn(const char *text,
+ int offset,
+ int startLine)
+{
+ if (text == nullptr || offset < 0)
+ return {};
+
+ int lineCounter = startLine;
+ const char *lineStart = text;
+
+ for (const char *c = text; *c != '\0'; ++c) {
+ // Advance to line
+ if (c > text && *(c - 1) == '\n') {
+ ++lineCounter;
+ lineStart = c;
+ }
+
+ // Advance to column
+ if (c - text == offset) {
+ int columnCounter = 1;
+ c = lineStart;
+ while (c < text + offset && Utils::Text::utf8AdvanceCodePoint(c))
+ ++columnCounter;
+ if (c == text + offset)
+ return LineColumnInfo{lineCounter, columnCounter, static_cast<int>(lineStart - text)};
+ return {}; // Ops, offset was not pointing to start of multi byte code point.
+ }
+ }
+
+ return {};
+}
+
+static QString asString(const YAML::Node &node)
+{
+ return QString::fromStdString(node.as<std::string>());
+}
+
+namespace {
+class FileCache
+{
+public:
+ class LineInfo {
+ public:
+ bool isValid() { return line != 0; }
+ int line = 0; // 1-based
+ int lineStartOffset = 0;
+ };
+
+ class Item {
+ public:
+ friend class FileCache;
+
+ QByteArray fileContents()
+ {
+ if (data.isNull())
+ data = readFile(filePath);
+ return data;
+ }
+
+ LineInfo &lineInfo() { return lastLookup; }
+
+ private:
+ QString filePath;
+ LineInfo lastLookup;
+ QByteArray data;
+ };
+
+ Item &item(const QString &filePath)
+ {
+ Item &i = m_cache[filePath];
+ if (i.filePath.isEmpty())
+ i.filePath = filePath;
+ return i;
+ }
+
+private:
+ static QByteArray readFile(const QString &filePath)
+ {
+ if (filePath.isEmpty())
+ return {};
+
+ Utils::FileReader reader;
+ // Do not use QIODevice::Text as we have to deal with byte offsets.
+ if (reader.fetch(filePath, QIODevice::ReadOnly))
+ return reader.data();
+
+ return {};
+ }
+
+private:
+ QHash<QString, Item> m_cache;
+};
+
+class Location
+{
+public:
+ Location(const YAML::Node &node,
+ FileCache &fileCache,
+ const char *fileOffsetKey = "FileOffset",
+ int extraOffset = 0)
+ : m_node(node)
+ , m_fileCache(fileCache)
+ , m_filePath(asString(node["FilePath"]))
+ , m_fileOffsetKey(fileOffsetKey)
+ , m_extraOffset(extraOffset)
+ {}
+
+ QString filePath() const { return m_filePath; }
+
+ Debugger::DiagnosticLocation toDiagnosticLocation() const
+ {
+ FileCache::Item &cacheItem = m_fileCache.item(m_filePath);
+ const QByteArray fileContents = cacheItem.fileContents();
+
+ const char *data = fileContents.data();
+ int fileOffset = m_node[m_fileOffsetKey].as<int>() + m_extraOffset;
+ int startLine = 1;
+
+ // Check cache for last lookup
+ FileCache::LineInfo &cachedLineInfo = cacheItem.lineInfo();
+ if (cachedLineInfo.isValid() && fileOffset >= cachedLineInfo.lineStartOffset) {
+ // Cache hit, adjust inputs in order not to start from the beginning of the file again.
+ data = data + cachedLineInfo.lineStartOffset;
+ fileOffset = fileOffset - cachedLineInfo.lineStartOffset;
+ startLine = cachedLineInfo.line;
+ }
+
+ // Convert
+ OptionalLineColumnInfo info = byteOffsetInUtf8TextToLineColumn(data, fileOffset, startLine);
+ if (!info)
+ return {m_filePath, 1, 1};
+
+ // Save/update lookup
+ int lineStartOffset = info->lineStartOffset;
+ if (data != fileContents.data())
+ lineStartOffset += cachedLineInfo.lineStartOffset;
+ cachedLineInfo = FileCache::LineInfo{info->line, lineStartOffset};
+ return Debugger::DiagnosticLocation{m_filePath, info->line, info->column};
+ }
+
+ static QVector<Debugger::DiagnosticLocation> toRange(const YAML::Node &node,
+ FileCache &fileCache)
+ {
+ // The Replacements nodes use "Offset" instead of "FileOffset" as the key name.
+ auto startLoc = Location(node, fileCache, "Offset");
+ auto endLoc = Location(node, fileCache, "Offset", node["Length"].as<int>());
+ return {startLoc.toDiagnosticLocation(), endLoc.toDiagnosticLocation()};
+ }
+
+private:
+ const YAML::Node &m_node;
+ FileCache &m_fileCache;
+ QString m_filePath;
+ const char *m_fileOffsetKey = nullptr;
+ int m_extraOffset = 0;
+};
+
+} // namespace
+
+Diagnostics readExportedDiagnostics(const Utils::FilePath &logFilePath,
+ const AcceptDiagsFromFilePath &acceptFromFilePath,
+ QString *errorMessage)
{
if (!checkFilePath(logFilePath, errorMessage))
- return QList<Diagnostic>();
+ return {};
+
+ FileCache fileCache;
+ Diagnostics diagnostics;
+
+ try {
+ YAML::Node document = YAML::LoadFile(logFilePath.toString().toStdString());
+ for (const auto &diagNode : document["Diagnostics"]) {
+ // clazy omits the "DiagnosticMessage" node.
+ const auto msgNode = diagNode["DiagnosticMessage"];
+ const YAML::Node &node = msgNode ? msgNode : diagNode;
+
+ Location loc(node, fileCache);
+ if (loc.filePath().isEmpty())
+ continue;
+ if (acceptFromFilePath
+ && !acceptFromFilePath(Utils::FilePath::fromString(loc.filePath()))) {
+ continue;
+ }
+
+ Diagnostic diag;
+ diag.location = loc.toDiagnosticLocation();
+ diag.type = "warning";
+ diag.description = asString(node["Message"]) + " ["
+ + (asString(diagNode["DiagnosticName"])) + "]";
+
+ // Process fixits/replacements
+ const YAML::Node &replacementsNode = node["Replacements"];
+ for (const YAML::Node &replacementNode : replacementsNode) {
+ ExplainingStep step;
+ step.isFixIt = true;
+ step.message = asString(replacementNode["ReplacementText"]);
+ step.ranges = Location::toRange(replacementNode, fileCache);
+ step.location = step.ranges[0];
+
+ if (step.location.isValid())
+ diag.explainingSteps.append(step);
+ }
+ diag.hasFixits = !diag.explainingSteps.isEmpty();
+
+ // Process notes
+ const auto notesNode = diagNode["Notes"];
+ for (const YAML::Node &noteNode : notesNode) {
+ Location loc(noteNode, fileCache);
+ // Ignore a note like
+ // - FileOffset: 0
+ // FilePath: ''
+ // Message: this fix will not be applied because it overlaps with another fix
+ if (loc.filePath().isEmpty())
+ continue;
+
+ ExplainingStep step;
+ step.message = asString(noteNode["Message"]);
+ step.location = loc.toDiagnosticLocation();
+ diag.explainingSteps.append(step);
+ }
+
+ diagnostics.append(diag);
+ }
+ } catch (std::exception &e) {
+ if (errorMessage) {
+ *errorMessage = QString(
+ QT_TRANSLATE_NOOP("LogFileReader",
+ "Error: Failed to parse YAML file \"%1\": %2."))
+ .arg(logFilePath.toUserOutput(), QString::fromUtf8(e.what()));
+ }
+ }
- return readSerializedDiagnostics_helper(filePath, projectFiles, logFilePath);
+ return diagnostics;
}
} // namespace Internal
diff --git a/src/plugins/clangtools/clangtoolslogfilereader.h b/src/plugins/clangtools/clangtoolslogfilereader.h
index de37c362b5..996f7ffbeb 100644
--- a/src/plugins/clangtools/clangtoolslogfilereader.h
+++ b/src/plugins/clangtools/clangtoolslogfilereader.h
@@ -25,19 +25,40 @@
#pragma once
-#include "clangtoolsdiagnostic.h"
+#include <utils/optional.h>
-#include <QList>
+#include "clangtoolsdiagnostic.h"
namespace Utils { class FilePath; }
namespace ClangTools {
namespace Internal {
-QList<Diagnostic> readSerializedDiagnostics(const QString &filePath,
- const QSet<Utils::FilePath> &projectFiles,
- const QString &logFilePath,
- QString *errorMessage);
+enum class OutputFileFormat { Serialized, Yaml };
+
+using AcceptDiagsFromFilePath = std::function<bool(const Utils::FilePath &)>;
+
+// Reads diagnostics generated by "clang -serialize-diagnostics path/to/file"
+Diagnostics readSerializedDiagnostics(const Utils::FilePath &logFilePath,
+ const Utils::FilePath &mainFilePath,
+ const AcceptDiagsFromFilePath &acceptFromFilePath,
+ QString *errorMessage);
+
+// Reads diagnostics generated by "clang-tidy/clazy-standalone -export-fixes=path/to/file"
+Diagnostics readExportedDiagnostics(const Utils::FilePath &logFilePath,
+ const AcceptDiagsFromFilePath &acceptFromFilePath,
+ QString *errorMessage);
+
+// Exposed for tests
+struct LineColumnInfo {
+ int line = 1; // 1-based
+ int column = 1; // 1-based
+ int lineStartOffset = 0; // for optimiation/caching purposes
+};
+using OptionalLineColumnInfo = Utils::optional<LineColumnInfo>;
+OptionalLineColumnInfo byteOffsetInUtf8TextToLineColumn(const char *text,
+ int offset,
+ int startLine = 1);
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsplugin.cpp b/src/plugins/clangtools/clangtoolsplugin.cpp
index fa0d6589d2..fed9cb2150 100644
--- a/src/plugins/clangtools/clangtoolsplugin.cpp
+++ b/src/plugins/clangtools/clangtoolsplugin.cpp
@@ -25,11 +25,11 @@
#include "clangtoolsplugin.h"
-#include "clangtoolsconfigwidget.h"
#include "clangtoolsconstants.h"
#include "clangtoolsprojectsettingswidget.h"
#include "clangtidyclazytool.h"
#include "clangtoolsprojectsettings.h"
+#include "settingswidget.h"
#ifdef WITH_TESTS
#include "clangtoolspreconfiguredsessiontests.h"
@@ -61,17 +61,16 @@
#include <QMessageBox>
#include <QMenu>
-#include <QtPlugin>
-
+using namespace Core;
using namespace ProjectExplorer;
namespace ClangTools {
namespace Internal {
-class ClangToolsOptionsPage : public Core::IOptionsPage
+class ClangToolsOptionsPage : public IOptionsPage
{
public:
- explicit ClangToolsOptionsPage()
+ ClangToolsOptionsPage()
{
setId(Constants::SETTINGS_PAGE_ID);
setDisplayName(QCoreApplication::translate(
@@ -85,7 +84,7 @@ public:
QWidget *widget() override
{
if (!m_widget)
- m_widget = new ClangToolsConfigWidget(ClangToolsSettings::instance());
+ m_widget = new SettingsWidget(ClangToolsSettings::instance());
return m_widget;
}
@@ -118,11 +117,16 @@ ClangToolsPlugin::~ClangToolsPlugin()
bool ClangToolsPlugin::initialize(const QStringList &arguments, QString *errorString)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorString);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
d = new ClangToolsPluginPrivate;
+ ActionManager::registerAction(d->clangTidyClazyTool.startAction(),
+ Constants::RUN_ON_PROJECT);
+ ActionManager::registerAction(d->clangTidyClazyTool.startOnCurrentFileAction(),
+ Constants::RUN_ON_CURRENT_FILE);
+
auto panelFactory = new ProjectPanelFactory();
panelFactory->setPriority(100);
panelFactory->setDisplayName(tr("Clang Tools"));
diff --git a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp
index d4b4e03272..5d711a8aef 100644
--- a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp
+++ b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp
@@ -121,7 +121,7 @@ void PreconfiguredSessionTests::testPreconfiguredSession()
QVERIFY(switchToProjectAndTarget(project, target));
- ClangTidyClazyTool::instance()->startTool(false);
+ ClangTidyClazyTool::instance()->startTool(ClangTidyClazyTool::FileSelection::AllFiles);
QSignalSpy waitUntilAnalyzerFinished(ClangTidyClazyTool::instance(), SIGNAL(finished(bool)));
QVERIFY(waitUntilAnalyzerFinished.wait(30000));
const QList<QVariant> arguments = waitUntilAnalyzerFinished.takeFirst();
diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.cpp b/src/plugins/clangtools/clangtoolsprojectsettings.cpp
index 862030b950..6c2597789d 100644
--- a/src/plugins/clangtools/clangtoolsprojectsettings.cpp
+++ b/src/plugins/clangtools/clangtoolsprojectsettings.cpp
@@ -36,14 +36,11 @@ namespace Internal {
static const char SETTINGS_KEY_USE_GLOBAL_SETTINGS[] = "ClangTools.UseGlobalSettings";
static const char SETTINGS_KEY_DIAGNOSTIC_CONFIG[] = "ClangTools.DiagnosticConfig";
-static const char SETTINGS_KEY_BUILD_BEFORE_ANALYSIS[] = "ClangTools.BuildBeforeAnalysis";
static const char SETTINGS_KEY_SELECTED_DIRS[] = "ClangTools.SelectedDirs";
static const char SETTINGS_KEY_SELECTED_FILES[] = "ClangTools.SelectedFiles";
static const char SETTINGS_KEY_SUPPRESSED_DIAGS[] = "ClangTools.SuppressedDiagnostics";
static const char SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH[] = "ClangTools.SuppressedDiagnosticFilePath";
static const char SETTINGS_KEY_SUPPRESSED_DIAGS_MESSAGE[] = "ClangTools.SuppressedDiagnosticMessage";
-static const char SETTINGS_KEY_SUPPRESSED_DIAGS_CONTEXTKIND[] = "ClangTools.SuppressedDiagnosticContextKind";
-static const char SETTINGS_KEY_SUPPRESSED_DIAGS_CONTEXT[] = "ClangTools.SuppressedDiagnosticContext";
static const char SETTINGS_KEY_SUPPRESSED_DIAGS_UNIQIFIER[] = "ClangTools.SuppressedDiagnosticUniquifier";
ClangToolsProjectSettings::ClangToolsProjectSettings(ProjectExplorer::Project *project)
@@ -88,9 +85,6 @@ void ClangToolsProjectSettings::load()
m_diagnosticConfig = Core::Id::fromSetting(
m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG));
- const QVariant value = m_project->namedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS);
- m_buildBeforeAnalysis = value.isValid() ? value.toBool() : true;
-
auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); };
const QStringList dirs = m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).toStringList();
@@ -113,11 +107,10 @@ void ClangToolsProjectSettings::load()
fullPath = m_project->projectDirectory().pathAppended(fp);
if (!fullPath.exists())
continue;
- const QString contextKind = diag.value(SETTINGS_KEY_SUPPRESSED_DIAGS_CONTEXTKIND).toString();
- const QString context = diag.value(SETTINGS_KEY_SUPPRESSED_DIAGS_CONTEXT).toString();
const int uniquifier = diag.value(SETTINGS_KEY_SUPPRESSED_DIAGS_UNIQIFIER).toInt();
- m_suppressedDiagnostics << SuppressedDiagnostic(Utils::FilePath::fromString(fp), message,
- contextKind, context, uniquifier);
+ m_suppressedDiagnostics << SuppressedDiagnostic(Utils::FilePath::fromString(fp),
+ message,
+ uniquifier);
}
emit suppressedDiagnosticsChanged();
}
@@ -126,7 +119,6 @@ void ClangToolsProjectSettings::store()
{
m_project->setNamedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS, m_useGlobalSettings);
m_project->setNamedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG, m_diagnosticConfig.toSetting());
- m_project->setNamedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS, m_buildBeforeAnalysis);
const QStringList dirs = Utils::transform<QList>(m_selectedDirs, &Utils::FilePath::toString);
m_project->setNamedSettings(SETTINGS_KEY_SELECTED_DIRS, dirs);
@@ -139,8 +131,6 @@ void ClangToolsProjectSettings::store()
QVariantMap diagMap;
diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH, diag.filePath.toString());
diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_MESSAGE, diag.description);
- diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_CONTEXTKIND, diag.contextKind);
- diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_CONTEXT, diag.context);
diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_UNIQIFIER, diag.uniquifier);
list << diagMap;
}
@@ -167,16 +157,6 @@ void ClangToolsProjectSettings::setDiagnosticConfig(const Core::Id &diagnosticCo
m_diagnosticConfig = diagnosticConfig;
}
-bool ClangToolsProjectSettings::buildBeforeAnalysis() const
-{
- return m_buildBeforeAnalysis;
-}
-
-void ClangToolsProjectSettings::setBuildBeforeAnalysis(bool build)
-{
- m_buildBeforeAnalysis = build;
-}
-
ClangToolsProjectSettingsManager::ClangToolsProjectSettingsManager()
{
QObject::connect(ProjectExplorer::SessionManager::instance(),
@@ -203,8 +183,6 @@ ClangToolsProjectSettingsManager::SettingsMap ClangToolsProjectSettingsManager::
SuppressedDiagnostic::SuppressedDiagnostic(const Diagnostic &diag)
: filePath(Utils::FilePath::fromString(diag.location.filePath))
, description(diag.description)
- , contextKind(diag.issueContextKind)
- , context(diag.issueContext)
, uniquifier(diag.explainingSteps.count())
{
}
diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.h b/src/plugins/clangtools/clangtoolsprojectsettings.h
index 757140bc2c..0a6aa477d3 100644
--- a/src/plugins/clangtools/clangtoolsprojectsettings.h
+++ b/src/plugins/clangtools/clangtoolsprojectsettings.h
@@ -39,12 +39,9 @@ class Diagnostic;
class SuppressedDiagnostic
{
public:
- SuppressedDiagnostic(const Utils::FilePath &filePath, const QString &description,
- const QString &contextKind, const QString &context, int uniquifier)
+ SuppressedDiagnostic(const Utils::FilePath &filePath, const QString &description, int uniquifier)
: filePath(filePath)
, description(description)
- , contextKind(contextKind)
- , context(context)
, uniquifier(uniquifier)
{
}
@@ -53,16 +50,14 @@ public:
Utils::FilePath filePath; // Relative for files in project, absolute otherwise.
QString description;
- QString contextKind;
- QString context;
int uniquifier;
};
inline bool operator==(const SuppressedDiagnostic &d1, const SuppressedDiagnostic &d2)
{
- return d1.filePath == d2.filePath && d1.description == d2.description
- && d1.contextKind == d2.contextKind && d1.context == d2.context
- && d1.uniquifier == d2.uniquifier;
+ return d1.filePath == d2.filePath
+ && d1.description == d2.description
+ && d1.uniquifier == d2.uniquifier;
}
using SuppressedDiagnosticsList = QList<SuppressedDiagnostic>;
@@ -81,9 +76,6 @@ public:
Core::Id diagnosticConfig() const;
void setDiagnosticConfig(const Core::Id &diagnosticConfig);
- bool buildBeforeAnalysis() const;
- void setBuildBeforeAnalysis(bool build);
-
QSet<Utils::FilePath> selectedDirs() const { return m_selectedDirs; }
void setSelectedDirs(const QSet<Utils::FilePath> &value) { m_selectedDirs = value; }
@@ -108,7 +100,6 @@ private:
QSet<Utils::FilePath> m_selectedDirs;
QSet<Utils::FilePath> m_selectedFiles;
SuppressedDiagnosticsList m_suppressedDiagnostics;
- bool m_buildBeforeAnalysis = true;
};
class ClangToolsProjectSettingsManager
diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp
index 419e2e917f..3e380aa9af 100644
--- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp
+++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp
@@ -45,7 +45,7 @@ public:
SuppressedDiagnostic diagnosticAt(int i) const;
private:
- enum Columns { ColumnFile, ColumnContext, ColumnDescription, ColumnLast = ColumnDescription };
+ enum Columns { ColumnFile, ColumnDescription, ColumnLast = ColumnDescription };
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex & = QModelIndex()) const override { return ColumnLast + 1; }
@@ -137,8 +137,6 @@ QVariant SuppressedDiagnosticsModel::headerData(int section, Qt::Orientation ori
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
if (section == ColumnFile)
return tr("File");
- if (section == ColumnContext)
- return tr("Context");
if (section == ColumnDescription)
return tr("Diagnostic");
}
@@ -152,11 +150,6 @@ QVariant SuppressedDiagnosticsModel::data(const QModelIndex &index, int role) co
const SuppressedDiagnostic &diag = m_diagnostics.at(index.row());
if (index.column() == ColumnFile)
return diag.filePath.toUserOutput();
- if (index.column() == ColumnContext) {
- if (diag.contextKind == QLatin1String("function") && !diag.context.isEmpty())
- return tr("Function \"%1\"").arg(diag.context);
- return QString();
- }
if (index.column() == ColumnDescription)
return diag.description;
return QVariant();
diff --git a/src/plugins/clangtools/clangtoolssettings.cpp b/src/plugins/clangtools/clangtoolssettings.cpp
index 059f15ecbf..86f152f660 100644
--- a/src/plugins/clangtools/clangtoolssettings.cpp
+++ b/src/plugins/clangtools/clangtoolssettings.cpp
@@ -38,6 +38,8 @@
static const char simultaneousProcessesKey[] = "simultaneousProcesses";
static const char buildBeforeAnalysisKey[] = "buildBeforeAnalysis";
static const char diagnosticConfigIdKey[] = "diagnosticConfigId";
+static const char clangTidyExecutableKey[] = "clangTidyExecutable";
+static const char clazyStandaloneExecutableKey[] = "clazyStandaloneExecutable";
namespace ClangTools {
namespace Internal {
@@ -106,6 +108,36 @@ void ClangToolsSettings::updateSavedBuildBeforeAnalysiIfRequired()
emit buildBeforeAnalysisChanged(m_savedBuildBeforeAnalysis);
}
+QString ClangToolsSettings::savedClazyStandaloneExecutable() const
+{
+ return m_savedClazyStandaloneExecutable;
+}
+
+QString ClangToolsSettings::savedClangTidyExecutable() const
+{
+ return m_savedClangTidyExecutable;
+}
+
+QString ClangToolsSettings::clazyStandaloneExecutable() const
+{
+ return m_clazyStandaloneExecutable;
+}
+
+void ClangToolsSettings::setClazyStandaloneExecutable(const QString &path)
+{
+ m_clazyStandaloneExecutable = path;
+}
+
+QString ClangToolsSettings::clangTidyExecutable() const
+{
+ return m_clangTidyExecutable;
+}
+
+void ClangToolsSettings::setClangTidyExecutable(const QString &path)
+{
+ m_clangTidyExecutable = path;
+}
+
void ClangToolsSettings::readSettings()
{
QSettings *settings = Core::ICore::settings();
@@ -118,6 +150,11 @@ void ClangToolsSettings::readSettings()
m_buildBeforeAnalysis = settings->value(QString(buildBeforeAnalysisKey), true).toBool();
+ m_savedClangTidyExecutable = m_clangTidyExecutable
+ = settings->value(QLatin1String(clangTidyExecutableKey)).toString();
+ m_savedClazyStandaloneExecutable = m_clazyStandaloneExecutable
+ = settings->value(QLatin1String(clazyStandaloneExecutableKey)).toString();
+
m_diagnosticConfigId = Core::Id::fromSetting(settings->value(QString(diagnosticConfigIdKey)));
if (!m_diagnosticConfigId.isValid())
m_diagnosticConfigId = "Builtin.TidyAndClazy";
@@ -135,10 +172,14 @@ void ClangToolsSettings::writeSettings()
settings->beginGroup(QString(Constants::SETTINGS_ID));
settings->setValue(QString(simultaneousProcessesKey), m_simultaneousProcesses);
settings->setValue(QString(buildBeforeAnalysisKey), m_buildBeforeAnalysis);
+ settings->setValue(QString(clangTidyExecutableKey), m_clangTidyExecutable);
+ settings->setValue(QString(clazyStandaloneExecutableKey), m_clazyStandaloneExecutable);
settings->setValue(QString(diagnosticConfigIdKey), m_diagnosticConfigId.toSetting());
m_savedSimultaneousProcesses = m_simultaneousProcesses;
m_savedDiagnosticConfigId = m_diagnosticConfigId;
+ m_savedClangTidyExecutable = m_clangTidyExecutable;
+ m_savedClazyStandaloneExecutable = m_clazyStandaloneExecutable;
updateSavedBuildBeforeAnalysiIfRequired();
settings->endGroup();
diff --git a/src/plugins/clangtools/clangtoolssettings.h b/src/plugins/clangtools/clangtoolssettings.h
index 07f5bc7f47..402845d20f 100644
--- a/src/plugins/clangtools/clangtoolssettings.h
+++ b/src/plugins/clangtools/clangtoolssettings.h
@@ -33,6 +33,7 @@
namespace ClangTools {
namespace Internal {
+// TODO: Remove need for "saved* members
class ClangToolsSettings : public QObject
{
Q_OBJECT
@@ -44,6 +45,8 @@ public:
int savedSimultaneousProcesses() const;
bool savedBuildBeforeAnalysis() const;
Core::Id savedDiagnosticConfigId() const;
+ QString savedClangTidyExecutable() const;
+ QString savedClazyStandaloneExecutable() const;
int simultaneousProcesses() const;
void setSimultaneousProcesses(int processes);
@@ -54,6 +57,12 @@ public:
Core::Id diagnosticConfigId() const;
void setDiagnosticConfigId(Core::Id id);
+ QString clangTidyExecutable() const;
+ void setClangTidyExecutable(const QString &path);
+
+ QString clazyStandaloneExecutable() const;
+ void setClazyStandaloneExecutable(const QString &path);
+
signals:
void buildBeforeAnalysisChanged(bool checked) const;
@@ -67,6 +76,10 @@ private:
int m_savedSimultaneousProcesses = -1;
bool m_buildBeforeAnalysis = false;
bool m_savedBuildBeforeAnalysis= false;
+ QString m_clangTidyExecutable;
+ QString m_savedClangTidyExecutable;
+ QString m_clazyStandaloneExecutable;
+ QString m_savedClazyStandaloneExecutable;
Core::Id m_diagnosticConfigId;
Core::Id m_savedDiagnosticConfigId;
};
diff --git a/src/plugins/clangtools/clangtoolsunittestfiles.pri b/src/plugins/clangtools/clangtoolsunittestfiles.pri
new file mode 100644
index 0000000000..48e4ed05bc
--- /dev/null
+++ b/src/plugins/clangtools/clangtoolsunittestfiles.pri
@@ -0,0 +1,13 @@
+shared {
+ DEFINES += CLANGTOOLS_LIBRARY
+} else {
+ DEFINES += CLANGTOOLS_STATIC_LIBRARY
+}
+
+HEADERS += \
+ $$PWD/clangtoolsdiagnostic.h \
+ $$PWD/clangtoolslogfilereader.h \
+
+SOURCES += \
+ $$PWD/clangtoolsdiagnostic.cpp \
+ $$PWD/clangtoolslogfilereader.cpp \
diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp
index a4d300c844..b8546c58bd 100644
--- a/src/plugins/clangtools/clangtoolsunittests.cpp
+++ b/src/plugins/clangtools/clangtoolsunittests.cpp
@@ -131,7 +131,7 @@ void ClangToolsUnitTests::testProject()
clangToolsSettings->setDiagnosticConfigId(diagnosticConfig.id());
clangToolsSettings->writeSettings();
- tool->startTool(false);
+ tool->startTool(ClangTidyClazyTool::FileSelection::AllFiles);
QSignalSpy waiter(tool, SIGNAL(finished(bool)));
QVERIFY(waiter.wait(30000));
diff --git a/src/plugins/clangtools/clangtoolsutils.cpp b/src/plugins/clangtools/clangtoolsutils.cpp
index 173d97e31d..acb87f5ec1 100644
--- a/src/plugins/clangtools/clangtoolsutils.cpp
+++ b/src/plugins/clangtools/clangtoolsutils.cpp
@@ -26,6 +26,7 @@
#include "clangtoolsutils.h"
#include "clangtool.h"
+#include "clangtoolsconstants.h"
#include "clangtoolsdiagnostic.h"
#include "clangtoolssettings.h"
@@ -70,5 +71,88 @@ void showHintAboutBuildBeforeAnalysis()
"ClangToolsDisablingBuildBeforeAnalysisHint");
}
+bool isFileExecutable(const QString &filePath)
+{
+ if (filePath.isEmpty())
+ return false;
+
+ const QFileInfo fileInfo(filePath);
+ return fileInfo.isFile() && fileInfo.isExecutable();
+}
+
+QString shippedClangTidyExecutable()
+{
+ const QString shippedExecutable = Core::ICore::clangTidyExecutable(CLANG_BINDIR);
+ if (isFileExecutable(shippedExecutable))
+ return shippedExecutable;
+ return {};
+}
+
+QString shippedClazyStandaloneExecutable()
+{
+ const QString shippedExecutable = Core::ICore::clazyStandaloneExecutable(CLANG_BINDIR);
+ if (isFileExecutable(shippedExecutable))
+ return shippedExecutable;
+ return {};
+}
+
+static QString fullPath(const QString &executable)
+{
+ const QString hostExeSuffix = QLatin1String(QTC_HOST_EXE_SUFFIX);
+ const Qt::CaseSensitivity caseSensitivity = Utils::HostOsInfo::fileNameCaseSensitivity();
+
+ QString candidate = executable;
+ const bool hasSuffix = candidate.endsWith(hostExeSuffix, caseSensitivity);
+
+ const QFileInfo fileInfo = QFileInfo(candidate);
+ if (fileInfo.isAbsolute()) {
+ if (!hasSuffix)
+ candidate.append(hostExeSuffix);
+ } else {
+ const Utils::Environment environment = Utils::Environment::systemEnvironment();
+ const QString expandedPath = environment.searchInPath(candidate).toString();
+ if (!expandedPath.isEmpty())
+ candidate = expandedPath;
+ }
+
+ return candidate;
+}
+
+static QString findValidExecutable(const QStringList &candidates)
+{
+ for (QString candidate : candidates) {
+ const QString expandedPath = fullPath(candidate);
+ if (isFileExecutable(expandedPath))
+ return expandedPath;
+ }
+
+ return {};
+}
+
+QString clangTidyExecutable()
+{
+ const QString fromSettings = ClangToolsSettings::instance()->clangTidyExecutable();
+ if (!fromSettings.isEmpty())
+ return fullPath(fromSettings);
+
+ return findValidExecutable({
+ shippedClangTidyExecutable(),
+ Constants::CLANG_TIDY_EXECUTABLE_NAME,
+ });
+}
+
+QString clazyStandaloneExecutable()
+{
+ const QString fromSettings = ClangToolsSettings::instance()->clazyStandaloneExecutable();
+ if (!fromSettings.isEmpty())
+ return fullPath(fromSettings);
+
+ return findValidExecutable({
+ shippedClazyStandaloneExecutable(),
+ qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH"),
+ Constants::CLAZY_STANDALONE_EXECUTABLE_NAME,
+ });
+}
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsutils.h b/src/plugins/clangtools/clangtoolsutils.h
index 05acb953c5..a7ae9620de 100644
--- a/src/plugins/clangtools/clangtoolsutils.h
+++ b/src/plugins/clangtools/clangtoolsutils.h
@@ -44,5 +44,13 @@ QString createFullLocationString(const Debugger::DiagnosticLocation &location);
QString hintAboutBuildBeforeAnalysis();
void showHintAboutBuildBeforeAnalysis();
+bool isFileExecutable(const QString &filePath);
+
+QString shippedClazyStandaloneExecutable();
+QString clazyStandaloneExecutable();
+
+QString shippedClangTidyExecutable();
+QString clangTidyExecutable();
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/settingswidget.cpp b/src/plugins/clangtools/settingswidget.cpp
new file mode 100644
index 0000000000..de5976a04f
--- /dev/null
+++ b/src/plugins/clangtools/settingswidget.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "settingswidget.h"
+
+#include "ui_settingswidget.h"
+
+#include "clangtoolsconstants.h"
+#include "clangtoolsutils.h"
+
+#include <coreplugin/icore.h>
+
+#include <cpptools/clangdiagnosticconfigswidget.h>
+#include <cpptools/cppcodemodelsettings.h>
+#include <cpptools/cpptoolsreuse.h>
+
+#include <QDir>
+#include <QThread>
+
+#include <memory>
+
+namespace ClangTools {
+namespace Internal {
+
+static void setupPathChooser(Utils::PathChooser *const chooser,
+ const QString &promptDiaglogTitle,
+ const QString &placeHolderText,
+ const QString &pathFromSettings,
+ const QString &historyCompleterId,
+ std::function<void(const QString &path)> savePath)
+{
+ chooser->setPromptDialogTitle(promptDiaglogTitle);
+ chooser->lineEdit()->setPlaceholderText(placeHolderText);
+ chooser->setPath(pathFromSettings);
+ chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
+ chooser->setHistoryCompleter(historyCompleterId);
+ QObject::connect(chooser, &Utils::PathChooser::rawPathChanged, savePath),
+ chooser->setValidationFunction([chooser](Utils::FancyLineEdit *edit, QString *errorMessage) {
+ const QString currentFilePath = chooser->fileName().toString();
+ Utils::PathChooser pc;
+ Utils::PathChooser *helperPathChooser;
+ if (currentFilePath.isEmpty()) {
+ pc.setExpectedKind(chooser->expectedKind());
+ pc.setPath(edit->placeholderText());
+ helperPathChooser = &pc;
+ } else {
+ helperPathChooser = chooser;
+ }
+
+ return chooser->defaultValidationFunction()(helperPathChooser->lineEdit(), errorMessage);
+ });
+}
+
+SettingsWidget::SettingsWidget(ClangToolsSettings *settings, QWidget *parent)
+ : QWidget(parent)
+ , m_ui(new Ui::SettingsWidget)
+ , m_settings(settings)
+{
+ m_ui->setupUi(this);
+
+ //
+ // Group box "Executables"
+ //
+
+ QString placeHolderText = shippedClangTidyExecutable();
+ QString path = settings->clangTidyExecutable();
+ if (path.isEmpty() && placeHolderText.isEmpty())
+ path = Constants::CLANG_TIDY_EXECUTABLE_NAME;
+ setupPathChooser(m_ui->clangTidyPathChooser,
+ tr("Clang-Tidy Executable"),
+ placeHolderText,
+ path,
+ "ClangTools.ClangTidyExecutable.History",
+ [settings](const QString &path) { settings->setClangTidyExecutable(path); });
+
+ if (qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty()) {
+ m_ui->clazyStandalonePathChooser->setVisible(false);
+ m_ui->clazyStandaloneLabel->setVisible(false);
+ } else {
+ placeHolderText = shippedClazyStandaloneExecutable();
+ path = settings->clazyStandaloneExecutable();
+ if (path.isEmpty() && placeHolderText.isEmpty())
+ path = Constants::CLAZY_STANDALONE_EXECUTABLE_NAME;
+ setupPathChooser(m_ui->clazyStandalonePathChooser,
+ tr("Clazy Executable"),
+ placeHolderText,
+ path,
+ "ClangTools.ClazyStandaloneExecutable.History",
+ [settings](const QString &path) {
+ settings->setClazyStandaloneExecutable(path);
+ });
+ }
+
+ //
+ // Group box "Run Options"
+ //
+ m_ui->simultaneousProccessesSpinBox->setValue(settings->savedSimultaneousProcesses());
+ m_ui->simultaneousProccessesSpinBox->setMinimum(1);
+ m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
+ connect(m_ui->simultaneousProccessesSpinBox,
+ QOverload<int>::of(&QSpinBox::valueChanged),
+ [settings](int count) { settings->setSimultaneousProcesses(count); });
+
+ QCheckBox *buildBeforeAnalysis = m_ui->buildBeforeAnalysis;
+ buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
+ buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis()
+ ? Qt::Checked : Qt::Unchecked);
+ connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) {
+ if (!checked)
+ showHintAboutBuildBeforeAnalysis();
+ settings->setBuildBeforeAnalysis(checked);
+ });
+
+ CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticWidget = m_ui->diagnosticWidget;
+ diagnosticWidget->refresh(settings->savedDiagnosticConfigId());
+
+ connect(diagnosticWidget,
+ &CppTools::ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
+ this, [this](const Core::Id &currentConfigId) {
+ m_settings->setDiagnosticConfigId(currentConfigId);
+ });
+
+ connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed,
+ this, [=]() {
+ // Settings were applied so apply also the current selection if possible.
+ diagnosticWidget->refresh(m_settings->diagnosticConfigId());
+ m_settings->writeSettings();
+ });
+}
+
+SettingsWidget::~SettingsWidget() = default;
+
+} // namespace Internal
+} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsconfigwidget.h b/src/plugins/clangtools/settingswidget.h
index 177aadd259..6eeaeb5d98 100644
--- a/src/plugins/clangtools/clangtoolsconfigwidget.h
+++ b/src/plugins/clangtools/settingswidget.h
@@ -34,19 +34,17 @@
namespace ClangTools {
namespace Internal {
-namespace Ui { class ClangToolsConfigWidget; }
+namespace Ui { class SettingsWidget; }
-class ClangExecutableVersion;
-
-class ClangToolsConfigWidget : public QWidget
+class SettingsWidget : public QWidget
{
Q_OBJECT
public:
- ClangToolsConfigWidget(ClangToolsSettings *settings, QWidget *parent = nullptr);
- ~ClangToolsConfigWidget() override;
+ SettingsWidget(ClangToolsSettings *settings, QWidget *parent = nullptr);
+ ~SettingsWidget() override;
private:
- std::unique_ptr<Ui::ClangToolsConfigWidget> m_ui;
+ std::unique_ptr<Ui::SettingsWidget> m_ui;
ClangToolsSettings *m_settings;
};
diff --git a/src/plugins/clangtools/clangtoolsconfigwidget.ui b/src/plugins/clangtools/settingswidget.ui
index b2d5aa9875..c73148d0da 100644
--- a/src/plugins/clangtools/clangtoolsconfigwidget.ui
+++ b/src/plugins/clangtools/settingswidget.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>ClangTools::Internal::ClangToolsConfigWidget</class>
- <widget class="QWidget" name="ClangTools::Internal::ClangToolsConfigWidget">
+ <class>ClangTools::Internal::SettingsWidget</class>
+ <widget class="QWidget" name="ClangTools::Internal::SettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
@@ -15,13 +15,49 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Executables</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Clang-Tidy:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="Utils::PathChooser" name="clangTidyPathChooser" native="true"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="clazyStandaloneLabel">
+ <property name="text">
+ <string>Clazy-Standalone:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="Utils::PathChooser" name="clazyStandalonePathChooser" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
- <string>General</string>
+ <string>Run Options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="ClangTools::Internal::ClangToolsBasicSettings" name="clangToolsBasicSettings" native="true"/>
+ <widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="diagnosticWidget" native="true"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="buildBeforeAnalysis">
+ <property name="text">
+ <string>Build the project before analysis</string>
+ </property>
+ </widget>
</item>
<item>
<layout class="QHBoxLayout" name="processesLayout">
@@ -77,9 +113,15 @@
</widget>
<customwidgets>
<customwidget>
- <class>ClangTools::Internal::ClangToolsBasicSettings</class>
+ <class>CppTools::ClangDiagnosticConfigsSelectionWidget</class>
+ <extends>QWidget</extends>
+ <header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
+ </customwidget>
+ <customwidget>
+ <class>Utils::PathChooser</class>
<extends>QWidget</extends>
- <header>clangtools/clangtoolsbasicsettings.h</header>
+ <header location="global">utils/pathchooser.h</header>
+ <container>1</container>
</customwidget>
</customwidgets>
<resources/>
diff --git a/src/plugins/classview/classviewparser.cpp b/src/plugins/classview/classviewparser.cpp
index 13f258b9eb..07892d04d5 100644
--- a/src/plugins/classview/classviewparser.cpp
+++ b/src/plugins/classview/classviewparser.cpp
@@ -285,9 +285,7 @@ ParserTreeItem::ConstPtr Parser::parse()
for (const Project *prj : SessionManager::projects()) {
ParserTreeItem::Ptr item;
QString prjName(prj->displayName());
- QString prjType(prjName);
- if (prj->document())
- prjType = prj->projectFilePath().toString();
+ QString prjType = prj->projectFilePath().toString();
SymbolInformation inf(prjName, prjType);
item = ParserTreeItem::Ptr(new ParserTreeItem());
diff --git a/src/plugins/clearcase/clearcasecontrol.cpp b/src/plugins/clearcase/clearcasecontrol.cpp
index c3fdbc8d64..a9dd295518 100644
--- a/src/plugins/clearcase/clearcasecontrol.cpp
+++ b/src/plugins/clearcase/clearcasecontrol.cpp
@@ -51,7 +51,7 @@ Core::Id ClearCaseControl::id() const
bool ClearCaseControl::isVcsFileOrDirectory(const Utils::FilePath &fileName) const
{
- Q_UNUSED(fileName);
+ Q_UNUSED(fileName)
return false; // ClearCase has no files/directories littering the sources
}
diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp
index f33fa88639..9ba8c9db9f 100644
--- a/src/plugins/clearcase/clearcaseplugin.cpp
+++ b/src/plugins/clearcase/clearcaseplugin.cpp
@@ -1452,8 +1452,9 @@ ClearCasePlugin::runCleartool(const QString &workingDir,
}
const SynchronousProcessResponse sp_resp =
- VcsBasePlugin::runVcs(workingDir, FilePath::fromUserInput(executable),
- arguments, timeOutS,
+ VcsBasePlugin::runVcs(workingDir,
+ {executable, arguments},
+ timeOutS,
flags, outputCodec);
response.error = sp_resp.result != SynchronousProcessResponse::Finished;
@@ -2140,15 +2141,15 @@ void ClearCasePlugin::diffGraphical(const QString &file1, const QString &file2)
QString ClearCasePlugin::runExtDiff(const QString &workingDir, const QStringList &arguments,
int timeOutS, QTextCodec *outputCodec)
{
- const QString executable(QLatin1String("diff"));
- QStringList args(m_settings.diffArgs.split(QLatin1Char(' '), QString::SkipEmptyParts));
- args << arguments;
+ CommandLine diff("diff");
+ diff.addArgs(m_settings.diffArgs.split(' ', QString::SkipEmptyParts));
+ diff.addArgs(arguments);
SynchronousProcess process;
process.setTimeoutS(timeOutS);
process.setWorkingDirectory(workingDir);
process.setCodec(outputCodec ? outputCodec : QTextCodec::codecForName("UTF-8"));
- SynchronousProcessResponse response = process.run(executable, args);
+ SynchronousProcessResponse response = process.run(diff);
if (response.result != SynchronousProcessResponse::Finished)
return QString();
return response.allOutput();
diff --git a/src/plugins/cmakeprojectmanager/CMakeLists.txt b/src/plugins/cmakeprojectmanager/CMakeLists.txt
index 6062e40d53..651b557e86 100644
--- a/src/plugins/cmakeprojectmanager/CMakeLists.txt
+++ b/src/plugins/cmakeprojectmanager/CMakeLists.txt
@@ -10,6 +10,7 @@ add_qtc_plugin(CMakeProjectManager
cmakeautocompleter.cpp cmakeautocompleter.h
cmakebuildconfiguration.cpp cmakebuildconfiguration.h
cmakebuildsettingswidget.cpp cmakebuildsettingswidget.h
+ cmakebuildsystem.cpp cmakebuildsystem.h
cmakebuildstep.cpp cmakebuildstep.h
cmakebuildtarget.h
cmakecbpparser.cpp cmakecbpparser.h
@@ -20,6 +21,7 @@ add_qtc_plugin(CMakeProjectManager
cmakekitinformation.cpp cmakekitinformation.h
cmakelocatorfilter.cpp cmakelocatorfilter.h
cmakeparser.cpp cmakeparser.h
+ cmakeprocess.cpp cmakeprocess.h
cmakeproject.cpp cmakeproject.h
cmakeproject.qrc
cmakeprojectconstants.h
@@ -27,7 +29,6 @@ add_qtc_plugin(CMakeProjectManager
cmakeprojectmanager.cpp cmakeprojectmanager.h
cmakeprojectnodes.cpp cmakeprojectnodes.h
cmakeprojectplugin.cpp cmakeprojectplugin.h
- cmakerunconfiguration.cpp cmakerunconfiguration.h
cmakesettingspage.cpp cmakesettingspage.h
cmakespecificsettings.cpp cmakespecificsettings.h
cmakespecificsettingspage.cpp cmakespecificsettingspage.h cmakespecificsettingspage.ui
@@ -36,6 +37,10 @@ add_qtc_plugin(CMakeProjectManager
cmaketoolsettingsaccessor.cpp cmaketoolsettingsaccessor.h
configmodel.cpp configmodel.h
configmodelitemdelegate.cpp configmodelitemdelegate.h
+ fileapidataextractor.cpp fileapidataextractor.h
+ fileapiparser.cpp fileapiparser.h
+ fileapireader.cpp fileapireader.h
+ projecttreehelper.cpp projecttreehelper.h
servermode.cpp servermode.h
servermodereader.cpp servermodereader.h
tealeafreader.cpp tealeafreader.h
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index 490082d517..7e92932d20 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -45,7 +45,9 @@
#include <utils/qtcassert.h>
#include <QDir>
+#include <QLoggingCategory>
#include <QMessageBox>
+#include <QPointer>
#include <QPushButton>
#include <QSet>
@@ -55,11 +57,14 @@ using namespace Utils;
namespace CMakeProjectManager {
namespace Internal {
+Q_LOGGING_CATEGORY(cmakeBuildDirManagerLog, "qtc.cmake.builddirmanager", QtWarningMsg);
+
// --------------------------------------------------------------------
// BuildDirManager:
// --------------------------------------------------------------------
-BuildDirManager::BuildDirManager() = default;
+BuildDirManager::BuildDirManager(CMakeProject *project) : m_project(project) { assert(project); }
+
BuildDirManager::~BuildDirManager() = default;
Utils::FilePath BuildDirManager::workDirectory(const BuildDirParameters &parameters) const
@@ -91,6 +96,18 @@ Utils::FilePath BuildDirManager::workDirectory(const BuildDirParameters &paramet
return Utils::FilePath::fromString(tmpDirIt->second->path());
}
+void BuildDirManager::updateReparseParameters(const int parameters)
+{
+ m_reparseParameters |= parameters;
+}
+
+int BuildDirManager::takeReparseParameters()
+{
+ int result = m_reparseParameters;
+ m_reparseParameters = REPARSE_DEFAULT;
+ return result;
+}
+
void BuildDirManager::emitDataAvailable()
{
if (!isParsing())
@@ -104,27 +121,32 @@ void BuildDirManager::emitErrorOccured(const QString &message) const
m_isHandlingError = false;
}
+void BuildDirManager::emitReparseRequest() const
+{
+ if (m_reparseParameters & REPARSE_URGENT)
+ emit requestReparse();
+ else
+ emit requestDelayedReparse();
+}
+
void BuildDirManager::updateReaderType(const BuildDirParameters &p,
std::function<void()> todo)
{
- if (!m_reader || !m_reader->isCompatible(p)) {
- m_reader.reset(BuildDirReader::createReader(p));
- connect(m_reader.get(), &BuildDirReader::configurationStarted,
- this, &BuildDirManager::parsingStarted);
- connect(m_reader.get(), &BuildDirReader::dataAvailable,
- this, &BuildDirManager::emitDataAvailable);
- connect(m_reader.get(), &BuildDirReader::errorOccured,
- this, &BuildDirManager::emitErrorOccured);
- connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty);
- }
+ if (!m_reader || !m_reader->isCompatible(p))
+ m_reader = BuildDirReader::createReader(p);
+
QTC_ASSERT(m_reader, return);
- m_reader->setParameters(p);
+ connect(m_reader.get(), &BuildDirReader::configurationStarted,
+ this, &BuildDirManager::parsingStarted);
+ connect(m_reader.get(), &BuildDirReader::dataAvailable,
+ this, &BuildDirManager::emitDataAvailable);
+ connect(m_reader.get(), &BuildDirReader::errorOccured,
+ this, &BuildDirManager::emitErrorOccured);
+ connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty);
+ connect(m_reader.get(), &BuildDirReader::isReadyNow, this, todo);
- if (m_reader->isReady())
- todo();
- else
- connect(m_reader.get(), &BuildDirReader::isReadyNow, this, todo);
+ m_reader->setParameters(p);
}
bool BuildDirManager::hasConfigChanged()
@@ -140,7 +162,10 @@ bool BuildDirManager::hasConfigChanged()
const QByteArrayList criticalKeys
= {GENERATOR_KEY, CMAKE_COMMAND_KEY, CMAKE_C_COMPILER_KEY, CMAKE_CXX_COMPILER_KEY};
- const CMakeConfig currentConfig = takeCMakeConfiguration();
+ QString errorMessage;
+ const CMakeConfig currentConfig = takeCMakeConfiguration(errorMessage);
+ if (!errorMessage.isEmpty())
+ return false;
const CMakeTool *tool = m_parameters.cmakeTool();
QTC_ASSERT(tool, return false); // No cmake... we should not have ended up here in the first place
@@ -193,9 +218,18 @@ bool BuildDirManager::isParsing() const
return m_reader && m_reader->isParsing();
}
+void BuildDirManager::stopParsingAndClearState()
+{
+ if (m_reader) {
+ disconnect(m_reader.get(), nullptr, this, nullptr);
+ m_reader->stop();
+ }
+ m_reader.reset();
+ resetData();
+}
+
void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &parameters,
- int newReaderReparseOptions,
- int existingReaderReparseOptions)
+ const int reparseParameters)
{
if (!parameters.cmakeTool()) {
TaskHub::addTask(Task::Error,
@@ -203,49 +237,40 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par
ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
return;
}
- QTC_ASSERT(parameters.isValid(), return);
-
- if (m_reader)
- m_reader->stop();
+ QTC_ASSERT(parameters.isValid(), return );
- BuildDirReader *old = m_reader.get();
+ stopParsingAndClearState();
m_parameters = parameters;
m_parameters.workDirectory = workDirectory(parameters);
+ updateReparseParameters(reparseParameters);
- updateReaderType(m_parameters,
- [this, old, newReaderReparseOptions, existingReaderReparseOptions]() {
- int options = REPARSE_DEFAULT;
- if (old != m_reader.get()) {
- options = newReaderReparseOptions;
- } else {
- if (!QFileInfo::exists(m_parameters.workDirectory.toString() + "/CMakeCache.txt"))
- options = newReaderReparseOptions;
- else
- options = existingReaderReparseOptions;
- }
- emit requestReparse(options);
- });
+ updateReaderType(m_parameters, [this]() { emitReparseRequest(); });
}
CMakeBuildConfiguration *BuildDirManager::buildConfiguration() const
{
- return m_parameters.buildConfiguration;
+ if (m_project->activeTarget() && m_project->activeTarget()->activeBuildConfiguration() == m_parameters.buildConfiguration)
+ return m_parameters.buildConfiguration;
+ return nullptr;
}
-void BuildDirManager::becameDirty()
+FilePath BuildDirManager::buildDirectory() const
{
- if (isParsing())
- return;
+ return buildConfiguration() ? m_parameters.buildDirectory : FilePath();
+}
- if (!m_parameters.buildConfiguration || !m_parameters.buildConfiguration->isActive())
+void BuildDirManager::becameDirty()
+{
+ if (isParsing() || !buildConfiguration())
return;
const CMakeTool *tool = m_parameters.cmakeTool();
if (!tool->isAutoRun())
return;
- emit requestReparse(REPARSE_CHECK_CONFIGURATION);
+ updateReparseParameters(REPARSE_CHECK_CONFIGURATION | REPARSE_SCAN);
+ emit requestReparse();
}
void BuildDirManager::resetData()
@@ -267,43 +292,83 @@ bool BuildDirManager::persistCMakeState()
BuildDirParameters newParameters = m_parameters;
newParameters.workDirectory.clear();
- setParametersAndRequestParse(newParameters, REPARSE_URGENT | REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION,
- REPARSE_FAIL);
+ setParametersAndRequestParse(newParameters,
+ REPARSE_URGENT | REPARSE_FORCE_CMAKE_RUN
+ | REPARSE_FORCE_CONFIGURATION | REPARSE_CHECK_CONFIGURATION);
return true;
}
-void BuildDirManager::parse(int reparseParameters)
+void BuildDirManager::requestFilesystemScan()
{
- QTC_ASSERT(m_parameters.isValid(), return);
+ updateReparseParameters(REPARSE_SCAN);
+}
+
+bool BuildDirManager::isFilesystemScanRequested() const
+{
+ return m_reparseParameters & REPARSE_SCAN;
+}
+
+void BuildDirManager::parse()
+{
+ QTC_ASSERT(m_parameters.isValid(), return );
QTC_ASSERT(m_reader, return);
- QTC_ASSERT((reparseParameters & REPARSE_FAIL) == 0, return);
- QTC_ASSERT((reparseParameters & REPARSE_IGNORE) == 0, return);
m_reader->stop();
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
- if (reparseParameters & REPARSE_CHECK_CONFIGURATION) {
- if (checkConfiguration())
- reparseParameters |= REPARSE_FORCE_CONFIGURATION;
+ int reparseParameters = takeReparseParameters();
+
+ qCDebug(cmakeBuildDirManagerLog)
+ << "Parse called with flags:" << flagsString(reparseParameters);
+
+ const QString cache = m_parameters.workDirectory.pathAppended("CMakeCache.txt").toString();
+ if (!QFileInfo::exists(cache)) {
+ reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN;
+ qCDebug(cmakeBuildDirManagerLog)
+ << "No" << cache << "file found, new flags:" << flagsString(reparseParameters);
+ } else if (reparseParameters & REPARSE_CHECK_CONFIGURATION) {
+ if (checkConfiguration()) {
+ reparseParameters |= REPARSE_FORCE_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN;
+ qCDebug(cmakeBuildDirManagerLog)
+ << "Config check triggered flags change:" << flagsString(reparseParameters);
+ }
}
- m_reader->parse(reparseParameters & REPARSE_FORCE_CONFIGURATION);
+ m_reader->parse(reparseParameters & REPARSE_FORCE_CMAKE_RUN,
+ reparseParameters & REPARSE_FORCE_CONFIGURATION);
}
-void BuildDirManager::generateProjectTree(CMakeProjectNode *root, const QList<const FileNode *> &allFiles) const
+QVector<FilePath> BuildDirManager::takeProjectFilesToWatch()
{
- QTC_ASSERT(!m_isHandlingError, return);
- QTC_ASSERT(m_reader, return);
+ QTC_ASSERT(!m_isHandlingError, return {});
+ QTC_ASSERT(m_reader, return {});
- m_reader->generateProjectTree(root, allFiles);
+ Utils::FilePath sourceDir = m_parameters.sourceDirectory;
+ Utils::FilePath buildDir = m_parameters.workDirectory;
+
+ return Utils::filtered(m_reader->takeProjectFilesToWatch(),
+ [&sourceDir,
+ &buildDir](const Utils::FilePath &p) {
+ return p.isChildOf(sourceDir)
+ || p.isChildOf(buildDir);
+ });
+}
+
+std::unique_ptr<CMakeProjectNode> BuildDirManager::generateProjectTree(
+ const QList<const FileNode *> &allFiles, QString &errorMessage) const
+{
+ QTC_ASSERT(!m_isHandlingError, return {});
+ QTC_ASSERT(m_reader, return {});
+
+ return m_reader->generateProjectTree(allFiles, errorMessage);
}
-CppTools::RawProjectParts BuildDirManager::createRawProjectParts() const
+RawProjectParts BuildDirManager::createRawProjectParts(QString &errorMessage) const
{
QTC_ASSERT(!m_isHandlingError, return {});
QTC_ASSERT(m_reader, return {});
- return m_reader->createRawProjectParts();
+ return m_reader->createRawProjectParts(errorMessage);
}
void BuildDirManager::clearCache()
@@ -330,13 +395,13 @@ static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManage
target.title = title;
target.targetType = UtilityType;
- target.workingDirectory = bdm->buildConfiguration()->buildDirectory();
- target.sourceDirectory = bdm->buildConfiguration()->target()->project()->projectDirectory();
+ target.workingDirectory = bdm->buildDirectory();
+ target.sourceDirectory = bdm->project()->projectDirectory();
return target;
}
-QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets() const
+QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets(QString &errorMessage) const
{
QList<CMakeBuildTarget> result = { utilityTarget(CMakeBuildStep::allTarget(), this),
utilityTarget(CMakeBuildStep::cleanTarget(), this),
@@ -345,22 +410,34 @@ QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets() const
QTC_ASSERT(!m_isHandlingError, return result);
if (m_reader) {
- result.append(Utils::filtered(m_reader->takeBuildTargets(), [](const CMakeBuildTarget &bt) {
- return bt.title != CMakeBuildStep::allTarget()
- && bt.title != CMakeBuildStep::cleanTarget()
- && bt.title != CMakeBuildStep::installTarget()
- && bt.title != CMakeBuildStep::testTarget();
- }));
+ QList<CMakeBuildTarget> readerTargets
+ = Utils::filtered(m_reader->takeBuildTargets(errorMessage),
+ [](const CMakeBuildTarget &bt) {
+ return bt.title != CMakeBuildStep::allTarget()
+ && bt.title != CMakeBuildStep::cleanTarget()
+ && bt.title != CMakeBuildStep::installTarget()
+ && bt.title != CMakeBuildStep::testTarget();
+ });
+
+ // Guess at the target definition position when no details are known
+ for (CMakeBuildTarget &t : readerTargets) {
+ if (t.backtrace.isEmpty()) {
+ t.backtrace.append(
+ FolderNode::LocationInfo(tr("CMakeLists.txt in source directory"),
+ t.sourceDirectory.pathAppended("CMakeLists.txt")));
+ }
+ }
+ result.append(readerTargets);
}
return result;
}
-CMakeConfig BuildDirManager::takeCMakeConfiguration() const
+CMakeConfig BuildDirManager::takeCMakeConfiguration(QString &errorMessage) const
{
if (!m_reader)
return CMakeConfig();
- CMakeConfig result = m_reader->takeParsedConfiguration();
+ CMakeConfig result = m_reader->takeParsedConfiguration(errorMessage);
for (auto &ci : result)
ci.inCMakeCache = true;
@@ -381,14 +458,35 @@ CMakeConfig BuildDirManager::parseCMakeConfiguration(const Utils::FilePath &cach
return result;
}
+QString BuildDirManager::flagsString(int reparseFlags)
+{
+ QString result;
+ if (reparseFlags == REPARSE_DEFAULT) {
+ result = "<NONE>";
+ } else {
+ if (reparseFlags & REPARSE_URGENT)
+ result += " URGENT";
+ if (reparseFlags & REPARSE_FORCE_CMAKE_RUN)
+ result += " FORCE_CMAKE_RUN";
+ if (reparseFlags & REPARSE_FORCE_CONFIGURATION)
+ result += " FORCE_CONFIG";
+ if (reparseFlags & REPARSE_CHECK_CONFIGURATION)
+ result += " CHECK_CONFIG";
+ if (reparseFlags & REPARSE_SCAN)
+ result += " SCAN";
+ }
+ return result.trimmed();
+}
+
bool BuildDirManager::checkConfiguration()
{
- QTC_ASSERT(m_parameters.isValid(), return false);
+ CMakeBuildConfiguration *bc = buildConfiguration();
+ QTC_ASSERT(m_parameters.isValid() || !bc, return false);
if (m_parameters.workDirectory != m_parameters.buildDirectory) // always throw away changes in the tmpdir!
return false;
- const CMakeConfig cache = m_parameters.buildConfiguration->configurationFromCMake();
+ const CMakeConfig cache = bc->configurationFromCMake();
if (cache.isEmpty())
return false; // No cache file yet.
@@ -434,8 +532,8 @@ bool BuildDirManager::checkConfiguration()
box->exec();
if (box->clickedButton() == applyButton) {
m_parameters.configuration = newConfig;
- QSignalBlocker blocker(m_parameters.buildConfiguration);
- m_parameters.buildConfiguration->setConfigurationForCMake(newConfig);
+ QSignalBlocker blocker(bc);
+ bc->setConfigurationForCMake(newConfig);
return false;
} else if (box->clickedButton() == defaultButton)
return true;
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h
index e2f9b8ff05..91233b79a8 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.h
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.h
@@ -27,10 +27,11 @@
#include "builddirparameters.h"
#include "builddirreader.h"
+#include "cmakebuildsystem.h"
#include "cmakebuildtarget.h"
#include "cmakeconfigitem.h"
-#include <cpptools/cpprawprojectpart.h>
+#include <projectexplorer/rawprojectpart.h>
#include <utils/fileutils.h>
#include <utils/temporarydirectory.h>
@@ -46,6 +47,7 @@ namespace ProjectExplorer { class FileNode; }
namespace CMakeProjectManager {
+class CMakeProject;
class CMakeTool;
namespace Internal {
@@ -58,50 +60,65 @@ class BuildDirManager : public QObject
Q_OBJECT
public:
- BuildDirManager();
+ enum ReparseParameters {
+ REPARSE_DEFAULT = 0, // Nothing special:-)
+ REPARSE_FORCE_CMAKE_RUN = (1 << 0), // Force cmake to run
+ REPARSE_FORCE_CONFIGURATION = (1 << 1), // Force configuration arguments to cmake
+ REPARSE_CHECK_CONFIGURATION = (1 << 2), // Check for on-disk config and QtC config diff
+ REPARSE_SCAN = (1 << 3), // Run filesystem scan
+ REPARSE_URGENT = (1 << 4), // Do not delay the parser run by 1s
+ };
+
+ static QString flagsString(int reparseFlags);
+
+ BuildDirManager(CMakeProject *project);
~BuildDirManager() final;
bool isParsing() const;
+ void stopParsingAndClearState();
+
void setParametersAndRequestParse(const BuildDirParameters &parameters,
- int newReaderReparseOptions, int existingReaderReparseOptions);
+ const int reparseOptions);
+ // nullptr if the BC is not active anymore!
CMakeBuildConfiguration *buildConfiguration() const;
+ CMakeProject *project() const {return m_project; }
+ Utils::FilePath buildDirectory() const;
void clearCache();
void resetData();
bool persistCMakeState();
- void parse(int reparseParameters);
+ void requestFilesystemScan();
+ bool isFilesystemScanRequested() const;
+ void parse();
- void generateProjectTree(CMakeProjectNode *root,
- const QList<const ProjectExplorer::FileNode *> &allFiles) const;
- CppTools::RawProjectParts createRawProjectParts() const;
+ QVector<Utils::FilePath> takeProjectFilesToWatch();
+ std::unique_ptr<CMakeProjectNode> generateProjectTree(const QList<const ProjectExplorer::FileNode *> &allFiles,
+ QString &errorMessage) const;
+ ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage) const;
- QList<CMakeBuildTarget> takeBuildTargets() const;
- CMakeConfig takeCMakeConfiguration() const;
+ QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) const;
+ CMakeConfig takeCMakeConfiguration(QString &errorMessage) const;
static CMakeConfig parseCMakeConfiguration(const Utils::FilePath &cacheFile,
- QString *errorMessage);
-
- enum ReparseParameters { REPARSE_DEFAULT = 0, // use defaults
- REPARSE_URGENT = 1, // Do not wait for more requests, start ASAP
- REPARSE_FORCE_CONFIGURATION = 2, // Force configuration arguments to cmake
- REPARSE_CHECK_CONFIGURATION = 4, // Check and warn if on-disk config and QtC config differ
- REPARSE_SCAN = 8,
- REPARSE_IGNORE = 16, // Do not reparse:-)
- REPARSE_FAIL = 32 // Do not reparse and raise a warning
- };
+ QString *errorMessage);
signals:
- void requestReparse(int reparseParameters) const;
+ void requestReparse() const;
+ void requestDelayedReparse() const;
void parsingStarted() const;
void dataAvailable() const;
void errorOccured(const QString &err) const;
private:
+ void updateReparseParameters(const int parameters);
+ int takeReparseParameters();
+
void emitDataAvailable();
void emitErrorOccured(const QString &message) const;
+ void emitReparseRequest() const;
bool checkConfiguration();
Utils::FilePath workDirectory(const BuildDirParameters &parameters) const;
@@ -114,6 +131,8 @@ private:
void becameDirty();
BuildDirParameters m_parameters;
+ int m_reparseParameters;
+ CMakeProject *m_project = nullptr;
mutable std::unordered_map<Utils::FilePath, std::unique_ptr<Utils::TemporaryDirectory>> m_buildDirToTempDir;
mutable std::unique_ptr<BuildDirReader> m_reader;
mutable bool m_isHandlingError = false;
diff --git a/src/plugins/cmakeprojectmanager/builddirreader.cpp b/src/plugins/cmakeprojectmanager/builddirreader.cpp
index 3cf74ad6f4..ca808d36fd 100644
--- a/src/plugins/cmakeprojectmanager/builddirreader.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirreader.cpp
@@ -25,6 +25,7 @@
#include "builddirreader.h"
+#include "fileapireader.h"
#include "servermodereader.h"
#include "tealeafreader.h"
@@ -39,18 +40,19 @@ namespace Internal {
// BuildDirReader:
// --------------------------------------------------------------------
-BuildDirReader *BuildDirReader::createReader(const BuildDirParameters &p)
+std::unique_ptr<BuildDirReader> BuildDirReader::createReader(const BuildDirParameters &p)
{
CMakeTool *cmake = p.cmakeTool();
- QTC_ASSERT(p.isValid() && cmake, return nullptr);
- if (cmake->hasServerMode())
- return new ServerModeReader;
- return new TeaLeafReader;
-}
-
-void BuildDirReader::setParameters(const BuildDirParameters &p)
-{
- m_parameters = p;
+ QTC_ASSERT(p.isValid() && cmake, return {});
+
+ switch (cmake->readerType()) {
+ case CMakeTool::FileApi:
+ return std::make_unique<FileApiReader>();
+ case CMakeTool::ServerMode:
+ return std::make_unique<ServerModeReader>();
+ default:
+ return std::make_unique<TeaLeafReader>();
+ }
}
} // namespace Internal
diff --git a/src/plugins/cmakeprojectmanager/builddirreader.h b/src/plugins/cmakeprojectmanager/builddirreader.h
index 3e600cfe39..bd04f5676d 100644
--- a/src/plugins/cmakeprojectmanager/builddirreader.h
+++ b/src/plugins/cmakeprojectmanager/builddirreader.h
@@ -30,7 +30,7 @@
#include "cmakeconfigitem.h"
#include "cmaketool.h"
-#include <cpptools/cpprawprojectpart.h>
+#include <projectexplorer/rawprojectpart.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
@@ -38,6 +38,7 @@
#include <QFutureInterface>
#include <QObject>
+#include <QVector>
namespace ProjectExplorer { class FileNode; }
@@ -52,22 +53,23 @@ class BuildDirReader : public QObject
Q_OBJECT
public:
- static BuildDirReader *createReader(const BuildDirParameters &p);
- virtual void setParameters(const BuildDirParameters &p);
+ static std::unique_ptr<BuildDirReader> createReader(const BuildDirParameters &p);
+ virtual void setParameters(const BuildDirParameters &p) = 0;
virtual bool isCompatible(const BuildDirParameters &p) = 0;
virtual void resetData() = 0;
- virtual void parse(bool forceConfiguration) = 0;
+ virtual void parse(bool forceCMakeRun, bool forceConfiguration) = 0;
virtual void stop() = 0;
- virtual bool isReady() const { return true; }
virtual bool isParsing() const = 0;
- virtual QList<CMakeBuildTarget> takeBuildTargets() = 0;
- virtual CMakeConfig takeParsedConfiguration() = 0;
- virtual void generateProjectTree(CMakeProjectNode *root,
- const QList<const ProjectExplorer::FileNode *> &allFiles) = 0;
- virtual CppTools::RawProjectParts createRawProjectParts() const = 0;
+ virtual QVector<Utils::FilePath> takeProjectFilesToWatch() = 0;
+ virtual QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) = 0;
+ virtual CMakeConfig takeParsedConfiguration(QString &errorMessage) = 0;
+ virtual std::unique_ptr<CMakeProjectNode> generateProjectTree(
+ const QList<const ProjectExplorer::FileNode *> &allFiles, QString &errorMessage)
+ = 0;
+ virtual ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage) = 0;
signals:
void isReadyNow() const;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index f7cfa7f33f..95ba123d5b 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -48,11 +48,15 @@
#include <projectexplorer/projectmacroexpander.h>
#include <projectexplorer/target.h>
+#include <qtsupport/qtkitinformation.h>
+
#include <utils/algorithm.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
+#include <QLoggingCategory>
+
using namespace ProjectExplorer;
using namespace Utils;
@@ -73,25 +77,115 @@ Q_DECLARE_METATYPE(CMakeProjectManager::CMakeExtraBuildInfo)
namespace CMakeProjectManager {
namespace Internal {
-const char INITIAL_ARGUMENTS[] = "CMakeProjectManager.CMakeBuildConfiguration.InitialArgument"; // Obsolete since QtC 3.7
+Q_LOGGING_CATEGORY(cmakeBuildConfigurationLog, "qtc.cmake.bc", QtWarningMsg);
+
const char CONFIGURATION_KEY[] = "CMake.Configuration";
CMakeBuildConfiguration::CMakeBuildConfiguration(Target *parent, Core::Id id)
: BuildConfiguration(parent, id)
+ , m_buildDirManager(qobject_cast<CMakeProject *>(parent->project()))
{
- auto project = target()->project();
- setBuildDirectory(shadowBuildDirectory(project->projectFilePath(),
+ setBuildDirectory(shadowBuildDirectory(project()->projectFilePath(),
target()->kit(),
- displayName(), BuildConfiguration::Unknown));
- connect(project, &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
+ displayName(),
+ BuildConfiguration::Unknown));
+
+ BuildSystem *bs = qobject_cast<CMakeBuildSystem *>(project()->buildSystem());
+
+ // BuildDirManager:
+ connect(&m_buildDirManager, &BuildDirManager::requestReparse, this, [this, bs]() {
+ if (isActive())
+ bs->requestParse();
+ });
+ connect(&m_buildDirManager, &BuildDirManager::requestDelayedReparse, this, [this, bs]() {
+ if (isActive())
+ bs->requestDelayedParse();
+ });
+ connect(&m_buildDirManager,
+ &BuildDirManager::dataAvailable,
+ this,
+ &CMakeBuildConfiguration::handleParsingSucceeded);
+ connect(&m_buildDirManager,
+ &BuildDirManager::errorOccured,
+ this,
+ &CMakeBuildConfiguration::handleParsingFailed);
+ connect(&m_buildDirManager, &BuildDirManager::parsingStarted, this, [this]() {
+ clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
+ });
+
+ // Kit changed:
+ connect(KitManager::instance(), &KitManager::kitUpdated, this, [this](Kit *k) {
+ if (k != target()->kit())
+ return; // not for us...
+ // Build configuration has not changed, but Kit settings might have:
+ // reparse and check the configuration, independent of whether the reader has changed
+ m_buildDirManager.setParametersAndRequestParse(BuildDirParameters(this),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ });
+
+ // Became active/inactive:
+ connect(project(), &Project::activeBuildConfigurationChanged, this, [this]() {
+ if (isActive()) {
+ // Build configuration has switched:
+ // * Check configuration if reader changes due to it not existing yet:-)
+ // * run cmake without configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(this),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ } else {
+ m_buildDirManager.stopParsingAndClearState();
+ }
+ });
+
+ // BuildConfiguration changed:
+ connect(this, &CMakeBuildConfiguration::environmentChanged, this, [this]() {
+ if (isActive()) {
+ // The environment on our BC has changed:
+ // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
+ // * run cmake without configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(this),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ }
+ });
+ connect(this, &CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
+ if (isActive()) {
+ // The build directory of our BC has changed:
+ // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
+ // * run cmake without configuration arguments if the reader stays
+ // If no configuration exists, then the arguments will get added automatically by
+ // the reader.
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(this),
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ }
+ });
+ connect(this, &CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() {
+ if (isActive()) {
+ // The CMake configuration has changed on our BC:
+ // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
+ // * run cmake with configuration arguments if the reader stays
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(this),
+ BuildDirManager::REPARSE_FORCE_CONFIGURATION);
+ }
+ });
+
+ connect(parent->project(), &Project::projectFileIsDirty, this, [this]() {
+ if (isActive()) {
+ m_buildDirManager
+ .setParametersAndRequestParse(BuildDirParameters(this),
+ BuildDirManager::REPARSE_DEFAULT);
+ }
+ });
}
-void CMakeBuildConfiguration::initialize(const BuildInfo &info)
+void CMakeBuildConfiguration::initialize()
{
- BuildConfiguration::initialize(info);
+ BuildConfiguration::initialize();
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
- buildSteps->appendStep(new CMakeBuildStep(buildSteps));
+ buildSteps->appendStep(Constants::CMAKE_BUILD_STEP_ID);
if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== Android::Constants::ANDROID_DEVICE_TYPE) {
@@ -110,10 +204,21 @@ void CMakeBuildConfiguration::initialize(const BuildInfo &info)
CMakeProjectManager::CMakeConfigItem::Type::PATH,
"Android CMake toolchain file",
ndkLocation.pathAppended("build/cmake/android.toolchain.cmake").toUserOutput().toUtf8()});
+ auto androidAbis = bs->data(Android::Constants::AndroidABIs).toStringList();
+ QString preferredAbi;
+ if (androidAbis.contains("arm64-v8a")) {
+ preferredAbi = "arm64-v8a";
+ } else if (androidAbis.isEmpty() || androidAbis.contains("armeabi-v7a")) {
+ preferredAbi = "armeabi-v7a";
+ } else {
+ preferredAbi = androidAbis.first();
+ }
+ // FIXME: configmodel doesn't care about our androidAbis list...
m_initialConfiguration.prepend(CMakeProjectManager::CMakeConfigItem{"ANDROID_ABI",
CMakeProjectManager::CMakeConfigItem::Type::STRING,
"Android ABI",
- bs->data(Android::Constants::AndroidABI).toString().toUtf8()});
+ preferredAbi.toLatin1(),
+ androidAbis});
m_initialConfiguration.prepend(CMakeProjectManager::CMakeConfigItem{"ANDROID_STL",
CMakeProjectManager::CMakeConfigItem::Type::STRING,
"Android STL",
@@ -125,21 +230,17 @@ void CMakeBuildConfiguration::initialize(const BuildInfo &info)
}
BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
- cleanSteps->appendStep(new CMakeBuildStep(cleanSteps));
+ cleanSteps->appendStep(Constants::CMAKE_BUILD_STEP_ID);
- if (info.buildDirectory.isEmpty()) {
+ if (initialBuildDirectory().isEmpty()) {
auto project = target()->project();
setBuildDirectory(CMakeBuildConfiguration::shadowBuildDirectory(project->projectFilePath(),
target()->kit(),
- info.displayName, info.buildType));
+ initialDisplayName(),
+ initialBuildType()));
}
- auto extraInfo = info.extraInfo.value<CMakeExtraBuildInfo>();
- setConfigurationForCMake(extraInfo.configuration);
-}
-
-bool CMakeBuildConfiguration::isEnabled() const
-{
- return m_error.isEmpty() && !isParsing();
+ auto info = extraInfo().value<CMakeExtraBuildInfo>();
+ setConfigurationForCMake(info.configuration);
}
QString CMakeBuildConfiguration::disabledReason() const
@@ -166,32 +267,11 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
[](const QString &v) { return CMakeConfigItem::fromString(v); }),
[](const CMakeConfigItem &c) { return !c.isNull(); });
- // Legacy (pre QtC 3.7):
- const QStringList args = QtcProcess::splitArgs(map.value(QLatin1String(INITIAL_ARGUMENTS)).toString());
- CMakeConfig legacyConf;
- bool nextIsConfig = false;
- foreach (const QString &a, args) {
- if (a == QLatin1String("-D")) {
- nextIsConfig = true;
- continue;
- }
- if (!a.startsWith(QLatin1String("-D")))
- continue;
- legacyConf << CMakeConfigItem::fromString(nextIsConfig ? a : a.mid(2));
- nextIsConfig = false;
- }
- // End Legacy
-
- setConfigurationForCMake(legacyConf + conf);
+ setConfigurationForCMake(conf);
return true;
}
-bool CMakeBuildConfiguration::isParsing() const
-{
- return project()->isParsing() && isActive();
-}
-
const QList<BuildTargetInfo> CMakeBuildConfiguration::appTargets() const
{
QList<BuildTargetInfo> appTargetList;
@@ -206,7 +286,19 @@ const QList<BuildTargetInfo> CMakeBuildConfiguration::appTargets() const
bti.targetFilePath = ct.executable;
bti.projectFilePath = ct.sourceDirectory.stringAppended("/");
bti.workingDirectory = ct.workingDirectory;
- bti.buildKey = CMakeTargetNode::generateId(ct.sourceDirectory, ct.title);
+ bti.buildKey = ct.title;
+
+ // Workaround for QTCREATORBUG-19354:
+ bti.runEnvModifier = [this](Environment &env, bool) {
+ if (HostOsInfo::isWindowsHost()) {
+ const Kit *k = target()->kit();
+ if (const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k)) {
+ const QString installBinPath = qt->qmakeProperty("QT_INSTALL_BINS");
+ env.prependOrSetPath(installBinPath);
+ }
+ }
+ };
+
appTargetList.append(bti);
}
}
@@ -237,7 +329,7 @@ DeploymentData CMakeBuildConfiguration::deploymentData() const
for (const CMakeBuildTarget &ct : m_buildTargets) {
if (ct.targetType == ExecutableType || ct.targetType == DynamicLibraryType) {
if (!ct.executable.isEmpty()
- && !result.deployableForLocalFile(ct.executable.toString()).isValid()) {
+ && !result.deployableForLocalFile(ct.executable).isValid()) {
result.addFile(ct.executable.toString(),
deploymentPrefix + buildDir.relativeFilePath(ct.executable.toFileInfo().dir().path()),
DeployableFile::TypeExecutable);
@@ -267,7 +359,7 @@ FilePath CMakeBuildConfiguration::shadowBuildDirectory(const FilePath &projectFi
return FilePath();
const QString projectName = projectFilePath.parentDir().fileName();
- ProjectMacroExpander expander(projectFilePath.toString(), projectName, k, bcName, buildType);
+ ProjectMacroExpander expander(projectFilePath, projectName, k, bcName, buildType);
QDir projectDir = QDir(Project::projectDirectory(projectFilePath).toString());
QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate());
buildPath.replace(" ", "-");
@@ -427,6 +519,65 @@ void CMakeBuildConfiguration::setWarning(const QString &message)
emit warningOccured(m_warning);
}
+void CMakeBuildConfiguration::handleParsingSucceeded()
+{
+ if (!isActive()) {
+ m_buildDirManager.stopParsingAndClearState();
+ return;
+ }
+
+ clearError();
+
+ QString errorMessage;
+ {
+ const QList<CMakeBuildTarget> buildTargets = m_buildDirManager.takeBuildTargets(
+ errorMessage);
+ checkAndReportError(errorMessage);
+ setBuildTargets(buildTargets);
+ }
+
+ {
+ const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration(errorMessage);
+ checkAndReportError(errorMessage);
+ setConfigurationFromCMake(cmakeConfig);
+ }
+
+ {
+ target()->setApplicationTargets(appTargets());
+ target()->setDeploymentData(deploymentData());
+ }
+
+ static_cast<CMakeBuildSystem *>(project()->buildSystem())->handleParsingSuccess(this);
+}
+
+void CMakeBuildConfiguration::handleParsingFailed(const QString &msg)
+{
+ setError(msg);
+
+ QString errorMessage;
+ setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration(errorMessage));
+ // ignore errorMessage here, we already got one.
+
+ static_cast<CMakeBuildSystem *>(project()->buildSystem())->handleParsingError(this);
+}
+
+std::unique_ptr<CMakeProjectNode> CMakeBuildConfiguration::generateProjectTree(
+ const QList<const FileNode *> &allFiles)
+{
+ QString errorMessage;
+ auto root = m_buildDirManager.generateProjectTree(allFiles, errorMessage);
+ checkAndReportError(errorMessage);
+ return root;
+}
+
+void CMakeBuildConfiguration::checkAndReportError(QString &errorMessage)
+{
+ if (!errorMessage.isEmpty()) {
+ setError(errorMessage);
+ errorMessage.clear();
+ }
+}
+
QString CMakeBuildConfiguration::error() const
{
return m_error;
@@ -448,13 +599,15 @@ ProjectExplorer::NamedWidget *CMakeBuildConfiguration::createConfigWidget()
CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory()
{
- registerBuildConfiguration<CMakeBuildConfiguration>("CMakeProjectManager.CMakeBuildConfiguration");
+ registerBuildConfiguration<CMakeBuildConfiguration>(
+ "CMakeProjectManager.CMakeBuildConfiguration");
setSupportedProjectType(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
setSupportedProjectMimeTypeName(Constants::CMAKEPROJECTMIMETYPE);
}
-CMakeBuildConfigurationFactory::BuildType CMakeBuildConfigurationFactory::buildTypeFromByteArray(const QByteArray &in)
+CMakeBuildConfigurationFactory::BuildType CMakeBuildConfigurationFactory::buildTypeFromByteArray(
+ const QByteArray &in)
{
const QByteArray bt = in.toLower();
if (bt == "debug")
@@ -468,7 +621,8 @@ CMakeBuildConfigurationFactory::BuildType CMakeBuildConfigurationFactory::buildT
return BuildTypeNone;
}
-BuildConfiguration::BuildType CMakeBuildConfigurationFactory::cmakeBuildTypeToBuildType(const CMakeBuildConfigurationFactory::BuildType &in)
+BuildConfiguration::BuildType CMakeBuildConfigurationFactory::cmakeBuildTypeToBuildType(
+ const CMakeBuildConfigurationFactory::BuildType &in)
{
// Cover all common CMake build types
if (in == BuildTypeRelease || in == BuildTypeMinSizeRel)
@@ -481,30 +635,23 @@ BuildConfiguration::BuildType CMakeBuildConfigurationFactory::cmakeBuildTypeToBu
return BuildConfiguration::Unknown;
}
-QList<BuildInfo> CMakeBuildConfigurationFactory::availableBuilds(const Target *parent) const
+QList<BuildInfo> CMakeBuildConfigurationFactory::availableBuilds(const Kit *k,
+ const FilePath &projectPath,
+ bool forSetup) const
{
QList<BuildInfo> result;
- for (int type = BuildTypeNone; type != BuildTypeLast; ++type) {
- result << createBuildInfo(parent->kit(),
- parent->project()->projectDirectory().toString(),
- BuildType(type));
- }
- return result;
-}
+ FilePath path = forSetup ? Project::projectDirectory(projectPath) : projectPath;
-QList<BuildInfo> CMakeBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
-{
- QList<BuildInfo> result;
- const FilePath projectPathName = FilePath::fromString(projectPath);
for (int type = BuildTypeDebug; type != BuildTypeLast; ++type) {
- BuildInfo info = createBuildInfo(k,
- ProjectExplorer::Project::projectDirectory(projectPathName).toString(),
- BuildType(type));
- info.displayName = info.typeName;
- info.buildDirectory
- = CMakeBuildConfiguration::shadowBuildDirectory(projectPathName, k,
- info.displayName, info.buildType);
+ BuildInfo info = createBuildInfo(k, path.toString(), BuildType(type));
+ if (forSetup) {
+ info.displayName = info.typeName;
+ info.buildDirectory = CMakeBuildConfiguration::shadowBuildDirectory(projectPath,
+ k,
+ info.displayName,
+ info.buildType);
+ }
result << info;
}
return result;
@@ -587,9 +734,14 @@ ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildTyp
// Cover all common CMake build types
const CMakeBuildConfigurationFactory::BuildType cmakeBuildType
- = CMakeBuildConfigurationFactory::buildTypeFromByteArray(cmakeBuildTypeName);
+ = CMakeBuildConfigurationFactory::buildTypeFromByteArray(cmakeBuildTypeName);
return CMakeBuildConfigurationFactory::cmakeBuildTypeToBuildType(cmakeBuildType);
}
+CMakeProject *CMakeBuildConfiguration::project() const
+{
+ return qobject_cast<CMakeProject *>(BuildConfiguration::project());
+}
+
} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
index 050dd6f084..833f77131f 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
@@ -29,13 +29,12 @@
#include "cmakeproject.h"
#include "configmodel.h"
-#include <cpptools/cpprawprojectpart.h>
-
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h>
namespace CMakeProjectManager {
+class CMakeBuildSystem;
class CMakeExtraBuildInfo;
class CMakeProject;
@@ -54,14 +53,14 @@ class CMakeBuildConfiguration : public ProjectExplorer::BuildConfiguration
public:
void emitBuildTypeChanged();
- bool isEnabled() const override;
-
CMakeConfig configurationForCMake() const;
CMakeConfig configurationFromCMake() const;
QString error() const;
QString warning() const;
+ CMakeProject *project() const;
+
QStringList buildTargetTitles() const;
const QList<CMakeBuildTarget> &buildTargets() const;
const QList<ProjectExplorer::BuildTargetInfo> appTargets() const;
@@ -83,15 +82,13 @@ private:
QVariantMap toMap() const override;
BuildType buildType() const override;
- void initialize(const ProjectExplorer::BuildInfo &info) override;
+ void initialize() override;
QString disabledReason() const override;
ProjectExplorer::NamedWidget *createConfigWidget() override;
bool fromMap(const QVariantMap &map) override;
- bool isParsing() const;
-
enum ForceEnabledChanged { False, True };
void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);
@@ -103,6 +100,16 @@ private:
void setError(const QString &message);
void setWarning(const QString &message);
+ void handleParsingSucceeded();
+ void handleParsingFailed(const QString &msg);
+
+ std::unique_ptr<CMakeProjectNode> generateProjectTree(
+ const QList<const ProjectExplorer::FileNode *> &allFiles);
+
+ void checkAndReportError(QString &errorMessage);
+
+ Internal::BuildDirManager m_buildDirManager;
+
CMakeConfig m_configurationForCMake;
CMakeConfig m_initialConfiguration;
QString m_error;
@@ -112,6 +119,7 @@ private:
QList<CMakeBuildTarget> m_buildTargets;
friend class CMakeBuildSettingsWidget;
+ friend class CMakeProjectManager::CMakeBuildSystem;
friend class CMakeProjectManager::CMakeProject;
friend class BuildDirManager;
};
@@ -134,9 +142,9 @@ public:
static BuildType buildTypeFromByteArray(const QByteArray &in);
static ProjectExplorer::BuildConfiguration::BuildType cmakeBuildTypeToBuildType(const BuildType &in);
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override;
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k,
+ const Utils::FilePath &projectPath,
+ bool forSetup) const override;
private:
ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k,
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
index cf94cbf23d..c8b4b8d70b 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp
@@ -91,7 +91,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
setDisplayName(tr("CMake"));
auto vbox = new QVBoxLayout(this);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
auto container = new Utils::DetailsWidget;
container->setState(Utils::DetailsWidget::NoSummary);
vbox->addWidget(container);
@@ -100,7 +100,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
container->setWidget(details);
auto mainLayout = new QGridLayout(details);
- mainLayout->setMargin(0);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setColumnStretch(1, 10);
auto project = static_cast<CMakeProject *>(bc->project());
@@ -252,7 +252,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
m_showProgressTimer.start();
});
- if (m_buildConfiguration->isParsing())
+ if (project->isParsing())
m_showProgressTimer.start();
else {
m_configModel->setConfiguration(m_buildConfiguration->configurationFromCMake());
@@ -363,7 +363,7 @@ void CMakeBuildSettingsWidget::setWarning(const QString &message)
void CMakeBuildSettingsWidget::updateButtonState()
{
- const bool isParsing = m_buildConfiguration->isParsing();
+ const bool isParsing = m_buildConfiguration->project()->isParsing();
const bool hasChanges = m_configModel->hasChanges();
m_resetButton->setEnabled(hasChanges && !isParsing);
m_reconfigureButton->setEnabled((hasChanges || m_configModel->hasCMakeChanges()) && !isParsing);
@@ -408,7 +408,7 @@ void CMakeBuildSettingsWidget::setConfigurationForCMake()
void CMakeBuildSettingsWidget::updateSelection(const QModelIndex &current, const QModelIndex &previous)
{
- Q_UNUSED(previous);
+ Q_UNUSED(previous)
m_editButton->setEnabled(current.isValid() && current.flags().testFlag(Qt::ItemIsEditable));
m_unsetButton->setEnabled(current.isValid() && current.flags().testFlag(Qt::ItemIsSelectable));
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index 05ce969a85..68b514d6f1 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -30,7 +30,6 @@
#include "cmakeparser.h"
#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
-#include "cmakerunconfiguration.h"
#include "cmaketool.h"
#include <projectexplorer/buildsteplist.h>
@@ -52,9 +51,10 @@
#include <utils/qtcprocess.h>
#include <utils/pathchooser.h>
+#include <QCheckBox>
+#include <QDir>
#include <QFormLayout>
#include <QGroupBox>
-#include <QCheckBox>
#include <QLineEdit>
#include <QListWidget>
@@ -83,17 +83,12 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl) :
//: Default display name for the cmake make step.
setDefaultDisplayName(tr("CMake Build"));
- auto bc = qobject_cast<CMakeBuildConfiguration *>(bsl->parent());
- if (!bc) {
- auto t = qobject_cast<Target *>(bsl->parent()->parent());
- QTC_ASSERT(t, return);
- bc = qobject_cast<CMakeBuildConfiguration *>(t->activeBuildConfiguration());
- }
-
// Set a good default build target:
if (m_buildTarget.isEmpty())
setBuildTarget(defaultBuildTarget());
+ setLowPriority();
+
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
connect(project(), &Project::parsingFinished,
this, &CMakeBuildStep::handleBuildTargetChanges);
@@ -104,17 +99,11 @@ CMakeBuildConfiguration *CMakeBuildStep::cmakeBuildConfiguration() const
return static_cast<CMakeBuildConfiguration *>(buildConfiguration());
}
-CMakeRunConfiguration *CMakeBuildStep::targetsActiveRunConfiguration() const
-{
- return qobject_cast<CMakeRunConfiguration *>(target()->activeRunConfiguration());
-}
-
void CMakeBuildStep::handleBuildTargetChanges(bool success)
{
if (!success)
return; // Do not change when parsing failed.
- if (!isCurrentExecutableTarget(m_buildTarget)
- && !static_cast<CMakeProject *>(project())->buildTargetTitles().contains(m_buildTarget)) {
+ if (!isCurrentExecutableTarget(m_buildTarget) && !knownBuildTargets().contains(m_buildTarget)) {
setBuildTarget(defaultBuildTarget());
}
emit buildTargetsChanged();
@@ -168,7 +157,7 @@ bool CMakeBuildStep::init()
canInit = false;
}
- CMakeRunConfiguration *rc = targetsActiveRunConfiguration();
+ RunConfiguration *rc = target()->activeRunConfiguration();
if (isCurrentExecutableTarget(m_buildTarget) && (!rc || rc->buildKey().isEmpty())) {
emit addTask(Task(Task::Error,
QCoreApplication::translate("ProjectExplorer::Task",
@@ -205,14 +194,16 @@ bool CMakeBuildStep::init()
pp->setMacroExpander(bc->macroExpander());
Utils::Environment env = bc->environment();
Utils::Environment::setupEnglishOutput(&env);
- if (!env.value("NINJA_STATUS").startsWith(m_ninjaProgressString))
+ if (!env.expandedValueForKey("NINJA_STATUS").startsWith(m_ninjaProgressString))
env.set("NINJA_STATUS", m_ninjaProgressString + "%o/sec] ");
pp->setEnvironment(env);
pp->setWorkingDirectory(bc->buildDirectory());
pp->setCommandLine(cmakeCommand(rc));
pp->resolveAll();
- setOutputParser(new CMakeParser);
+ CMakeParser *cmakeParser = new CMakeParser;
+ cmakeParser->setSourceDirectory(projectDirectory.toString());
+ setOutputParser(cmakeParser);
appendOutputParser(new GnuMakeParser);
IOutputParser *parser = target()->kit()->createOutputParser();
if (parser)
@@ -273,8 +264,9 @@ BuildStepConfigWidget *CMakeBuildStep::createConfigWidget()
QString CMakeBuildStep::defaultBuildTarget() const
{
- const ProjectConfiguration *const pc = qobject_cast<ProjectConfiguration *>(parent());
- const Core::Id parentId = pc ? pc->id() : Core::Id();
+ const BuildStepList *const bsl = stepList();
+ QTC_ASSERT(bsl, return {});
+ const Core::Id parentId = bsl->id();
if (parentId == ProjectExplorer::Constants::BUILDSTEPS_CLEAN)
return cleanTarget();
if (parentId == ProjectExplorer::Constants::BUILDSTEPS_DEPLOY)
@@ -344,7 +336,7 @@ void CMakeBuildStep::setToolArguments(const QString &list)
m_toolArguments = list;
}
-Utils::CommandLine CMakeBuildStep::cmakeCommand(CMakeRunConfiguration *rc) const
+Utils::CommandLine CMakeBuildStep::cmakeCommand(RunConfiguration *rc) const
{
CMakeTool *tool = CMakeKitAspect::cmakeTool(target()->kit());
@@ -371,12 +363,18 @@ Utils::CommandLine CMakeBuildStep::cmakeCommand(CMakeRunConfiguration *rc) const
if (!m_toolArguments.isEmpty()) {
cmd.addArg("--");
- cmd.addArgs(m_toolArguments);
+ cmd.addArgs(m_toolArguments, Utils::CommandLine::Raw);
}
return cmd;
}
+QStringList CMakeBuildStep::knownBuildTargets()
+{
+ auto bc = qobject_cast<CMakeBuildConfiguration *>(buildConfiguration());
+ return bc ? bc->buildTargetTitles() : QStringList();
+}
+
QString CMakeBuildStep::cleanTarget()
{
return QString("clean");
@@ -415,7 +413,7 @@ CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep
setDisplayName(tr("Build", "CMakeProjectManager::CMakeBuildStepConfigWidget display name."));
auto fl = new QFormLayout(this);
- fl->setMargin(0);
+ fl->setContentsMargins(0, 0, 0, 0);
fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
setLayout(fl);
@@ -428,7 +426,7 @@ CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep
auto frame = new QFrame(this);
frame->setFrameStyle(QFrame::StyledPanel);
auto frameLayout = new QVBoxLayout(frame);
- frameLayout->setMargin(0);
+ frameLayout->setContentsMargins(0, 0, 0, 0);
frameLayout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_buildTargetsList,
Core::ItemViewFind::LightColored));
@@ -444,15 +442,9 @@ CMakeBuildStepConfigWidget::CMakeBuildStepConfigWidget(CMakeBuildStep *buildStep
connect(m_buildStep, &CMakeBuildStep::buildTargetsChanged, this, &CMakeBuildStepConfigWidget::buildTargetsChanged);
connect(m_buildStep, &CMakeBuildStep::targetToBuildChanged, this, &CMakeBuildStepConfigWidget::selectedBuildTargetsChanged);
- m_buildStep->project()->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
- if (static_cast<BuildConfiguration *>(sender())->isActive())
- updateDetails();
- });
- connect(m_buildStep->project(), &Project::activeProjectConfigurationChanged,
- this, [this](ProjectConfiguration *pc) {
- if (pc && pc->isActive())
- updateDetails();
- });
+
+ connect(m_buildStep->buildConfiguration(), &BuildConfiguration::environmentChanged,
+ this, &CMakeBuildStepConfigWidget::updateDetails);
}
void CMakeBuildStepConfigWidget::toolArgumentsEdited()
@@ -475,8 +467,7 @@ void CMakeBuildStepConfigWidget::buildTargetsChanged()
QSignalBlocker blocker(m_buildTargetsList);
m_buildTargetsList->clear();
- auto pro = static_cast<CMakeProject *>(m_buildStep->project());
- QStringList targetList = pro->buildTargetTitles();
+ QStringList targetList = m_buildStep->knownBuildTargets();
targetList.sort();
QFont italics;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.h b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
index 51f621abc7..28c6ccb46e 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
@@ -40,13 +40,15 @@ class CommandLine;
class PathChooser;
} // Utils
-namespace ProjectExplorer { class ToolChain; }
+namespace ProjectExplorer {
+class RunConfiguration;
+class ToolChain;
+} // ProjectManager
namespace CMakeProjectManager {
namespace Internal {
class CMakeBuildConfiguration;
-class CMakeRunConfiguration;
class CMakeBuildStepFactory;
class CMakeBuildStep : public ProjectExplorer::AbstractProcessStep
@@ -67,7 +69,9 @@ public:
QString toolArguments() const;
void setToolArguments(const QString &list);
- Utils::CommandLine cmakeCommand(CMakeRunConfiguration *rc) const;
+ Utils::CommandLine cmakeCommand(ProjectExplorer::RunConfiguration *rc) const;
+
+ QStringList knownBuildTargets();
QVariantMap toMap() const override;
@@ -104,7 +108,6 @@ private:
void handleProjectWasParsed(bool success);
void handleBuildTargetChanges(bool success);
- CMakeRunConfiguration *targetsActiveRunConfiguration() const;
QMetaObject::Connection m_runTrigger;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
new file mode 100644
index 0000000000..2cc69e4c9a
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp
@@ -0,0 +1,380 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "cmakebuildsystem.h"
+
+#include "cmakebuildconfiguration.h"
+#include "cmakeproject.h"
+#include "cmakeprojectconstants.h"
+#include "cmakeprojectnodes.h"
+
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <cpptools/cppprojectupdater.h>
+#include <cpptools/generatedcodemodelsupport.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
+#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <qtsupport/qtcppkitinfo.h>
+
+#include <utils/fileutils.h>
+#include <utils/mimetypes/mimetype.h>
+#include <utils/qtcassert.h>
+
+#include <QLoggingCategory>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace CMakeProjectManager {
+
+using namespace Internal;
+
+Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarningMsg);
+
+// --------------------------------------------------------------------
+// CMakeBuildSystem:
+// --------------------------------------------------------------------
+
+CMakeBuildSystem::CMakeBuildSystem(CMakeProject *p)
+ : BuildSystem(p)
+ , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
+{
+ // TreeScanner:
+ connect(&m_treeScanner,
+ &TreeScanner::finished,
+ this,
+ &CMakeBuildSystem::handleTreeScanningFinished);
+
+ m_treeScanner.setFilter([this, p](const Utils::MimeType &mimeType, const Utils::FilePath &fn) {
+ // Mime checks requires more resources, so keep it last in check list
+ auto isIgnored = fn.toString().startsWith(p->projectFilePath().toString() + ".user")
+ || TreeScanner::isWellKnownBinary(mimeType, fn);
+
+ // Cache mime check result for speed up
+ if (!isIgnored) {
+ auto it = m_mimeBinaryCache.find(mimeType.name());
+ if (it != m_mimeBinaryCache.end()) {
+ isIgnored = *it;
+ } else {
+ isIgnored = TreeScanner::isMimeBinary(mimeType, fn);
+ m_mimeBinaryCache[mimeType.name()] = isIgnored;
+ }
+ }
+
+ return isIgnored;
+ });
+
+ m_treeScanner.setTypeFactory([](const Utils::MimeType &mimeType, const Utils::FilePath &fn) {
+ auto type = TreeScanner::genericFileType(mimeType, fn);
+ if (type == FileType::Unknown) {
+ if (mimeType.isValid()) {
+ const QString mt = mimeType.name();
+ if (mt == CMakeProjectManager::Constants::CMAKEPROJECTMIMETYPE
+ || mt == CMakeProjectManager::Constants::CMAKEMIMETYPE)
+ type = FileType::Project;
+ }
+ }
+ return type;
+ });
+}
+
+CMakeBuildSystem::~CMakeBuildSystem()
+{
+ if (!m_treeScanner.isFinished()) {
+ auto future = m_treeScanner.future();
+ future.cancel();
+ future.waitForFinished();
+ }
+ delete m_cppCodeModelUpdater;
+ qDeleteAll(m_extraCompilers);
+ qDeleteAll(m_allFiles);
+}
+
+bool CMakeBuildSystem::validateParsingContext(const ParsingContext &ctx)
+{
+ return ctx.project && qobject_cast<CMakeBuildConfiguration *>(ctx.buildConfiguration);
+}
+
+void CMakeBuildSystem::parseProject(ParsingContext &&ctx)
+{
+ m_currentContext = std::move(ctx);
+
+ auto bc = qobject_cast<CMakeBuildConfiguration *>(m_currentContext.buildConfiguration);
+ QTC_ASSERT(bc, return );
+
+ if (m_allFiles.isEmpty())
+ bc->m_buildDirManager.requestFilesystemScan();
+
+ m_waitingForScan = bc->m_buildDirManager.isFilesystemScanRequested();
+ m_waitingForParse = true;
+ m_combinedScanAndParseResult = true;
+
+ if (m_waitingForScan) {
+ QTC_CHECK(m_treeScanner.isFinished());
+ m_treeScanner.asyncScanForFiles(m_currentContext.project->projectDirectory());
+ Core::ProgressManager::addTask(m_treeScanner.future(),
+ tr("Scan \"%1\" project tree")
+ .arg(m_currentContext.project->displayName()),
+ "CMake.Scan.Tree");
+ }
+
+ bc->m_buildDirManager.parse();
+}
+
+void CMakeBuildSystem::handleTreeScanningFinished()
+{
+ QTC_CHECK(m_waitingForScan);
+
+ qDeleteAll(m_allFiles);
+ m_allFiles = Utils::transform(m_treeScanner.release(), [](const FileNode *fn) { return fn; });
+
+ m_combinedScanAndParseResult = m_combinedScanAndParseResult && true;
+ m_waitingForScan = false;
+
+ combineScanAndParse();
+}
+
+void CMakeBuildSystem::handleParsingSuccess(CMakeBuildConfiguration *bc)
+{
+ if (bc != m_currentContext.buildConfiguration)
+ return; // Not current information, ignore.
+
+ QTC_ASSERT(m_waitingForParse, return );
+
+ m_waitingForParse = false;
+ m_combinedScanAndParseResult = m_combinedScanAndParseResult && true;
+
+ combineScanAndParse();
+}
+
+void CMakeBuildSystem::handleParsingError(CMakeBuildConfiguration *bc)
+{
+ if (bc != m_currentContext.buildConfiguration)
+ return; // Not current information, ignore.
+
+ QTC_CHECK(m_waitingForParse);
+
+ m_waitingForParse = false;
+ m_combinedScanAndParseResult = false;
+
+ combineScanAndParse();
+}
+
+void CMakeBuildSystem::combineScanAndParse()
+{
+ auto bc = qobject_cast<CMakeBuildConfiguration *>(m_currentContext.buildConfiguration);
+ if (bc && bc->isActive()) {
+ if (m_waitingForParse || m_waitingForScan)
+ return;
+
+ if (m_combinedScanAndParseResult) {
+ updateProjectData(qobject_cast<CMakeProject *>(m_currentContext.project), bc);
+ m_currentContext.guard.markAsSuccess();
+ }
+ }
+
+ m_currentContext = BuildSystem::ParsingContext();
+}
+
+void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguration *bc)
+{
+ qCDebug(cmakeBuildSystemLog) << "Updating CMake project data";
+
+ QTC_ASSERT(m_treeScanner.isFinished() && !bc->m_buildDirManager.isParsing(), return );
+
+ project()->setExtraProjectFiles(bc->m_buildDirManager.takeProjectFilesToWatch());
+
+ CMakeConfig patchedConfig = bc->configurationFromCMake();
+ {
+ CMakeConfigItem settingFileItem;
+ settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE";
+ settingFileItem.value = bc->buildDirectory()
+ .pathAppended("android_deployment_settings.json")
+ .toString()
+ .toUtf8();
+ patchedConfig.append(settingFileItem);
+ }
+ {
+ QSet<QString> res;
+ QStringList apps;
+ for (const auto &target : bc->buildTargets()) {
+ if (target.targetType == CMakeProjectManager::DynamicLibraryType) {
+ res.insert(target.executable.parentDir().toString());
+ apps.push_back(target.executable.toUserOutput());
+ }
+ // ### shall we add also the ExecutableType ?
+ }
+ {
+ CMakeConfigItem paths;
+ paths.key = "ANDROID_SO_LIBS_PATHS";
+ paths.values = Utils::toList(res);
+ patchedConfig.append(paths);
+ }
+
+ apps.sort();
+ {
+ CMakeConfigItem appsPaths;
+ appsPaths.key = "TARGETS_BUILD_PATH";
+ appsPaths.values = apps;
+ patchedConfig.append(appsPaths);
+ }
+ }
+
+ {
+ auto newRoot = bc->generateProjectTree(m_allFiles);
+ if (newRoot) {
+ p->setRootProjectNode(std::move(newRoot));
+ if (p->rootProjectNode())
+ p->setDisplayName(p->rootProjectNode()->displayName());
+
+ for (const CMakeBuildTarget &bt : bc->buildTargets()) {
+ const QString buildKey = bt.title;
+ if (ProjectNode *node = p->findNodeForBuildKey(buildKey)) {
+ if (auto targetNode = dynamic_cast<CMakeTargetNode *>(node))
+ targetNode->setConfig(patchedConfig);
+ }
+ }
+ }
+ }
+
+ {
+ qDeleteAll(m_extraCompilers);
+ m_extraCompilers = findExtraCompilers(p);
+ CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
+ qCDebug(cmakeBuildSystemLog) << "Extra compilers updated.";
+ }
+
+ QtSupport::CppKitInfo kitInfo(p);
+ QTC_ASSERT(kitInfo.isValid(), return );
+
+ {
+ QString errorMessage;
+ RawProjectParts rpps = bc->m_buildDirManager.createRawProjectParts(errorMessage);
+ if (!errorMessage.isEmpty())
+ bc->setError(errorMessage);
+ qCDebug(cmakeBuildSystemLog) << "Raw project parts created." << errorMessage;
+
+ for (RawProjectPart &rpp : rpps) {
+ rpp.setQtVersion(
+ kitInfo.projectPartQtVersion); // TODO: Check if project actually uses Qt.
+ if (kitInfo.cxxToolChain)
+ rpp.setFlagsForCxx({kitInfo.cxxToolChain, rpp.flagsForCxx.commandLineFlags});
+ if (kitInfo.cToolChain)
+ rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags});
+ }
+
+ m_cppCodeModelUpdater->update({p, kitInfo, bc->environment(), rpps});
+ }
+ {
+ updateQmlJSCodeModel(p, bc);
+ }
+
+ emit p->fileListChanged();
+
+ emit bc->emitBuildTypeChanged();
+
+ bc->m_buildDirManager.resetData();
+
+ qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
+}
+
+QList<ProjectExplorer::ExtraCompiler *> CMakeBuildSystem::findExtraCompilers(CMakeProject *p)
+{
+ qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: start.";
+
+ QList<ProjectExplorer::ExtraCompiler *> extraCompilers;
+ const QList<ExtraCompilerFactory *> factories = ExtraCompilerFactory::extraCompilerFactories();
+
+ qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: Got factories.";
+
+ const QSet<QString> fileExtensions = Utils::transform<QSet>(factories,
+ &ExtraCompilerFactory::sourceTag);
+
+ qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: Got file extensions:"
+ << fileExtensions;
+
+ // Find all files generated by any of the extra compilers, in a rather crude way.
+ const FilePathList fileList = p->files([&fileExtensions, p](const Node *n) {
+ if (!p->SourceFiles(n))
+ return false;
+ const QString fp = n->filePath().toString();
+ const int pos = fp.lastIndexOf('.');
+ return pos >= 0 && fileExtensions.contains(fp.mid(pos + 1));
+ });
+
+ qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: Got list of files to check.";
+
+ // Generate the necessary information:
+ for (const FilePath &file : fileList) {
+ qCDebug(cmakeBuildSystemLog)
+ << "Finding Extra Compilers: Processing" << file.toUserOutput();
+ ExtraCompilerFactory *factory = Utils::findOrDefault(factories,
+ [&file](const ExtraCompilerFactory *f) {
+ return file.endsWith(
+ '.' + f->sourceTag());
+ });
+ QTC_ASSERT(factory, continue);
+
+ QStringList generated = p->filesGeneratedFrom(file.toString());
+ qCDebug(cmakeBuildSystemLog)
+ << "Finding Extra Compilers: generated files:" << generated;
+ if (generated.isEmpty())
+ continue;
+
+ const FilePathList fileNames = transform(generated, [](const QString &s) {
+ return FilePath::fromString(s);
+ });
+ extraCompilers.append(factory->create(p, file, fileNames));
+ qCDebug(cmakeBuildSystemLog)
+ << "Finding Extra Compilers: done with" << file.toUserOutput();
+ }
+
+ qCDebug(cmakeBuildSystemLog) << "Finding Extra Compilers: done.";
+
+ return extraCompilers;
+}
+
+void CMakeBuildSystem::updateQmlJSCodeModel(CMakeProject *p, CMakeBuildConfiguration *bc)
+{
+ QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
+
+ if (!modelManager)
+ return;
+
+ QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager
+ ->defaultProjectInfoForProject(p);
+
+ projectInfo.importPaths.clear();
+
+ const CMakeConfig &cm = bc->configurationFromCMake();
+ const QString cmakeImports = QString::fromUtf8(CMakeConfigItem::valueOf("QML_IMPORT_PATH", cm));
+
+ foreach (const QString &cmakeImport, CMakeConfigItem::cmakeSplitValue(cmakeImports))
+ projectInfo.importPaths.maybeInsert(FilePath::fromString(cmakeImport), QmlJS::Dialect::Qml);
+
+ modelManager->updateProjectInfo(projectInfo, p);
+}
+
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
new file mode 100644
index 0000000000..1170a38e12
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/buildsystem.h>
+
+namespace CppTools {
+class CppProjectUpdater;
+} // namespace CppTools
+
+namespace CMakeProjectManager {
+
+class CMakeProject;
+
+namespace Internal {
+class CMakeBuildConfiguration;
+} // namespace Internal
+
+// --------------------------------------------------------------------
+// CMakeBuildSystem:
+// --------------------------------------------------------------------
+
+class CMakeBuildSystem : public ProjectExplorer::BuildSystem
+{
+ Q_OBJECT
+
+public:
+ explicit CMakeBuildSystem(CMakeProject *project);
+ ~CMakeBuildSystem() final;
+
+protected:
+ bool validateParsingContext(const ParsingContext &ctx) final;
+ void parseProject(ParsingContext &&ctx) final;
+
+private:
+ // Treescanner states:
+ void handleTreeScanningFinished();
+
+ // Parser states:
+ void handleParsingSuccess(Internal::CMakeBuildConfiguration *bc);
+ void handleParsingError(Internal::CMakeBuildConfiguration *bc);
+
+ // Combining Treescanner and Parser states:
+ void combineScanAndParse();
+
+ void updateProjectData(CMakeProject *p, Internal::CMakeBuildConfiguration *bc);
+ QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers(CMakeProject *p);
+ void updateQmlJSCodeModel(CMakeProject *p, Internal::CMakeBuildConfiguration *bc);
+
+ ProjectExplorer::TreeScanner m_treeScanner;
+ QHash<QString, bool> m_mimeBinaryCache;
+ QList<const ProjectExplorer::FileNode *> m_allFiles;
+
+ bool m_waitingForScan = false;
+ bool m_waitingForParse = false;
+ bool m_combinedScanAndParseResult = false;
+
+ ParsingContext m_currentContext;
+
+ CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
+ QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
+
+ friend class Internal::CMakeBuildConfiguration; // For handleParsing* callbacks
+};
+
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h
index e46394bef5..98127f20b3 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h
@@ -28,6 +28,7 @@
#include "cmake_global.h"
#include <projectexplorer/projectmacro.h>
+#include <projectexplorer/projectnodes.h>
#include <utils/fileutils.h>
@@ -36,12 +37,16 @@
namespace CMakeProjectManager {
enum TargetType {
- ExecutableType = 0,
- StaticLibraryType = 2,
- DynamicLibraryType = 3,
- UtilityType = 64
+ ExecutableType,
+ StaticLibraryType,
+ DynamicLibraryType,
+ ObjectLibraryType,
+ UtilityType
};
+using Backtrace = QVector<ProjectExplorer::FolderNode::LocationInfo>;
+using Backtraces = QVector<Backtrace>;
+
class CMAKE_EXPORT CMakeBuildTarget
{
public:
@@ -52,6 +57,14 @@ public:
Utils::FilePath sourceDirectory;
Utils::FilePath makeCommand;
+ Backtrace backtrace;
+
+ Backtraces dependencyDefinitions;
+ Backtraces sourceDefinitions;
+ Backtraces defineDefinitions;
+ Backtraces includeDefinitions;
+ Backtraces installDefinitions;
+
// code model
QList<Utils::FilePath> includeFiles;
QStringList compilerOptions;
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
index c3e27c001b..e63641cf28 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
@@ -43,8 +43,9 @@ namespace CMakeProjectManager {
CMakeConfigItem::CMakeConfigItem() = default;
CMakeConfigItem::CMakeConfigItem(const QByteArray &k, Type t,
- const QByteArray &d, const QByteArray &v) :
- key(k), type(t), value(v), documentation(d)
+ const QByteArray &d, const QByteArray &v,
+ const QStringList &s) :
+ key(k), type(t), value(v), documentation(d), values(s)
{ }
CMakeConfigItem::CMakeConfigItem(const QByteArray &k, const QByteArray &v) :
@@ -148,6 +149,25 @@ CMakeConfigItem::Type CMakeConfigItem::typeStringToType(const QByteArray &type)
return CMakeConfigItem::INTERNAL;
}
+Utils::optional<bool> CMakeConfigItem::toBool(const QByteArray &value)
+{
+ // Taken from CMakes if(<constant>) documentation:
+ // "Named boolean constants are case-insensitive."
+ const QString v = QString::fromUtf8(value).toUpper();
+
+ bool isInt = false;
+ v.toInt(&isInt);
+
+ // "False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in the suffix -NOTFOUND."
+ if (v == "0" || v == "OFF" || v == "NO" || v == "FALSE" || v == "N" || v == "IGNORE" || v == "NOTFOUND" || v == "" || v.endsWith("-NOTFOUND"))
+ return false;
+ // "True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number."
+ if (v == "1" || v == "ON" || v == "YES" || v == "TRUE" || v == "Y" || isInt)
+ return true;
+
+ return {};
+}
+
QString CMakeConfigItem::expandedValue(const ProjectExplorer::Kit *k) const
{
return expandedValue(k->macroExpander());
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
index 16bc8acea3..ae06252c7c 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/optional.h>
+
#include <QByteArray>
#include <QList>
@@ -42,7 +44,7 @@ class CMakeConfigItem {
public:
enum Type { FILEPATH, PATH, BOOL, STRING, INTERNAL, STATIC };
CMakeConfigItem();
- CMakeConfigItem(const QByteArray &k, Type t, const QByteArray &d, const QByteArray &v);
+ CMakeConfigItem(const QByteArray &k, Type t, const QByteArray &d, const QByteArray &v, const QStringList &s = {});
CMakeConfigItem(const QByteArray &k, const QByteArray &v);
static QByteArray valueOf(const QByteArray &key, const QList<CMakeConfigItem> &input);
@@ -50,6 +52,7 @@ public:
const QList<CMakeConfigItem> &input);
static QStringList cmakeSplitValue(const QString &in, bool keepEmpty = false);
static Type typeStringToType(const QByteArray &typeString);
+ static Utils::optional<bool> toBool(const QByteArray &value);
bool isNull() const { return key.isEmpty(); }
QString expandedValue(const ProjectExplorer::Kit *k) const;
diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
index 042cb363c8..351c08c6f9 100644
--- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
@@ -45,6 +45,7 @@
#include <texteditor/texteditorconstants.h>
#include <utils/qtcassert.h>
+#include <utils/textutils.h>
#include <QFileInfo>
#include <QTextBlock>
@@ -71,7 +72,7 @@ void CMakeEditor::contextHelp(const HelpCallback &callback) const
break;
chr = characterAt(pos);
if (chr == QLatin1Char('(')) {
- callback({});
+ BaseTextEditor::contextHelp(callback);
return;
}
} while (chr.unicode() != QChar::ParagraphSeparator);
@@ -97,12 +98,13 @@ void CMakeEditor::contextHelp(const HelpCallback &callback) const
// Not a command
if (chr != QLatin1Char('(')) {
- callback({});
+ BaseTextEditor::contextHelp(callback);
return;
}
const QString id = "command/" + textAt(begin, end - begin).toLower();
- callback(id);
+ callback(
+ {{id, Utils::Text::wordUnderCursor(editorWidget()->textCursor())}, {}, HelpItem::Unknown});
}
//
@@ -130,12 +132,9 @@ void CMakeEditorWidget::contextMenuEvent(QContextMenuEvent *e)
static bool isValidFileNameChar(const QChar &c)
{
- return c.isLetterOrNumber()
- || c == QLatin1Char('.')
- || c == QLatin1Char('_')
- || c == QLatin1Char('-')
- || c == QLatin1Char('/')
- || c == QLatin1Char('\\');
+ return c.isLetterOrNumber() || c == QLatin1Char('.') || c == QLatin1Char('_')
+ || c == QLatin1Char('-') || c == QLatin1Char('/') || c == QLatin1Char('\\') || c == '{'
+ || c == '}' || c == '$';
}
void CMakeEditorWidget::findLinkAt(const QTextCursor &cursor,
@@ -185,9 +184,12 @@ void CMakeEditorWidget::findLinkAt(const QTextCursor &cursor,
if (buffer.isEmpty())
return processLinkCallback(link);
- // TODO: Resolve variables
-
QDir dir(textDocument()->filePath().toFileInfo().absolutePath());
+ buffer.replace("${CMAKE_CURRENT_SOURCE_DIR}", dir.path());
+ buffer.replace("${CMAKE_CURRENT_LIST_DIR}", dir.path());
+
+ // TODO: Resolve more variables
+
QString fileName = dir.filePath(buffer);
QFileInfo fi(fileName);
if (fi.exists()) {
diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
index efe0dccc57..8c4ee8877d 100644
--- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp
@@ -46,6 +46,7 @@
#include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
+#include <QFileInfo>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
@@ -678,7 +679,8 @@ Tasks CMakeGeneratorKitAspect::validate(const Kit *k) const
Utils::FilePath(), -1, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
}
}
- if (!tool->hasServerMode() && info.extraGenerator != "CodeBlocks") {
+ if ((!tool->hasServerMode() && !tool->hasFileApi())
+ && info.extraGenerator != "CodeBlocks") {
result << Task(Task::Warning, tr("The selected CMake binary has no server-mode and the CMake "
"generator does not generate a CodeBlocks file. "
"%1 will not be able to parse CMake projects.")
@@ -928,7 +930,7 @@ void CMakeConfigurationKitAspect::fromStringList(Kit *k, const QStringList &in)
CMakeConfig CMakeConfigurationKitAspect::defaultConfiguration(const Kit *k)
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
CMakeConfig config;
// Qt4:
config << CMakeConfigItem(CMAKE_QMAKE_KEY, "%{Qt:qmakeExecutable}");
@@ -943,7 +945,7 @@ CMakeConfig CMakeConfigurationKitAspect::defaultConfiguration(const Kit *k)
QVariant CMakeConfigurationKitAspect::defaultValue(const Kit *k) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
// FIXME: Convert preload scripts
CMakeConfig config = defaultConfiguration(k);
@@ -1058,7 +1060,7 @@ void CMakeConfigurationKitAspect::setup(Kit *k)
void CMakeConfigurationKitAspect::fix(Kit *k)
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
}
KitAspect::ItemList CMakeConfigurationKitAspect::toUserOutput(const Kit *k) const
diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
index 47c8219c06..4745dc4cfa 100644
--- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp
@@ -24,15 +24,17 @@
****************************************************************************/
#include "cmakelocatorfilter.h"
+#include "cmakebuildconfiguration.h"
#include "cmakebuildstep.h"
#include "cmakeproject.h"
+#include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/buildsteplist.h>
#include <utils/algorithm.h>
@@ -41,67 +43,112 @@ using namespace CMakeProjectManager::Internal;
using namespace ProjectExplorer;
using namespace Utils;
-CMakeLocatorFilter::CMakeLocatorFilter()
-{
- setId("Build CMake target");
- setDisplayName(tr("Build CMake target"));
- setShortcutString("cm");
- setPriority(High);
+// --------------------------------------------------------------------
+// CMakeTargetLocatorFilter:
+// --------------------------------------------------------------------
+CMakeTargetLocatorFilter::CMakeTargetLocatorFilter()
+{
connect(SessionManager::instance(), &SessionManager::projectAdded,
- this, &CMakeLocatorFilter::projectListUpdated);
+ this, &CMakeTargetLocatorFilter::projectListUpdated);
connect(SessionManager::instance(), &SessionManager::projectRemoved,
- this, &CMakeLocatorFilter::projectListUpdated);
+ this, &CMakeTargetLocatorFilter::projectListUpdated);
// Initialize the filter
projectListUpdated();
}
-void CMakeLocatorFilter::prepareSearch(const QString &entry)
+void CMakeTargetLocatorFilter::prepareSearch(const QString &entry)
{
m_result.clear();
const QList<Project *> projects = SessionManager::projects();
for (Project *p : projects) {
auto cmakeProject = qobject_cast<const CMakeProject *>(p);
- if (!cmakeProject)
+ if (!cmakeProject || !cmakeProject->activeTarget())
+ continue;
+ auto bc = qobject_cast<CMakeBuildConfiguration *>(
+ cmakeProject->activeTarget()->activeBuildConfiguration());
+ if (!bc)
continue;
- const QStringList buildTargetTitles = cmakeProject->buildTargetTitles();
- for (const QString &title : buildTargetTitles) {
- const int index = title.indexOf(entry);
+
+ const QList<CMakeBuildTarget> buildTargets = bc->buildTargets();
+ for (const CMakeBuildTarget &target : buildTargets) {
+ const int index = target.title.indexOf(entry);
if (index >= 0) {
- Core::LocatorFilterEntry filterEntry(this, title, cmakeProject->projectFilePath().toString());
- filterEntry.extraInfo = cmakeProject->projectFilePath().shortNativePath();
+ const FilePath path = target.backtrace.isEmpty() ? cmakeProject->projectFilePath()
+ : target.backtrace.first().path;
+ const int line = target.backtrace.isEmpty() ? -1 : target.backtrace.first().line;
+
+ QVariantMap extraData;
+ extraData.insert("project", cmakeProject->projectFilePath().toString());
+ extraData.insert("line", line);
+ extraData.insert("file", path.toString());
+
+ Core::LocatorFilterEntry filterEntry(this, target.title, extraData);
+ filterEntry.extraInfo = path.shortNativePath();
filterEntry.highlightInfo = {index, entry.length()};
+ filterEntry.fileName = path.toString();
+
m_result.append(filterEntry);
}
}
}
}
-QList<Core::LocatorFilterEntry> CMakeLocatorFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry)
+QList<Core::LocatorFilterEntry> CMakeTargetLocatorFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry)
{
Q_UNUSED(future)
Q_UNUSED(entry)
return m_result;
}
-void CMakeLocatorFilter::accept(Core::LocatorFilterEntry selection,
- QString *newText, int *selectionStart, int *selectionLength) const
+void CMakeTargetLocatorFilter::refresh(QFutureInterface<void> &future)
+{
+ Q_UNUSED(future)
+}
+
+void CMakeTargetLocatorFilter::projectListUpdated()
+{
+ // Enable the filter if there's at least one CMake project
+ setEnabled(Utils::contains(SessionManager::projects(), [](Project *p) { return qobject_cast<CMakeProject *>(p); }));
+}
+
+// --------------------------------------------------------------------
+// BuildCMakeTargetLocatorFilter:
+// --------------------------------------------------------------------
+
+BuildCMakeTargetLocatorFilter::BuildCMakeTargetLocatorFilter()
+{
+ setId("Build CMake target");
+ setDisplayName(tr("Build CMake target"));
+ setShortcutString("cm");
+ setPriority(High);
+}
+
+void BuildCMakeTargetLocatorFilter::accept(Core::LocatorFilterEntry selection,
+ QString *newText,
+ int *selectionStart,
+ int *selectionLength) const
{
Q_UNUSED(newText)
Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength)
+
+ const QVariantMap extraData = selection.internalData.toMap();
+ const FilePath projectPath = FilePath::fromString(extraData.value("project").toString());
+
// Get the project containing the target selected
const auto cmakeProject = qobject_cast<CMakeProject *>(
- Utils::findOrDefault(SessionManager::projects(), [selection](Project *p) {
- return p->projectFilePath().toString() == selection.internalData.toString();
- }));
- if (!cmakeProject || !cmakeProject->activeTarget() || !cmakeProject->activeTarget()->activeBuildConfiguration())
+ Utils::findOrDefault(SessionManager::projects(), [projectPath](Project *p) {
+ return p->projectFilePath() == projectPath;
+ }));
+ if (!cmakeProject || !cmakeProject->activeTarget()
+ || !cmakeProject->activeTarget()->activeBuildConfiguration())
return;
// Find the make step
- BuildStepList *buildStepList = cmakeProject->activeTarget()->activeBuildConfiguration()
- ->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
+ BuildStepList *buildStepList = cmakeProject->activeTarget()->activeBuildConfiguration()->stepList(
+ ProjectExplorer::Constants::BUILDSTEPS_BUILD);
auto buildStep = buildStepList->firstOfType<CMakeBuildStep>();
if (!buildStep)
return;
@@ -116,13 +163,33 @@ void CMakeLocatorFilter::accept(Core::LocatorFilterEntry selection,
buildStep->setBuildTarget(oldTarget);
}
-void CMakeLocatorFilter::refresh(QFutureInterface<void> &future)
+// --------------------------------------------------------------------
+// OpenCMakeTargetLocatorFilter:
+// --------------------------------------------------------------------
+
+OpenCMakeTargetLocatorFilter::OpenCMakeTargetLocatorFilter()
{
- Q_UNUSED(future)
+ setId("Open CMake target definition");
+ setDisplayName(tr("Open CMake target"));
+ setShortcutString("cmo");
+ setPriority(Medium);
}
-void CMakeLocatorFilter::projectListUpdated()
+void OpenCMakeTargetLocatorFilter::accept(Core::LocatorFilterEntry selection,
+ QString *newText,
+ int *selectionStart,
+ int *selectionLength) const
{
- // Enable the filter if there's at least one CMake project
- setEnabled(Utils::contains(SessionManager::projects(), [](Project *p) { return qobject_cast<CMakeProject *>(p); }));
+ Q_UNUSED(newText)
+ Q_UNUSED(selectionStart)
+ Q_UNUSED(selectionLength)
+
+ const QVariantMap extraData = selection.internalData.toMap();
+ const int line = extraData.value("line").toInt();
+ const QString file = extraData.value("file").toString();
+
+ if (line >= 0)
+ Core::EditorManager::openEditorAt(file, line);
+ else
+ Core::EditorManager::openEditor(file);
}
diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h
index 28fede0f75..7bf295dd28 100644
--- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h
+++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.h
@@ -30,19 +30,17 @@
namespace CMakeProjectManager {
namespace Internal {
-class CMakeLocatorFilter : public Core::ILocatorFilter
+class CMakeTargetLocatorFilter : public Core::ILocatorFilter
{
Q_OBJECT
public:
- CMakeLocatorFilter();
+ CMakeTargetLocatorFilter();
void prepareSearch(const QString &entry) override;
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
- const QString &entry) override;
- void accept(Core::LocatorFilterEntry selection,
- QString *newText, int *selectionStart, int *selectionLength) const override;
- void refresh(QFutureInterface<void> &future) override;
+ const QString &entry) final;
+ void refresh(QFutureInterface<void> &future) final;
private:
void projectListUpdated();
@@ -50,5 +48,31 @@ private:
QList<Core::LocatorFilterEntry> m_result;
};
+class BuildCMakeTargetLocatorFilter : CMakeTargetLocatorFilter
+{
+ Q_OBJECT
+
+public:
+ BuildCMakeTargetLocatorFilter();
+
+ void accept(Core::LocatorFilterEntry selection,
+ QString *newText,
+ int *selectionStart,
+ int *selectionLength) const final;
+};
+
+class OpenCMakeTargetLocatorFilter : CMakeTargetLocatorFilter
+{
+ Q_OBJECT
+
+public:
+ OpenCMakeTargetLocatorFilter();
+
+ void accept(Core::LocatorFilterEntry selection,
+ QString *newText,
+ int *selectionStart,
+ int *selectionLength) const final;
+};
+
} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakeparser.cpp b/src/plugins/cmakeprojectmanager/cmakeparser.cpp
index be67db464f..515bf89222 100644
--- a/src/plugins/cmakeprojectmanager/cmakeparser.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeparser.cpp
@@ -50,6 +50,11 @@ CMakeParser::CMakeParser()
QTC_CHECK(m_locationLine.isValid());
}
+void CMakeParser::setSourceDirectory(const QString &sourceDir)
+{
+ m_sourceDirectory = QDir(sourceDir);
+}
+
void CMakeParser::stdError(const QString &line)
{
QString trimmedLine = rightTrimmed(line);
@@ -67,8 +72,15 @@ void CMakeParser::stdError(const QString &line)
m_skippedFirstEmptyLine = false;
if (m_commonError.indexIn(trimmedLine) != -1) {
- m_lastTask = Task(Task::Error, QString(), Utils::FilePath::fromUserInput(m_commonError.cap(1)),
- m_commonError.cap(2).toInt(), Constants::TASK_CATEGORY_BUILDSYSTEM);
+ QString path = m_sourceDirectory ? m_sourceDirectory->absoluteFilePath(
+ QDir::fromNativeSeparators(m_commonError.cap(1)))
+ : QDir::fromNativeSeparators(m_commonError.cap(1));
+
+ m_lastTask = Task(Task::Error,
+ QString(),
+ Utils::FilePath::fromUserInput(path),
+ m_commonError.cap(2).toInt(),
+ Constants::TASK_CATEGORY_BUILDSYSTEM);
m_lines = 1;
return;
} else if (m_nextSubError.indexIn(trimmedLine) != -1) {
diff --git a/src/plugins/cmakeprojectmanager/cmakeparser.h b/src/plugins/cmakeprojectmanager/cmakeparser.h
index 85a20d870d..57b41ce559 100644
--- a/src/plugins/cmakeprojectmanager/cmakeparser.h
+++ b/src/plugins/cmakeprojectmanager/cmakeparser.h
@@ -30,6 +30,7 @@
#include <projectexplorer/ioutputparser.h>
#include <projectexplorer/task.h>
+#include <QDir>
#include <QRegExp>
#include <QRegularExpression>
@@ -41,6 +42,7 @@ class CMAKE_EXPORT CMakeParser : public ProjectExplorer::IOutputParser
public:
explicit CMakeParser();
+ void setSourceDirectory(const QString &sourceDir);
void stdError(const QString &line) override;
protected:
@@ -51,6 +53,7 @@ private:
TripleLineError m_expectTripleLineErrorData = NONE;
+ Utils::optional<QDir> m_sourceDirectory;
ProjectExplorer::Task m_lastTask;
QRegExp m_commonError;
QRegExp m_nextSubError;
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
new file mode 100644
index 0000000000..45b7b119ee
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "cmakeprocess.h"
+
+#include "cmakeparser.h"
+
+#include <coreplugin/messagemanager.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <coreplugin/reaper.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/taskhub.h>
+
+#include <utils/algorithm.h>
+#include <utils/fileutils.h>
+
+#include <QDir>
+#include <QObject>
+#include <QTimer>
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+using namespace ProjectExplorer;
+
+static QString lineSplit(const QString &rest, const QByteArray &array, std::function<void(const QString &)> f)
+{
+ QString tmp = rest + Utils::SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(array));
+ int start = 0;
+ int end = tmp.indexOf(QLatin1Char('\n'), start);
+ while (end >= 0) {
+ f(tmp.mid(start, end - start));
+ start = end + 1;
+ end = tmp.indexOf(QLatin1Char('\n'), start);
+ }
+ return tmp.mid(start);
+}
+
+CMakeProcess::CMakeProcess()
+{
+ connect(&m_cancelTimer, &QTimer::timeout, this, &CMakeProcess::checkForCancelled);
+ m_cancelTimer.setInterval(500);
+}
+
+CMakeProcess::~CMakeProcess()
+{
+ if (m_process) {
+ processStandardOutput();
+ processStandardError();
+
+ m_process->disconnect();
+ Core::Reaper::reap(m_process.release());
+ }
+
+ // Delete issue parser:
+ if (m_parser)
+ m_parser->flush();
+
+ if (m_future) {
+ reportCanceled();
+ reportFinished();
+ }
+}
+
+QStringList CMakeProcess::toArguments(const CMakeConfig &config,
+ const Utils::MacroExpander *expander) {
+ return Utils::transform(config, [expander](const CMakeConfigItem &i) -> QString {
+ return i.toArgument(expander);
+ });
+}
+
+void CMakeProcess::run(const BuildDirParameters &parameters, const QStringList &arguments)
+{
+ QTC_ASSERT(!m_process && !m_parser && !m_future, return);
+
+ CMakeTool *cmake = parameters.cmakeTool();
+ QTC_ASSERT(parameters.isValid() && cmake, return);
+
+ const Utils::FilePath workDirectory = parameters.workDirectory;
+ QTC_ASSERT(workDirectory.exists(), return);
+
+ const QString srcDir = parameters.sourceDirectory.toString();
+
+ auto parser = std::make_unique<CMakeParser>();
+ parser->setSourceDirectory(srcDir);
+ QDir source = QDir(srcDir);
+ connect(parser.get(), &IOutputParser::addTask, parser.get(),
+ [source](const Task &task) {
+ if (task.file.isEmpty() || task.file.toFileInfo().isAbsolute()) {
+ TaskHub::addTask(task);
+ } else {
+ Task t = task;
+ t.file = Utils::FilePath::fromString(source.absoluteFilePath(task.file.toString()));
+ TaskHub::addTask(t);
+ }
+ });
+
+ // Always use the sourceDir: If we are triggered because the build directory is getting deleted
+ // then we are racing against CMakeCache.txt also getting deleted.
+
+ auto process = std::make_unique<Utils::QtcProcess>();
+ m_processWasCanceled = false;
+
+ m_cancelTimer.start();
+
+ process->setWorkingDirectory(workDirectory.toString());
+ process->setEnvironment(parameters.environment);
+
+ connect(process.get(), &QProcess::readyReadStandardOutput,
+ this, &CMakeProcess::processStandardOutput);
+ connect(process.get(), &QProcess::readyReadStandardError,
+ this, &CMakeProcess::processStandardError);
+ connect(process.get(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
+ this, &CMakeProcess::handleProcessFinished);
+
+ QStringList args(srcDir);
+ args += parameters.generatorArguments;
+ args += arguments;
+ Utils::CommandLine commandLine(cmake->cmakeExecutable(), args);
+
+ TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
+
+ Core::MessageManager::write(tr("Running %1 in %2.")
+ .arg(commandLine.toUserOutput())
+ .arg(workDirectory.toUserOutput()));
+
+ auto future = std::make_unique<QFutureInterface<void>>();
+ future->setProgressRange(0, 1);
+ Core::ProgressManager::addTimedTask(*future.get(),
+ tr("Configuring \"%1\"").arg(parameters.projectName),
+ "CMake.Configure",
+ 10);
+
+ process->setCommand(commandLine);
+ emit started();
+ process->start();
+
+ m_process = std::move(process);
+ m_parser = std::move(parser);
+ m_future = std::move(future);
+}
+
+QProcess::ProcessState CMakeProcess::state() const
+{
+ if (m_process)
+ return m_process->state();
+ return QProcess::NotRunning;
+}
+
+void CMakeProcess::reportCanceled()
+{
+ QTC_ASSERT(m_future, return);
+ m_future->reportCanceled();
+}
+
+void CMakeProcess::reportFinished()
+{
+ QTC_ASSERT(m_future, return);
+ m_future->reportFinished();
+ m_future.reset();
+}
+
+void CMakeProcess::setProgressValue(int p)
+{
+ QTC_ASSERT(m_future, return);
+ m_future->setProgressValue(p);
+}
+
+void CMakeProcess::processStandardOutput()
+{
+ QTC_ASSERT(m_process, return);
+
+ static QString rest;
+ rest = lineSplit(rest, m_process->readAllStandardOutput(),
+ [](const QString &s) { Core::MessageManager::write(s); });
+
+}
+
+void CMakeProcess::processStandardError()
+{
+ QTC_ASSERT(m_process, return);
+
+ static QString rest;
+ rest = lineSplit(rest, m_process->readAllStandardError(), [this](const QString &s) {
+ m_parser->stdError(s);
+ Core::MessageManager::write(s);
+ });
+}
+
+void CMakeProcess::handleProcessFinished(int code, QProcess::ExitStatus status)
+{
+ QTC_ASSERT(m_process && m_future, return);
+
+ m_cancelTimer.stop();
+
+ processStandardOutput();
+ processStandardError();
+
+ QString msg;
+ if (status != QProcess::NormalExit) {
+ if (m_processWasCanceled) {
+ msg = tr("*** cmake process was canceled by the user.");
+ } else {
+ msg = tr("*** cmake process crashed.");
+ }
+ } else if (code != 0) {
+ msg = tr("*** cmake process exited with exit code %1.").arg(code);
+ }
+
+ if (!msg.isEmpty()) {
+ Core::MessageManager::write(msg);
+ TaskHub::addTask(Task::Error, msg, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
+ m_future->reportCanceled();
+ } else {
+ m_future->setProgressValue(1);
+ }
+
+ m_future->reportFinished();
+
+ emit finished(code, status);
+}
+
+void CMakeProcess::checkForCancelled()
+{
+ if (!m_process || !m_future)
+ return;
+
+ if (m_future->isCanceled()) {
+ m_cancelTimer.stop();
+ m_processWasCanceled = true;
+ m_process->close();
+ }
+}
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.h b/src/plugins/cmakeprojectmanager/cmakeprocess.h
new file mode 100644
index 0000000000..9675822435
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/cmakeprocess.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "builddirparameters.h"
+
+#include <projectexplorer/ioutputparser.h>
+
+#include <utils/qtcprocess.h>
+
+#include <QFutureInterface>
+#include <QTimer>
+
+#include <memory>
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+class CMakeProcess : public QObject {
+ Q_OBJECT
+
+public:
+ CMakeProcess();
+ CMakeProcess(const CMakeProcess&) = delete;
+ ~CMakeProcess();
+
+ static QStringList toArguments(const CMakeConfig &config, const Utils::MacroExpander *expander);
+
+ void run(const BuildDirParameters &parameters, const QStringList &arguments);
+
+ QProcess::ProcessState state() const;
+
+ // Update progress information:
+ void reportCanceled();
+ void reportFinished(); // None of the progress related functions will work after this!
+ void setProgressValue(int p);
+
+ // Process stdout/stderr:
+ void processStandardOutput();
+ void processStandardError();
+
+signals:
+ void started();
+ void finished(int exitCode, QProcess::ExitStatus exitStatus);
+
+private:
+ void handleProcessFinished(int code, QProcess::ExitStatus status);
+ void checkForCancelled();
+
+ std::unique_ptr<Utils::QtcProcess> m_process;
+ std::unique_ptr<ProjectExplorer::IOutputParser> m_parser;
+ std::unique_ptr<QFutureInterface<void>> m_future;
+ bool m_processWasCanceled = false;
+ QTimer m_cancelTimer;
+};
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index a1764e18d1..9ebc052b06 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -33,11 +33,10 @@
#include "cmakeprojectmanager.h"
#include <coreplugin/progressmanager/progressmanager.h>
-#include <cpptools/cpprawprojectpart.h>
#include <cpptools/cppprojectupdater.h>
+#include <cpptools/cpptoolsconstants.h>
#include <cpptools/generatedcodemodelsupport.h>
#include <cpptools/projectinfo.h>
-#include <cpptools/cpptoolsconstants.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h>
@@ -47,10 +46,10 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
+#include <qmljs/qmljsmodelmanagerinterface.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtcppkitinfo.h>
#include <qtsupport/qtkitinformation.h>
-#include <qmljs/qmljsmodelmanagerinterface.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -59,6 +58,7 @@
#include <utils/hostosinfo.h>
#include <QDir>
+#include <QElapsedTimer>
#include <QSet>
using namespace ProjectExplorer;
@@ -81,326 +81,20 @@ static CMakeBuildConfiguration *activeBc(const CMakeProject *p)
/*!
\class CMakeProject
*/
-CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEMIMETYPE, fileName),
- m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
+CMakeProject::CMakeProject(const FilePath &fileName)
+ : Project(Constants::CMAKEMIMETYPE, fileName)
{
setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(projectDirectory().fileName());
+ setCanBuildProducts();
+ setKnowsAllBuildExecutables(false);
+ setHasMakeInstallEquivalent(true);
- // Timer:
- m_delayedParsingTimer.setSingleShot(true);
-
- connect(&m_delayedParsingTimer, &QTimer::timeout,
- this, [this]() { startParsing(m_delayedParsingParameters); });
-
- // BuildDirManager:
- connect(&m_buildDirManager, &BuildDirManager::requestReparse,
- this, &CMakeProject::handleReparseRequest);
- connect(&m_buildDirManager, &BuildDirManager::dataAvailable,
- this, [this]() {
- CMakeBuildConfiguration *bc = activeBc(this);
- if (bc && bc == m_buildDirManager.buildConfiguration()) {
- bc->clearError();
- handleParsingSuccess(bc);
- }
- });
- connect(&m_buildDirManager, &BuildDirManager::errorOccured,
- this, [this](const QString &msg) {
- CMakeBuildConfiguration *bc = activeBc(this);
- if (bc && bc == m_buildDirManager.buildConfiguration()) {
- bc->setError(msg);
- bc->setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration());
- handleParsingError(bc);
- }
- });
- connect(&m_buildDirManager, &BuildDirManager::parsingStarted,
- this, [this]() {
- CMakeBuildConfiguration *bc = activeBc(this);
- if (bc && bc == m_buildDirManager.buildConfiguration())
- bc->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True);
- });
-
- // Kit changed:
- connect(KitManager::instance(), &KitManager::kitUpdated,
- this, [this](Kit *k) {
- CMakeBuildConfiguration *bc = activeBc(this);
- if (!bc || k != bc->target()->kit())
- return; // not for us...
-
- // Build configuration has not changed, but Kit settings might have:
- // reparse and check the configuration, independent of whether the reader has changed
- m_buildDirManager.setParametersAndRequestParse(
- BuildDirParameters(bc),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- });
-
- // Target switched:
- connect(this, &Project::activeTargetChanged, this, [this]() {
- CMakeBuildConfiguration *bc = activeBc(this);
-
- if (!bc)
- return;
-
- // Target has switched, so the kit has changed, too.
- // * run cmake with configuration arguments if the reader needs to be switched
- // * run cmake without configuration arguments if the reader stays
- m_buildDirManager.setParametersAndRequestParse(
- BuildDirParameters(bc),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- });
-
- // BuildConfiguration switched:
- subscribeSignal(&Target::activeBuildConfigurationChanged, this, [this]() {
- CMakeBuildConfiguration *bc = activeBc(this);
-
- if (!bc)
- return;
-
- // Build configuration has switched:
- // * Check configuration if reader changes due to it not existing yet:-)
- // * run cmake without configuration arguments if the reader stays
- m_buildDirManager.setParametersAndRequestParse(
- BuildDirParameters(bc),
- BuildDirManager::REPARSE_CHECK_CONFIGURATION,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- });
-
- // BuildConfiguration changed:
- subscribeSignal(&CMakeBuildConfiguration::environmentChanged, this, [this]() {
- auto senderBc = qobject_cast<CMakeBuildConfiguration *>(sender());
-
- if (senderBc && senderBc->isActive()) {
- // The environment on our BC has changed:
- // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
- // * run cmake without configuration arguments if the reader stays
- m_buildDirManager.setParametersAndRequestParse(
- BuildDirParameters(senderBc),
- BuildDirManager::REPARSE_FAIL,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- }
- });
- subscribeSignal(&CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() {
- auto senderBc = qobject_cast<CMakeBuildConfiguration *>(sender());
-
- if (senderBc && senderBc->isActive() && senderBc == m_buildDirManager.buildConfiguration()) {
- // The build directory of our BC has changed:
- // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
- // * run cmake without configuration arguments if the reader stays
- // If no configuration exists, then the arguments will get added automatically by
- // the reader.
- m_buildDirManager.setParametersAndRequestParse(
- BuildDirParameters(senderBc),
- BuildDirManager::REPARSE_FAIL,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
- }
- });
- subscribeSignal(&CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() {
- auto senderBc = qobject_cast<CMakeBuildConfiguration *>(sender());
-
- if (senderBc && senderBc->isActive() && senderBc == m_buildDirManager.buildConfiguration()) {
- // The CMake configuration has changed on our BC:
- // * Error out if the reader updates, cannot happen since all BCs share a target/kit.
- // * run cmake with configuration arguments if the reader stays
- m_buildDirManager.setParametersAndRequestParse(
- BuildDirParameters(senderBc),
- BuildDirManager::REPARSE_FAIL,
- BuildDirManager::REPARSE_FORCE_CONFIGURATION);
- }
- });
-
- // TreeScanner:
- connect(&m_treeScanner, &TreeScanner::finished, this, &CMakeProject::handleTreeScanningFinished);
-
- m_treeScanner.setFilter([this](const Utils::MimeType &mimeType, const Utils::FilePath &fn) {
- // Mime checks requires more resources, so keep it last in check list
- auto isIgnored =
- fn.toString().startsWith(projectFilePath().toString() + ".user") ||
- TreeScanner::isWellKnownBinary(mimeType, fn);
-
- // Cache mime check result for speed up
- if (!isIgnored) {
- auto it = m_mimeBinaryCache.find(mimeType.name());
- if (it != m_mimeBinaryCache.end()) {
- isIgnored = *it;
- } else {
- isIgnored = TreeScanner::isMimeBinary(mimeType, fn);
- m_mimeBinaryCache[mimeType.name()] = isIgnored;
- }
- }
-
- return isIgnored;
- });
-
- m_treeScanner.setTypeFactory([](const Utils::MimeType &mimeType, const Utils::FilePath &fn) {
- auto type = TreeScanner::genericFileType(mimeType, fn);
- if (type == FileType::Unknown) {
- if (mimeType.isValid()) {
- const QString mt = mimeType.name();
- if (mt == CMakeProjectManager::Constants::CMAKEPROJECTMIMETYPE
- || mt == CMakeProjectManager::Constants::CMAKEMIMETYPE)
- type = FileType::Project;
- }
- }
- return type;
- });
-}
-
-CMakeProject::~CMakeProject()
-{
- if (!m_treeScanner.isFinished()) {
- auto future = m_treeScanner.future();
- future.cancel();
- future.waitForFinished();
- }
- delete m_cppCodeModelUpdater;
- qDeleteAll(m_extraCompilers);
- qDeleteAll(m_allFiles);
-}
-
-void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
-{
- const CMakeBuildConfiguration *aBc = activeBc(this);
-
- QTC_ASSERT(bc, return);
- QTC_ASSERT(bc == aBc, return);
- QTC_ASSERT(m_treeScanner.isFinished() && !m_buildDirManager.isParsing(), return);
-
- const QList<CMakeBuildTarget> buildTargets = m_buildDirManager.takeBuildTargets();
- bc->setBuildTargets(buildTargets);
- const CMakeConfig cmakeConfig = m_buildDirManager.takeCMakeConfiguration();
- bc->setConfigurationFromCMake(cmakeConfig);
-
- CMakeConfig patchedConfig = cmakeConfig;
- {
- CMakeConfigItem settingFileItem;
- settingFileItem.key = "ANDROID_DEPLOYMENT_SETTINGS_FILE";
- settingFileItem.value = bc->buildDirectory()
- .pathAppended("android_deployment_settings.json").toString().toUtf8();
- patchedConfig.append(settingFileItem);
- }
-
- QSet<QString> res;
- QStringList apps;
- for (const auto &target : bc->buildTargets()) {
- if (target.targetType == CMakeProjectManager::DynamicLibraryType) {
- res.insert(target.executable.parentDir().toString());
- apps.push_back(target.executable.toUserOutput());
- }
- // ### shall we add also the ExecutableType ?
- }
- {
- CMakeConfigItem paths;
- paths.key = "ANDROID_SO_LIBS_PATHS";
- paths.values = Utils::toList(res);
- patchedConfig.append(paths);
- }
-
- apps.sort();
- {
- CMakeConfigItem appsPaths;
- appsPaths.key = "TARGETS_BUILD_PATH";
- appsPaths.values = apps;
- patchedConfig.append(appsPaths);
- }
-
-
- auto newRoot = generateProjectTree(m_allFiles);
- if (newRoot) {
- setDisplayName(newRoot->displayName());
- setRootProjectNode(std::move(newRoot));
-
- for (const CMakeBuildTarget &bt : buildTargets) {
- const QString buildKey = CMakeTargetNode::generateId(bt.sourceDirectory, bt.title);
- if (ProjectNode *node = findNodeForBuildKey(buildKey)) {
- if (auto targetNode = dynamic_cast<CMakeTargetNode *>(node))
- targetNode->setConfig(patchedConfig);
- }
- }
- }
-
- Target *t = bc->target();
- t->setApplicationTargets(bc->appTargets());
- t->setDeploymentData(bc->deploymentData());
-
- t->updateDefaultRunConfigurations();
-
- qDeleteAll(m_extraCompilers);
- m_extraCompilers = findExtraCompilers();
- CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
-
- QtSupport::CppKitInfo kitInfo(this);
- QTC_ASSERT(kitInfo.isValid(), return);
-
- CppTools::RawProjectParts rpps = m_buildDirManager.createRawProjectParts();
-
- for (CppTools::RawProjectPart &rpp : rpps) {
- rpp.setQtVersion(kitInfo.projectPartQtVersion); // TODO: Check if project actually uses Qt.
- if (kitInfo.cxxToolChain)
- rpp.setFlagsForCxx({kitInfo.cxxToolChain, rpp.flagsForCxx.commandLineFlags});
- if (kitInfo.cToolChain)
- rpp.setFlagsForC({kitInfo.cToolChain, rpp.flagsForC.commandLineFlags});
- }
-
- m_cppCodeModelUpdater->update({this, kitInfo, rpps});
-
- updateQmlJSCodeModel();
-
- m_buildDirManager.resetData();
-
- emit fileListChanged();
-
- bc->emitBuildTypeChanged();
+ setBuildSystem(std::make_unique<CMakeBuildSystem>(this));
}
-void CMakeProject::updateQmlJSCodeModel()
-{
- QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
-
- if (!modelManager || !activeTarget() || !activeTarget()->activeBuildConfiguration())
- return;
-
- QmlJS::ModelManagerInterface::ProjectInfo projectInfo =
- modelManager->defaultProjectInfoForProject(this);
-
- projectInfo.importPaths.clear();
-
- QString cmakeImports;
- auto bc = qobject_cast<const CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
- if (!bc)
- return;
-
- const CMakeConfig &cm = bc->configurationFromCMake();
- foreach (const CMakeConfigItem &di, cm) {
- if (di.key.contains("QML_IMPORT_PATH")) {
- cmakeImports = QString::fromUtf8(di.value);
- break;
- }
- }
-
- foreach (const QString &cmakeImport, CMakeConfigItem::cmakeSplitValue(cmakeImports))
- projectInfo.importPaths.maybeInsert(FilePath::fromString(cmakeImport), QmlJS::Dialect::Qml);
-
- modelManager->updateProjectInfo(projectInfo, this);
-}
-
-std::unique_ptr<CMakeProjectNode>
-CMakeProject::generateProjectTree(const QList<const FileNode *> &allFiles) const
-{
- if (m_buildDirManager.isParsing())
- return nullptr;
-
- auto root = std::make_unique<CMakeProjectNode>(projectDirectory());
- m_buildDirManager.generateProjectTree(root.get(), allFiles);
- return root;
-}
-
-bool CMakeProject::knowsAllBuildExecutables() const
-{
- return false;
-}
+CMakeProject::~CMakeProject() = default;
Tasks CMakeProject::projectIssues(const Kit *k) const
{
@@ -421,9 +115,10 @@ void CMakeProject::runCMake()
return;
BuildDirParameters parameters(bc);
- m_buildDirManager.setParametersAndRequestParse(parameters,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION);
+ bc->m_buildDirManager
+ .setParametersAndRequestParse(parameters,
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION
+ | BuildDirManager::REPARSE_FORCE_CMAKE_RUN);
}
void CMakeProject::runCMakeAndScanProjectTree()
@@ -431,12 +126,11 @@ void CMakeProject::runCMakeAndScanProjectTree()
CMakeBuildConfiguration *bc = activeBc(this);
if (isParsing() || !bc)
return;
- QTC_ASSERT(m_treeScanner.isFinished(), return);
BuildDirParameters parameters(bc);
- m_buildDirManager.setParametersAndRequestParse(parameters,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION | BuildDirManager::REPARSE_SCAN,
- BuildDirManager::REPARSE_CHECK_CONFIGURATION | BuildDirManager::REPARSE_SCAN);
+ bc->m_buildDirManager.setParametersAndRequestParse(parameters,
+ BuildDirManager::REPARSE_CHECK_CONFIGURATION
+ | BuildDirManager::REPARSE_SCAN);
}
void CMakeProject::buildCMakeTarget(const QString &buildTarget)
@@ -456,66 +150,15 @@ ProjectImporter *CMakeProject::projectImporter() const
bool CMakeProject::persistCMakeState()
{
- return m_buildDirManager.persistCMakeState();
+ CMakeBuildConfiguration *bc = activeBc(this);
+ return bc ? bc->m_buildDirManager.persistCMakeState() : false;
}
void CMakeProject::clearCMakeCache()
{
- m_buildDirManager.clearCache();
-}
-
-void CMakeProject::handleReparseRequest(int reparseParameters)
-{
- QTC_ASSERT(!(reparseParameters & BuildDirManager::REPARSE_FAIL), return);
- if (reparseParameters & BuildDirManager::REPARSE_IGNORE)
- return;
-
- m_delayedParsingTimer.setInterval((reparseParameters & BuildDirManager::REPARSE_URGENT) ? 0 : 1000);
- m_delayedParsingTimer.start();
- m_delayedParsingParameters = m_delayedParsingParameters | reparseParameters;
- if (m_allFiles.isEmpty())
- m_delayedParsingParameters |= BuildDirManager::REPARSE_SCAN;
-}
-
-void CMakeProject::startParsing(int reparseParameters)
-{
- m_delayedParsingParameters = BuildDirManager::REPARSE_DEFAULT;
-
- QTC_ASSERT((reparseParameters & BuildDirManager::REPARSE_FAIL) == 0, return);
- if (reparseParameters & BuildDirManager::REPARSE_IGNORE)
- return;
-
- QTC_ASSERT(activeBc(this), return);
-
- emitParsingStarted();
-
- m_waitingForScan = reparseParameters & BuildDirManager::REPARSE_SCAN;
- m_waitingForParse = true;
- m_combinedScanAndParseResult = true;
-
- if (m_waitingForScan) {
- QTC_CHECK(m_treeScanner.isFinished());
- m_treeScanner.asyncScanForFiles(projectDirectory());
- Core::ProgressManager::addTask(m_treeScanner.future(),
- tr("Scan \"%1\" project tree").arg(displayName()),
- "CMake.Scan.Tree");
- }
-
- m_buildDirManager.parse(reparseParameters);
-}
-
-QStringList CMakeProject::buildTargetTitles() const
-{
CMakeBuildConfiguration *bc = activeBc(this);
- return bc ? bc->buildTargetTitles() : QStringList();
-}
-
-Project::RestoreResult CMakeProject::fromMap(const QVariantMap &map, QString *errorMessage)
-{
- RestoreResult result = Project::fromMap(map, errorMessage);
- if (result != RestoreResult::Ok)
- return result;
- return RestoreResult::Ok;
+ if (bc)
+ bc->m_buildDirManager.clearCache();
}
bool CMakeProject::setupTarget(Target *t)
@@ -527,62 +170,6 @@ bool CMakeProject::setupTarget(Target *t)
return true;
}
-void CMakeProject::handleTreeScanningFinished()
-{
- QTC_CHECK(m_waitingForScan);
-
- qDeleteAll(m_allFiles);
- m_allFiles = Utils::transform(m_treeScanner.release(), [](const FileNode *fn) { return fn; });
-
- CMakeBuildConfiguration *bc = activeBc(this);
- QTC_ASSERT(bc, return);
-
- m_combinedScanAndParseResult = m_combinedScanAndParseResult && true;
- m_waitingForScan = false;
-
- combineScanAndParse(bc);
-}
-
-void CMakeProject::handleParsingSuccess(CMakeBuildConfiguration *bc)
-{
- QTC_ASSERT(m_waitingForParse, return);
-
- if (!bc || !bc->isActive())
- return;
-
- m_waitingForParse = false;
- m_combinedScanAndParseResult = m_combinedScanAndParseResult && true;
-
- combineScanAndParse(bc);
-}
-
-void CMakeProject::handleParsingError(CMakeBuildConfiguration *bc)
-{
- QTC_CHECK(m_waitingForParse);
-
- if (!bc || !bc->isActive())
- return;
-
- m_waitingForParse = false;
- m_combinedScanAndParseResult = false;
-
- combineScanAndParse(bc);
-}
-
-
-void CMakeProject::combineScanAndParse(CMakeBuildConfiguration *bc)
-{
- QTC_ASSERT(bc && bc->isActive(), return);
-
- if (m_waitingForParse || m_waitingForScan)
- return;
-
- if (m_combinedScanAndParseResult)
- updateProjectData(bc);
-
- emitParsingFinished(m_combinedScanAndParseResult);
-}
-
QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const
{
if (!activeTarget())
@@ -595,9 +182,7 @@ QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const
const FilePath cmakeListsTxt = baseDirectory.pathAppended("CMakeLists.txt");
if (cmakeListsTxt.exists())
break;
- QDir dir(baseDirectory.toString());
- dir.cdUp();
- baseDirectory = FilePath::fromString(dir.absolutePath());
+ baseDirectory = baseDirectory.parentDir();
}
QDir srcDirRoot = QDir(project.toString());
@@ -623,9 +208,12 @@ QStringList CMakeProject::filesGeneratedFrom(const QString &sourceFile) const
ProjectExplorer::DeploymentKnowledge CMakeProject::deploymentKnowledge() const
{
- return contains(files(AllFiles), [](const FilePath &f) {
- return f.fileName() == "QtCreatorDeployment.txt";
- }) ? DeploymentKnowledge::Approximative : DeploymentKnowledge::Bad;
+ return !files([](const ProjectExplorer::Node *n) {
+ return n->filePath().fileName() == "QtCreatorDeployment.txt";
+ })
+ .isEmpty()
+ ? DeploymentKnowledge::Approximative
+ : DeploymentKnowledge::Bad;
}
MakeInstallCommand CMakeProject::makeInstallCommand(const Target *target,
@@ -644,47 +232,9 @@ MakeInstallCommand CMakeProject::makeInstallCommand(const Target *target,
return cmd;
}
-bool CMakeProject::mustUpdateCMakeStateBeforeBuild()
+bool CMakeProject::mustUpdateCMakeStateBeforeBuild() const
{
- return m_delayedParsingTimer.isActive();
-}
-
-QList<ProjectExplorer::ExtraCompiler *> CMakeProject::findExtraCompilers() const
-{
- QList<ProjectExplorer::ExtraCompiler *> extraCompilers;
- const QList<ExtraCompilerFactory *> factories =
- ExtraCompilerFactory::extraCompilerFactories();
-
- const QSet<QString> fileExtensions
- = Utils::transform<QSet>(factories, &ExtraCompilerFactory::sourceTag);
-
- // Find all files generated by any of the extra compilers, in a rather crude way.
- const FilePathList fileList = files([&fileExtensions](const Node *n) {
- if (!SourceFiles(n))
- return false;
- const QString fp = n->filePath().toString();
- const int pos = fp.lastIndexOf('.');
- return pos >= 0 && fileExtensions.contains(fp.mid(pos + 1));
- });
-
- // Generate the necessary information:
- for (const FilePath &file : fileList) {
- ExtraCompilerFactory *factory = Utils::findOrDefault(factories, [&file](const ExtraCompilerFactory *f) {
- return file.endsWith('.' + f->sourceTag());
- });
- QTC_ASSERT(factory, continue);
-
- QStringList generated = filesGeneratedFrom(file.toString());
- if (generated.isEmpty())
- continue;
-
- const FilePathList fileNames
- = transform(generated,
- [](const QString &s) { return FilePath::fromString(s); });
- extraCompilers.append(factory->create(this, file, fileNames));
- }
-
- return extraCompilers;
+ return buildSystem()->isWaitingForParse();
}
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index 3af409f1b6..cf7a1f058e 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -28,13 +28,12 @@
#include "cmake_global.h"
#include "builddirmanager.h"
+#include "cmakebuildsystem.h"
#include "cmakebuildtarget.h"
#include "cmakeprojectimporter.h"
-#include <projectexplorer/extracompiler.h>
+#include <projectexplorer/buildsystem.h>
#include <projectexplorer/project.h>
-#include <projectexplorer/projectmacro.h>
-#include <projectexplorer/treescanner.h>
#include <utils/fileutils.h>
@@ -63,10 +62,6 @@ public:
explicit CMakeProject(const Utils::FilePath &filename);
~CMakeProject() final;
- QStringList buildTargetTitles() const;
-
- bool knowsAllBuildExecutables() const final;
-
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
void runCMake();
@@ -79,56 +74,21 @@ public:
bool persistCMakeState();
void clearCMakeCache();
- bool mustUpdateCMakeStateBeforeBuild();
+ bool mustUpdateCMakeStateBeforeBuild() const;
protected:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
bool setupTarget(ProjectExplorer::Target *t) final;
private:
- void handleReparseRequest(int reparseParameters);
-
- void startParsing(int reparseParameters);
-
- void handleTreeScanningFinished();
- void handleParsingSuccess(Internal::CMakeBuildConfiguration *bc);
- void handleParsingError(Internal::CMakeBuildConfiguration *bc);
- void combineScanAndParse(Internal::CMakeBuildConfiguration *bc);
- void updateProjectData(Internal::CMakeBuildConfiguration *bc);
- void updateQmlJSCodeModel();
-
- std::unique_ptr<Internal::CMakeProjectNode>
- generateProjectTree(const QList<const ProjectExplorer::FileNode*> &allFiles) const;
-
- QList<ProjectExplorer::ExtraCompiler *> findExtraCompilers() const;
QStringList filesGeneratedFrom(const QString &sourceFile) const final;
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
- bool hasMakeInstallEquivalent() const override { return true; }
ProjectExplorer::MakeInstallCommand makeInstallCommand(const ProjectExplorer::Target *target,
const QString &installRoot) override;
- // TODO probably need a CMake specific node structure
- QList<CMakeBuildTarget> m_buildTargets;
- CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
- QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
-
- ProjectExplorer::TreeScanner m_treeScanner;
- Internal::BuildDirManager m_buildDirManager;
-
- bool m_waitingForScan = false;
- bool m_waitingForParse = false;
- bool m_combinedScanAndParseResult = false;
-
- QHash<QString, bool> m_mimeBinaryCache;
- QList<const ProjectExplorer::FileNode *> m_allFiles;
mutable std::unique_ptr<Internal::CMakeProjectImporter> m_projectImporter;
- QTimer m_delayedParsingTimer;
- int m_delayedParsingParameters = 0;
-
- friend class Internal::CMakeBuildConfiguration;
- friend class Internal::CMakeBuildSettingsWidget;
+ friend class CMakeBuildSystem;
};
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp
index e647692439..00302f6d35 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp
@@ -53,22 +53,6 @@ namespace {
Q_LOGGING_CATEGORY(cmInputLog, "qtc.cmake.import", QtWarningMsg);
-struct CMakeToolChainData
-{
- QByteArray languageId;
- Utils::FilePath compilerPath;
- Core::Id mapLanguageIdToQtC() const
- {
- const QByteArray li = languageId.toLower();
- if (li == "cxx")
- return ProjectExplorer::Constants::CXX_LANGUAGE_ID;
- else if (li == "c")
- return ProjectExplorer::Constants::C_LANGUAGE_ID;
- else
- return Core::Id::fromName(languageId);
- }
-};
-
struct DirectoryData
{
// Project Stuff:
@@ -83,7 +67,7 @@ struct DirectoryData
QByteArray toolset;
QByteArray sysroot;
QtProjectImporter::QtVersionData qt;
- QVector<CMakeToolChainData> toolChains;
+ QVector<ToolChainDescription> toolChains;
};
static QStringList scanDirectory(const QString &path, const QString &prefix)
@@ -218,14 +202,21 @@ static Utils::FilePath qmakeFromCMakeCache(const CMakeConfig &config)
return Utils::FilePath();
}
-QVector<CMakeToolChainData> extractToolChainsFromCache(const CMakeConfig &config)
+static QVector<ToolChainDescription> extractToolChainsFromCache(const CMakeConfig &config)
{
- QVector<CMakeToolChainData> result;
+ QVector<ToolChainDescription> result;
for (const CMakeConfigItem &i : config) {
if (!i.key.startsWith("CMAKE_") || !i.key.endsWith("_COMPILER"))
continue;
const QByteArray language = i.key.mid(6, i.key.count() - 6 - 9); // skip "CMAKE_" and "_COMPILER"
- result.append({language, Utils::FilePath::fromUtf8(i.value)});
+ Core::Id languageId;
+ if (language == "CXX")
+ languageId = ProjectExplorer::Constants::CXX_LANGUAGE_ID;
+ else if (language == "C")
+ languageId = ProjectExplorer::Constants::C_LANGUAGE_ID;
+ else
+ languageId = Core::Id::fromName(language);
+ result.append({Utils::FilePath::fromUtf8(i.value), languageId});
}
return result;
}
@@ -300,8 +291,8 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const
if (data->qt.qt && QtSupport::QtKitAspect::qtVersionId(k) != data->qt.qt->uniqueId())
return false;
- for (const CMakeToolChainData &tcd : data->toolChains) {
- ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.mapLanguageIdToQtC());
+ for (const ToolChainDescription &tcd : data->toolChains) {
+ ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language);
if (!tc || tc->compilerCommand() != tcd.compilerPath)
return false;
}
@@ -328,9 +319,8 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const
SysRootKitAspect::setSysRoot(k, Utils::FilePath::fromUtf8(data->sysroot));
- for (const CMakeToolChainData &cmtcd : data->toolChains) {
- const ToolChainData tcd
- = findOrCreateToolChains(cmtcd.compilerPath, cmtcd.mapLanguageIdToQtC());
+ for (const ToolChainDescription &cmtcd : data->toolChains) {
+ const ToolChainData tcd = findOrCreateToolChains(cmtcd);
QTC_ASSERT(!tcd.tcs.isEmpty(), continue);
if (tcd.areTemporary) {
@@ -349,7 +339,7 @@ const QList<BuildInfo> CMakeProjectImporter::buildInfoListForKit(const Kit *k, v
{
auto data = static_cast<const DirectoryData *>(directoryData);
auto factory = qobject_cast<CMakeBuildConfigurationFactory *>(
- BuildConfigurationFactory::find(k, projectFilePath().toString()));
+ BuildConfigurationFactory::find(k, projectFilePath()));
if (!factory)
return {};
@@ -464,17 +454,17 @@ void CMakeProjectPlugin::testCMakeProjectImporterToolChain_data()
<< QStringList("CMAKE_SOMETHING_ELSE=/tmp") << QByteArrayList() << QStringList();
QTest::newRow("CXX compiler")
<< QStringList({"CMAKE_CXX_COMPILER=/usr/bin/g++"})
- << QByteArrayList({"CXX"})
+ << QByteArrayList({"Cxx"})
<< QStringList({"/usr/bin/g++"});
QTest::newRow("CXX compiler, C compiler")
<< QStringList({"CMAKE_CXX_COMPILER=/usr/bin/g++", "CMAKE_C_COMPILER=/usr/bin/clang"})
- << QByteArrayList({"CXX", "C"})
+ << QByteArrayList({"Cxx", "C"})
<< QStringList({"/usr/bin/g++", "/usr/bin/clang"});
QTest::newRow("CXX compiler, C compiler, strange compiler")
<< QStringList({"CMAKE_CXX_COMPILER=/usr/bin/g++",
"CMAKE_C_COMPILER=/usr/bin/clang",
"CMAKE_STRANGE_LANGUAGE_COMPILER=/tmp/strange/compiler"})
- << QByteArrayList({"CXX", "C", "STRANGE_LANGUAGE"})
+ << QByteArrayList({"Cxx", "C", "STRANGE_LANGUAGE"})
<< QStringList({"/usr/bin/g++", "/usr/bin/clang", "/tmp/strange/compiler"});
QTest::newRow("CXX compiler, C compiler, strange compiler (with junk)")
<< QStringList({"FOO=test",
@@ -484,7 +474,7 @@ void CMakeProjectPlugin::testCMakeProjectImporterToolChain_data()
"SOMETHING_COMPILER=/usr/bin/something",
"CMAKE_STRANGE_LANGUAGE_COMPILER=/tmp/strange/compiler",
"BAR=more test"})
- << QByteArrayList({"CXX", "C", "STRANGE_LANGUAGE"})
+ << QByteArrayList({"Cxx", "C", "STRANGE_LANGUAGE"})
<< QStringList({"/usr/bin/g++", "/usr/bin/clang", "/tmp/strange/compiler"});
}
@@ -505,10 +495,10 @@ void CMakeProjectPlugin::testCMakeProjectImporterToolChain()
config.append(CMakeConfigItem(key.toUtf8(), value.toUtf8()));
}
- QVector<CMakeToolChainData> tcs = extractToolChainsFromCache(config);
+ const QVector<ToolChainDescription> tcs = extractToolChainsFromCache(config);
QCOMPARE(tcs.count(), expectedLanguages.count());
for (int i = 0; i < tcs.count(); ++i) {
- QCOMPARE(tcs.at(i).languageId, expectedLanguages.at(i));
+ QCOMPARE(tcs.at(i).language, expectedLanguages.at(i));
QCOMPARE(tcs.at(i).compilerPath.toString(), expectedToolChains.at(i));
}
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
index 21be7d1995..10f8202ad5 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
@@ -32,12 +32,13 @@
#include "cmaketoolmanager.h"
#include "cmakeprojectnodes.h"
-#include <coreplugin/icore.h>
-#include <coreplugin/messagemanager.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
-#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/messagemanager.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro
index dc4e30223b..c1b26eabd8 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro
@@ -5,15 +5,16 @@ HEADERS = builddirmanager.h \
builddirparameters.h \
builddirreader.h \
cmakebuildstep.h \
+ cmakebuildsystem.h \
cmakebuildtarget.h \
cmakeconfigitem.h \
+ cmakeprocess.h \
cmakeproject.h \
cmakeprojectimporter.h \
cmakeprojectplugin.h \
cmakeprojectmanager.h \
cmakeprojectconstants.h \
cmakeprojectnodes.h \
- cmakerunconfiguration.h \
cmakebuildconfiguration.h \
cmakeeditor.h \
cmakelocatorfilter.h \
@@ -33,6 +34,10 @@ HEADERS = builddirmanager.h \
cmakespecificsettingspage.h \
configmodel.h \
configmodelitemdelegate.h \
+ fileapidataextractor.h \
+ fileapiparser.h \
+ fileapireader.h \
+ projecttreehelper.h \
servermode.h \
servermodereader.h \
tealeafreader.h
@@ -41,13 +46,14 @@ SOURCES = builddirmanager.cpp \
builddirparameters.cpp \
builddirreader.cpp \
cmakebuildstep.cpp \
+ cmakebuildsystem.cpp \
cmakeconfigitem.cpp \
+ cmakeprocess.cpp \
cmakeproject.cpp \
cmakeprojectimporter.cpp \
cmakeprojectplugin.cpp \
cmakeprojectmanager.cpp \
cmakeprojectnodes.cpp \
- cmakerunconfiguration.cpp \
cmakebuildconfiguration.cpp \
cmakeeditor.cpp \
cmakelocatorfilter.cpp \
@@ -66,6 +72,10 @@ SOURCES = builddirmanager.cpp \
cmakespecificsettingspage.cpp \
configmodel.cpp \
configmodelitemdelegate.cpp \
+ fileapidataextractor.cpp \
+ fileapiparser.cpp \
+ fileapireader.cpp \
+ projecttreehelper.cpp \
servermode.cpp \
servermodereader.cpp \
tealeafreader.cpp
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs
index e31c42886a..6b002345ed 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs
@@ -32,6 +32,8 @@ QtcPlugin {
"cmakebuildsettingswidget.h",
"cmakebuildstep.cpp",
"cmakebuildstep.h",
+ "cmakebuildsystem.cpp",
+ "cmakebuildsystem.h",
"cmakebuildtarget.h",
"cmakecbpparser.cpp",
"cmakecbpparser.h",
@@ -47,6 +49,8 @@ QtcPlugin {
"cmakelocatorfilter.h",
"cmakeparser.cpp",
"cmakeparser.h",
+ "cmakeprocess.cpp",
+ "cmakeprocess.h",
"cmakeproject.cpp",
"cmakeproject.h",
"cmakeproject.qrc",
@@ -59,8 +63,6 @@ QtcPlugin {
"cmakeprojectnodes.h",
"cmakeprojectplugin.cpp",
"cmakeprojectplugin.h",
- "cmakerunconfiguration.cpp",
- "cmakerunconfiguration.h",
"cmaketool.cpp",
"cmaketool.h",
"cmaketoolmanager.cpp",
@@ -82,6 +84,14 @@ QtcPlugin {
"configmodel.h",
"configmodelitemdelegate.cpp",
"configmodelitemdelegate.h",
+ "fileapidataextractor.cpp",
+ "fileapidataextractor.h",
+ "fileapiparser.cpp",
+ "fileapiparser.h",
+ "fileapireader.cpp",
+ "fileapireader.h",
+ "projecttreehelper.cpp",
+ "projecttreehelper.h",
"servermode.cpp",
"servermode.h",
"servermodereader.cpp",
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index f14f627b34..aeee344aea 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -26,6 +26,7 @@
#include "cmakeprojectnodes.h"
#include "cmakeconfigitem.h"
+#include "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectplugin.h"
@@ -176,11 +177,6 @@ CMakeTargetNode::CMakeTargetNode(const Utils::FilePath &directory, const QString
setIsProduct();
}
-QString CMakeTargetNode::generateId(const Utils::FilePath &directory, const QString &target)
-{
- return directory.toString() + "///::///" + target;
-}
-
QString CMakeTargetNode::tooltip() const
{
return m_tooltip;
@@ -188,7 +184,7 @@ QString CMakeTargetNode::tooltip() const
QString CMakeTargetNode::buildKey() const
{
- return generateId(filePath(), m_target);
+ return m_target;
}
Utils::FilePath CMakeTargetNode::buildDirectory() const
@@ -264,6 +260,11 @@ Utils::optional<Utils::FilePath> CMakeTargetNode::visibleAfterAddFileAction() co
return filePath().pathAppended("CMakeLists.txt");
}
+void CMakeTargetNode::build()
+{
+ static_cast<CMakeProject *>(getProject())->buildCMakeTarget(displayName());
+}
+
void CMakeTargetNode::setTargetInformation(const QList<Utils::FilePath> &artifacts,
const QString &type)
{
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
index 5a61737925..f4cea98db4 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
@@ -63,8 +63,6 @@ class CMakeTargetNode : public ProjectExplorer::ProjectNode
public:
CMakeTargetNode(const Utils::FilePath &directory, const QString &target);
- static QString generateId(const Utils::FilePath &directory, const QString &target);
-
void setTargetInformation(const QList<Utils::FilePath> &artifacts, const QString &type);
QString tooltip() const final;
@@ -76,6 +74,8 @@ public:
bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
Utils::optional<Utils::FilePath> visibleAfterAddFileAction() const override;
+ void build() override;
+
QVariant data(Core::Id role) const override;
void setConfig(const CMakeConfig &config);
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
index 53825f4d7c..5418a1994e 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
@@ -32,7 +32,6 @@
#include "cmakeprojectmanager.h"
#include "cmakeprojectnodes.h"
#include "cmakebuildconfiguration.h"
-#include "cmakerunconfiguration.h"
#include "cmakeprojectconstants.h"
#include "cmakelocatorfilter.h"
#include "cmakesettingspage.h"
@@ -71,11 +70,10 @@ public:
static const std::unique_ptr<CMakeSpecificSettings> projectTypeSpecificSettings;
CMakeManager manager;
CMakeBuildStepFactory buildStepFactory;
- CMakeRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, CMakeRunConfiguration> runWorkerFactory;
CMakeBuildConfigurationFactory buildConfigFactory;
CMakeEditorFactory editorFactor;
- CMakeLocatorFilter locatorFiler;
+ BuildCMakeTargetLocatorFilter buildCMakeTargetLocatorFilter;
+ OpenCMakeTargetLocatorFilter openCMakeTargetLocationFilter;
CMakeKitAspect cmakeKitAspect;
CMakeGeneratorKitAspect cmakeGeneratorKitAspect;
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
deleted file mode 100644
index 30514b70a5..0000000000
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "cmakerunconfiguration.h"
-
-#include "cmakeprojectconstants.h"
-
-#include <qtsupport/qtkitinformation.h>
-#include <qtsupport/qtoutputformatter.h>
-
-#include <projectexplorer/localenvironmentaspect.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/runconfigurationaspects.h>
-#include <projectexplorer/runcontrol.h>
-#include <projectexplorer/target.h>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace CMakeProjectManager {
-namespace Internal {
-
-CMakeRunConfiguration::CMakeRunConfiguration(Target *target, Core::Id id)
- : RunConfiguration(target, id)
-{
- auto envAspect = addAspect<LocalEnvironmentAspect>(target);
-
- // Workaround for QTCREATORBUG-19354:
- if (HostOsInfo::isWindowsHost()) {
- envAspect->addModifier([target](Environment &env) {
- const Kit *k = target->kit();
- if (const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k)) {
- const QString installBinPath = qt->qmakeProperty("QT_INSTALL_BINS");
- env.prependOrSetPath(installBinPath);
- }
- });
- }
-
- addAspect<ExecutableAspect>();
- addAspect<ArgumentsAspect>();
- addAspect<WorkingDirectoryAspect>();
- addAspect<TerminalAspect>();
-
- connect(target->project(), &Project::parsingFinished,
- this, &CMakeRunConfiguration::updateTargetInformation);
-
- if (QtSupport::QtKitAspect::qtVersion(target->kit()))
- setOutputFormatter<QtSupport::QtOutputFormatter>();
-}
-
-void CMakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info)
-{
- Q_UNUSED(info);
- updateTargetInformation();
-}
-
-bool CMakeRunConfiguration::isBuildTargetValid() const
-{
- return Utils::anyOf(target()->applicationTargets(), [this](const BuildTargetInfo &bti) {
- return bti.buildKey == buildKey();
- });
-}
-
-void CMakeRunConfiguration::updateEnabledState()
-{
- if (!isBuildTargetValid())
- setEnabled(false);
- else
- RunConfiguration::updateEnabledState();
-}
-
-QString CMakeRunConfiguration::disabledReason() const
-{
- if (!isBuildTargetValid())
- return tr("The project no longer builds the target associated with this run configuration.");
- return RunConfiguration::disabledReason();
-}
-
-void CMakeRunConfiguration::updateTargetInformation()
-{
- BuildTargetInfo bti = buildTargetInfo();
- aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
- aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
- aspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
-
- auto terminalAspect = aspect<TerminalAspect>();
- terminalAspect->setUseTerminalHint(bti.usesTerminal);
-}
-
-// Factory
-CMakeRunConfigurationFactory::CMakeRunConfigurationFactory()
-{
- registerRunConfiguration<CMakeRunConfiguration>("CMakeProjectManager.CMakeRunConfiguration.");
- addSupportedProjectType(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
- addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
-}
-
-} // Internal
-} // CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
index 991eb274c4..5b4ca9d051 100644
--- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
@@ -27,25 +27,27 @@
#include "cmakesettingspage.h"
#include "cmaketoolmanager.h"
+#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorericons.h>
-#include <coreplugin/icore.h>
-#include <utils/environment.h>
#include <utils/detailswidget.h>
+#include <utils/environment.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <utils/treemodel.h>
+#include <utils/utilsicons.h>
#include <QCheckBox>
+#include <QFileInfo>
#include <QFormLayout>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTreeView>
-#include <QWidget>
#include <QUuid>
+#include <QWidget>
using namespace Utils;
@@ -91,25 +93,44 @@ class CMakeToolTreeItem : public TreeItem
Q_DECLARE_TR_FUNCTIONS(CMakeProjectManager::CMakeSettingsPage)
public:
- CMakeToolTreeItem(const CMakeTool *item, bool changed) :
- m_id(item->id()),
- m_name(item->displayName()),
- m_executable(item->cmakeExecutable()),
- m_isAutoRun(item->isAutoRun()),
- m_autoCreateBuildDirectory(item->autoCreateBuildDirectory()),
- m_autodetected(item->isAutoDetected()),
- m_changed(changed)
- {}
-
- CMakeToolTreeItem(const QString &name, const Utils::FilePath &executable,
- bool autoRun, bool autoCreate, bool autodetected) :
- m_id(Core::Id::fromString(QUuid::createUuid().toString())),
- m_name(name),
- m_executable(executable),
- m_isAutoRun(autoRun),
- m_autoCreateBuildDirectory(autoCreate),
- m_autodetected(autodetected)
- {}
+ CMakeToolTreeItem(const CMakeTool *item, bool changed)
+ : m_id(item->id())
+ , m_name(item->displayName())
+ , m_executable(item->filePath())
+ , m_isAutoRun(item->isAutoRun())
+ , m_autoCreateBuildDirectory(item->autoCreateBuildDirectory())
+ , m_autodetected(item->isAutoDetected())
+ , m_changed(changed)
+ {
+ updateErrorFlags();
+ m_tooltip = tr("Version: %1<br>Supports fileApi: %2<br>Supports server-mode: %3")
+ .arg(QString::fromUtf8(item->version().fullVersion))
+ .arg(item->hasFileApi() ? tr("yes") : tr("no"))
+ .arg(item->hasServerMode() ? tr("yes") : tr("no"));
+ }
+
+ CMakeToolTreeItem(const QString &name,
+ const Utils::FilePath &executable,
+ bool autoRun,
+ bool autoCreate,
+ bool autodetected)
+ : m_id(Core::Id::fromString(QUuid::createUuid().toString()))
+ , m_name(name)
+ , m_executable(executable)
+ , m_isAutoRun(autoRun)
+ , m_autoCreateBuildDirectory(autoCreate)
+ , m_autodetected(autodetected)
+ {
+ updateErrorFlags();
+ }
+
+ void updateErrorFlags()
+ {
+ const QFileInfo fi = CMakeTool::cmakeExecutable(m_executable).toFileInfo();
+ m_pathExists = fi.exists();
+ m_pathIsFile = fi.isFile();
+ m_pathIsExecutable = fi.isExecutable();
+ }
CMakeToolTreeItem() = default;
@@ -118,7 +139,7 @@ public:
QVariant data(int column, int role) const override
{
switch (role) {
- case Qt::DisplayRole:
+ case Qt::DisplayRole: {
switch (column) {
case 0: {
QString name = m_name;
@@ -126,25 +147,60 @@ public:
name += tr(" (Default)");
return name;
}
- case 1:
+ case 1: {
return m_executable.toUserOutput();
}
- break;
-
+ } // switch (column)
+ return QVariant();
+ }
case Qt::FontRole: {
QFont font;
font.setBold(m_changed);
font.setItalic(model()->defaultItemId() == m_id);
return font;
}
+ case Qt::ToolTipRole: {
+ QString result = m_tooltip;
+ QString error;
+ if (!m_pathExists) {
+ error = QCoreApplication::translate(
+ "CMakeProjectManager::Internal::CMakeToolTreeItem",
+ "CMake executable path does not exist.");
+ } else if (!m_pathIsFile) {
+ error = QCoreApplication::translate(
+ "CMakeProjectManager::Internal::CMakeToolTreeItem",
+ "CMake executable path is not a file.");
+ } else if (!m_pathIsExecutable) {
+ error = QCoreApplication::translate(
+ "CMakeProjectManager::Internal::CMakeToolTreeItem",
+ "CMake executable path is not executable.");
+ }
+ if (result.isEmpty() || error.isEmpty())
+ return QString("%1%2").arg(result).arg(error);
+ else
+ return QString("%1<br><br><b>%2</b>").arg(result).arg(error);
+ }
+ case Qt::DecorationRole: {
+ if (column != 0)
+ return QVariant();
+
+ const bool hasError = !m_pathExists || !m_pathIsFile || !m_pathIsExecutable;
+ if (hasError)
+ return Utils::Icons::CRITICAL.icon();
+ return QVariant();
+ }
}
return QVariant();
}
Core::Id m_id;
- QString m_name;
+ QString m_name;
+ QString m_tooltip;
FilePath m_executable;
bool m_isAutoRun = true;
+ bool m_pathExists = false;
+ bool m_pathIsFile = false;
+ bool m_pathIsExecutable = false;
bool m_autoCreateBuildDirectory = false;
bool m_autodetected = false;
bool m_changed = true;
@@ -209,7 +265,7 @@ void CMakeToolItemModel::reevaluateChangedFlag(CMakeToolTreeItem *item) const
{
CMakeTool *orig = CMakeToolManager::findById(item->m_id);
item->m_changed = !orig || orig->displayName() != item->m_name
- || orig->cmakeExecutable() != item->m_executable;
+ || orig->filePath() != item->m_executable;
//make sure the item is marked as changed when the default cmake was changed
CMakeTool *origDefTool = CMakeToolManager::defaultCMakeTool();
@@ -227,13 +283,15 @@ void CMakeToolItemModel::updateCMakeTool(const Core::Id &id, const QString &disp
bool autoCreate)
{
CMakeToolTreeItem *treeItem = cmakeToolItem(id);
- QTC_ASSERT(treeItem, return);
+ QTC_ASSERT(treeItem, return );
treeItem->m_name = displayName;
treeItem->m_executable = executable;
treeItem->m_isAutoRun = autoRun;
treeItem->m_autoCreateBuildDirectory = autoCreate;
+ treeItem->updateErrorFlags();
+
reevaluateChangedFlag(treeItem);
}
@@ -269,7 +327,7 @@ void CMakeToolItemModel::apply()
item->m_changed = false;
if (CMakeTool *cmake = CMakeToolManager::findById(item->m_id)) {
cmake->setDisplayName(item->m_name);
- cmake->setCMakeExecutable(item->m_executable);
+ cmake->setFilePath(item->m_executable);
cmake->setAutorun(item->m_isAutoRun);
cmake->setAutoCreateBuildDirectory(item->m_autoCreateBuildDirectory);
} else {
@@ -282,7 +340,7 @@ void CMakeToolItemModel::apply()
: CMakeTool::ManualDetection;
auto cmake = std::make_unique<CMakeTool>(detection, item->m_id);
cmake->setDisplayName(item->m_name);
- cmake->setCMakeExecutable(item->m_executable);
+ cmake->setFilePath(item->m_executable);
if (!CMakeToolManager::registerCMakeTool(std::move(cmake)))
item->m_changed = true;
}
diff --git a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp
index d9c8f508a5..e458e7fbd5 100644
--- a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.cpp
@@ -31,8 +31,7 @@
namespace CMakeProjectManager {
namespace Internal {
-CMakeSpecificSettingWidget::CMakeSpecificSettingWidget(QWidget *parent):
- QWidget(parent)
+CMakeSpecificSettingWidget::CMakeSpecificSettingWidget()
{
m_ui.setupUi(this);
m_ui.newFileAddedCopyToCpliSettingGroup->setId(m_ui.alwaysAskRadio,
diff --git a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h
index d0b9b266bb..2d4419d0d5 100644
--- a/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h
+++ b/src/plugins/cmakeprojectmanager/cmakespecificsettingspage.h
@@ -40,7 +40,8 @@ class CMakeSpecificSettingWidget : public QWidget
Q_OBJECT
public:
- explicit CMakeSpecificSettingWidget(QWidget *parent = nullptr);
+ CMakeSpecificSettingWidget();
+
void setSettings(const CMakeSpecificSettings &settings);
CMakeSpecificSettings settings() const;
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp
index 8ba4fbcbba..0ed1d50513 100644
--- a/src/plugins/cmakeprojectmanager/cmaketool.cpp
+++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp
@@ -48,7 +48,7 @@ const char CMAKE_INFORMATION_DISPLAYNAME[] = "DisplayName";
const char CMAKE_INFORMATION_AUTORUN[] = "AutoRun";
const char CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY[] = "AutoCreateBuildDirectory";
const char CMAKE_INFORMATION_AUTODETECTED[] = "AutoDetected";
-
+const char CMAKE_INFORMATION_READERTYPE[] = "ReaderType";
bool CMakeTool::Generator::matches(const QString &n, const QString &ex) const
{
@@ -57,10 +57,50 @@ bool CMakeTool::Generator::matches(const QString &n, const QString &ex) const
namespace Internal {
+const char READER_TYPE_TEALEAF[] = "tealeaf";
+const char READER_TYPE_SERVERMODE[] = "servermode";
+const char READER_TYPE_FILEAPI[] = "fileapi";
+
+static bool ignoreFileApi()
+{
+ static bool s_ignoreFileApi = qEnvironmentVariableIsSet("QTC_CMAKE_IGNORE_FILEAPI");
+ return s_ignoreFileApi;
+}
+
+static Utils::optional<CMakeTool::ReaderType> readerTypeFromString(const QString &input)
+{
+ if (input == READER_TYPE_TEALEAF)
+ return CMakeTool::TeaLeaf;
+ if (input == READER_TYPE_SERVERMODE)
+ return CMakeTool::ServerMode;
+ if (input == READER_TYPE_FILEAPI)
+ return ignoreFileApi() ? CMakeTool::ServerMode : CMakeTool::FileApi;
+ return {};
+}
+
+static QString readerTypeToString(const CMakeTool::ReaderType &type)
+{
+ switch (type) {
+ case CMakeTool::TeaLeaf:
+ return QString(READER_TYPE_TEALEAF);
+ case CMakeTool::ServerMode:
+ return QString(READER_TYPE_SERVERMODE);
+ case CMakeTool::FileApi:
+ return QString(READER_TYPE_FILEAPI);
+ }
+ return QString();
+}
+
// --------------------------------------------------------------------
// CMakeIntrospectionData:
// --------------------------------------------------------------------
+class FileApi {
+public:
+ QString kind;
+ std::pair<int, int> version;
+};
+
class IntrospectionData
{
public:
@@ -73,6 +113,7 @@ public:
QList<CMakeTool::Generator> m_generators;
QMap<QString, QStringList> m_functionArgs;
+ QVector<FileApi> m_fileApis;
QStringList m_variables;
QStringList m_functions;
CMakeTool::Version m_version;
@@ -97,12 +138,14 @@ CMakeTool::CMakeTool(const QVariantMap &map, bool fromSdk) :
m_displayName = map.value(CMAKE_INFORMATION_DISPLAYNAME).toString();
m_isAutoRun = map.value(CMAKE_INFORMATION_AUTORUN, true).toBool();
m_autoCreateBuildDirectory = map.value(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, false).toBool();
+ m_readerType = Internal::readerTypeFromString(
+ map.value(CMAKE_INFORMATION_READERTYPE).toString());
//loading a CMakeTool from SDK is always autodetection
if (!fromSdk)
m_isAutoDetected = map.value(CMAKE_INFORMATION_AUTODETECTED, false).toBool();
- setCMakeExecutable(Utils::FilePath::fromString(map.value(CMAKE_INFORMATION_COMMAND).toString()));
+ setFilePath(Utils::FilePath::fromString(map.value(CMAKE_INFORMATION_COMMAND).toString()));
}
CMakeTool::~CMakeTool() = default;
@@ -112,7 +155,7 @@ Core::Id CMakeTool::createId()
return Core::Id::fromString(QUuid::createUuid().toString());
}
-void CMakeTool::setCMakeExecutable(const Utils::FilePath &executable)
+void CMakeTool::setFilePath(const Utils::FilePath &executable)
{
if (m_executable == executable)
return;
@@ -124,6 +167,11 @@ void CMakeTool::setCMakeExecutable(const Utils::FilePath &executable)
CMakeToolManager::notifyAboutUpdate(this);
}
+Utils::FilePath CMakeTool::filePath() const
+{
+ return m_executable;
+}
+
void CMakeTool::setAutorun(bool autoRun)
{
if (m_isAutoRun == autoRun)
@@ -169,7 +217,7 @@ Utils::SynchronousProcessResponse CMakeTool::run(const QStringList &args, bool m
cmake.setProcessEnvironment(env.toProcessEnvironment());
cmake.setTimeOutMessageBoxEnabled(false);
- Utils::SynchronousProcessResponse response = cmake.runBlocking(m_executable.toString(), args);
+ Utils::SynchronousProcessResponse response = cmake.runBlocking({cmakeExecutable(), args});
m_introspection->m_didAttemptToRun = true;
m_introspection->m_didRun = mayFail ? true : (response.result == Utils::SynchronousProcessResponse::Finished);
return response;
@@ -183,18 +231,36 @@ QVariantMap CMakeTool::toMap() const
data.insert(CMAKE_INFORMATION_COMMAND, m_executable.toString());
data.insert(CMAKE_INFORMATION_AUTORUN, m_isAutoRun);
data.insert(CMAKE_INFORMATION_AUTO_CREATE_BUILD_DIRECTORY, m_autoCreateBuildDirectory);
+ if (m_readerType.has_value())
+ data.insert(CMAKE_INFORMATION_READERTYPE,
+ Internal::readerTypeToString(m_readerType.value()));
data.insert(CMAKE_INFORMATION_AUTODETECTED, m_isAutoDetected);
return data;
}
Utils::FilePath CMakeTool::cmakeExecutable() const
{
- if (Utils::HostOsInfo::isMacHost() && m_executable.endsWith(".app")) {
- const Utils::FilePath toTest = m_executable.pathAppended("Contents/bin/cmake");
- if (toTest.exists())
- return toTest;
+ return cmakeExecutable(m_executable);
+}
+
+Utils::FilePath CMakeTool::cmakeExecutable(const Utils::FilePath &path)
+{
+ if (Utils::HostOsInfo::isMacHost()) {
+ const QString executableString = path.toString();
+ const int appIndex = executableString.lastIndexOf(".app");
+ const int appCutIndex = appIndex + 4;
+ const bool endsWithApp = appIndex >= 0 && appCutIndex >= executableString.size();
+ const bool containsApp = appIndex >= 0 && !endsWithApp
+ && executableString.at(appCutIndex) == '/';
+ if (endsWithApp || containsApp) {
+ const Utils::FilePath toTest = Utils::FilePath::fromString(
+ executableString.left(appCutIndex))
+ .pathAppended("Contents/bin/cmake");
+ if (toTest.exists())
+ return toTest.canonicalPath();
+ }
}
- return m_executable;
+ return path.canonicalPath();
}
bool CMakeTool::isAutoRun() const
@@ -248,6 +314,18 @@ bool CMakeTool::hasServerMode() const
return m_introspection->m_hasServerMode;
}
+bool CMakeTool::hasFileApi() const
+{
+ readInformation(QueryType::SERVER_MODE);
+ return !m_introspection->m_fileApis.isEmpty();
+}
+
+QVector<std::pair<QString, int> > CMakeTool::supportedFileApiObjects() const
+{
+ readInformation(QueryType::SERVER_MODE);
+ return Utils::transform(m_introspection->m_fileApis, [](const Internal::FileApi &api) { return std::make_pair(api.kind, api.version.first); });
+}
+
CMakeTool::Version CMakeTool::version() const
{
readInformation(QueryType::VERSION);
@@ -282,11 +360,27 @@ CMakeTool::PathMapper CMakeTool::pathMapper() const
return [](const Utils::FilePath &fn) { return fn; };
}
+CMakeTool::ReaderType CMakeTool::readerType() const
+{
+ if (!m_readerType.has_value()) {
+ // Find best possible reader type:
+ if (hasFileApi()) {
+ if (hasServerMode() && Internal::ignoreFileApi())
+ return ServerMode; // We were asked to fall back to server mode
+ return FileApi;
+ }
+ if (hasServerMode())
+ return ServerMode;
+ return TeaLeaf;
+ }
+ return m_readerType.value();
+}
+
void CMakeTool::readInformation(CMakeTool::QueryType type) const
{
if ((type == QueryType::GENERATORS && !m_introspection->m_generators.isEmpty())
- || (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode)
- || (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty()))
+ || (type == QueryType::SERVER_MODE && m_introspection->m_queriedServerMode)
+ || (type == QueryType::VERSION && !m_introspection->m_version.fullVersion.isEmpty()))
return;
if (!m_introspection->m_triedCapabilities) {
@@ -304,7 +398,7 @@ void CMakeTool::readInformation(CMakeTool::QueryType type) const
} else if (type == QueryType::VERSION) {
fetchVersionFromVersionOutput();
} else {
- QTC_ASSERT(false, return);
+ QTC_ASSERT(false, return );
}
}
@@ -324,10 +418,10 @@ static QStringList parseDefinition(const QString &definition)
ignoreWord = true;
}
- if (c == ' ' || c == '[' || c == '<' || c == '('
- || c == ']' || c == '>' || c == ')') {
+ if (c == ' ' || c == '[' || c == '<' || c == '(' || c == ']' || c == '>' || c == ')') {
if (!ignoreWord && !word.isEmpty()) {
- if (result.isEmpty() || Utils::allOf(word, [](const QChar &c) { return c.isUpper() || c == '_'; }))
+ if (result.isEmpty()
+ || Utils::allOf(word, [](const QChar &c) { return c.isUpper() || c == '_'; }))
result.append(word);
}
word.clear();
@@ -383,11 +477,12 @@ QStringList CMakeTool::parseVariableOutput(const QString &output)
QStringList result;
foreach (const QString &v, variableList) {
if (v.startsWith("CMAKE_COMPILER_IS_GNU<LANG>")) { // This key takes a compiler name :-/
- result << "CMAKE_COMPILER_IS_GNUCC" << "CMAKE_COMPILER_IS_GNUCXX";
+ result << "CMAKE_COMPILER_IS_GNUCC"
+ << "CMAKE_COMPILER_IS_GNUCXX";
} else if (v.contains("<CONFIG>")) {
const QString tmp = QString(v).replace("<CONFIG>", "%1");
- result << tmp.arg("DEBUG") << tmp.arg("RELEASE")
- << tmp.arg("MINSIZEREL") << tmp.arg("RELWITHDEBINFO");
+ result << tmp.arg("DEBUG") << tmp.arg("RELEASE") << tmp.arg("MINSIZEREL")
+ << tmp.arg("RELWITHDEBINFO");
} else if (v.contains("<LANG>")) {
const QString tmp = QString(v).replace("<LANG>", "%1");
result << tmp.arg("C") << tmp.arg("CXX");
@@ -455,7 +550,7 @@ void CMakeTool::parseGeneratorsFromHelp(const QStringList &lines) const
void CMakeTool::fetchVersionFromVersionOutput() const
{
- Utils::SynchronousProcessResponse response = run({"--version" });
+ Utils::SynchronousProcessResponse response = run({"--version"});
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
@@ -480,13 +575,22 @@ void CMakeTool::parseVersionFormVersionOutput(const QStringList &lines) const
void CMakeTool::fetchFromCapabilities() const
{
- Utils::SynchronousProcessResponse response = run({"-E", "capabilities" }, true);
+ Utils::SynchronousProcessResponse response = run({"-E", "capabilities"}, true);
if (response.result != Utils::SynchronousProcessResponse::Finished)
return;
parseFromCapabilities(response.stdOut());
}
+static int getVersion(const QVariantMap &obj, const QString value)
+{
+ bool ok;
+ int result = obj.value(value).toInt(&ok);
+ if (!ok)
+ return -1;
+ return result;
+}
+
void CMakeTool::parseFromCapabilities(const QString &input) const
{
auto doc = QJsonDocument::fromJson(input.toUtf8());
@@ -504,11 +608,42 @@ void CMakeTool::parseFromCapabilities(const QString &input) const
gen.value("toolsetSupport").toBool()));
}
+ {
+ const QVariantMap fileApis = data.value("fileApi").toMap();
+ const QVariantList requests = fileApis.value("requests").toList();
+ for (const QVariant &r : requests) {
+ const QVariantMap object = r.toMap();
+ const QString kind = object.value("kind").toString();
+ const QVariantList versionList = object.value("version").toList();
+ std::pair<int, int> highestVersion = std::make_pair(-1, -1);
+ for (const QVariant &v : versionList) {
+ const QVariantMap versionObject = v.toMap();
+ const std::pair<int, int> version = std::make_pair(getVersion(versionObject,
+ "major"),
+ getVersion(versionObject,
+ "minor"));
+ if (version.first > highestVersion.first
+ || (version.first == highestVersion.first
+ && version.second > highestVersion.second))
+ highestVersion = version;
+ }
+ if (!kind.isNull() && highestVersion.first != -1 && highestVersion.second != -1)
+ m_introspection->m_fileApis.append({kind, highestVersion});
+ }
+ }
+
const QVariantMap versionInfo = data.value("version").toMap();
m_introspection->m_version.major = versionInfo.value("major").toInt();
m_introspection->m_version.minor = versionInfo.value("minor").toInt();
m_introspection->m_version.patch = versionInfo.value("patch").toInt();
m_introspection->m_version.fullVersion = versionInfo.value("string").toByteArray();
+
+ // Fix up fileapi support for cmake 3.14:
+ if (m_introspection->m_version.major == 3 && m_introspection->m_version.minor == 14) {
+ m_introspection->m_fileApis.append({QString("codemodel"), std::make_pair(2, 0)});
+ m_introspection->m_fileApis.append({QString("cache"), std::make_pair(2, 0)});
+ m_introspection->m_fileApis.append({QString("cmakefiles"), std::make_pair(1, 0)});
+ }
}
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmaketool.h b/src/plugins/cmakeprojectmanager/cmaketool.h
index 85feaf41e5..579f6e4d72 100644
--- a/src/plugins/cmakeprojectmanager/cmaketool.h
+++ b/src/plugins/cmakeprojectmanager/cmaketool.h
@@ -31,6 +31,7 @@
#include <texteditor/codeassist/keywordscompletionassist.h>
#include <utils/fileutils.h>
+#include <utils/optional.h>
#include <utils/synchronousprocess.h>
#include <QObject>
@@ -48,10 +49,9 @@ namespace Internal { class IntrospectionData; }
class CMAKE_EXPORT CMakeTool
{
public:
- enum Detection {
- ManualDetection,
- AutoDetection
- };
+ enum Detection { ManualDetection, AutoDetection };
+
+ enum ReaderType { TeaLeaf, ServerMode, FileApi };
struct Version
{
@@ -89,16 +89,20 @@ public:
Core::Id id() const { return m_id; }
QVariantMap toMap () const;
- void setCMakeExecutable(const Utils::FilePath &executable);
void setAutorun(bool autoRun);
void setAutoCreateBuildDirectory(bool autoBuildDir);
+ void setFilePath(const Utils::FilePath &executable);
+ Utils::FilePath filePath() const;
Utils::FilePath cmakeExecutable() const;
+ static Utils::FilePath cmakeExecutable(const Utils::FilePath &path);
bool isAutoRun() const;
bool autoCreateBuildDirectory() const;
QList<Generator> supportedGenerators() const;
TextEditor::Keywords keywords();
bool hasServerMode() const;
+ bool hasFileApi() const;
+ QVector<std::pair<QString, int>> supportedFileApiObjects() const;
Version version() const;
bool isAutoDetected() const;
@@ -108,6 +112,8 @@ public:
void setPathMapper(const PathMapper &includePathMapper);
PathMapper pathMapper() const;
+ ReaderType readerType() const;
+
private:
enum class QueryType {
GENERATORS,
@@ -135,6 +141,8 @@ private:
bool m_isAutoDetected = false;
bool m_autoCreateBuildDirectory = false;
+ Utils::optional<ReaderType> m_readerType;
+
std::unique_ptr<Internal::IntrospectionData> m_introspection;
PathMapper m_pathMapper;
diff --git a/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp b/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp
index b9b70c5352..77f3e077a2 100644
--- a/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/cmaketoolmanager.cpp
@@ -86,20 +86,6 @@ QList<CMakeTool *> CMakeToolManager::cmakeTools()
return Utils::toRawPointer<QList>(d->m_cmakeTools);
}
-Id CMakeToolManager::registerOrFindCMakeTool(const FilePath &command)
-{
- if (CMakeTool *cmake = findByCommand(command))
- return cmake->id();
-
- auto cmake = std::make_unique<CMakeTool>(CMakeTool::ManualDetection, CMakeTool::createId());
- cmake->setCMakeExecutable(command);
- cmake->setDisplayName(tr("CMake at %1").arg(command.toUserOutput()));
-
- Core::Id id = cmake->id();
- QTC_ASSERT(registerCMakeTool(std::move(cmake)), return Core::Id());
- return id;
-}
-
bool CMakeToolManager::registerCMakeTool(std::unique_ptr<CMakeTool> &&tool)
{
if (!tool || Utils::contains(d->m_cmakeTools, tool.get()))
diff --git a/src/plugins/cmakeprojectmanager/cmaketoolmanager.h b/src/plugins/cmakeprojectmanager/cmaketoolmanager.h
index 49308e616b..b5ea3221dd 100644
--- a/src/plugins/cmakeprojectmanager/cmaketoolmanager.h
+++ b/src/plugins/cmakeprojectmanager/cmaketoolmanager.h
@@ -47,7 +47,6 @@ public:
static QList<CMakeTool *> cmakeTools();
- static Core::Id registerOrFindCMakeTool(const Utils::FilePath &command);
static bool registerCMakeTool(std::unique_ptr<CMakeTool> &&tool);
static void deregisterCMakeTool(const Core::Id &id);
diff --git a/src/plugins/cmakeprojectmanager/cmaketoolsettingsaccessor.cpp b/src/plugins/cmakeprojectmanager/cmaketoolsettingsaccessor.cpp
index a34f463318..b126ded5f7 100644
--- a/src/plugins/cmakeprojectmanager/cmaketoolsettingsaccessor.cpp
+++ b/src/plugins/cmakeprojectmanager/cmaketoolsettingsaccessor.cpp
@@ -110,7 +110,7 @@ static std::vector<std::unique_ptr<CMakeTool>> autoDetectCMakeTools()
std::vector<std::unique_ptr<CMakeTool>> found;
foreach (const FilePath &command, suspects) {
auto item = std::make_unique<CMakeTool>(CMakeTool::AutoDetection, CMakeTool::createId());
- item->setCMakeExecutable(command);
+ item->setFilePath(command);
item->setDisplayName(CMakeToolManager::tr("System CMake at %1").arg(command.toUserOutput()));
found.emplace_back(std::move(item));
diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp
index 804dc6d770..c402478d3c 100644
--- a/src/plugins/cmakeprojectmanager/configmodel.cpp
+++ b/src/plugins/cmakeprojectmanager/configmodel.cpp
@@ -36,13 +36,6 @@
namespace CMakeProjectManager {
-static bool isTrue(const QString &value)
-{
- const QString lower = value.toLower();
- return lower == QStringLiteral("true") || lower == QStringLiteral("on")
- || lower == QStringLiteral("1") || lower == QStringLiteral("yes");
-}
-
ConfigModel::ConfigModel(QObject *parent) : Utils::TreeModel<>(parent)
{
setHeader({tr("Key"), tr("Value")});
@@ -431,15 +424,17 @@ QVariant ConfigModelTreeItem::data(int column, int role) const
}
case 1: {
const QString value = currentValue();
+ const auto boolValue = CMakeConfigItem::toBool(value.toUtf8());
+ const bool isTrue = boolValue.has_value() && boolValue.value();
switch (role) {
case Qt::CheckStateRole:
return (dataItem->type == ConfigModel::DataItem::BOOLEAN)
- ? QVariant(isTrue(value) ? Qt::Checked : Qt::Unchecked) : QVariant();
+ ? QVariant(isTrue ? Qt::Checked : Qt::Unchecked) : QVariant();
case Qt::DisplayRole:
return value;
case Qt::EditRole:
- return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value);
+ return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue) : QVariant(value);
case Qt::FontRole: {
QFont font;
font.setBold((dataItem->isUserChanged || dataItem->isUserNew) && !dataItem->isUnset);
diff --git a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
index 588855d345..72d5561556 100644
--- a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
+++ b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
@@ -126,8 +126,8 @@ void ConfigModelItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *
QSize CMakeProjectManager::ConfigModelItemDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
- Q_UNUSED(option);
- Q_UNUSED(index);
+ Q_UNUSED(option)
+ Q_UNUSED(index)
return QSize(100, m_measurement.sizeHint().height());
}
diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp
new file mode 100644
index 0000000000..53d8a126be
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp
@@ -0,0 +1,617 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "fileapidataextractor.h"
+
+#include "cmakeprojectnodes.h"
+#include "projecttreehelper.h"
+
+#include <projectexplorer/projectnodes.h>
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+
+#include <QDir>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace {
+
+using namespace CMakeProjectManager;
+using namespace CMakeProjectManager::Internal;
+using namespace CMakeProjectManager::Internal::FileApiDetails;
+
+// --------------------------------------------------------------------
+// Helpers:
+// --------------------------------------------------------------------
+
+class CMakeFileResult
+{
+public:
+ QSet<FilePath> cmakeFiles;
+
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesSource;
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesBuild;
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesOther;
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeListNodes;
+};
+
+CMakeFileResult extractCMakeFilesData(const std::vector<FileApiDetails::CMakeFileInfo> &cmakefiles,
+ const FilePath &sourceDirectory,
+ const FilePath &buildDirectory)
+{
+ CMakeFileResult result;
+
+ QDir sourceDir(sourceDirectory.toString());
+ QDir buildDir(buildDirectory.toString());
+
+ for (const CMakeFileInfo &info : cmakefiles) {
+ const FilePath sfn = FilePath::fromString(
+ QDir::cleanPath(sourceDir.absoluteFilePath(info.path)));
+ const int oldCount = result.cmakeFiles.count();
+ result.cmakeFiles.insert(sfn);
+ if (oldCount < result.cmakeFiles.count()) {
+ if (info.isCMake && !info.isCMakeListsDotTxt) {
+ // Skip files that cmake considers to be part of the installation -- but include
+ // CMakeLists.txt files. This unbreaks cmake binaries running from their own
+ // build directory.
+ continue;
+ }
+
+ auto node = std::make_unique<FileNode>(sfn, FileType::Project);
+ node->setIsGenerated(info.isGenerated
+ && !info.isCMakeListsDotTxt); // CMakeLists.txt are never
+ // generated, independent
+ // what cmake thinks:-)
+
+ if (info.isCMakeListsDotTxt) {
+ result.cmakeListNodes.emplace_back(std::move(node));
+ } else if (sfn.isChildOf(sourceDir)) {
+ result.cmakeNodesSource.emplace_back(std::move(node));
+ } else if (sfn.isChildOf(buildDir)) {
+ result.cmakeNodesBuild.emplace_back(std::move(node));
+ } else {
+ result.cmakeNodesOther.emplace_back(std::move(node));
+ }
+ }
+ }
+
+ return result;
+}
+
+Configuration extractConfiguration(std::vector<Configuration> &codemodel, QString &errorMessage)
+{
+ if (codemodel.size() == 0) {
+ qWarning() << "No configuration found!";
+ errorMessage = "No configuration found!";
+ return {};
+ }
+ if (codemodel.size() > 1)
+ qWarning() << "Multi-configuration generator found, ignoring all but first configuration";
+
+ Configuration result = std::move(codemodel[0]);
+ codemodel.clear();
+
+ return result;
+}
+
+class PreprocessedData
+{
+public:
+ CMakeProjectManager::CMakeConfig cache;
+
+ QSet<FilePath> cmakeFiles;
+
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesSource;
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesBuild;
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesOther;
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeListNodes;
+
+ Configuration codemodel;
+ std::vector<TargetDetails> targetDetails;
+};
+
+PreprocessedData preprocess(FileApiData &data,
+ const FilePath &sourceDirectory,
+ const FilePath &buildDirectory,
+ QString &errorMessage)
+{
+ PreprocessedData result;
+
+ result.cache = std::move(data.cache); // Make sure this is available, even when nothing else is
+
+ // Simplify to only one configuration:
+ result.codemodel = extractConfiguration(data.codemodel, errorMessage);
+ if (!errorMessage.isEmpty()) {
+ return result;
+ }
+
+ CMakeFileResult cmakeFileResult = extractCMakeFilesData(data.cmakeFiles,
+ sourceDirectory,
+ buildDirectory);
+
+ result.cmakeFiles = std::move(cmakeFileResult.cmakeFiles);
+ result.cmakeNodesSource = std::move(cmakeFileResult.cmakeNodesSource);
+ result.cmakeNodesBuild = std::move(cmakeFileResult.cmakeNodesBuild);
+ result.cmakeNodesOther = std::move(cmakeFileResult.cmakeNodesOther);
+ result.cmakeListNodes = std::move(cmakeFileResult.cmakeListNodes);
+
+ result.targetDetails = std::move(data.targetDetails);
+
+ return result;
+}
+
+QVector<FolderNode::LocationInfo> extractBacktraceInformation(const BacktraceInfo &backtraces,
+ const QDir &sourceDir,
+ int backtraceIndex,
+ unsigned int locationInfoPriority)
+{
+ QVector<FolderNode::LocationInfo> info;
+ // Set up a default target path:
+ while (backtraceIndex != -1) {
+ const size_t bi = static_cast<size_t>(backtraceIndex);
+ QTC_ASSERT(bi < backtraces.nodes.size(), break);
+ const BacktraceNode &btNode = backtraces.nodes[bi];
+ backtraceIndex = btNode.parent; // advance to next node
+
+ const size_t fileIndex = static_cast<size_t>(btNode.file);
+ QTC_ASSERT(fileIndex < backtraces.files.size(), break);
+ const FilePath path = FilePath::fromString(
+ sourceDir.absoluteFilePath(backtraces.files[fileIndex]));
+
+ if (btNode.command < 0) {
+ // No command, skip: The file itself is already covered:-)
+ continue;
+ }
+
+ const size_t commandIndex = static_cast<size_t>(btNode.command);
+ QTC_ASSERT(commandIndex < backtraces.commands.size(), break);
+
+ const QString command = backtraces.commands[commandIndex];
+
+ info.append(FolderNode::LocationInfo(command, path, btNode.line, locationInfoPriority));
+ }
+ return info;
+}
+
+QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input,
+ const FilePath &sourceDirectory,
+ const FilePath &buildDirectory)
+{
+ QDir sourceDir(sourceDirectory.toString());
+ QDir buildDir(buildDirectory.toString());
+
+ const QList<CMakeBuildTarget> result = transform<QList>(
+ input.targetDetails, [&sourceDir, &buildDir](const TargetDetails &t) -> CMakeBuildTarget {
+ CMakeBuildTarget ct;
+ ct.title = t.name;
+ ct.executable = t.artifacts.isEmpty()
+ ? FilePath()
+ : FilePath::fromString(QDir::cleanPath(
+ buildDir.absoluteFilePath(t.artifacts.at(0).toString())));
+ TargetType type = UtilityType;
+ if (t.type == "EXECUTABLE")
+ type = ExecutableType;
+ else if (t.type == "STATIC_LIBRARY")
+ type = StaticLibraryType;
+ else if (t.type == "OBJECT_LIBRARY")
+ type = ObjectLibraryType;
+ else if (t.type == "MODULE_LIBRARY" || t.type == "SHARED_LIBRARY")
+ type = DynamicLibraryType;
+ else
+ type = UtilityType;
+ ct.targetType = type;
+ ct.workingDirectory = ct.executable.isEmpty() ? FilePath::fromString(
+ buildDir.absoluteFilePath(t.buildDir.toString()))
+ : ct.executable.parentDir();
+ ct.sourceDirectory = FilePath::fromString(
+ QDir::cleanPath(sourceDir.absoluteFilePath(t.sourceDir.toString())));
+
+ ct.backtrace = extractBacktraceInformation(t.backtraceGraph, sourceDir, t.backtrace, 0);
+
+ for (const DependencyInfo &d : t.dependencies) {
+ ct.dependencyDefinitions.append(
+ extractBacktraceInformation(t.backtraceGraph, sourceDir, d.backtrace, 100));
+ }
+ for (const SourceInfo &si : t.sources) {
+ ct.sourceDefinitions.append(
+ extractBacktraceInformation(t.backtraceGraph, sourceDir, si.backtrace, 200));
+ }
+ for (const CompileInfo &ci : t.compileGroups) {
+ for (const IncludeInfo &ii : ci.includes) {
+ ct.includeDefinitions.append(
+ extractBacktraceInformation(t.backtraceGraph, sourceDir, ii.backtrace, 300));
+ }
+ for (const DefineInfo &di : ci.defines) {
+ ct.defineDefinitions.append(
+ extractBacktraceInformation(t.backtraceGraph, sourceDir, di.backtrace, 400));
+ }
+ }
+ for (const InstallDestination &id : t.installDestination) {
+ ct.includeDefinitions.append(
+ extractBacktraceInformation(t.backtraceGraph, sourceDir, id.backtrace, 500));
+ }
+
+ return ct;
+ });
+ return result;
+}
+
+static QStringList splitFragments(const QStringList &fragments)
+{
+ QStringList result;
+ for (const QString &f : fragments) {
+ result += QtcProcess::splitArgs(f);
+ }
+ return result;
+}
+
+RawProjectParts generateRawProjectParts(const PreprocessedData &input,
+ const FilePath &sourceDirectory)
+{
+ RawProjectParts rpps;
+
+ int counter = 0;
+ for (const TargetDetails &t : input.targetDetails) {
+ QDir sourceDir(sourceDirectory.toString());
+
+ bool needPostfix = t.compileGroups.size() > 1;
+ int count = 1;
+ for (const CompileInfo &ci : t.compileGroups) {
+ if (ci.language != "C" && ci.language != "CXX" && ci.language != "CUDA")
+ continue; // No need to bother the C++ codemodel
+
+ // CMake users worked around Creator's inability of listing header files by creating
+ // custom targets with all the header files. This target breaks the code model, so
+ // keep quiet about it:-)
+ if (ci.defines.empty() && ci.includes.empty() && allOf(ci.sources, [t](const int sid) {
+ const SourceInfo &source = t.sources[static_cast<size_t>(sid)];
+ return Node::fileTypeForFileName(FilePath::fromString(source.path))
+ == FileType::Header;
+ })) {
+ qWarning() << "Not reporting all-header compilegroup of target" << t.name
+ << "to code model.";
+ continue;
+ }
+
+ QString ending;
+ if (ci.language == "C")
+ ending = "/cmake_pch.h";
+ else if (ci.language == "CXX")
+ ending = "/cmake_pch.hxx";
+
+ ++counter;
+ RawProjectPart rpp;
+ rpp.setProjectFileLocation(t.sourceDir.pathAppended("CMakeLists.txt").toString());
+ rpp.setBuildSystemTarget(t.name);
+ const QString postfix = needPostfix ? "_cg" + QString::number(count) : QString();
+ rpp.setDisplayName(t.id + postfix);
+ rpp.setMacros(transform<QVector>(ci.defines, &DefineInfo::define));
+ rpp.setHeaderPaths(transform<QVector>(ci.includes, &IncludeInfo::path));
+
+ RawProjectPartFlags cProjectFlags;
+ cProjectFlags.commandLineFlags = splitFragments(ci.fragments);
+ rpp.setFlagsForC(cProjectFlags);
+
+ RawProjectPartFlags cxxProjectFlags;
+ cxxProjectFlags.commandLineFlags = cProjectFlags.commandLineFlags;
+ rpp.setFlagsForCxx(cxxProjectFlags);
+
+ const QString precompiled_header
+ = findOrDefault(t.sources, [&ending](const SourceInfo &si) {
+ return si.path.endsWith(ending);
+ }).path;
+
+ rpp.setFiles(transform<QList>(ci.sources, [&t, &sourceDir](const int si) {
+ return sourceDir.absoluteFilePath(t.sources[static_cast<size_t>(si)].path);
+ }));
+ if (!precompiled_header.isEmpty())
+ rpp.setPreCompiledHeaders({precompiled_header});
+
+ const bool isExecutable = t.type == "EXECUTABLE";
+ rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable
+ : ProjectExplorer::BuildTargetType::Library);
+ rpps.append(rpp);
+ ++count;
+ }
+ }
+
+ return rpps;
+}
+
+FilePath directorySourceDir(const Configuration &c, const QDir &sourceDir, int directoryIndex)
+{
+ const size_t di = static_cast<size_t>(directoryIndex);
+ QTC_ASSERT(di < c.directories.size(), return FilePath());
+
+ return FilePath::fromString(
+ QDir::cleanPath(sourceDir.absoluteFilePath(c.directories[di].sourcePath)));
+}
+
+FilePath directoryBuildDir(const Configuration &c, const QDir &buildDir, int directoryIndex)
+{
+ const size_t di = static_cast<size_t>(directoryIndex);
+ QTC_ASSERT(di < c.directories.size(), return FilePath());
+
+ return FilePath::fromString(
+ QDir::cleanPath(buildDir.absoluteFilePath(c.directories[di].buildPath)));
+}
+
+void addProjects(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
+ const Configuration &config,
+ const QDir &sourceDir)
+{
+ for (const FileApiDetails::Project &p : config.projects) {
+ if (p.parent == -1)
+ continue; // Top-level project has already been covered
+ FilePath dir = directorySourceDir(config, sourceDir, p.directories[0]);
+ createProjectNode(cmakeListsNodes, dir, p.name);
+ }
+}
+
+QVector<FolderNode *> addSourceGroups(ProjectNode *targetRoot,
+ const TargetDetails &td,
+ const FilePath &sourceDirectory)
+{
+ QVector<FolderNode *> sourceGroupNodes;
+ if (td.sourceGroups.size() == 1) {
+ sourceGroupNodes.append(
+ targetRoot); // Only one source group, so do not bother to display any:-)
+ } else {
+ for (const QString &sg : td.sourceGroups) {
+ if (sg.isEmpty()) {
+ sourceGroupNodes.append(targetRoot);
+ } else {
+ auto sgNode = createCMakeVFolder(sourceDirectory,
+ Node::DefaultFolderPriority + 5,
+ sg);
+ sgNode->setListInProject(false);
+
+ sourceGroupNodes.append(sgNode.get());
+ targetRoot->addNode(std::move(sgNode));
+ }
+ }
+ }
+
+ return sourceGroupNodes;
+}
+
+void addCompileGroups(ProjectNode *targetRoot,
+ const Utils::FilePath &topSourceDirectory,
+ const Utils::FilePath &sourceDirectory,
+ const Utils::FilePath &buildDirectory,
+ const TargetDetails &td,
+ QSet<FilePath> &knownHeaderNodes)
+{
+ const bool inSourceBuild = (sourceDirectory == buildDirectory);
+ const QDir currentSourceDir(sourceDirectory.toString());
+
+ std::vector<std::unique_ptr<FileNode>> toList;
+ QSet<Utils::FilePath> alreadyListed;
+
+ // Files already added by other configurations:
+ targetRoot->forEachGenericNode(
+ [&alreadyListed](const Node *n) { alreadyListed.insert(n->filePath()); });
+
+ QVector<FolderNode *> sourceGroupNodes = addSourceGroups(targetRoot, td, sourceDirectory);
+ const QDir topSourceDir(topSourceDirectory.toString());
+
+ std::vector<std::unique_ptr<FileNode>> buildFileNodes;
+ std::vector<std::unique_ptr<FileNode>> otherFileNodes;
+
+ for (const SourceInfo &si : td.sources) {
+ const FilePath sourcePath = FilePath::fromString(
+ QDir::cleanPath(topSourceDir.absoluteFilePath(si.path)));
+
+ // Filter out already known files:
+ const int count = alreadyListed.count();
+ alreadyListed.insert(sourcePath);
+ if (count == alreadyListed.count())
+ continue;
+
+ // Create FileNodes from the file
+ auto node = std::make_unique<FileNode>(sourcePath, Node::fileTypeForFileName(sourcePath));
+ node->setIsGenerated(si.isGenerated);
+
+ // Register headers:
+ if (node->fileType() == FileType::Header)
+ knownHeaderNodes.insert(node->filePath());
+
+ // Where does the file node need to go?
+ if (sourcePath.isChildOf(buildDirectory) && !inSourceBuild) {
+ buildFileNodes.emplace_back(std::move(node));
+ } else if (sourcePath.isChildOf(sourceDirectory)) {
+ sourceGroupNodes[si.sourceGroup]->addNode(std::move(node));
+ } else {
+ otherFileNodes.emplace_back(std::move(node));
+ }
+ }
+
+ addCMakeVFolder(targetRoot,
+ buildDirectory,
+ 100,
+ QCoreApplication::translate("CMakeProjectManager::Internal::FileApi",
+ "<Build Directory>"),
+ std::move(buildFileNodes));
+ addCMakeVFolder(targetRoot,
+ Utils::FilePath(),
+ 10,
+ QCoreApplication::translate("CMakeProjectManager::Internal::FileApi",
+ "<Other Locations>"),
+ std::move(otherFileNodes));
+}
+
+void addTargets(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
+ const Configuration &config,
+ const std::vector<TargetDetails> &targetDetails,
+ const FilePath &topSourceDir,
+ const QDir &sourceDir,
+ const QDir &buildDir,
+ QSet<FilePath> &knownHeaderNodes)
+{
+ for (const FileApiDetails::Target &t : config.targets) {
+ const TargetDetails &td = Utils::findOrDefault(targetDetails,
+ Utils::equal(&TargetDetails::id, t.id));
+
+ const FilePath dir = directorySourceDir(config, sourceDir, t.directory);
+
+ CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, dir, t.name);
+ QTC_ASSERT(tNode, continue);
+
+ tNode->setTargetInformation(td.artifacts, td.type);
+ tNode->setBuildDirectory(directoryBuildDir(config, buildDir, t.directory));
+
+ addCompileGroups(tNode, topSourceDir, dir, tNode->buildDirectory(), td, knownHeaderNodes);
+ }
+}
+
+std::pair<std::unique_ptr<CMakeProjectNode>, QSet<FilePath>> generateRootProjectNode(
+ PreprocessedData &data, const FilePath &sourceDirectory, const FilePath &buildDirectory)
+{
+ std::pair<std::unique_ptr<CMakeProjectNode>, QSet<FilePath>> result;
+ result.first = std::make_unique<CMakeProjectNode>(sourceDirectory);
+
+ const QDir sourceDir(sourceDirectory.toString());
+ const QDir buildDir(buildDirectory.toString());
+
+ const FileApiDetails::Project topLevelProject
+ = findOrDefault(data.codemodel.projects, equal(&FileApiDetails::Project::parent, -1));
+ if (!topLevelProject.name.isEmpty())
+ result.first->setDisplayName(topLevelProject.name);
+
+ QHash<FilePath, ProjectNode *> cmakeListsNodes = addCMakeLists(result.first.get(),
+ std::move(data.cmakeListNodes));
+ data.cmakeListNodes.clear(); // Remove all the nullptr in the vector...
+
+ QSet<FilePath> knownHeaders;
+ addProjects(cmakeListsNodes, data.codemodel, sourceDir);
+
+ addTargets(cmakeListsNodes,
+ data.codemodel,
+ data.targetDetails,
+ sourceDirectory,
+ sourceDir,
+ buildDir,
+ knownHeaders);
+
+ // addHeaderNodes(root.get(), knownHeaders, allFiles);
+
+ if (!data.cmakeNodesSource.empty() || !data.cmakeNodesBuild.empty()
+ || !data.cmakeNodesOther.empty())
+ addCMakeInputs(result.first.get(),
+ sourceDirectory,
+ buildDirectory,
+ std::move(data.cmakeNodesSource),
+ std::move(data.cmakeNodesBuild),
+ std::move(data.cmakeNodesOther));
+
+ data.cmakeNodesSource.clear(); // Remove all the nullptr in the vector...
+ data.cmakeNodesBuild.clear(); // Remove all the nullptr in the vector...
+ data.cmakeNodesOther.clear(); // Remove all the nullptr in the vector...
+
+ result.second = knownHeaders;
+
+ return result;
+}
+
+void setupLocationInfoForTargets(CMakeProjectNode *rootNode, const QList<CMakeBuildTarget> &targets)
+{
+ for (const CMakeBuildTarget &t : targets) {
+ FolderNode *folderNode = static_cast<FolderNode *>(
+ rootNode->findNode(Utils::equal(&Node::buildKey, t.title)));
+ if (folderNode) {
+ QSet<std::pair<FilePath, int>> locations;
+ auto dedup = [&locations](const Backtrace &bt) {
+ QVector<FolderNode::LocationInfo> result;
+ for (const FolderNode::LocationInfo &i : bt) {
+ int count = locations.count();
+ locations.insert(std::make_pair(i.path, i.line));
+ if (count != locations.count()) {
+ result.append(i);
+ }
+ }
+ return result;
+ };
+
+ QVector<FolderNode::LocationInfo> result = dedup(t.backtrace);
+ auto dedupMulti = [&dedup](const Backtraces &bts) {
+ QVector<FolderNode::LocationInfo> result;
+ for (const Backtrace &bt : bts) {
+ result.append(dedup(bt));
+ }
+ return result;
+ };
+ result += dedupMulti(t.dependencyDefinitions);
+ result += dedupMulti(t.includeDefinitions);
+ result += dedupMulti(t.defineDefinitions);
+ result += dedupMulti(t.sourceDefinitions);
+ result += dedupMulti(t.installDefinitions);
+
+ folderNode->setLocationInfo(result);
+ }
+ }
+}
+
+} // namespace
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+using namespace FileApiDetails;
+
+// --------------------------------------------------------------------
+// extractData:
+// --------------------------------------------------------------------
+
+FileApiQtcData extractData(FileApiData &input,
+ const FilePath &sourceDirectory,
+ const FilePath &buildDirectory)
+{
+ FileApiQtcData result;
+
+ // Preprocess our input:
+ PreprocessedData data = preprocess(input, sourceDirectory, buildDirectory, result.errorMessage);
+ result.cache = std::move(data.cache); // Make sure this is available, even when nothing else is
+ if (!result.errorMessage.isEmpty()) {
+ return {};
+ }
+
+ result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory);
+ result.cmakeFiles = std::move(data.cmakeFiles);
+ result.projectParts = generateRawProjectParts(data, sourceDirectory);
+
+ auto pair = generateRootProjectNode(data, sourceDirectory, buildDirectory);
+ result.rootProjectNode = std::move(pair.first);
+ result.knownHeaders = std::move(pair.second);
+
+ setupLocationInfoForTargets(result.rootProjectNode.get(), result.buildTargets);
+
+ return result;
+}
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h b/src/plugins/cmakeprojectmanager/fileapidataextractor.h
index e9d0e18827..403e041a62 100644
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.h
@@ -25,33 +25,34 @@
#pragma once
-#include <projectexplorer/runconfiguration.h>
+#include "fileapiparser.h"
-namespace CMakeProjectManager {
-namespace Internal {
-
-class CMakeRunConfiguration : public ProjectExplorer::RunConfiguration
-{
- Q_OBJECT
-
-public:
- CMakeRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
+#include "cmakebuildtarget.h"
+#include "cmakeprocess.h"
+#include "cmakeprojectnodes.h"
-private:
- QString disabledReason() const override;
+#include <projectexplorer/rawprojectpart.h>
- void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) override;
- bool isBuildTargetValid() const;
- void updateTargetInformation();
+#include <memory>
- void updateEnabledState() final;
-};
+namespace CMakeProjectManager {
+namespace Internal {
-class CMakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
+class FileApiQtcData
{
public:
- CMakeRunConfigurationFactory();
+ QString errorMessage;
+ CMakeConfig cache;
+ QSet<Utils::FilePath> cmakeFiles;
+ QList<CMakeBuildTarget> buildTargets;
+ ProjectExplorer::RawProjectParts projectParts;
+ std::unique_ptr<CMakeProjectNode> rootProjectNode;
+ QSet<Utils::FilePath> knownHeaders;
};
+FileApiQtcData extractData(FileApiData &data,
+ const Utils::FilePath &sourceDirectory,
+ const Utils::FilePath &buildDirectory);
+
} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp
new file mode 100644
index 0000000000..657f798ceb
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp
@@ -0,0 +1,956 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "fileapiparser.h"
+
+#include <coreplugin/messagemanager.h>
+#include <projectexplorer/headerpath.h>
+#include <projectexplorer/rawprojectpart.h>
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
+
+#include <QDir>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QLoggingCategory>
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+using namespace FileApiDetails;
+using namespace Utils;
+
+const char CMAKE_RELATIVE_REPLY_PATH[] = ".cmake/api/v1/reply";
+const char CMAKE_RELATIVE_QUERY_PATH[] = ".cmake/api/v1/query";
+
+Q_LOGGING_CATEGORY(cmakeFileApi, "qtc.cmake.fileApi", QtWarningMsg);
+
+// --------------------------------------------------------------------
+// Helper:
+// --------------------------------------------------------------------
+
+static void reportFileApiSetupFailure()
+{
+ Core::MessageManager::write(QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Failed to set up cmake fileapi support. Creator can not extract project information."));
+}
+
+static std::pair<int, int> cmakeVersion(const QJsonObject &obj)
+{
+ const QJsonObject version = obj.value("version").toObject();
+ const int major = version.value("major").toInt(-1);
+ const int minor = version.value("minor").toInt(-1);
+ return std::make_pair(major, minor);
+}
+
+static bool checkJsonObject(const QJsonObject &obj, const QString &kind, int major, int minor = -1)
+{
+ auto version = cmakeVersion(obj);
+ if (major == -1)
+ version.first = major;
+ if (minor == -1)
+ version.second = minor;
+ return obj.value("kind").toString() == kind && version == std::make_pair(major, minor);
+}
+
+static std::pair<QString, QString> nameValue(const QJsonObject &obj)
+{
+ return std::make_pair(obj.value("name").toString(), obj.value("value").toString());
+}
+
+static QJsonDocument readJsonFile(const QString &path)
+{
+ qCDebug(cmakeFileApi) << "readJsonFile:" << path;
+
+ QFile file(path);
+ file.open(QIODevice::ReadOnly | QIODevice::Text);
+ const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
+
+ return doc;
+}
+
+std::vector<int> indexList(const QJsonValue &v)
+{
+ const QJsonArray &indexList = v.toArray();
+ std::vector<int> result;
+ result.reserve(static_cast<size_t>(indexList.count()));
+
+ for (const QJsonValue &v : indexList) {
+ result.push_back(v.toInt(-1));
+ }
+ return result;
+}
+
+// Reply file:
+
+static ReplyFileContents readReplyFile(const QFileInfo &fi, QString &errorMessage)
+{
+ const QJsonDocument document = readJsonFile(fi.filePath());
+ static const QString msg = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid reply file created by cmake.");
+
+ ReplyFileContents result;
+ if (document.isNull() || document.isEmpty() || !document.isObject()) {
+ errorMessage = msg;
+ return result;
+ }
+
+ const QJsonObject rootObject = document.object();
+
+ {
+ const QJsonObject cmakeObject = rootObject.value("cmake").toObject();
+ {
+ const QJsonObject paths = cmakeObject.value("paths").toObject();
+ {
+ result.cmakeExecutable = paths.value("cmake").toString();
+ result.cmakeRoot = paths.value("root").toString();
+ }
+ const QJsonObject generator = cmakeObject.value("generator").toObject();
+ {
+ result.generator = generator.value("name").toString();
+ }
+ }
+ }
+
+ bool hadInvalidObject = false;
+ {
+ const QJsonArray objects = rootObject.value("objects").toArray();
+ for (const QJsonValue &v : objects) {
+ const QJsonObject object = v.toObject();
+ {
+ ReplyObject r;
+ r.kind = object.value("kind").toString();
+ r.file = object.value("jsonFile").toString();
+ r.version = cmakeVersion(object);
+
+ if (r.kind.isEmpty() || r.file.isEmpty() || r.version.first == -1
+ || r.version.second == -1)
+ hadInvalidObject = true;
+ else
+ result.replies.append(r);
+ }
+ }
+ }
+
+ if (result.generator.isEmpty() || result.cmakeExecutable.isEmpty() || result.cmakeRoot.isEmpty()
+ || result.replies.isEmpty() || hadInvalidObject)
+ errorMessage = msg;
+
+ return result;
+}
+
+// Cache file:
+
+static CMakeConfig readCacheFile(const QString &cacheFile, QString &errorMessage)
+{
+ CMakeConfig result;
+
+ const QJsonDocument doc = readJsonFile(cacheFile);
+ const QJsonObject root = doc.object();
+
+ if (!checkJsonObject(root, "cache", 2)) {
+ errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid cache file generated by cmake.");
+ return {};
+ }
+
+ const QJsonArray entries = root.value("entries").toArray();
+ for (const QJsonValue &v : entries) {
+ CMakeConfigItem item;
+
+ const QJsonObject entry = v.toObject();
+ auto nv = nameValue(entry);
+ item.key = nv.first.toUtf8();
+ item.value = nv.second.toUtf8();
+
+ item.type = CMakeConfigItem::typeStringToType(entry.value("type").toString().toUtf8());
+
+ {
+ const QJsonArray properties = entry.value("properties").toArray();
+ for (const QJsonValue &v : properties) {
+ const QJsonObject prop = v.toObject();
+ auto nv = nameValue(prop);
+ if (nv.first == "ADVANCED") {
+ const auto boolValue = CMakeConfigItem::toBool(nv.second.toUtf8());
+ item.isAdvanced = boolValue.has_value() && boolValue.value();
+ } else if (nv.first == "HELPSTRING") {
+ item.documentation = nv.second.toUtf8();
+ } else if (nv.first == "STRINGS") {
+ item.values = nv.second.split(';');
+ }
+ }
+ }
+ result.append(item);
+ }
+ return result;
+}
+
+// CMake Files:
+
+std::vector<CMakeFileInfo> readCMakeFilesFile(const QString &cmakeFilesFile, QString &errorMessage)
+{
+ std::vector<CMakeFileInfo> result;
+
+ const QJsonDocument doc = readJsonFile(cmakeFilesFile);
+ const QJsonObject root = doc.object();
+
+ if (!checkJsonObject(root, "cmakeFiles", 1)) {
+ errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid cmakeFiles file generated by cmake.");
+ return {};
+ }
+
+ const QJsonArray inputs = root.value("inputs").toArray();
+ for (const QJsonValue &v : inputs) {
+ CMakeFileInfo info;
+ const QJsonObject input = v.toObject();
+ info.path = input.value("path").toString();
+
+ info.isCMake = input.value("isCMake").toBool();
+ const QString filename = FilePath::fromString(info.path).fileName();
+ info.isCMakeListsDotTxt = (filename.compare("CMakeLists.txt",
+ HostOsInfo::fileNameCaseSensitivity())
+ == 0);
+
+ info.isGenerated = input.value("isGenerated").toBool();
+ info.isExternal = input.value("isExternal").toBool();
+
+ result.emplace_back(std::move(info));
+ }
+ return result;
+}
+
+// Codemodel file:
+
+std::vector<Directory> extractDirectories(const QJsonArray &directories, QString &errorMessage)
+{
+ if (directories.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: No directories.");
+ return {};
+ }
+
+ std::vector<Directory> result;
+ for (const QJsonValue &v : directories) {
+ const QJsonObject obj = v.toObject();
+ if (obj.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Empty directory object.");
+ continue;
+ }
+ Directory dir;
+ dir.sourcePath = obj.value("source").toString();
+ dir.buildPath = obj.value("build").toString();
+ dir.parent = obj.value("parentIndex").toInt(-1);
+ dir.project = obj.value("projectIndex").toInt(-1);
+ dir.children = indexList(obj.value("childIndexes"));
+ dir.targets = indexList(obj.value("targetIndexes"));
+ dir.hasInstallRule = obj.value("hasInstallRule").toBool();
+
+ result.emplace_back(std::move(dir));
+ }
+ return result;
+}
+
+static std::vector<Project> extractProjects(const QJsonArray &projects, QString &errorMessage)
+{
+ if (projects.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: No projects.");
+ return {};
+ }
+
+ std::vector<Project> result;
+ for (const QJsonValue &v : projects) {
+ const QJsonObject obj = v.toObject();
+ if (obj.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Empty project object.");
+ continue;
+ }
+ Project project;
+ project.name = obj.value("name").toString();
+ project.parent = obj.value("parentIndex").toInt(-1);
+ project.children = indexList(obj.value("childIndexes"));
+ project.directories = indexList(obj.value("directoryIndexes"));
+ project.targets = indexList(obj.value("targetIndexes"));
+
+ qCDebug(cmakeFileApi) << "Project read:" << project.name << project.directories;
+
+ if (project.name.isEmpty() || project.directories.empty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Broken project data.");
+ continue;
+ }
+
+ result.emplace_back(std::move(project));
+ }
+ return result;
+}
+
+static std::vector<Target> extractTargets(const QJsonArray &targets, QString &errorMessage)
+{
+ if (targets.isEmpty()) {
+ errorMessage
+ = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: No targets.");
+ return {};
+ }
+
+ std::vector<Target> result;
+ for (const QJsonValue &v : targets) {
+ const QJsonObject obj = v.toObject();
+ if (obj.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Empty target object.");
+ continue;
+ }
+ Target target;
+ target.name = obj.value("name").toString();
+ target.id = obj.value("id").toString();
+ target.directory = obj.value("directoryIndex").toInt(-1);
+ target.project = obj.value("projectIndex").toInt(-1);
+ target.jsonFile = obj.value("jsonFile").toString();
+
+ if (target.name.isEmpty() || target.id.isEmpty() || target.jsonFile.isEmpty()
+ || target.directory == -1 || target.project == -1) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Broken target data.");
+ continue;
+ }
+
+ result.emplace_back(std::move(target));
+ }
+ return result;
+}
+
+static bool validateIndexes(const Configuration &config)
+{
+ const int directoryCount = static_cast<int>(config.directories.size());
+ const int projectCount = static_cast<int>(config.projects.size());
+ const int targetCount = static_cast<int>(config.targets.size());
+
+ int topLevelCount = 0;
+ for (const Directory &d : config.directories) {
+ if (d.parent == -1)
+ ++topLevelCount;
+
+ if (d.parent < -1 || d.parent >= directoryCount) {
+ qCWarning(cmakeFileApi)
+ << "Directory" << d.sourcePath << ": parent index" << d.parent << "is broken.";
+ return false;
+ }
+ if (d.project < 0 || d.project >= projectCount) {
+ qCWarning(cmakeFileApi)
+ << "Directory" << d.sourcePath << ": project index" << d.project << "is broken.";
+ return false;
+ }
+ if (contains(d.children, [directoryCount](int c) { return c < 0 || c >= directoryCount; })) {
+ qCWarning(cmakeFileApi)
+ << "Directory" << d.sourcePath << ": A child index" << d.children << "is broken.";
+ return false;
+ }
+ if (contains(d.targets, [targetCount](int t) { return t < 0 || t >= targetCount; })) {
+ qCWarning(cmakeFileApi)
+ << "Directory" << d.sourcePath << ": A target index" << d.targets << "is broken.";
+ return false;
+ }
+ }
+ if (topLevelCount != 1) {
+ qCWarning(cmakeFileApi) << "Directories: Invalid number of top level directories, "
+ << topLevelCount << " (expected: 1).";
+ return false;
+ }
+
+ topLevelCount = 0;
+ for (const Project &p : config.projects) {
+ if (p.parent == -1)
+ ++topLevelCount;
+
+ if (p.parent < -1 || p.parent >= projectCount) {
+ qCWarning(cmakeFileApi)
+ << "Project" << p.name << ": parent index" << p.parent << "is broken.";
+ return false;
+ }
+ if (contains(p.children, [projectCount](int p) { return p < 0 || p >= projectCount; })) {
+ qCWarning(cmakeFileApi)
+ << "Project" << p.name << ": A child index" << p.children << "is broken.";
+ return false;
+ }
+ if (contains(p.targets, [targetCount](int t) { return t < 0 || t >= targetCount; })) {
+ qCWarning(cmakeFileApi)
+ << "Project" << p.name << ": A target index" << p.targets << "is broken.";
+ return false;
+ }
+ if (contains(p.directories,
+ [directoryCount](int d) { return d < 0 || d >= directoryCount; })) {
+ qCWarning(cmakeFileApi)
+ << "Project" << p.name << ": A directory index" << p.directories << "is broken.";
+ return false;
+ }
+ }
+ if (topLevelCount != 1) {
+ qCWarning(cmakeFileApi) << "Projects: Invalid number of top level projects, "
+ << topLevelCount << " (expected: 1).";
+ return false;
+ }
+
+ for (const Target &t : config.targets) {
+ if (t.directory < 0 || t.directory >= directoryCount) {
+ qCWarning(cmakeFileApi)
+ << "Target" << t.name << ": directory index" << t.directory << "is broken.";
+ return false;
+ }
+ if (t.project < 0 || t.project >= projectCount) {
+ qCWarning(cmakeFileApi)
+ << "Target" << t.name << ": project index" << t.project << "is broken.";
+ return false;
+ }
+ }
+ return true;
+}
+
+static std::vector<Configuration> extractConfigurations(const QJsonArray &configs,
+ QString &errorMessage)
+{
+ if (configs.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: No configurations.");
+ return {};
+ }
+
+ std::vector<FileApiDetails::Configuration> result;
+ for (const QJsonValue &v : configs) {
+ const QJsonObject obj = v.toObject();
+ if (obj.isEmpty()) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Empty configuration object.");
+ continue;
+ }
+ Configuration config;
+ config.name = obj.value("name").toString();
+
+ config.directories = extractDirectories(obj.value("directories").toArray(), errorMessage);
+ config.projects = extractProjects(obj.value("projects").toArray(), errorMessage);
+ config.targets = extractTargets(obj.value("targets").toArray(), errorMessage);
+
+ if (!validateIndexes(config)) {
+ errorMessage
+ = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake: Broken "
+ "indexes in directories/projects/targets.");
+ return {};
+ }
+
+ result.emplace_back(std::move(config));
+ }
+ return result;
+}
+
+static std::vector<Configuration> readCodemodelFile(const QString &codemodelFile,
+ QString &errorMessage)
+{
+ const QJsonDocument doc = readJsonFile(codemodelFile);
+ const QJsonObject root = doc.object();
+
+ if (!checkJsonObject(root, "codemodel", 2)) {
+ errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid codemodel file generated by cmake.");
+ return {};
+ }
+
+ return extractConfigurations(root.value("configurations").toArray(), errorMessage);
+}
+
+// TargetDetails:
+
+std::vector<FileApiDetails::FragmentInfo> extractFragments(const QJsonObject &obj)
+{
+ const QJsonArray fragments = obj.value("commandFragments").toArray();
+ return Utils::transform<std::vector>(fragments, [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return FileApiDetails::FragmentInfo{o.value("fragment").toString(),
+ o.value("role").toString()};
+ });
+}
+
+TargetDetails extractTargetDetails(const QJsonObject &root, QString &errorMessage)
+{
+ TargetDetails t;
+ t.name = root.value("name").toString();
+ t.id = root.value("id").toString();
+ t.type = root.value("type").toString();
+
+ if (t.name.isEmpty() || t.id.isEmpty() || t.type.isEmpty()) {
+ errorMessage = QCoreApplication::translate("CMakeProjectManager::Internal",
+ "Invalid target file: Information is missing.");
+ return {};
+ }
+
+ t.backtrace = root.value("backtrace").toInt(-1);
+ {
+ const QJsonObject folder = root.value("folder").toObject();
+ t.folderTargetProperty = folder.value("name").toString();
+ }
+ {
+ const QJsonObject paths = root.value("paths").toObject();
+ t.sourceDir = FilePath::fromString(paths.value("source").toString());
+ t.buildDir = FilePath::fromString(paths.value("build").toString());
+ }
+ t.nameOnDisk = root.value("nameOnDisk").toString();
+ {
+ const QJsonArray artifacts = root.value("artifacts").toArray();
+ t.artifacts = transform<QList>(artifacts, [](const QJsonValue &v) {
+ return FilePath::fromString(v.toObject().value("path").toString());
+ });
+ }
+ t.isGeneratorProvided = root.value("isGeneratorProvided").toBool();
+ {
+ const QJsonObject install = root.value("install").toObject();
+ t.installPrefix = install.value("prefix").toObject().value("path").toString();
+ {
+ const QJsonArray destinations = install.value("destinations").toArray();
+ t.installDestination = transform<std::vector>(destinations, [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return InstallDestination{o.value("path").toString(),
+ o.value("backtrace").toInt(-1)};
+ });
+ }
+ }
+ {
+ const QJsonObject link = root.value("link").toObject();
+ if (link.isEmpty()) {
+ t.link = {};
+ } else {
+ LinkInfo info;
+ info.language = link.value("language").toString();
+ info.isLto = link.value("lto").toBool();
+ info.sysroot = link.value("sysroot").toObject().value("path").toString();
+ info.fragments = extractFragments(link);
+ t.link = info;
+ }
+ }
+ {
+ const QJsonObject archive = root.value("archive").toObject();
+ if (archive.isEmpty()) {
+ t.archive = {};
+ } else {
+ ArchiveInfo info;
+ info.isLto = archive.value("lto").toBool();
+ info.fragments = extractFragments(archive);
+ t.archive = info;
+ }
+ }
+ {
+ const QJsonArray dependencies = root.value("dependencies").toArray();
+ t.dependencies = transform<std::vector>(dependencies, [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return DependencyInfo{o.value("id").toString(), o.value("backtrace").toInt(-1)};
+ });
+ }
+ {
+ const QJsonArray sources = root.value("sources").toArray();
+ t.sources = transform<std::vector>(sources, [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return SourceInfo{o.value("path").toString(),
+ o.value("compileGroupIndex").toInt(-1),
+ o.value("sourceGroupIndex").toInt(-1),
+ o.value("backtrace").toInt(-1),
+ o.value("isGenerated").toBool()};
+ });
+ }
+ {
+ const QJsonArray sourceGroups = root.value("sourceGroups").toArray();
+ t.sourceGroups = transform<std::vector>(sourceGroups, [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return o.value("name").toString();
+ });
+ }
+ {
+ const QJsonArray compileGroups = root.value("compileGroups").toArray();
+ t.compileGroups = transform<std::vector>(compileGroups, [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return CompileInfo{
+ transform<std::vector>(o.value("sourceIndexes").toArray(),
+ [](const QJsonValue &v) { return v.toInt(-1); }),
+ o.value("language").toString(),
+ transform<QList>(o.value("compileCommandFragments").toArray(),
+ [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return o.value("fragment").toString();
+ }),
+ transform<std::vector>(
+ o.value("includes").toArray(),
+ [](const QJsonValue &v) {
+ const QJsonObject i = v.toObject();
+ const QString path = i.value("path").toString();
+ const bool isSystem = i.value("isSystem").toBool();
+ const ProjectExplorer::HeaderPath
+ hp(path,
+ isSystem ? ProjectExplorer::HeaderPathType::System
+ : ProjectExplorer::HeaderPathType::User);
+
+ return IncludeInfo{
+ ProjectExplorer::RawProjectPart::frameworkDetectionHeuristic(hp),
+ i.value("backtrace").toInt(-1)};
+ }),
+ transform<std::vector>(o.value("defines").toArray(),
+ [](const QJsonValue &v) {
+ const QJsonObject d = v.toObject();
+ return DefineInfo{
+ ProjectExplorer::Macro::fromKeyValue(
+ d.value("define").toString()),
+ d.value("backtrace").toInt(-1),
+ };
+ }),
+ o.value("sysroot").toString(),
+ };
+ });
+ }
+ {
+ const QJsonObject backtraceGraph = root.value("backtraceGraph").toObject();
+ t.backtraceGraph.files = transform<std::vector>(backtraceGraph.value("files").toArray(),
+ [](const QJsonValue &v) {
+ return v.toString();
+ });
+ t.backtraceGraph.commands
+ = transform<std::vector>(backtraceGraph.value("commands").toArray(),
+ [](const QJsonValue &v) { return v.toString(); });
+ t.backtraceGraph.nodes = transform<std::vector>(backtraceGraph.value("nodes").toArray(),
+ [](const QJsonValue &v) {
+ const QJsonObject o = v.toObject();
+ return BacktraceNode{
+ o.value("file").toInt(-1),
+ o.value("line").toInt(-1),
+ o.value("command").toInt(-1),
+ o.value("parent").toInt(-1),
+ };
+ });
+ }
+
+ return t;
+}
+
+int validateBacktraceGraph(const TargetDetails &t)
+{
+ const int backtraceFilesCount = static_cast<int>(t.backtraceGraph.files.size());
+ const int backtraceCommandsCount = static_cast<int>(t.backtraceGraph.commands.size());
+ const int backtraceNodeCount = static_cast<int>(t.backtraceGraph.nodes.size());
+
+ int topLevelNodeCount = 0;
+ for (const BacktraceNode &n : t.backtraceGraph.nodes) {
+ if (n.parent == -1) {
+ ++topLevelNodeCount;
+ }
+ if (n.file < 0 || n.file >= backtraceFilesCount) {
+ qCWarning(cmakeFileApi) << "BacktraceNode: file index" << n.file << "is broken.";
+ return -1;
+ }
+ if (n.command < -1 || n.command >= backtraceCommandsCount) {
+ qCWarning(cmakeFileApi) << "BacktraceNode: command index" << n.command << "is broken.";
+ return -1;
+ }
+ if (n.parent < -1 || n.parent >= backtraceNodeCount) {
+ qCWarning(cmakeFileApi) << "BacktraceNode: parent index" << n.parent << "is broken.";
+ return -1;
+ }
+ }
+
+ if (topLevelNodeCount == 0 && backtraceNodeCount > 0) { // This is a forest, not a tree
+ qCWarning(cmakeFileApi) << "BacktraceNode: Invalid number of top level nodes"
+ << topLevelNodeCount;
+ return -1;
+ }
+
+ return backtraceNodeCount;
+}
+
+bool validateTargetDetails(const TargetDetails &t)
+{
+ // The part filled in by the codemodel file has already been covered!
+
+ // Internal consistency of backtraceGraph:
+ const int backtraceCount = validateBacktraceGraph(t);
+ if (backtraceCount < 0)
+ return false;
+
+ const int sourcesCount = static_cast<int>(t.sources.size());
+ const int sourceGroupsCount = static_cast<int>(t.sourceGroups.size());
+ const int compileGroupsCount = static_cast<int>(t.compileGroups.size());
+
+ if (t.backtrace < -1 || t.backtrace >= backtraceCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": backtrace index" << t.backtrace
+ << "is broken.";
+ return false;
+ }
+ for (const InstallDestination &id : t.installDestination) {
+ if (id.backtrace < -1 || id.backtrace >= backtraceCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": backtrace index"
+ << t.backtrace << "of install destination is broken.";
+ return false;
+ }
+ }
+
+ for (const DependencyInfo &dep : t.dependencies) {
+ if (dep.backtrace < -1 || dep.backtrace >= backtraceCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": backtrace index"
+ << t.backtrace << "of dependency is broken.";
+ return false;
+ }
+ }
+
+ for (const SourceInfo &s : t.sources) {
+ if (s.compileGroup < -1 || s.compileGroup >= compileGroupsCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": compile group index"
+ << s.compileGroup << "of source info is broken.";
+ return false;
+ }
+ if (s.sourceGroup < -1 || s.sourceGroup >= sourceGroupsCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": source group index"
+ << s.sourceGroup << "of source info is broken.";
+ return false;
+ }
+ if (s.backtrace < -1 || s.backtrace >= backtraceCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": backtrace index"
+ << s.backtrace << "of source info is broken.";
+ return false;
+ }
+ }
+
+ for (const CompileInfo &cg : t.compileGroups) {
+ for (int s : cg.sources) {
+ if (s < 0 || s >= sourcesCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": sources index" << s
+ << "of compile group is broken.";
+ return false;
+ }
+ }
+ for (const IncludeInfo &i : cg.includes) {
+ if (i.backtrace < -1 || i.backtrace >= backtraceCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": includes/backtrace index"
+ << i.backtrace << "of compile group is broken.";
+ return false;
+ }
+ }
+ for (const DefineInfo &d : cg.defines) {
+ if (d.backtrace < -1 || d.backtrace >= backtraceCount) {
+ qCWarning(cmakeFileApi) << "TargetDetails" << t.name << ": defines/backtrace index"
+ << d.backtrace << "of compile group is broken.";
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+TargetDetails readTargetFile(const QString &targetFile, QString &errorMessage)
+{
+ const QJsonDocument doc = readJsonFile(targetFile);
+ const QJsonObject root = doc.object();
+
+ TargetDetails result = extractTargetDetails(root, errorMessage);
+ if (errorMessage.isEmpty() && !validateTargetDetails(result)) {
+ errorMessage = QCoreApplication::translate(
+ "CMakeProjectManager::Internal",
+ "Invalid target file generated by cmake: Broken indexes in target details.");
+ }
+ return result;
+}
+
+// --------------------------------------------------------------------
+// ReplyFileContents:
+// --------------------------------------------------------------------
+
+QString FileApiDetails::ReplyFileContents::jsonFile(const QString &kind, const QDir &replyDir) const
+{
+ const auto ro = findOrDefault(replies, equal(&ReplyObject::kind, kind));
+ if (ro.file.isEmpty())
+ return QString();
+ else
+ return replyDir.absoluteFilePath(ro.file);
+}
+
+// --------------------------------------------------------------------
+// FileApi:
+// --------------------------------------------------------------------
+
+FileApiParser::FileApiParser(const FilePath &sourceDirectory, const FilePath &buildDirectory)
+ : m_sourceDirectory(sourceDirectory)
+ , m_buildDirectory(buildDirectory)
+{
+ setupCMakeFileApi();
+
+ QObject::connect(&m_watcher,
+ &FileSystemWatcher::directoryChanged,
+ this,
+ &FileApiParser::replyDirectoryHasChanged);
+
+ m_watcher.addDirectory(cmakeReplyDirectory().toString(), FileSystemWatcher::WatchAllChanges);
+}
+
+FilePath FileApiParser::cmakeReplyDirectory() const
+{
+ return m_buildDirectory.pathAppended(CMAKE_RELATIVE_REPLY_PATH);
+}
+
+FileApiParser::~FileApiParser() = default;
+
+void FileApiParser::setupCMakeFileApi() const
+{
+ const QDir buildDir = QDir(m_buildDirectory.toString());
+ const QString relativeQueryPath = QString::fromLatin1(CMAKE_RELATIVE_QUERY_PATH);
+
+ buildDir.mkpath(relativeQueryPath);
+ buildDir.mkpath(
+ QString::fromLatin1(CMAKE_RELATIVE_REPLY_PATH)); // So that we have a directory to watch!
+
+ QDir queryDir = buildDir;
+ queryDir.cd(relativeQueryPath);
+
+ if (!queryDir.exists()) {
+ reportFileApiSetupFailure();
+ return;
+ }
+ QTC_ASSERT(queryDir.exists(), );
+
+ bool failedBefore = false;
+ for (const QString &fileName : cmakeQueryFileNames()) {
+ const QString filePath = queryDir.filePath(fileName);
+
+ QFile f(filePath);
+ if (!f.exists()) {
+ f.open(QFile::WriteOnly);
+ f.close();
+ }
+
+ if (!f.exists() && !failedBefore) {
+ failedBefore = true;
+ reportFileApiSetupFailure();
+ }
+ }
+}
+
+static QStringList uniqueTargetFiles(const std::vector<Configuration> &configs)
+{
+ QSet<QString> knownIds;
+ QStringList files;
+ for (const Configuration &config : configs) {
+ for (const Target &t : config.targets) {
+ const int knownCount = knownIds.count();
+ knownIds.insert(t.id);
+ if (knownIds.count() > knownCount) {
+ files.append(t.jsonFile);
+ }
+ }
+ }
+ return files;
+}
+
+FileApiData FileApiParser::parseData(const QFileInfo &replyFileInfo, QString &errorMessage)
+{
+ QTC_CHECK(errorMessage.isEmpty());
+ const QDir replyDir = replyFileInfo.dir();
+
+ FileApiData result;
+
+ result.replyFile = readReplyFile(replyFileInfo, errorMessage);
+ result.cache = readCacheFile(result.replyFile.jsonFile("cache", replyDir), errorMessage);
+ result.cmakeFiles = readCMakeFilesFile(result.replyFile.jsonFile("cmakeFiles", replyDir),
+ errorMessage);
+ result.codemodel = readCodemodelFile(result.replyFile.jsonFile("codemodel", replyDir),
+ errorMessage);
+
+ const QStringList targetFiles = uniqueTargetFiles(result.codemodel);
+
+ for (const QString &targetFile : targetFiles) {
+ QString targetErrorMessage;
+ TargetDetails td = readTargetFile(replyDir.absoluteFilePath(targetFile), targetErrorMessage);
+ if (targetErrorMessage.isEmpty()) {
+ result.targetDetails.emplace_back(std::move(td));
+ } else {
+ qWarning() << "Failed to retrieve target data from cmake fileapi:"
+ << targetErrorMessage;
+ errorMessage = targetErrorMessage;
+ }
+ }
+
+ return result;
+}
+
+QFileInfo FileApiParser::scanForCMakeReplyFile() const
+{
+ QDir replyDir(cmakeReplyDirectory().toString());
+ if (!replyDir.exists())
+ return {};
+
+ const QFileInfoList fis = replyDir.entryInfoList(QStringList("index-*.json"),
+ QDir::Files,
+ QDir::Name);
+ return fis.isEmpty() ? QFileInfo() : fis.last();
+}
+
+QStringList FileApiParser::cmakeQueryFileNames() const
+{
+ return {"cache-v2", "codemodel-v2", "cmakeFiles-v1"};
+}
+
+QStringList FileApiParser::cmakeQueryFilePaths() const
+{
+ QDir queryDir(QDir::cleanPath(m_sourceDirectory.toString() + "/"
+ + QString::fromLatin1(CMAKE_RELATIVE_QUERY_PATH)));
+ return transform(cmakeQueryFileNames(),
+ [&queryDir](const QString &name) { return queryDir.absoluteFilePath(name); });
+}
+
+void FileApiParser::setParsedReplyFilePath(const QString &filePath)
+{
+ m_lastParsedReplyFile = filePath;
+}
+
+void FileApiParser::replyDirectoryHasChanged(const QString &directory) const
+{
+ if (directory == cmakeReplyDirectory().toString()) {
+ QFileInfo fi = scanForCMakeReplyFile();
+ if (fi.isFile() && fi.filePath() != m_lastParsedReplyFile) {
+ emit dirty();
+ }
+ }
+}
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.h b/src/plugins/cmakeprojectmanager/fileapiparser.h
new file mode 100644
index 0000000000..4524a64985
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/fileapiparser.h
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "cmakeconfigitem.h"
+
+#include <projectexplorer/headerpath.h>
+#include <projectexplorer/projectmacro.h>
+
+#include <utils/filesystemwatcher.h>
+#include <utils/fileutils.h>
+
+#include <QObject>
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+namespace FileApiDetails {
+
+class ReplyObject
+{
+public:
+ QString kind;
+ QString file;
+ std::pair<int, int> version;
+};
+
+class ReplyFileContents
+{
+public:
+ QString generator;
+ QString cmakeExecutable;
+ QString cmakeRoot;
+
+ QVector<ReplyObject> replies;
+
+ QString jsonFile(const QString &kind, const QDir &replyDir) const;
+};
+
+class CMakeFileInfo
+{
+public:
+ QString path;
+ bool isCMake = false;
+ bool isCMakeListsDotTxt = false;
+ bool isExternal = false;
+ bool isGenerated = false;
+};
+
+class Directory
+{
+public:
+ QString buildPath;
+ QString sourcePath;
+ int parent = -1;
+ int project = -1;
+ std::vector<int> children;
+ std::vector<int> targets;
+ bool hasInstallRule = false;
+};
+
+class Project
+{
+public:
+ QString name;
+ int parent = -1;
+ std::vector<int> children;
+ std::vector<int> directories;
+ std::vector<int> targets;
+};
+
+class Target
+{
+public:
+ // From codemodel file:
+ QString name;
+ QString id;
+ int directory = -1;
+ int project = -1;
+ QString jsonFile;
+};
+
+class Configuration
+{
+public:
+ QString name;
+ std::vector<Directory> directories;
+ std::vector<Project> projects;
+ std::vector<Target> targets;
+};
+
+class InstallDestination
+{
+public:
+ QString path;
+ int backtrace;
+};
+
+class FragmentInfo
+{
+public:
+ QString fragment;
+ QString role;
+};
+
+class LinkInfo
+{
+public:
+ QString language;
+ std::vector<FragmentInfo> fragments;
+ bool isLto = false;
+ QString sysroot;
+};
+
+class ArchiveInfo
+{
+public:
+ std::vector<FragmentInfo> fragments;
+ bool isLto = false;
+};
+
+class DependencyInfo
+{
+public:
+ QString targetId;
+ int backtrace;
+};
+
+class SourceInfo
+{
+public:
+ QString path;
+ int compileGroup = -1;
+ int sourceGroup = -1;
+ int backtrace = -1;
+ bool isGenerated = false;
+};
+
+class IncludeInfo
+{
+public:
+ ProjectExplorer::HeaderPath path;
+ int backtrace;
+};
+
+class DefineInfo
+{
+public:
+ ProjectExplorer::Macro define;
+ int backtrace;
+};
+
+class CompileInfo
+{
+public:
+ std::vector<int> sources;
+ QString language;
+ QStringList fragments;
+ std::vector<IncludeInfo> includes;
+ std::vector<DefineInfo> defines;
+ QString sysroot;
+};
+
+class BacktraceNode
+{
+public:
+ int file = -1;
+ int line = -1;
+ int command = -1;
+ int parent = -1;
+};
+
+class BacktraceInfo
+{
+public:
+ std::vector<QString> commands;
+ std::vector<QString> files;
+ std::vector<BacktraceNode> nodes;
+};
+
+class TargetDetails
+{
+public:
+ QString name;
+ QString id;
+ QString type;
+ QString folderTargetProperty;
+ Utils::FilePath sourceDir;
+ Utils::FilePath buildDir;
+ int backtrace = -1;
+ bool isGeneratorProvided = false;
+ QString nameOnDisk;
+ QList<Utils::FilePath> artifacts;
+ QString installPrefix;
+ std::vector<InstallDestination> installDestination;
+ Utils::optional<LinkInfo> link;
+ Utils::optional<ArchiveInfo> archive;
+ std::vector<DependencyInfo> dependencies;
+ std::vector<SourceInfo> sources;
+ std::vector<QString> sourceGroups;
+ std::vector<CompileInfo> compileGroups;
+ BacktraceInfo backtraceGraph;
+};
+
+} // namespace FileApiDetails
+
+class FileApiData
+{
+public:
+ FileApiDetails::ReplyFileContents replyFile;
+ CMakeConfig cache;
+ std::vector<FileApiDetails::CMakeFileInfo> cmakeFiles;
+ std::vector<FileApiDetails::Configuration> codemodel;
+ std::vector<FileApiDetails::TargetDetails> targetDetails;
+};
+
+class FileApiParser : public QObject
+{
+ Q_OBJECT
+
+public:
+ FileApiParser(const Utils::FilePath &sourceDirectory, const Utils::FilePath &buildDirectory);
+ ~FileApiParser() final;
+
+ Utils::FilePath cmakeReplyDirectory() const;
+ QFileInfo scanForCMakeReplyFile() const;
+
+ QStringList cmakeQueryFileNames() const;
+ QStringList cmakeQueryFilePaths() const;
+
+ void setParsedReplyFilePath(const QString &filePath);
+
+ static FileApiData parseData(const QFileInfo &replyFileInfo, QString &errorMessage);
+
+signals:
+ void dataAvailable() const;
+ void errorOccurred(const QString &message) const;
+ void dirty() const;
+
+private:
+ void setupCMakeFileApi() const;
+
+ const Utils::FilePath &m_sourceDirectory;
+ const Utils::FilePath &m_buildDirectory;
+
+ void replyDirectoryHasChanged(const QString &directory) const;
+ Utils::FileSystemWatcher m_watcher;
+ QString m_lastParsedReplyFile;
+};
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp
new file mode 100644
index 0000000000..f1fcbe1ea2
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "fileapireader.h"
+
+#include "cmakebuildconfiguration.h"
+#include "cmakeprojectconstants.h"
+#include "cmakeprojectmanager.h"
+#include "fileapidataextractor.h"
+#include "projecttreehelper.h"
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/fileiconprovider.h>
+#include <coreplugin/messagemanager.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/task.h>
+#include <projectexplorer/taskhub.h>
+#include <projectexplorer/toolchain.h>
+
+#include <utils/algorithm.h>
+#include <utils/optional.h>
+#include <utils/qtcassert.h>
+#include <utils/runextensions.h>
+
+#include <QDateTime>
+#include <QLoggingCategory>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+Q_LOGGING_CATEGORY(cmakeFileApiMode, "qtc.cmake.fileApiMode", QtWarningMsg);
+
+using namespace FileApiDetails;
+
+// --------------------------------------------------------------------
+// FileApiReader:
+// --------------------------------------------------------------------
+
+FileApiReader::FileApiReader()
+{
+ connect(Core::EditorManager::instance(),
+ &Core::EditorManager::aboutToSave,
+ this,
+ [this](const Core::IDocument *document) {
+ if (m_cmakeFiles.contains(document->filePath())) {
+ qCDebug(cmakeFileApiMode) << "FileApiReader: DIRTY SIGNAL";
+ emit dirty();
+ }
+ });
+}
+
+FileApiReader::~FileApiReader()
+{
+ stop();
+ resetData();
+}
+
+void FileApiReader::setParameters(const BuildDirParameters &p)
+{
+ qCDebug(cmakeFileApiMode)
+ << "\n\n\n\n\n=============================================================\n";
+
+ // Update:
+ m_parameters = p;
+ qCDebug(cmakeFileApiMode) << "Work directory:" << m_parameters.workDirectory.toUserOutput();
+
+ resetData();
+
+ m_fileApi = std::make_unique<FileApiParser>(m_parameters.sourceDirectory, m_parameters.workDirectory);
+ connect(m_fileApi.get(), &FileApiParser::dirty, this, [this]() {
+ if (!m_isParsing)
+ emit dirty();
+ });
+
+ qCDebug(cmakeFileApiMode) << "FileApiReader: IS READY NOW SIGNAL";
+ emit isReadyNow();
+}
+
+bool FileApiReader::isCompatible(const BuildDirParameters &p)
+{
+ const CMakeTool *cmakeTool = p.cmakeTool();
+ return cmakeTool && cmakeTool->readerType() == CMakeTool::FileApi;
+}
+
+void FileApiReader::resetData()
+{
+ m_cmakeFiles.clear();
+ if (!m_parameters.sourceDirectory.isEmpty())
+ m_cmakeFiles.insert(m_parameters.sourceDirectory.pathAppended("CMakeLists.txt"));
+
+ m_cache.clear();
+ m_buildTargets.clear();
+ m_projectParts.clear();
+ m_rootProjectNode.reset();
+ m_knownHeaders.clear();
+}
+
+void FileApiReader::parse(bool forceCMakeRun, bool forceConfiguration)
+{
+ qCDebug(cmakeFileApiMode) << "Parse called with arguments: ForceCMakeRun:" << forceCMakeRun
+ << " - forceConfiguration:" << forceConfiguration;
+ startState();
+
+ if (forceConfiguration) {
+ // Initial create:
+ qCDebug(cmakeFileApiMode) << "FileApiReader: Starting CMake with forced configuration.";
+ startCMakeState(
+ CMakeProcess::toArguments(m_parameters.configuration, m_parameters.expander));
+ // Keep m_isParsing enabled!
+ return;
+ }
+
+ const QFileInfo replyFi = m_fileApi->scanForCMakeReplyFile();
+ // Only need to update when one of the following conditions is met:
+ // * The user forces the update,
+ // * There is no reply file,
+ // * One of the cmakefiles is newer than the replyFile and the user asked
+ // for creator to run CMake as needed,
+ // * A query files are newer than the reply file
+ const bool mustUpdate = forceCMakeRun || !replyFi.exists()
+ || (m_parameters.cmakeTool() && m_parameters.cmakeTool()->isAutoRun()
+ && anyOf(m_cmakeFiles,
+ [&replyFi](const FilePath &f) {
+ return f.toFileInfo().lastModified()
+ > replyFi.lastModified();
+ }))
+ || anyOf(m_fileApi->cmakeQueryFilePaths(), [&replyFi](const QString &qf) {
+ return QFileInfo(qf).lastModified() > replyFi.lastModified();
+ });
+
+ if (mustUpdate) {
+ qCDebug(cmakeFileApiMode) << "FileApiReader: Starting CMake with no arguments.";
+ startCMakeState(QStringList());
+ // Keep m_isParsing enabled!
+ return;
+ }
+
+ endState(replyFi);
+}
+
+void FileApiReader::stop()
+{
+ m_cmakeProcess.reset();
+}
+
+bool FileApiReader::isParsing() const
+{
+ return m_isParsing;
+}
+
+QVector<FilePath> FileApiReader::takeProjectFilesToWatch()
+{
+ return QVector<FilePath>::fromList(Utils::toList(m_cmakeFiles));
+}
+
+QList<CMakeBuildTarget> FileApiReader::takeBuildTargets(QString &errorMessage){
+ Q_UNUSED(errorMessage)
+
+ auto result = std::move(m_buildTargets);
+ m_buildTargets.clear();
+ return result;
+}
+
+CMakeConfig FileApiReader::takeParsedConfiguration(QString &errorMessage)
+{
+ Q_UNUSED(errorMessage)
+
+ CMakeConfig cache = m_cache;
+ m_cache.clear();
+ return cache;
+}
+
+std::unique_ptr<CMakeProjectNode> FileApiReader::generateProjectTree(
+ const QList<const FileNode *> &allFiles, QString &errorMessage)
+{
+ Q_UNUSED(errorMessage)
+
+ addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles);
+ return std::move(m_rootProjectNode);
+}
+
+RawProjectParts FileApiReader::createRawProjectParts(QString &errorMessage)
+{
+ Q_UNUSED(errorMessage)
+
+ RawProjectParts result = std::move(m_projectParts);
+ m_projectParts.clear();
+ return result;
+}
+
+void FileApiReader::startState()
+{
+ qCDebug(cmakeFileApiMode) << "FileApiReader: START STATE.";
+ QTC_ASSERT(!m_isParsing, return );
+ QTC_ASSERT(!m_future.has_value(), return );
+
+ m_isParsing = true;
+
+ qCDebug(cmakeFileApiMode) << "FileApiReader: CONFIGURATION STARTED SIGNAL";
+ emit configurationStarted();
+}
+
+void FileApiReader::endState(const QFileInfo &replyFi)
+{
+ qCDebug(cmakeFileApiMode) << "FileApiReader: END STATE.";
+ QTC_ASSERT(m_isParsing, return );
+ QTC_ASSERT(!m_future.has_value(), return );
+
+ const FilePath sourceDirectory = m_parameters.sourceDirectory;
+ const FilePath buildDirectory = m_parameters.workDirectory;
+
+ m_fileApi->setParsedReplyFilePath(replyFi.filePath());
+
+ m_future = runAsync(ProjectExplorerPlugin::sharedThreadPool(),
+ [replyFi, sourceDirectory, buildDirectory]() {
+ auto result = std::make_unique<FileApiQtcData>();
+ FileApiData data = FileApiParser::parseData(replyFi,
+ result->errorMessage);
+ if (!result->errorMessage.isEmpty()) {
+ qWarning() << result->errorMessage;
+ return result.release();
+ }
+ *result = extractData(data, sourceDirectory, buildDirectory);
+ if (!result->errorMessage.isEmpty()) {
+ qWarning() << result->errorMessage;
+ }
+
+ return result.release();
+ });
+ onFinished(m_future.value(), this, [this](const QFuture<FileApiQtcData *> &f) {
+ std::unique_ptr<FileApiQtcData> value(f.result()); // Adopt the pointer again:-)
+
+ m_future = {};
+ m_isParsing = false;
+ m_cache = std::move(value->cache);
+ m_cmakeFiles = std::move(value->cmakeFiles);
+ m_buildTargets = std::move(value->buildTargets);
+ m_projectParts = std::move(value->projectParts);
+ m_rootProjectNode = std::move(value->rootProjectNode);
+ m_knownHeaders = std::move(value->knownHeaders);
+
+ if (value->errorMessage.isEmpty()) {
+ emit this->dataAvailable();
+ } else {
+ emit this->errorOccured(value->errorMessage);
+ }
+ });
+}
+
+void FileApiReader::startCMakeState(const QStringList &configurationArguments)
+{
+ qCDebug(cmakeFileApiMode) << "FileApiReader: START CMAKE STATE.";
+ QTC_ASSERT(!m_cmakeProcess, return );
+
+ m_cmakeProcess = std::make_unique<CMakeProcess>();
+
+ connect(m_cmakeProcess.get(), &CMakeProcess::finished, this, &FileApiReader::cmakeFinishedState);
+
+ qCDebug(cmakeFileApiMode) << ">>>>>> Running cmake with arguments:" << configurationArguments;
+ m_cmakeProcess->run(m_parameters, configurationArguments);
+}
+
+void FileApiReader::cmakeFinishedState(int code, QProcess::ExitStatus status)
+{
+ qCDebug(cmakeFileApiMode) << "FileApiReader: CMAKE FINISHED STATE.";
+
+ Q_UNUSED(code)
+ Q_UNUSED(status)
+
+ endState(m_fileApi->scanForCMakeReplyFile());
+}
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/fileapireader.h b/src/plugins/cmakeprojectmanager/fileapireader.h
new file mode 100644
index 0000000000..ccb2c897d5
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/fileapireader.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "builddirreader.h"
+#include "fileapiparser.h"
+
+#include "cmakeprocess.h"
+
+#include <utils/optional.h>
+
+#include <memory>
+
+#include <QFuture>
+
+namespace ProjectExplorer {
+class ProjectNode;
+}
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+class FileApiQtcData;
+
+class FileApiReader : public BuildDirReader
+{
+ Q_OBJECT
+
+public:
+ FileApiReader();
+ ~FileApiReader() final;
+
+ void setParameters(const BuildDirParameters &p) final;
+
+ bool isCompatible(const BuildDirParameters &p) final;
+ void resetData() final;
+ void parse(bool forceCMakeRun, bool forceConfiguration) final;
+ void stop() final;
+
+ bool isParsing() const final;
+
+ QVector<Utils::FilePath> takeProjectFilesToWatch() final;
+ QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) final;
+ CMakeConfig takeParsedConfiguration(QString &errorMessage) final;
+ std::unique_ptr<CMakeProjectNode> generateProjectTree(
+ const QList<const ProjectExplorer::FileNode *> &allFiles, QString &errorMessage) final;
+ ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage) final;
+
+private:
+ void startState();
+ void endState(const QFileInfo &replyFi);
+ void startCMakeState(const QStringList &configurationArguments);
+ void cmakeFinishedState(int code, QProcess::ExitStatus status);
+
+ std::unique_ptr<CMakeProcess> m_cmakeProcess;
+
+ // cmake data:
+ CMakeConfig m_cache;
+ QSet<Utils::FilePath> m_cmakeFiles;
+ QList<CMakeBuildTarget> m_buildTargets;
+ ProjectExplorer::RawProjectParts m_projectParts;
+ std::unique_ptr<CMakeProjectNode> m_rootProjectNode;
+ QSet<Utils::FilePath> m_knownHeaders;
+
+ Utils::optional<QFuture<FileApiQtcData *>> m_future;
+
+ // Update related:
+ bool m_isParsing = false;
+
+ std::unique_ptr<FileApiParser> m_fileApi;
+};
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.cpp b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
new file mode 100644
index 0000000000..46d0810b60
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "projecttreehelper.h"
+
+#include <coreplugin/fileiconprovider.h>
+#include <projectexplorer/projectexplorerconstants.h>
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
+
+using namespace ProjectExplorer;
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+std::unique_ptr<FolderNode> createCMakeVFolder(const Utils::FilePath &basePath,
+ int priority,
+ const QString &displayName)
+{
+ auto newFolder = std::make_unique<VirtualFolderNode>(basePath);
+ newFolder->setPriority(priority);
+ newFolder->setDisplayName(displayName);
+ return newFolder;
+}
+
+void addCMakeVFolder(FolderNode *base,
+ const Utils::FilePath &basePath,
+ int priority,
+ const QString &displayName,
+ std::vector<std::unique_ptr<FileNode>> &&files)
+{
+ if (files.size() == 0)
+ return;
+ FolderNode *folder = base;
+ if (!displayName.isEmpty()) {
+ auto newFolder = createCMakeVFolder(basePath, priority, displayName);
+ folder = newFolder.get();
+ base->addNode(std::move(newFolder));
+ }
+ folder->addNestedNodes(std::move(files));
+ for (FolderNode *fn : folder->folderNodes())
+ fn->compress();
+}
+
+std::vector<std::unique_ptr<FileNode>> &&removeKnownNodes(
+ const QSet<Utils::FilePath> &knownFiles, std::vector<std::unique_ptr<FileNode>> &&files)
+{
+ Utils::erase(files, [&knownFiles](const std::unique_ptr<FileNode> &n) {
+ return knownFiles.contains(n->filePath());
+ });
+ return std::move(files);
+}
+
+void addCMakeInputs(FolderNode *root,
+ const Utils::FilePath &sourceDir,
+ const Utils::FilePath &buildDir,
+ std::vector<std::unique_ptr<FileNode>> &&sourceInputs,
+ std::vector<std::unique_ptr<FileNode>> &&buildInputs,
+ std::vector<std::unique_ptr<FileNode>> &&rootInputs)
+{
+ std::unique_ptr<ProjectNode> cmakeVFolder = std::make_unique<CMakeInputsNode>(root->filePath());
+
+ QSet<Utils::FilePath> knownFiles;
+ root->forEachGenericNode([&knownFiles](const Node *n) {
+ if (n->listInProject())
+ knownFiles.insert(n->filePath());
+ });
+
+ addCMakeVFolder(cmakeVFolder.get(),
+ sourceDir,
+ 1000,
+ QString(),
+ removeKnownNodes(knownFiles, std::move(sourceInputs)));
+ addCMakeVFolder(cmakeVFolder.get(),
+ buildDir,
+ 100,
+ QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader",
+ "<Build Directory>"),
+ removeKnownNodes(knownFiles, std::move(buildInputs)));
+ addCMakeVFolder(cmakeVFolder.get(),
+ Utils::FilePath(),
+ 10,
+ QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader",
+ "<Other Locations>"),
+ removeKnownNodes(knownFiles, std::move(rootInputs)));
+
+ root->addNode(std::move(cmakeVFolder));
+}
+QHash<Utils::FilePath, ProjectNode *> addCMakeLists(
+ CMakeProjectNode *root, std::vector<std::unique_ptr<FileNode>> &&cmakeLists)
+{
+ QHash<Utils::FilePath, ProjectNode *> cmakeListsNodes;
+ cmakeListsNodes.insert(root->filePath(), root);
+
+ const QSet<Utils::FilePath> cmakeDirs
+ = Utils::transform<QSet>(cmakeLists, [](const std::unique_ptr<FileNode> &n) {
+ return n->filePath().parentDir();
+ });
+ root->addNestedNodes(std::move(cmakeLists),
+ Utils::FilePath(),
+ [&cmakeDirs, &cmakeListsNodes](const Utils::FilePath &fp)
+ -> std::unique_ptr<ProjectExplorer::FolderNode> {
+ if (cmakeDirs.contains(fp)) {
+ auto fn = std::make_unique<CMakeListsNode>(fp);
+ cmakeListsNodes.insert(fp, fn.get());
+ return fn;
+ }
+
+ return std::make_unique<FolderNode>(fp);
+ });
+ root->compress();
+ return cmakeListsNodes;
+}
+
+void createProjectNode(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
+ const Utils::FilePath &dir,
+ const QString &displayName)
+{
+ ProjectNode *cmln = cmakeListsNodes.value(dir);
+ QTC_ASSERT(cmln, return );
+
+ const Utils::FilePath projectName = dir.pathAppended(".project::" + displayName);
+
+ ProjectNode *pn = cmln->projectNode(projectName);
+ if (!pn) {
+ auto newNode = std::make_unique<CMakeProjectNode>(projectName);
+ pn = newNode.get();
+ cmln->addNode(std::move(newNode));
+ }
+ pn->setDisplayName(displayName);
+}
+
+CMakeTargetNode *createTargetNode(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
+ const Utils::FilePath &dir,
+ const QString &displayName)
+{
+ ProjectNode *cmln = cmakeListsNodes.value(dir);
+ QTC_ASSERT(cmln, return nullptr);
+
+ QString targetId = displayName;
+
+ CMakeTargetNode *tn = static_cast<CMakeTargetNode *>(
+ cmln->findNode([&targetId](const Node *n) { return n->buildKey() == targetId; }));
+ if (!tn) {
+ auto newNode = std::make_unique<CMakeTargetNode>(dir, displayName);
+ tn = newNode.get();
+ cmln->addNode(std::move(newNode));
+ }
+ tn->setDisplayName(displayName);
+ return tn;
+}
+
+void addHeaderNodes(ProjectNode *root,
+ QSet<Utils::FilePath> &seenHeaders,
+ const QList<const FileNode *> &allFiles)
+{
+ QTC_ASSERT(root, return );
+
+ if (root->isEmpty())
+ return;
+
+ static QIcon headerNodeIcon = Core::FileIconProvider::directoryIcon(
+ ProjectExplorer::Constants::FILEOVERLAY_H);
+ auto headerNode = std::make_unique<VirtualFolderNode>(root->filePath());
+ headerNode->setPriority(Node::DefaultPriority - 5);
+ headerNode->setDisplayName(
+ QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "<Headers>"));
+ headerNode->setIcon(headerNodeIcon);
+
+ // Add scanned headers:
+ for (const FileNode *fn : allFiles) {
+ if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath()))
+ continue;
+ const int count = seenHeaders.count();
+ seenHeaders.insert(fn->filePath());
+ if (seenHeaders.count() != count) {
+ std::unique_ptr<FileNode> node(fn->clone());
+ node->setEnabled(false);
+ headerNode->addNestedNode(std::move(node));
+ }
+ }
+
+ if (!headerNode->isEmpty())
+ root->addNode(std::move(headerNode));
+}
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.h b/src/plugins/cmakeprojectmanager/projecttreehelper.h
new file mode 100644
index 0000000000..1371330f70
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/projecttreehelper.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "cmakeprojectnodes.h"
+
+#include <projectexplorer/projectnodes.h>
+
+#include <utils/fileutils.h>
+
+#include <memory>
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+std::unique_ptr<ProjectExplorer::FolderNode> createCMakeVFolder(const Utils::FilePath &basePath,
+ int priority,
+ const QString &displayName);
+
+void addCMakeVFolder(ProjectExplorer::FolderNode *base,
+ const Utils::FilePath &basePath,
+ int priority,
+ const QString &displayName,
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&files);
+
+std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&removeKnownNodes(
+ const QSet<Utils::FilePath> &knownFiles,
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&files);
+
+void addCMakeInputs(ProjectExplorer::FolderNode *root,
+ const Utils::FilePath &sourceDir,
+ const Utils::FilePath &buildDir,
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&sourceInputs,
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&buildInputs,
+ std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&rootInputs);
+
+QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> addCMakeLists(
+ CMakeProjectNode *root, std::vector<std::unique_ptr<ProjectExplorer::FileNode>> &&cmakeLists);
+
+void createProjectNode(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
+ const Utils::FilePath &dir,
+ const QString &displayName);
+CMakeTargetNode *createTargetNode(
+ const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
+ const Utils::FilePath &dir,
+ const QString &displayName);
+
+void addHeaderNodes(ProjectExplorer::ProjectNode *root,
+ QSet<Utils::FilePath> &seenHeaders,
+ const QList<const ProjectExplorer::FileNode *> &allFiles);
+
+} // namespace Internal
+} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/servermode.cpp b/src/plugins/cmakeprojectmanager/servermode.cpp
index bd37c4f6fe..64448a149e 100644
--- a/src/plugins/cmakeprojectmanager/servermode.cpp
+++ b/src/plugins/cmakeprojectmanager/servermode.cpp
@@ -453,7 +453,7 @@ void ServerMode::parseJson(const QVariantMap &data)
void ServerMode::handleHello(const QVariantMap &data)
{
- Q_UNUSED(data);
+ Q_UNUSED(data)
QVariantMap extra;
QVariantMap version;
version.insert("major", m_majorProtocol);
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp
index a0a70a8d85..3152a03393 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.cpp
+++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp
@@ -30,9 +30,9 @@
#include "cmakeprojectmanager.h"
#include "cmakeprojectnodes.h"
#include "servermode.h"
+#include "projecttreehelper.h"
#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/fileiconprovider.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
@@ -101,46 +101,18 @@ void ServerModeReader::setParameters(const BuildDirParameters &p)
CMakeTool *cmake = p.cmakeTool();
QTC_ASSERT(cmake, return);
- BuildDirReader::setParameters(p);
- if (!m_cmakeServer) {
- m_cmakeServer.reset(new ServerMode(p.environment,
- p.sourceDirectory, p.workDirectory,
- cmake->cmakeExecutable(),
- p.generator, p.extraGenerator, p.platform, p.toolset,
- true, 1));
- connect(m_cmakeServer.get(), &ServerMode::errorOccured,
- this, &ServerModeReader::errorOccured);
- connect(m_cmakeServer.get(), &ServerMode::cmakeReply,
- this, &ServerModeReader::handleReply);
- connect(m_cmakeServer.get(), &ServerMode::cmakeError,
- this, &ServerModeReader::handleError);
- connect(m_cmakeServer.get(), &ServerMode::cmakeProgress,
- this, &ServerModeReader::handleProgress);
- connect(m_cmakeServer.get(), &ServerMode::cmakeSignal,
- this, &ServerModeReader::handleSignal);
- connect(m_cmakeServer.get(), &ServerMode::cmakeMessage, [this](const QString &m) {
- const QStringList lines = m.split('\n');
- for (const QString &l : lines) {
- m_parser.stdError(l);
- Core::MessageManager::write(l);
- }
- });
- connect(m_cmakeServer.get(), &ServerMode::message,
- this, [](const QString &m) { Core::MessageManager::write(m); });
- connect(m_cmakeServer.get(), &ServerMode::connected,
- this, &ServerModeReader::isReadyNow, Qt::QueuedConnection); // Delay
- connect(m_cmakeServer.get(), &ServerMode::disconnected,
- this, [this]() {
- stop();
- Core::MessageManager::write(tr("Parsing of CMake project failed: Connection to CMake server lost."));
- m_cmakeServer.reset();
- }, Qt::QueuedConnection); // Delay
- }
+ m_parameters = p;
+
+ m_parser.setSourceDirectory(m_parameters.sourceDirectory.toString());
+ createNewServer();
}
bool ServerModeReader::isCompatible(const BuildDirParameters &p)
{
CMakeTool *newCmake = p.cmakeTool();
+ if (newCmake->readerType() != CMakeTool::FileApi)
+ return false;
+
CMakeTool *oldCmake = m_parameters.cmakeTool();
if (!newCmake || !oldCmake)
return false;
@@ -171,13 +143,20 @@ void ServerModeReader::resetData()
m_fileGroups.clear();
}
-void ServerModeReader::parse(bool forceConfiguration)
+void ServerModeReader::parse(bool forceCMakeRun, bool forceConfiguration)
{
emit configurationStarted();
QTC_ASSERT(m_cmakeServer, return);
QVariantMap extra;
- if (forceConfiguration || !QDir(m_parameters.buildDirectory.toString()).exists("CMakeCache.txt")) {
+
+ bool delayConfigurationRun = false;
+ if (forceCMakeRun && m_cmakeServer->isConnected()) {
+ createNewServer();
+ delayConfigurationRun = true;
+ }
+
+ if (forceConfiguration) {
QStringList cacheArguments = transform(m_parameters.configuration,
[this](const CMakeConfigItem &i) {
return i.toArgument(m_parameters.expander);
@@ -199,8 +178,11 @@ void ServerModeReader::parse(bool forceConfiguration)
tr("Configuring \"%1\"").arg(m_parameters.projectName),
"CMake.Configure");
- m_delayedErrorMessage.clear();
- m_cmakeServer->sendRequest(CONFIGURE_TYPE, extra);
+ if (!delayConfigurationRun) {
+ sendConfigureRequest(extra);
+ } else {
+ m_delayedConfigurationData = extra;
+ }
}
void ServerModeReader::stop()
@@ -213,112 +195,61 @@ void ServerModeReader::stop()
m_parser.flush();
}
-bool ServerModeReader::isReady() const
-{
- return m_cmakeServer->isConnected();
-}
-
bool ServerModeReader::isParsing() const
{
return static_cast<bool>(m_future);
}
-QList<CMakeBuildTarget> ServerModeReader::takeBuildTargets()
-{
- const QList<CMakeBuildTarget> result = transform(m_targets, [](const Target *t) -> CMakeBuildTarget {
- CMakeBuildTarget ct;
- ct.title = t->name;
- ct.executable = t->artifacts.isEmpty() ? FilePath() : t->artifacts.at(0);
- TargetType type = UtilityType;
- if (t->type == "EXECUTABLE")
- type = ExecutableType;
- else if (t->type == "STATIC_LIBRARY")
- type = StaticLibraryType;
- else if (t->type == "MODULE_LIBRARY"
- || t->type == "SHARED_LIBRARY"
- || t->type == "INTERFACE_LIBRARY"
- || t->type == "OBJECT_LIBRARY")
- type = DynamicLibraryType;
- else
- type = UtilityType;
- ct.targetType = type;
- if (t->artifacts.isEmpty()) {
- ct.workingDirectory = t->buildDirectory;
- } else {
- ct.workingDirectory = Utils::FilePath::fromString(t->artifacts.at(0).toFileInfo().absolutePath());
- }
- ct.sourceDirectory = t->sourceDirectory;
- return ct;
- });
+QList<CMakeBuildTarget> ServerModeReader::takeBuildTargets(QString &errorMessage)
+{
+ Q_UNUSED(errorMessage)
+ QDir topSourceDir(m_parameters.sourceDirectory.toString());
+ const QList<CMakeBuildTarget> result
+ = transform(m_targets, [&topSourceDir](const Target *t) -> CMakeBuildTarget {
+ CMakeBuildTarget ct;
+ ct.title = t->name;
+ ct.executable = t->artifacts.isEmpty() ? FilePath() : t->artifacts.at(0);
+ TargetType type = UtilityType;
+ if (t->type == "EXECUTABLE")
+ type = ExecutableType;
+ else if (t->type == "STATIC_LIBRARY")
+ type = StaticLibraryType;
+ else if (t->type == "OBJECT_LIBRARY")
+ type = ObjectLibraryType;
+ else if (t->type == "MODULE_LIBRARY" || t->type == "SHARED_LIBRARY"
+ || t->type == "INTERFACE_LIBRARY")
+ type = DynamicLibraryType;
+ else
+ type = UtilityType;
+ ct.targetType = type;
+ if (t->artifacts.isEmpty()) {
+ ct.workingDirectory = t->buildDirectory;
+ } else {
+ ct.workingDirectory = Utils::FilePath::fromString(
+ t->artifacts.at(0).toFileInfo().absolutePath());
+ }
+ ct.sourceDirectory = FilePath::fromString(
+ QDir::cleanPath(topSourceDir.absoluteFilePath(t->sourceDirectory.toString())));
+ return ct;
+ });
m_targets.clear();
return result;
}
-CMakeConfig ServerModeReader::takeParsedConfiguration()
+CMakeConfig ServerModeReader::takeParsedConfiguration(QString &errorMessage)
{
+ Q_UNUSED(errorMessage)
CMakeConfig config = m_cmakeConfiguration;
m_cmakeConfiguration.clear();
return config;
}
-static void addCMakeVFolder(FolderNode *base, const Utils::FilePath &basePath, int priority,
- const QString &displayName,
- std::vector<std::unique_ptr<FileNode>> &&files)
+std::unique_ptr<CMakeProjectNode> ServerModeReader::generateProjectTree(const QList<const FileNode *> &allFiles,
+ QString &errorMessage)
{
- if (files.size() == 0)
- return;
- FolderNode *folder = base;
- if (!displayName.isEmpty()) {
- auto newFolder = std::make_unique<VirtualFolderNode>(basePath);
- newFolder->setPriority(priority);
- newFolder->setDisplayName(displayName);
- folder = newFolder.get();
- base->addNode(std::move(newFolder));
- }
- folder->addNestedNodes(std::move(files));
- for (FolderNode *fn : folder->folderNodes())
- fn->compress();
-}
-
-static std::vector<std::unique_ptr<FileNode>> &&
-removeKnownNodes(const QSet<Utils::FilePath> &knownFiles,
- std::vector<std::unique_ptr<FileNode>> &&files)
-{
- Utils::erase(files, [&knownFiles](const std::unique_ptr<FileNode> &n) {
- return knownFiles.contains(n->filePath());
- });
- return std::move(files);
-}
-
-static void addCMakeInputs(FolderNode *root,
- const Utils::FilePath &sourceDir,
- const Utils::FilePath &buildDir,
- std::vector<std::unique_ptr<FileNode>> &&sourceInputs,
- std::vector<std::unique_ptr<FileNode>> &&buildInputs,
- std::vector<std::unique_ptr<FileNode>> &&rootInputs)
-{
- std::unique_ptr<ProjectNode> cmakeVFolder = std::make_unique<CMakeInputsNode>(root->filePath());
-
- QSet<Utils::FilePath> knownFiles;
- root->forEachGenericNode([&knownFiles](const Node *n) {
- if (n->listInProject())
- knownFiles.insert(n->filePath());
- });
+ Q_UNUSED(errorMessage)
+ auto root = std::make_unique<CMakeProjectNode>(m_parameters.sourceDirectory);
- addCMakeVFolder(cmakeVFolder.get(), sourceDir, 1000, QString(), removeKnownNodes(knownFiles, std::move(sourceInputs)));
- addCMakeVFolder(cmakeVFolder.get(), buildDir, 100,
- QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "<Build Directory>"),
- removeKnownNodes(knownFiles, std::move(buildInputs)));
- addCMakeVFolder(cmakeVFolder.get(), Utils::FilePath(), 10,
- QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "<Other Locations>"),
- removeKnownNodes(knownFiles, std::move(rootInputs)));
-
- root->addNode(std::move(cmakeVFolder));
-}
-
-void ServerModeReader::generateProjectTree(CMakeProjectNode *root,
- const QList<const FileNode *> &allFiles)
-{
// Split up cmake inputs into useful chunks:
std::vector<std::unique_ptr<FileNode>> cmakeFilesSource;
std::vector<std::unique_ptr<FileNode>> cmakeFilesBuild;
@@ -344,22 +275,28 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root,
if (topLevel)
root->setDisplayName(topLevel->name);
- QHash<Utils::FilePath, ProjectNode *> cmakeListsNodes
- = addCMakeLists(root, std::move(cmakeLists));
- QList<FileNode *> knownHeaders;
+ QHash<Utils::FilePath, ProjectNode *> cmakeListsNodes = addCMakeLists(root.get(),
+ std::move(cmakeLists));
+ QSet<FilePath> knownHeaders;
addProjects(cmakeListsNodes, m_projects, knownHeaders);
- addHeaderNodes(root, knownHeaders, allFiles);
+ addHeaderNodes(root.get(), knownHeaders, allFiles);
if (cmakeFilesSource.size() > 0 || cmakeFilesBuild.size() > 0 || cmakeFilesOther.size() > 0)
- addCMakeInputs(root, m_parameters.sourceDirectory, m_parameters.workDirectory,
- std::move(cmakeFilesSource), std::move(cmakeFilesBuild),
+ addCMakeInputs(root.get(),
+ m_parameters.sourceDirectory,
+ m_parameters.workDirectory,
+ std::move(cmakeFilesSource),
+ std::move(cmakeFilesBuild),
std::move(cmakeFilesOther));
+
+ return root;
}
-CppTools::RawProjectParts ServerModeReader::createRawProjectParts() const
+RawProjectParts ServerModeReader::createRawProjectParts(QString &errorMessage)
{
- CppTools::RawProjectParts rpps;
+ Q_UNUSED(errorMessage)
+ RawProjectParts rpps;
int counter = 0;
for (const FileGroup *fg : qAsConst(m_fileGroups)) {
@@ -380,32 +317,78 @@ CppTools::RawProjectParts ServerModeReader::createRawProjectParts() const
const QStringList flags = QtcProcess::splitArgs(fg->compileFlags);
const QStringList includes = transform(fg->includePaths, [](const IncludePath *ip) { return ip->path.toString(); });
- CppTools::RawProjectPart rpp;
+ RawProjectPart rpp;
rpp.setProjectFileLocation(fg->target->sourceDirectory.toString() + "/CMakeLists.txt");
- rpp.setBuildSystemTarget(CMakeTargetNode::generateId(fg->target->sourceDirectory, fg->target->name));
+ rpp.setBuildSystemTarget(fg->target->name);
rpp.setDisplayName(fg->target->name + QString::number(counter));
rpp.setMacros(fg->macros);
rpp.setIncludePaths(includes);
- CppTools::RawProjectPartFlags cProjectFlags;
+ RawProjectPartFlags cProjectFlags;
cProjectFlags.commandLineFlags = flags;
rpp.setFlagsForC(cProjectFlags);
- CppTools::RawProjectPartFlags cxxProjectFlags;
+ RawProjectPartFlags cxxProjectFlags;
cxxProjectFlags.commandLineFlags = flags;
rpp.setFlagsForCxx(cxxProjectFlags);
rpp.setFiles(transform(fg->sources, &FilePath::toString));
const bool isExecutable = fg->target->type == "EXECUTABLE";
- rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
- : CppTools::ProjectPart::Library);
+ rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable
+ : ProjectExplorer::BuildTargetType::Library);
rpps.append(rpp);
}
return rpps;
}
+void ServerModeReader::createNewServer()
+{
+ QTC_ASSERT(m_parameters.cmakeTool(), return);
+ m_cmakeServer
+ = std::make_unique<ServerMode>(
+ m_parameters.environment,
+ m_parameters.sourceDirectory, m_parameters.workDirectory,
+ m_parameters.cmakeTool()->cmakeExecutable(),
+ m_parameters.generator,
+ m_parameters.extraGenerator,
+ m_parameters.platform, m_parameters.toolset,
+ true, 1);
+
+ connect(m_cmakeServer.get(), &ServerMode::errorOccured,
+ this, &ServerModeReader::errorOccured);
+ connect(m_cmakeServer.get(), &ServerMode::cmakeReply,
+ this, &ServerModeReader::handleReply);
+ connect(m_cmakeServer.get(), &ServerMode::cmakeError,
+ this, &ServerModeReader::handleError);
+ connect(m_cmakeServer.get(), &ServerMode::cmakeProgress,
+ this, &ServerModeReader::handleProgress);
+ connect(m_cmakeServer.get(), &ServerMode::cmakeSignal,
+ this, &ServerModeReader::handleSignal);
+ connect(m_cmakeServer.get(), &ServerMode::cmakeMessage, [this](const QString &m) {
+ const QStringList lines = m.split('\n');
+ for (const QString &l : lines) {
+ m_parser.stdError(l);
+ Core::MessageManager::write(l);
+ }
+ });
+ connect(m_cmakeServer.get(), &ServerMode::message,
+ this, [](const QString &m) { Core::MessageManager::write(m); });
+ connect(m_cmakeServer.get(),
+ &ServerMode::connected,
+ this,
+ &ServerModeReader::handleServerConnected,
+ Qt::QueuedConnection); // Delay
+ connect(m_cmakeServer.get(), &ServerMode::disconnected,
+ this, [this]() {
+ stop();
+ Core::MessageManager::write(tr("Parsing of CMake project failed: Connection to CMake server lost."));
+ m_cmakeServer.reset();
+ }, Qt::QueuedConnection); // Delay
+
+}
+
void ServerModeReader::handleReply(const QVariantMap &data, const QString &inReplyTo)
{
if (!m_delayedErrorMessage.isEmpty()) {
@@ -473,7 +456,7 @@ void ServerModeReader::handleError(const QString &message)
void ServerModeReader::handleProgress(int min, int cur, int max, const QString &inReplyTo)
{
- Q_UNUSED(inReplyTo);
+ Q_UNUSED(inReplyTo)
if (!m_future)
return;
@@ -483,12 +466,28 @@ void ServerModeReader::handleProgress(int min, int cur, int max, const QString &
void ServerModeReader::handleSignal(const QString &signal, const QVariantMap &data)
{
- Q_UNUSED(data);
+ Q_UNUSED(data)
// CMake on Windows sends false dirty signals on each edit (QTCREATORBUG-17944)
if (!HostOsInfo::isWindowsHost() && signal == "dirty")
emit dirty();
}
+void ServerModeReader::handleServerConnected()
+{
+ if (m_delayedConfigurationData) {
+ sendConfigureRequest(*m_delayedConfigurationData);
+ m_delayedConfigurationData.reset();
+ } else {
+ emit isReadyNow();
+ }
+}
+
+void ServerModeReader::sendConfigureRequest(const QVariantMap &extra)
+{
+ m_delayedErrorMessage.clear();
+ m_cmakeServer->sendRequest(CONFIGURE_TYPE, extra);
+}
+
void ServerModeReader::reportError()
{
stop();
@@ -521,7 +520,7 @@ void ServerModeReader::extractCodeModelData(const QVariantMap &data)
void ServerModeReader::extractConfigurationData(const QVariantMap &data)
{
const QString name = data.value(NAME_KEY).toString();
- Q_UNUSED(name);
+ Q_UNUSED(name)
QSet<QString> knownTargets; // To filter duplicate target names:-/
const QVariantList projects = data.value("projects").toList();
for (const QVariant &p : projects) {
@@ -781,89 +780,27 @@ void ServerModeReader::fixTarget(ServerModeReader::Target *target) const
}
}
-QHash<Utils::FilePath, ProjectNode *>
-ServerModeReader::addCMakeLists(CMakeProjectNode *root,
- std::vector<std::unique_ptr<FileNode>> &&cmakeLists)
-{
- QHash<Utils::FilePath, ProjectNode *> cmakeListsNodes;
- cmakeListsNodes.insert(root->filePath(), root);
-
- const QSet<Utils::FilePath> cmakeDirs
- = Utils::transform<QSet>(cmakeLists, [](const std::unique_ptr<FileNode> &n) {
- return n->filePath().parentDir();
- });
- root->addNestedNodes(std::move(cmakeLists), Utils::FilePath(),
- [&cmakeDirs, &cmakeListsNodes](const Utils::FilePath &fp)
- -> std::unique_ptr<ProjectExplorer::FolderNode> {
- if (cmakeDirs.contains(fp)) {
- auto fn = std::make_unique<CMakeListsNode>(fp);
- cmakeListsNodes.insert(fp, fn.get());
- return fn;
- }
-
- return std::make_unique<FolderNode>(fp);
- });
- root->compress();
- return cmakeListsNodes;
-}
-
-static void createProjectNode(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
- const Utils::FilePath &dir, const QString &displayName)
-{
- ProjectNode *cmln = cmakeListsNodes.value(dir);
- QTC_ASSERT(cmln, qDebug() << dir.toUserOutput(); return);
-
- const Utils::FilePath projectName = dir.pathAppended(".project::" + displayName);
-
- ProjectNode *pn = cmln->projectNode(projectName);
- if (!pn) {
- auto newNode = std::make_unique<CMakeProjectNode>(projectName);
- pn = newNode.get();
- cmln->addNode(std::move(newNode));
- }
- pn->setDisplayName(displayName);
-}
-
void ServerModeReader::addProjects(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
const QList<Project *> &projects,
- QList<FileNode *> &knownHeaderNodes)
+ QSet<FilePath> &knownHeaders)
{
for (const Project *p : projects) {
createProjectNode(cmakeListsNodes, p->sourceDirectory, p->name);
- addTargets(cmakeListsNodes, p->targets, knownHeaderNodes);
- }
-}
-
-static CMakeTargetNode *createTargetNode(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
- const Utils::FilePath &dir, const QString &displayName)
-{
- ProjectNode *cmln = cmakeListsNodes.value(dir);
- QTC_ASSERT(cmln, return nullptr);
-
- QString targetId = CMakeTargetNode::generateId(dir, displayName);
-
- CMakeTargetNode *tn = static_cast<CMakeTargetNode *>(cmln->findNode([&targetId](const Node *n) {
- return n->buildKey() == targetId;
- }));
- if (!tn) {
- auto newNode = std::make_unique<CMakeTargetNode>(dir, displayName);
- tn = newNode.get();
- cmln->addNode(std::move(newNode));
+ addTargets(cmakeListsNodes, p->targets, knownHeaders);
}
- tn->setDisplayName(displayName);
- return tn;
}
-void ServerModeReader::addTargets(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
- const QList<Target *> &targets,
- QList<ProjectExplorer::FileNode *> &knownHeaderNodes)
+void ServerModeReader::addTargets(
+ const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
+ const QList<Target *> &targets,
+ QSet<Utils::FilePath> &knownHeaders)
{
for (const Target *t : targets) {
CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, t->sourceDirectory, t->name);
QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; continue);
tNode->setTargetInformation(t->artifacts, t->type);
tNode->setBuildDirectory(t->buildDirectory);
- QList<FolderNode::LocationInfo> info;
+ QVector<FolderNode::LocationInfo> info;
// Set up a default target path:
FilePath targetPath = t->sourceDirectory.pathAppended("CMakeLists.txt");
for (CrossReference *cr : qAsConst(t->crossReferences)) {
@@ -892,7 +829,7 @@ void ServerModeReader::addTargets(const QHash<Utils::FilePath, ProjectExplorer::
}
}
tNode->setLocationInfo(info);
- addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, knownHeaderNodes);
+ addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, knownHeaders);
}
}
@@ -900,7 +837,7 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
const Utils::FilePath &sourceDirectory,
const Utils::FilePath &buildDirectory,
const QList<ServerModeReader::FileGroup *> &fileGroups,
- QList<FileNode *> &knownHeaderNodes)
+ QSet<Utils::FilePath> &knownHeaders)
{
std::vector<std::unique_ptr<FileNode>> toList;
QSet<Utils::FilePath> alreadyListed;
@@ -915,15 +852,14 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
alreadyListed.insert(fn);
return count != alreadyListed.count();
});
- std::vector<std::unique_ptr<FileNode>> newFileNodes
- = Utils::transform<std::vector>(newSources,
- [f, &knownHeaderNodes](const Utils::FilePath &fn) {
- auto node = std::make_unique<FileNode>(fn, Node::fileTypeForFileName(fn));
- node->setIsGenerated(f->isGenerated);
- if (node->fileType() == FileType::Header)
- knownHeaderNodes.append(node.get());
- return node;
- });
+ std::vector<std::unique_ptr<FileNode>> newFileNodes = Utils::transform<std::vector>(
+ newSources, [f, &knownHeaders](const Utils::FilePath &fn) {
+ auto node = std::make_unique<FileNode>(fn, Node::fileTypeForFileName(fn));
+ node->setIsGenerated(f->isGenerated);
+ if (node->fileType() == FileType::Header)
+ knownHeaders.insert(node->filePath());
+ return node;
+ });
std::move(std::begin(newFileNodes), std::end(newFileNodes), std::back_inserter(toList));
}
@@ -946,39 +882,6 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
addCMakeVFolder(targetRoot, Utils::FilePath(), 10, tr("<Other Locations>"), std::move(otherFileNodes));
}
-void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList<FileNode *> knownHeaders,
- const QList<const FileNode *> &allFiles)
-{
- if (root->isEmpty())
- return;
-
- static QIcon headerNodeIcon
- = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_H);
- auto headerNode = std::make_unique<VirtualFolderNode>(root->filePath());
- headerNode->setPriority(Node::DefaultPriority - 5);
- headerNode->setDisplayName(tr("<Headers>"));
- headerNode->setIcon(headerNodeIcon);
-
- // knownHeaders are already listed in their targets:
- QSet<Utils::FilePath> seenHeaders = Utils::transform<QSet>(knownHeaders, &FileNode::filePath);
-
- // Add scanned headers:
- for (const FileNode *fn : allFiles) {
- if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath()))
- continue;
- const int count = seenHeaders.count();
- seenHeaders.insert(fn->filePath());
- if (seenHeaders.count() != count) {
- std::unique_ptr<FileNode> node(fn->clone());
- node->setEnabled(false);
- headerNode->addNestedNode(std::move(node));
- }
- }
-
- if (!headerNode->isEmpty())
- root->addNode(std::move(headerNode));
-}
-
} // namespace Internal
} // namespace CMakeProjectManager
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h
index b362b15b3f..820a2d16f9 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.h
+++ b/src/plugins/cmakeprojectmanager/servermodereader.h
@@ -50,23 +50,27 @@ public:
bool isCompatible(const BuildDirParameters &p) final;
void resetData() final;
- void parse(bool forceConfiguration) final;
+ void parse(bool forceCMakeRun, bool forceConfiguration) final;
void stop() final;
- bool isReady() const final;
bool isParsing() const final;
- QList<CMakeBuildTarget> takeBuildTargets() final;
- CMakeConfig takeParsedConfiguration() final;
- void generateProjectTree(CMakeProjectNode *root,
- const QList<const ProjectExplorer::FileNode *> &allFiles) final;
- CppTools::RawProjectParts createRawProjectParts() const final;
+ QVector<Utils::FilePath> takeProjectFilesToWatch() final { return {}; };
+ QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) final;
+ CMakeConfig takeParsedConfiguration(QString &errorMessage) final;
+ std::unique_ptr<CMakeProjectNode> generateProjectTree(
+ const QList<const ProjectExplorer::FileNode *> &allFiles, QString &errorMessage) final;
+ ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage) final;
private:
+ void createNewServer();
void handleReply(const QVariantMap &data, const QString &inReplyTo);
void handleError(const QString &message);
void handleProgress(int min, int cur, int max, const QString &inReplyTo);
void handleSignal(const QString &signal, const QVariantMap &data);
+ void handleServerConnected();
+
+ void sendConfigureRequest(const QVariantMap &extra);
void reportError();
@@ -145,22 +149,17 @@ private:
void fixTarget(Target *target) const;
- QHash<Utils::FilePath, ProjectExplorer::ProjectNode *>
- addCMakeLists(CMakeProjectNode *root, std::vector<std::unique_ptr<ProjectExplorer::FileNode> > &&cmakeLists);
void addProjects(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
const QList<Project *> &projects,
- QList<ProjectExplorer::FileNode *> &knownHeaderNodes);
+ QSet<Utils::FilePath> &knownHeaders);
void addTargets(const QHash<Utils::FilePath, ProjectExplorer::ProjectNode *> &cmakeListsNodes,
const QList<Target *> &targets,
- QList<ProjectExplorer::FileNode *> &knownHeaderNodes);
+ QSet<Utils::FilePath> &knownHeaders);
void addFileGroups(ProjectExplorer::ProjectNode *targetRoot,
const Utils::FilePath &sourceDirectory,
- const Utils::FilePath &buildDirectory, const QList<FileGroup *> &fileGroups,
- QList<ProjectExplorer::FileNode *> &knowHeaderNodes);
-
- void addHeaderNodes(ProjectExplorer::ProjectNode *root,
- const QList<ProjectExplorer::FileNode *> knownHeaders,
- const QList<const ProjectExplorer::FileNode *> &allFiles);
+ const Utils::FilePath &buildDirectory,
+ const QList<FileGroup *> &fileGroups,
+ QSet<Utils::FilePath> &knownHeaders);
std::unique_ptr<ServerMode> m_cmakeServer;
std::unique_ptr<QFutureInterface<void>> m_future;
@@ -168,6 +167,8 @@ private:
int m_progressStepMinimum = 0;
int m_progressStepMaximum = 1000;
+ Utils::optional<QVariantMap> m_delayedConfigurationData;
+
QString m_delayedErrorMessage;
CMakeConfig m_cmakeConfiguration;
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index d33f461aaf..b611f12c65 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -29,23 +29,17 @@
#include "cmakebuildconfiguration.h"
#include "cmakecbpparser.h"
#include "cmakekitinformation.h"
-#include "cmakeparser.h"
+#include "cmakeprocess.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectnodes.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/idocument.h>
-#include <coreplugin/messagemanager.h>
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <coreplugin/reaper.h>
#include <projectexplorer/headerpath.h>
-#include <projectexplorer/ioutputparser.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
-#include <projectexplorer/task.h>
-#include <projectexplorer/taskhub.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
@@ -60,68 +54,9 @@ using namespace Core;
using namespace ProjectExplorer;
using namespace Utils;
-// --------------------------------------------------------------------
-// Helper:
-// --------------------------------------------------------------------
-
namespace CMakeProjectManager {
namespace Internal {
-class CMakeFile : public IDocument
-{
-public:
- CMakeFile(TeaLeafReader *r, const FilePath &fileName);
-
- ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override;
- bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
-
-private:
- TeaLeafReader *m_reader;
-};
-
-CMakeFile::CMakeFile(TeaLeafReader *r, const FilePath &fileName) : m_reader(r)
-{
- setId("Cmake.ProjectFile");
- setMimeType(Constants::CMAKEPROJECTMIMETYPE);
- setFilePath(fileName);
-}
-
-IDocument::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
-{
- Q_UNUSED(state)
- Q_UNUSED(type)
- return BehaviorSilent;
-}
-
-bool CMakeFile::reload(QString *errorString, IDocument::ReloadFlag flag, IDocument::ChangeType type)
-{
- Q_UNUSED(errorString);
- Q_UNUSED(flag);
-
- if (type != TypePermissions)
- emit m_reader->dirty();
- return true;
-}
-
-static QString lineSplit(const QString &rest, const QByteArray &array, std::function<void(const QString &)> f)
-{
- QString tmp = rest + SynchronousProcess::normalizeNewlines(QString::fromLocal8Bit(array));
- int start = 0;
- int end = tmp.indexOf(QLatin1Char('\n'), start);
- while (end >= 0) {
- f(tmp.mid(start, end - start));
- start = end + 1;
- end = tmp.indexOf(QLatin1Char('\n'), start);
- }
- return tmp.mid(start);
-}
-
-static QStringList toArguments(const CMakeConfig &config, const MacroExpander *expander) {
- return transform(config, [expander](const CMakeConfigItem &i) -> QString {
- return i.toArgument(expander);
- });
-}
-
// --------------------------------------------------------------------
// TeaLeafReader:
// --------------------------------------------------------------------
@@ -152,18 +87,19 @@ TeaLeafReader::~TeaLeafReader()
resetData();
}
+void TeaLeafReader::setParameters(const BuildDirParameters &p)
+{
+ m_parameters = p;
+ emit isReadyNow();
+}
+
bool TeaLeafReader::isCompatible(const BuildDirParameters &p)
{
- if (!p.cmakeTool())
- return false;
- return !p.cmakeTool()->hasServerMode();
+ return p.cmakeTool() && p.cmakeTool()->readerType() == CMakeTool::TeaLeaf;
}
void TeaLeafReader::resetData()
{
- qDeleteAll(m_watchedFiles);
- m_watchedFiles.clear();
-
m_projectName.clear();
m_buildTargets.clear();
m_files.clear();
@@ -189,17 +125,19 @@ static QString findCbpFile(const QDir &directory)
return file;
}
-void TeaLeafReader::parse(bool forceConfiguration)
+void TeaLeafReader::parse(bool forceCMakeRun, bool forceConfiguration)
{
+ emit configurationStarted();
+
const QString cbpFile = findCbpFile(QDir(m_parameters.workDirectory.toString()));
const QFileInfo cbpFileFi = cbpFile.isEmpty() ? QFileInfo() : QFileInfo(cbpFile);
if (!cbpFileFi.exists() || forceConfiguration) {
// Initial create:
- startCMake(toArguments(m_parameters.configuration, m_parameters.expander));
+ startCMake(CMakeProcess::toArguments(m_parameters.configuration, m_parameters.expander));
return;
}
- const bool mustUpdate = m_cmakeFiles.isEmpty()
+ const bool mustUpdate = forceCMakeRun || m_cmakeFiles.isEmpty()
|| anyOf(m_cmakeFiles, [&cbpFileFi](const FilePath &f) {
return f.toFileInfo().lastModified() > cbpFileFi.lastModified();
});
@@ -213,14 +151,7 @@ void TeaLeafReader::parse(bool forceConfiguration)
void TeaLeafReader::stop()
{
- cleanUpProcess();
-
- if (m_future) {
- m_future->reportCanceled();
- m_future->reportFinished();
- delete m_future;
- m_future = nullptr;
- }
+ m_cmakeProcess.reset();
}
bool TeaLeafReader::isParsing() const
@@ -228,23 +159,27 @@ bool TeaLeafReader::isParsing() const
return m_cmakeProcess && m_cmakeProcess->state() != QProcess::NotRunning;
}
-QList<CMakeBuildTarget> TeaLeafReader::takeBuildTargets()
+QVector<FilePath> TeaLeafReader::takeProjectFilesToWatch()
{
+ return transform<QVector>(m_cmakeFiles, [](const FilePath &p) { return p; });
+}
+
+QList<CMakeBuildTarget> TeaLeafReader::takeBuildTargets(QString &errorMessage)
+{
+ Q_UNUSED(errorMessage)
return m_buildTargets;
}
-CMakeConfig TeaLeafReader::takeParsedConfiguration()
+CMakeConfig TeaLeafReader::takeParsedConfiguration(QString &errorMessage)
{
const FilePath cacheFile = m_parameters.workDirectory.pathAppended("CMakeCache.txt");
if (!cacheFile.exists())
return { };
- QString errorMessage;
CMakeConfig result = BuildDirManager::parseCMakeConfiguration(cacheFile, &errorMessage);
if (!errorMessage.isEmpty()) {
- emit errorOccured(errorMessage);
return { };
}
@@ -253,44 +188,24 @@ CMakeConfig TeaLeafReader::takeParsedConfiguration()
const FilePath canonicalSourceOfBuildDir = sourceOfBuildDir.canonicalPath();
const FilePath canonicalSourceDirectory = m_parameters.sourceDirectory.canonicalPath();
if (canonicalSourceOfBuildDir != canonicalSourceDirectory) { // Uses case-insensitive compare where appropriate
- emit errorOccured(tr("The build directory is not for %1 but for %2")
+ errorMessage = tr("The build directory is not for %1 but for %2")
.arg(canonicalSourceOfBuildDir.toUserOutput(),
- canonicalSourceDirectory.toUserOutput()));
+ canonicalSourceDirectory.toUserOutput());
return { };
}
return result;
}
-void TeaLeafReader::generateProjectTree(CMakeProjectNode *root, const QList<const FileNode *> &allFiles)
+std::unique_ptr<CMakeProjectNode> TeaLeafReader::generateProjectTree(
+ const QList<const FileNode *> &allFiles, QString &errorMessage)
{
+ Q_UNUSED(errorMessage)
if (m_files.size() == 0)
- return;
+ return {};
+ auto root = std::make_unique<CMakeProjectNode>(m_parameters.sourceDirectory);
root->setDisplayName(m_projectName);
- // Delete no longer necessary file watcher based on m_cmakeFiles:
- const QSet<FilePath> currentWatched
- = transform(m_watchedFiles, &CMakeFile::filePath);
- const QSet<FilePath> toWatch = m_cmakeFiles;
- QSet<FilePath> toDelete = currentWatched;
- toDelete.subtract(toWatch);
- m_watchedFiles = filtered(m_watchedFiles, [&toDelete](Internal::CMakeFile *cmf) {
- if (toDelete.contains(cmf->filePath())) {
- delete cmf;
- return false;
- }
- return true;
- });
-
- // Add new file watchers:
- QSet<FilePath> toAdd = toWatch;
- toAdd.subtract(currentWatched);
- foreach (const FilePath &fn, toAdd) {
- auto cm = new CMakeFile(this, fn);
- DocumentManager::addDocument(cm);
- m_watchedFiles.insert(cm);
- }
-
QSet<FilePath> allIncludePathSet;
for (const CMakeBuildTarget &bt : m_buildTargets) {
const QList<Utils::FilePath> targetIncludePaths
@@ -324,6 +239,8 @@ void TeaLeafReader::generateProjectTree(CMakeProjectNode *root, const QList<cons
return std::unique_ptr<FileNode>(fn->clone());
});
root->addNestedNodes(std::move(fileNodes), m_parameters.sourceDirectory);
+
+ return root;
}
static void processCMakeIncludes(const CMakeBuildTarget &cbt, const ToolChain *tc,
@@ -333,21 +250,24 @@ static void processCMakeIncludes(const CMakeBuildTarget &cbt, const ToolChain *t
if (!tc)
return;
- foreach (const HeaderPath &hp, tc->builtInHeaderPaths(flags, sysroot))
+ foreach (const HeaderPath &hp, tc->builtInHeaderPaths(flags, sysroot,
+ Environment::systemEnvironment())) {
tcIncludes.insert(FilePath::fromString(hp.path));
+ }
foreach (const FilePath &i, cbt.includeFiles) {
if (!tcIncludes.contains(i))
includePaths.append(i.toString());
}
}
-CppTools::RawProjectParts TeaLeafReader::createRawProjectParts() const
+RawProjectParts TeaLeafReader::createRawProjectParts(QString &errorMessage)
{
+ Q_UNUSED(errorMessage)
const ToolChain *tcCxx = ToolChainManager::findToolChain(m_parameters.cxxToolChainId);
const ToolChain *tcC = ToolChainManager::findToolChain(m_parameters.cToolChainId);
const FilePath sysroot = m_parameters.sysRoot;
- CppTools::RawProjectParts rpps;
+ RawProjectParts rpps;
QHash<QString, QStringList> targetDataCacheCxx;
QHash<QString, QStringList> targetDataCacheC;
foreach (const CMakeBuildTarget &cbt, m_buildTargets) {
@@ -368,16 +288,16 @@ CppTools::RawProjectParts TeaLeafReader::createRawProjectParts() const
includePaths = transform(cbt.includeFiles, &FilePath::toString);
}
includePaths += m_parameters.workDirectory.toString();
- CppTools::RawProjectPart rpp;
+ RawProjectPart rpp;
rpp.setProjectFileLocation(cbt.sourceDirectory.toString() + "/CMakeLists.txt");
- rpp.setBuildSystemTarget(CMakeTargetNode::generateId(cbt.sourceDirectory, cbt.title));
+ rpp.setBuildSystemTarget(cbt.title);
rpp.setIncludePaths(includePaths);
- CppTools::RawProjectPartFlags cProjectFlags;
+ RawProjectPartFlags cProjectFlags;
cProjectFlags.commandLineFlags = cflags;
rpp.setFlagsForC(cProjectFlags);
- CppTools::RawProjectPartFlags cxxProjectFlags;
+ RawProjectPartFlags cxxProjectFlags;
cxxProjectFlags.commandLineFlags = cxxflags;
rpp.setFlagsForCxx(cxxProjectFlags);
@@ -386,29 +306,14 @@ CppTools::RawProjectParts TeaLeafReader::createRawProjectParts() const
rpp.setFiles(transform(cbt.files, &FilePath::toString));
const bool isExecutable = cbt.targetType == ExecutableType;
- rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
- : CppTools::ProjectPart::Library);
+ rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable
+ : ProjectExplorer::BuildTargetType::Library);
rpps.append(rpp);
}
return rpps;
}
-void TeaLeafReader::cleanUpProcess()
-{
- if (m_cmakeProcess) {
- m_cmakeProcess->disconnect();
- Reaper::reap(m_cmakeProcess);
- m_cmakeProcess = nullptr;
- }
-
- // Delete issue parser:
- if (m_parser)
- m_parser->flush();
- delete m_parser;
- m_parser = nullptr;
-}
-
void TeaLeafReader::extractData()
{
CMakeTool *cmake = m_parameters.cmakeTool();
@@ -463,117 +368,29 @@ void TeaLeafReader::extractData()
void TeaLeafReader::startCMake(const QStringList &configurationArguments)
{
- CMakeTool *cmake = m_parameters.cmakeTool();
- QTC_ASSERT(m_parameters.isValid() && cmake, return);
-
- const FilePath workDirectory = m_parameters.workDirectory;
QTC_ASSERT(!m_cmakeProcess, return);
- QTC_ASSERT(!m_parser, return);
- QTC_ASSERT(!m_future, return);
- QTC_ASSERT(workDirectory.exists(), return);
-
- const QString srcDir = m_parameters.sourceDirectory.toString();
-
- m_parser = new CMakeParser;
- QDir source = QDir(srcDir);
- connect(m_parser, &IOutputParser::addTask, m_parser,
- [source](const Task &task) {
- if (task.file.isEmpty() || task.file.toFileInfo().isAbsolute()) {
- TaskHub::addTask(task);
- } else {
- Task t = task;
- t.file = FilePath::fromString(source.absoluteFilePath(task.file.toString()));
- TaskHub::addTask(t);
- }
- });
-
- // Always use the sourceDir: If we are triggered because the build directory is getting deleted
- // then we are racing against CMakeCache.txt also getting deleted.
- m_cmakeProcess = new QtcProcess;
- m_cmakeProcess->setWorkingDirectory(workDirectory.toString());
- m_cmakeProcess->setEnvironment(m_parameters.environment);
+ m_cmakeProcess = std::make_unique<CMakeProcess>();
- connect(m_cmakeProcess, &QProcess::readyReadStandardOutput,
- this, &TeaLeafReader::processCMakeOutput);
- connect(m_cmakeProcess, &QProcess::readyReadStandardError,
- this, &TeaLeafReader::processCMakeError);
- connect(m_cmakeProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
+ connect(m_cmakeProcess.get(), &CMakeProcess::finished,
this, &TeaLeafReader::cmakeFinished);
- QString args;
- QtcProcess::addArg(&args, srcDir);
- QtcProcess::addArgs(&args, m_parameters.generatorArguments);
- QtcProcess::addArgs(&args, configurationArguments);
-
- TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
-
- MessageManager::write(tr("Running \"%1 %2\" in %3.")
- .arg(cmake->cmakeExecutable().toUserOutput())
- .arg(args)
- .arg(workDirectory.toUserOutput()));
-
- m_future = new QFutureInterface<void>();
- m_future->setProgressRange(0, 1);
- ProgressManager::addTask(m_future->future(),
- tr("Configuring \"%1\"").arg(m_parameters.projectName),
- "CMake.Configure");
-
- m_cmakeProcess->setCommand(CommandLine(cmake->cmakeExecutable(), args));
- emit configurationStarted();
- m_cmakeProcess->start();
+ m_cmakeProcess->run(m_parameters, configurationArguments);
}
void TeaLeafReader::cmakeFinished(int code, QProcess::ExitStatus status)
{
- QTC_ASSERT(m_cmakeProcess, return);
-
- // process rest of the output:
- processCMakeOutput();
- processCMakeError();
+ Q_UNUSED(code)
+ Q_UNUSED(status)
- m_cmakeProcess->disconnect();
- cleanUpProcess();
+ QTC_ASSERT(m_cmakeProcess, return);
+ m_cmakeProcess.reset();
extractData(); // try even if cmake failed...
- QString msg;
- if (status != QProcess::NormalExit)
- msg = tr("*** cmake process crashed.");
- else if (code != 0)
- msg = tr("*** cmake process exited with exit code %1.").arg(code);
-
- if (!msg.isEmpty()) {
- MessageManager::write(msg);
- TaskHub::addTask(Task::Error, msg, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
- m_future->reportCanceled();
- } else {
- m_future->setProgressValue(1);
- }
-
- m_future->reportFinished();
- delete m_future;
- m_future = nullptr;
-
emit dataAvailable();
}
-void TeaLeafReader::processCMakeOutput()
-{
- static QString rest;
- rest = lineSplit(rest, m_cmakeProcess->readAllStandardOutput(),
- [](const QString &s) { MessageManager::write(s); });
-}
-
-void TeaLeafReader::processCMakeError()
-{
- static QString rest;
- rest = lineSplit(rest, m_cmakeProcess->readAllStandardError(), [this](const QString &s) {
- m_parser->stdError(s);
- MessageManager::write(s);
- });
-}
-
QStringList TeaLeafReader::getFlagsFor(const CMakeBuildTarget &buildTarget,
QHash<QString, QStringList> &cache,
Id lang) const
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.h b/src/plugins/cmakeprojectmanager/tealeafreader.h
index 356adc8110..55d64bcdae 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.h
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.h
@@ -28,6 +28,7 @@
#include <projectexplorer/toolchain.h>
#include "builddirreader.h"
+#include "cmakeprocess.h"
#include <QRegularExpression>
@@ -36,8 +37,6 @@ namespace Utils { class QtcProcess; }
namespace CMakeProjectManager {
namespace Internal {
-class CMakeFile;
-
class TeaLeafReader : public BuildDirReader
{
Q_OBJECT
@@ -46,44 +45,40 @@ public:
TeaLeafReader();
~TeaLeafReader() final;
+ void setParameters(const BuildDirParameters &p) final;
+
bool isCompatible(const BuildDirParameters &p) final;
void resetData() final;
- void parse(bool forceConfiguration) final;
+ void parse(bool forceCMakeRun, bool forceConfiguration) final;
void stop() final;
bool isParsing() const final;
- QList<CMakeBuildTarget> takeBuildTargets() final;
- CMakeConfig takeParsedConfiguration() final;
- void generateProjectTree(CMakeProjectNode *root,
- const QList<const ProjectExplorer::FileNode *> &allFiles) final;
- CppTools::RawProjectParts createRawProjectParts() const final;
+ QVector<Utils::FilePath> takeProjectFilesToWatch() final;
+ QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) final;
+ CMakeConfig takeParsedConfiguration(QString &errorMessage) final;
+ std::unique_ptr<CMakeProjectNode> generateProjectTree(
+ const QList<const ProjectExplorer::FileNode *> &allFiles, QString &errorMessage) final;
+ ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage) final;
private:
- void cleanUpProcess();
void extractData();
void startCMake(const QStringList &configurationArguments);
void cmakeFinished(int code, QProcess::ExitStatus status);
- void processCMakeOutput();
- void processCMakeError();
QStringList getFlagsFor(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache, Core::Id lang) const;
bool extractFlagsFromMake(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache, Core::Id lang) const;
bool extractFlagsFromNinja(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache, Core::Id lang) const;
- Utils::QtcProcess *m_cmakeProcess = nullptr;
-
- // For error reporting:
- ProjectExplorer::IOutputParser *m_parser = nullptr;
- QFutureInterface<void> *m_future = nullptr;
+ // Process data:
+ std::unique_ptr<CMakeProcess> m_cmakeProcess;
QSet<Utils::FilePath> m_cmakeFiles;
QString m_projectName;
QList<CMakeBuildTarget> m_buildTargets;
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> m_files;
- QSet<Internal::CMakeFile *> m_watchedFiles;
// RegExps for function-like macrosses names fixups
QRegularExpression m_macroFixupRe1;
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
index 94bc8b40a7..ec16d72bd5 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
@@ -29,7 +29,6 @@
#include "compilationdbparser.h"
#include <coreplugin/icontext.h>
-#include <cpptools/cppkitinfo.h>
#include <cpptools/cppprojectupdater.h>
#include <cpptools/projectinfo.h>
#include <projectexplorer/buildinfo.h>
@@ -40,7 +39,6 @@
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/namedwidget.h>
-#include <projectexplorer/processstep.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/target.h>
@@ -60,6 +58,7 @@
#endif
using namespace ProjectExplorer;
+using namespace Utils;
namespace CompilationDatabaseProjectManager {
namespace Internal {
@@ -168,12 +167,12 @@ void addDriverModeFlagIfNeeded(const ToolChain *toolchain,
}
}
-CppTools::RawProjectPart makeRawProjectPart(const Utils::FilePath &projectFile,
- Kit *kit,
- CppTools::KitInfo &kitInfo,
- const QString &workingDir,
- const Utils::FilePath &fileName,
- QStringList flags)
+RawProjectPart makeRawProjectPart(const Utils::FilePath &projectFile,
+ Kit *kit,
+ ProjectExplorer::KitInfo &kitInfo,
+ const QString &workingDir,
+ const Utils::FilePath &fileName,
+ QStringList flags)
{
HeaderPaths headerPaths;
Macros macros;
@@ -188,7 +187,7 @@ CppTools::RawProjectPart makeRawProjectPart(const Utils::FilePath &projectFile,
fileKind,
kitInfo.sysRootPath);
- CppTools::RawProjectPart rpp;
+ RawProjectPart rpp;
rpp.setProjectFileLocation(projectFile.toString());
rpp.setBuildSystemTarget(workingDir);
rpp.setDisplayName(fileName.fileName());
@@ -286,13 +285,13 @@ void addChild(FolderNode *root, const Utils::FilePath &fileName)
void createTree(std::unique_ptr<ProjectNode> &root,
const Utils::FilePath &rootPath,
- const CppTools::RawProjectParts &rpps,
+ const RawProjectParts &rpps,
const QList<FileNode *> &scannedFiles = QList<FileNode *>())
{
root->setAbsoluteFilePathAndLine(rootPath, -1);
std::unique_ptr<FolderNode> secondRoot;
- for (const CppTools::RawProjectPart &rpp : rpps) {
+ for (const RawProjectPart &rpp : rpps) {
for (const QString &filePath : rpp.files) {
Utils::FilePath fileName = Utils::FilePath::fromString(filePath);
if (!fileName.isChildOf(rootPath)) {
@@ -338,12 +337,12 @@ void createTree(std::unique_ptr<ProjectNode> &root,
void CompilationDatabaseProject::buildTreeAndProjectParts()
{
- CppTools::KitInfo kitInfo(this);
+ ProjectExplorer::KitInfo kitInfo(this);
QTC_ASSERT(kitInfo.isValid(), return);
// Reset toolchains to pick them based on the database entries.
kitInfo.cToolChain = nullptr;
kitInfo.cxxToolChain = nullptr;
- CppTools::RawProjectParts rpps;
+ RawProjectParts rpps;
QTC_ASSERT(m_parser, return);
const DbContents dbContents = m_parser->dbContents();
@@ -356,12 +355,12 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
prevEntry = &entry;
- CppTools::RawProjectPart rpp = makeRawProjectPart(projectFilePath(),
- m_kit.get(),
- kitInfo,
- entry.workingDir,
- entry.fileName,
- entry.flags);
+ RawProjectPart rpp = makeRawProjectPart(projectFilePath(),
+ m_kit.get(),
+ kitInfo,
+ entry.workingDir,
+ entry.fileName,
+ entry.flags);
rpps.append(rpp);
}
@@ -373,7 +372,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
for (const QString &extra : dbContents.extras)
extraFiles.append(baseDir.pathAppended(extra).toString());
- CppTools::RawProjectPart rppExtra;
+ RawProjectPart rppExtra;
rppExtra.setFiles(extraFiles);
rpps.append(rppExtra);
}
@@ -390,7 +389,7 @@ void CompilationDatabaseProject::buildTreeAndProjectParts()
setRootProjectNode(std::move(root));
- m_cppCodeModelUpdater->update({this, kitInfo, rpps});
+ m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps});
}
CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &projectFile)
@@ -405,24 +404,21 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FilePath &pr
setPreferredKitPredicate([](const Kit *) { return false; });
m_kit.reset(KitManager::defaultKit()->clone());
- connect(this, &CompilationDatabaseProject::parsingFinished, this, [this]() {
- if (!m_hasTarget) {
- addTarget(createTarget(m_kit.get()));
- m_hasTarget = true;
- }
- });
+ addTargetForKit(m_kit.get());
- connect(this, &CompilationDatabaseProject::rootProjectDirectoryChanged,
- m_parseDelay, QOverload<>::of(&QTimer::start));
+ connect(this,
+ &CompilationDatabaseProject::rootProjectDirectoryChanged,
+ m_parseDelay,
+ QOverload<>::of(&QTimer::start));
- m_fileSystemWatcher.addFile(projectFile.toString(), Utils::FileSystemWatcher::WatchModifiedDate);
- m_fileSystemWatcher.addFile(projectFile.toString() + Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX,
- Utils::FileSystemWatcher::WatchModifiedDate);
- connect(&m_fileSystemWatcher, &Utils::FileSystemWatcher::fileChanged,
- m_parseDelay, QOverload<>::of(&QTimer::start));
+ setExtraProjectFiles(
+ {projectFile.stringAppended(Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX)});
connect(m_parseDelay, &QTimer::timeout, this, &CompilationDatabaseProject::reparseProject);
+
m_parseDelay->setSingleShot(true);
m_parseDelay->setInterval(1000);
+
+ connect(this, &Project::projectFileIsDirty, this, &CompilationDatabaseProject::reparseProject);
}
Utils::FilePath CompilationDatabaseProject::rootPathFromSettings() const
@@ -430,7 +426,7 @@ Utils::FilePath CompilationDatabaseProject::rootPathFromSettings() const
#ifdef WITH_TESTS
return Utils::FilePath::fromString(projectDirectory().fileName());
#else
- return Utils::FileName::fromString(
+ return Utils::FilePath::fromString(
namedSettings(ProjectExplorer::Constants::PROJECT_ROOT_PATH_KEY).toString());
#endif
}
@@ -455,17 +451,18 @@ void CompilationDatabaseProject::reparseProject()
if (m_parser) {
QTC_CHECK(isParsing());
m_parser->stop();
- emitParsingFinished(false);
}
- m_parser = new CompilationDbParser(displayName(), projectFilePath(), rootPathFromSettings(),
- m_mimeBinaryCache, this);
+ m_parser = new CompilationDbParser(displayName(),
+ projectFilePath(),
+ rootPathFromSettings(),
+ m_mimeBinaryCache,
+ guardParsingRun(),
+ this);
connect(m_parser, &CompilationDbParser::finished, this, [this](bool success) {
if (success)
buildTreeAndProjectParts();
m_parser = nullptr;
- emitParsingFinished(success);
});
- emitParsingStarted();
m_parser->start();
}
@@ -504,11 +501,11 @@ CompilationDatabaseBuildConfiguration::CompilationDatabaseBuildConfiguration(
target->setApplicationTargets({BuildTargetInfo()});
}
-void CompilationDatabaseBuildConfiguration::initialize(const ProjectExplorer::BuildInfo &info)
+void CompilationDatabaseBuildConfiguration::initialize()
{
- ProjectExplorer::BuildConfiguration::initialize(info);
+ ProjectExplorer::BuildConfiguration::initialize();
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
- buildSteps->appendStep(new ProjectExplorer::ProcessStep(buildSteps));
+ buildSteps->appendStep(ProjectExplorer::Constants::PROCESS_STEP_ID);
}
ProjectExplorer::NamedWidget *CompilationDatabaseBuildConfiguration::createConfigWidget()
@@ -516,11 +513,6 @@ ProjectExplorer::NamedWidget *CompilationDatabaseBuildConfiguration::createConfi
return new ProjectExplorer::NamedWidget();
}
-ProjectExplorer::BuildConfiguration::BuildType CompilationDatabaseBuildConfiguration::buildType() const
-{
- return ProjectExplorer::BuildConfiguration::Release;
-}
-
CompilationDatabaseBuildConfigurationFactory::CompilationDatabaseBuildConfigurationFactory()
{
registerBuildConfiguration<CompilationDatabaseBuildConfiguration>(
@@ -530,28 +522,16 @@ CompilationDatabaseBuildConfigurationFactory::CompilationDatabaseBuildConfigurat
setSupportedProjectMimeTypeName(Constants::COMPILATIONDATABASEMIMETYPE);
}
-static QList<ProjectExplorer::BuildInfo> defaultBuildInfos(
- const ProjectExplorer::BuildConfigurationFactory *factory, const QString &name)
+QList<BuildInfo> CompilationDatabaseBuildConfigurationFactory::availableBuilds
+ (const Kit *kit, const FilePath &, bool) const
{
- ProjectExplorer::BuildInfo info(factory);
+ const QString name = tr("Release");
+ ProjectExplorer::BuildInfo info(this);
info.typeName = name;
info.displayName = name;
info.buildType = BuildConfiguration::Release;
- QList<ProjectExplorer::BuildInfo> buildInfos;
- buildInfos << info;
- return buildInfos;
-}
-
-QList<ProjectExplorer::BuildInfo> CompilationDatabaseBuildConfigurationFactory::availableBuilds(
- const ProjectExplorer::Target * /*parent*/) const
-{
- return defaultBuildInfos(this, tr("Release"));
-}
-
-QList<ProjectExplorer::BuildInfo> CompilationDatabaseBuildConfigurationFactory::availableSetups(
- const ProjectExplorer::Kit * /*k*/, const QString & /*projectPath*/) const
-{
- return defaultBuildInfos(this, tr("Release"));
+ info.kitId = kit->id();
+ return {info};
}
} // namespace Internal
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
index 376ebcc63b..ca829f312a 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h
@@ -58,7 +58,6 @@ public:
explicit CompilationDatabaseProject(const Utils::FilePath &filename);
~CompilationDatabaseProject() override;
bool needsConfiguration() const override { return false; }
- bool needsBuildConfigurations() const override { return true; }
private:
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
@@ -70,11 +69,9 @@ private:
QFutureWatcher<void> m_parserWatcher;
std::unique_ptr<CppTools::CppProjectUpdater> m_cppCodeModelUpdater;
std::unique_ptr<ProjectExplorer::Kit> m_kit;
- Utils::FileSystemWatcher m_fileSystemWatcher;
MimeBinaryCache m_mimeBinaryCache;
QTimer * const m_parseDelay;
CompilationDbParser *m_parser = nullptr;
- bool m_hasTarget = false;
};
class CompilationDatabaseEditorFactory : public TextEditor::TextEditorFactory
@@ -91,10 +88,9 @@ class CompilationDatabaseBuildConfiguration : public ProjectExplorer::BuildConfi
public:
CompilationDatabaseBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
ProjectExplorer::NamedWidget *createConfigWidget() override;
- BuildType buildType() const override;
protected:
- void initialize(const ProjectExplorer::BuildInfo &info) override;
+ void initialize() override;
};
class CompilationDatabaseBuildConfigurationFactory
@@ -104,10 +100,9 @@ class CompilationDatabaseBuildConfigurationFactory
public:
CompilationDatabaseBuildConfigurationFactory();
- QList<ProjectExplorer::BuildInfo> availableBuilds(
- const ProjectExplorer::Target *parent) const override;
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k,
+ const Utils::FilePath &projectPath,
+ bool forSetup) const override;
};
} // namespace Internal
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
index 5da42c8bfd..0eca37325c 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
@@ -47,8 +47,8 @@ const char COMPILE_COMMANDS_JSON[] = "compile_commands.json";
bool CompilationDatabaseProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
Core::FileIconProvider::registerIconOverlayForFilename(
Utils::Icons::PROJECT.imageFileName(),
COMPILE_COMMANDS_JSON);
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp
index d75bf7be40..6c91311898 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.cpp
@@ -43,14 +43,18 @@ using namespace Utils;
namespace CompilationDatabaseProjectManager {
namespace Internal {
-CompilationDbParser::CompilationDbParser(const QString &projectName, const FilePath &projectPath,
- const FilePath &rootPath, MimeBinaryCache &mimeBinaryCache,
+CompilationDbParser::CompilationDbParser(const QString &projectName,
+ const FilePath &projectPath,
+ const FilePath &rootPath,
+ MimeBinaryCache &mimeBinaryCache,
+ ProjectExplorer::Project::ParseGuard &&guard,
QObject *parent)
- : QObject(parent),
- m_projectName(projectName),
- m_projectFilePath(projectPath),
- m_rootPath(rootPath),
- m_mimeBinaryCache(mimeBinaryCache)
+ : QObject(parent)
+ , m_projectName(projectName)
+ , m_projectFilePath(projectPath)
+ , m_rootPath(rootPath)
+ , m_mimeBinaryCache(mimeBinaryCache)
+ , m_guard(std::move(guard))
{
connect(&m_parserWatcher, &QFutureWatcher<void>::finished, this, [this] {
m_dbContents = m_parserWatcher.result();
@@ -112,6 +116,7 @@ void CompilationDbParser::stop()
m_treeScanner->disconnect();
m_treeScanner->future().cancel();
}
+ m_guard = {};
deleteLater();
}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h
index ded713d590..fe3e319076 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdbparser.h
@@ -27,6 +27,8 @@
#include "compilationdatabaseutils.h"
+#include <projectexplorer/project.h>
+
#include <utils/fileutils.h>
#include <QFutureWatcher>
@@ -48,15 +50,22 @@ class CompilationDbParser : public QObject
{
Q_OBJECT
public:
- explicit CompilationDbParser(const QString &projectName, const Utils::FilePath &projectPath,
- const Utils::FilePath &rootPath, MimeBinaryCache &mimeBinaryCache,
+ explicit CompilationDbParser(const QString &projectName,
+ const Utils::FilePath &projectPath,
+ const Utils::FilePath &rootPath,
+ MimeBinaryCache &mimeBinaryCache,
+ ProjectExplorer::Project::ParseGuard &&guard,
QObject *parent = nullptr);
void start();
void stop();
QList<ProjectExplorer::FileNode *> scannedFiles() const;
- DbContents dbContents() const { return m_dbContents; }
+ DbContents dbContents() const
+ {
+ m_guard.markAsSuccess();
+ return m_dbContents;
+ }
signals:
void finished(bool success);
@@ -72,6 +81,8 @@ private:
ProjectExplorer::TreeScanner *m_treeScanner = nullptr;
QFutureWatcher<DbContents> m_parserWatcher;
DbContents m_dbContents;
+
+ ProjectExplorer::Project::ParseGuard m_guard;
};
} // namespace Internal
diff --git a/src/plugins/coreplugin/CMakeLists.txt b/src/plugins/coreplugin/CMakeLists.txt
index 7783685969..edeadeb114 100644
--- a/src/plugins/coreplugin/CMakeLists.txt
+++ b/src/plugins/coreplugin/CMakeLists.txt
@@ -178,6 +178,7 @@ extend_qtc_plugin(Core
extend_qtc_plugin(Core
CONDITION TARGET Qt5::Script
+ FEATURE_INFO "Script Locator filter"
DEPENDS Qt5::Script
DEFINES WITH_JAVASCRIPTFILTER
SOURCES
diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp
index d604adf4e6..04a515b88d 100644
--- a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp
+++ b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp
@@ -276,9 +276,7 @@ void ActionContainerPrivate::addMenu(ActionContainer *before, ActionContainer *m
auto containerPrivate = static_cast<ActionContainerPrivate *>(menu);
QTC_ASSERT(containerPrivate->canBeAddedToContainer(this), return);
- QMutableListIterator<Group> it(m_groups);
- while (it.hasNext()) {
- Group &group = it.next();
+ for (Group &group : m_groups) {
const int insertionPoint = group.items.indexOf(before);
if (insertionPoint >= 0) {
group.items.insert(insertionPoint, menu);
@@ -319,9 +317,7 @@ Command *ActionContainerPrivate::addSeparator(const Context &context, Id group,
void ActionContainerPrivate::clear()
{
- QMutableListIterator<Group> it(m_groups);
- while (it.hasNext()) {
- Group &group = it.next();
+ for (Group &group : m_groups) {
foreach (QObject *item, group.items) {
if (auto command = qobject_cast<Command *>(item)) {
removeAction(command);
@@ -343,9 +339,7 @@ void ActionContainerPrivate::clear()
void ActionContainerPrivate::itemDestroyed()
{
QObject *obj = sender();
- QMutableListIterator<Group> it(m_groups);
- while (it.hasNext()) {
- Group &group = it.next();
+ for (Group &group : m_groups) {
if (group.items.removeAll(obj) > 0)
break;
}
@@ -454,9 +448,7 @@ bool MenuActionContainer::updateInternal()
bool hasitems = false;
QList<QAction *> actions = m_menu->actions();
- QListIterator<Group> it(m_groups);
- while (it.hasNext()) {
- const Group &group = it.next();
+ for (const Group &group : m_groups) {
foreach (QObject *item, group.items) {
if (auto container = qobject_cast<ActionContainerPrivate*>(item)) {
actions.removeAll(container->menu()->menuAction());
diff --git a/src/plugins/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp
index 25ed98ae96..21ac5c2987 100644
--- a/src/plugins/coreplugin/actionmanager/command.cpp
+++ b/src/plugins/coreplugin/actionmanager/command.cpp
@@ -325,14 +325,13 @@ void Action::addOverrideAction(QAction *action, const Context &context, bool scr
void Action::removeOverrideAction(QAction *action)
{
- QMutableMapIterator<Id, QPointer<QAction> > it(m_contextActionMap);
- while (it.hasNext()) {
- it.next();
- if (it.value() == nullptr)
- it.remove();
- else if (it.value() == action)
- it.remove();
+ QList<Id> toRemove;
+ for (auto it = m_contextActionMap.cbegin(), end = m_contextActionMap.cend(); it != end; ++it) {
+ if (it.value() == nullptr || it.value() == action)
+ toRemove.append(it.key());
}
+ for (Id id : toRemove)
+ m_contextActionMap.remove(id);
setCurrentContext(m_context);
}
diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp
index 95398acc29..1ed0ed0dd7 100644
--- a/src/plugins/coreplugin/coreplugin.cpp
+++ b/src/plugins/coreplugin/coreplugin.cpp
@@ -27,6 +27,7 @@
#include "designmode.h"
#include "editmode.h"
#include "helpmanager.h"
+#include "icore.h"
#include "idocument.h"
#include "infobar.h"
#include "iwizardfactory.h"
@@ -63,6 +64,8 @@
#include <QDebug>
#include <QDir>
#include <QMenu>
+#include <QMessageBox>
+#include <QSettings>
#include <QUuid>
#include <cstdlib>
@@ -77,6 +80,8 @@ CorePlugin::CorePlugin()
{
qRegisterMetaType<Id>();
qRegisterMetaType<Core::Search::TextPosition>();
+ qRegisterMetaType<Utils::CommandLine>();
+ qRegisterMetaType<Utils::FilePath>();
m_instance = this;
}
@@ -146,6 +151,7 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
Theme *themeFromArg = ThemeEntry::createTheme(args.themeId);
setCreatorTheme(themeFromArg ? themeFromArg
: ThemeEntry::createTheme(ThemeEntry::themeSetting()));
+ InfoBar::initialize(ICore::settings(), creatorTheme());
new ActionManager(this);
ActionManager::setPresentationModeEnabled(args.presentationMode);
m_mainWindow = new MainWindow;
@@ -156,7 +162,6 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
m_mainWindow->init();
m_editMode = new EditMode;
ModeManager::activateMode(m_editMode->id());
- InfoBar::initialize(ICore::settings(), creatorTheme());
IWizardFactory::initialize();
@@ -232,6 +237,7 @@ void CorePlugin::extensionsInitialized()
errorOverview->setModal(true);
errorOverview->show();
}
+ checkSettings();
}
bool CorePlugin::delayedInitialize()
@@ -295,6 +301,45 @@ void CorePlugin::addToPathChooserContextMenu(Utils::PathChooser *pathChooser, QM
menu->insertSeparator(firstAction);
}
+void CorePlugin::checkSettings()
+{
+ const auto showMsgBox = [this](const QString &msg, QMessageBox::Icon icon) {
+ connect(ICore::instance(), &ICore::coreOpened, this, [msg, icon]() {
+ QMessageBox msgBox(ICore::dialogParent());
+ msgBox.setWindowTitle(tr("Settings File Error"));
+ msgBox.setText(msg);
+ msgBox.setIcon(icon);
+ msgBox.exec();
+ }, Qt::QueuedConnection);
+ };
+ const QSettings * const userSettings = ICore::settings();
+ QString errorDetails;
+ switch (userSettings->status()) {
+ case QSettings::NoError: {
+ const QFileInfo fi(userSettings->fileName());
+ if (fi.exists() && !fi.isWritable()) {
+ const QString errorMsg = tr("The settings file \"%1\" is not writable.\n"
+ "You will not be able to store any %2 settings.")
+ .arg(QDir::toNativeSeparators(userSettings->fileName()),
+ QLatin1String(Core::Constants::IDE_DISPLAY_NAME));
+ showMsgBox(errorMsg, QMessageBox::Warning);
+ }
+ return;
+ }
+ case QSettings::AccessError:
+ errorDetails = tr("The file is not readable.");
+ break;
+ case QSettings::FormatError:
+ errorDetails = tr("The file is invalid.");
+ break;
+ }
+ const QString errorMsg = tr("Error reading settings file \"%1\": %2\n"
+ "You will likely experience further problems using this instance of %3.")
+ .arg(QDir::toNativeSeparators(userSettings->fileName()), errorDetails,
+ QLatin1String(Core::Constants::IDE_DISPLAY_NAME));
+ showMsgBox(errorMsg, QMessageBox::Critical);
+}
+
ExtensionSystem::IPlugin::ShutdownFlag CorePlugin::aboutToShutdown()
{
Find::aboutToShutdown();
diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h
index 23494cbabd..fee1458eab 100644
--- a/src/plugins/coreplugin/coreplugin.h
+++ b/src/plugins/coreplugin/coreplugin.h
@@ -80,6 +80,7 @@ private slots:
private:
static void addToPathChooserContextMenu(Utils::PathChooser *pathChooser, QMenu *menu);
+ void checkSettings();
MainWindow *m_mainWindow = nullptr;
EditMode *m_editMode = nullptr;
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
index 62f7030c6d..b78f0b5dba 100644
--- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
@@ -58,11 +58,8 @@ ExternalToolModel::ExternalToolModel(QObject *parent)
ExternalToolModel::~ExternalToolModel()
{
- QMapIterator<QString, QList<ExternalTool *> > it(m_tools);
- while (it.hasNext()) {
- it.next();
- qDeleteAll(it.value());
- }
+ for (QList<ExternalTool *> &toolInCategory : m_tools)
+ qDeleteAll(toolInCategory);
}
Qt::DropActions ExternalToolModel::supportedDropActions() const
@@ -192,10 +189,8 @@ QModelIndex ExternalToolModel::parent(const QModelIndex &child) const
{
if (ExternalTool *tool = toolForIndex(child)) {
int categoryIndex = 0;
- QMapIterator<QString, QList<ExternalTool *> > it(m_tools);
- while (it.hasNext()) {
- it.next();
- if (it.value().contains(tool))
+ for (const QList<ExternalTool *> &toolsInCategory : m_tools) {
+ if (toolsInCategory.contains(tool))
return index(categoryIndex, 0);
++categoryIndex;
}
@@ -376,10 +371,7 @@ void ExternalToolModel::removeTool(const QModelIndex &modelIndex)
QTC_ASSERT(!tool->preset(), return);
// remove the tool and the tree item
int categoryIndex = 0;
- QMutableMapIterator<QString, QList<ExternalTool *> > it(m_tools);
- while (it.hasNext()) {
- it.next();
- QList<ExternalTool *> &items = it.value();
+ for (QList<ExternalTool *> &items : m_tools) {
int pos = items.indexOf(tool);
if (pos != -1) {
beginRemoveRows(index(categoryIndex, 0), pos, pos);
@@ -400,8 +392,7 @@ static void fillBaseEnvironmentComboBox(QComboBox *box)
box->addItem(provider.displayName, Id::fromName(provider.id).toSetting());
}
-ExternalToolConfig::ExternalToolConfig(QWidget *parent) :
- QWidget(parent),
+ExternalToolConfig::ExternalToolConfig() :
ui(new Ui::ExternalToolConfig),
m_model(new ExternalToolModel(this))
{
@@ -473,9 +464,7 @@ ExternalToolConfig::~ExternalToolConfig()
void ExternalToolConfig::setTools(const QMap<QString, QList<ExternalTool *> > &tools)
{
QMap<QString, QList<ExternalTool *> > toolsCopy;
- QMapIterator<QString, QList<ExternalTool *> > it(tools);
- while (it.hasNext()) {
- it.next();
+ for (auto it = tools.cbegin(), end = tools.cend(); it != end; ++it) {
QList<ExternalTool *> itemCopy;
for (ExternalTool *tool : it.value())
itemCopy.append(new ExternalTool(tool));
@@ -630,19 +619,16 @@ void ExternalToolConfig::updateEffectiveArguments()
void ExternalToolConfig::editEnvironmentChanges()
{
- bool ok;
const QString placeholderText = Utils::HostOsInfo::isWindowsHost()
? tr("PATH=C:\\dev\\bin;${PATH}")
: tr("PATH=/opt/bin:${PATH}");
- const QList<Utils::EnvironmentItem> newItems =
- Utils::EnvironmentDialog::getEnvironmentItems(&ok, ui->environmentLabel,
- m_environment,
- placeholderText);
- if (!ok)
- return;
-
- m_environment = newItems;
- updateEnvironmentLabel();
+ const auto newItems = Utils::EnvironmentDialog::getEnvironmentItems(ui->environmentLabel,
+ m_environment,
+ placeholderText);
+ if (newItems) {
+ m_environment = *newItems;
+ updateEnvironmentLabel();
+ }
}
void ExternalToolConfig::updateEnvironmentLabel()
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.h b/src/plugins/coreplugin/dialogs/externaltoolconfig.h
index 298b70c54f..ff1b867706 100644
--- a/src/plugins/coreplugin/dialogs/externaltoolconfig.h
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.h
@@ -27,14 +27,14 @@
#include "../externaltool.h"
+#include <utils/environmentfwd.h>
+
#include <QAbstractItemModel>
#include <QDialog>
#include <QWidget>
QT_FORWARD_DECLARE_CLASS(QPlainTextEdit)
-namespace Utils { class EnvironmentItem; }
-
namespace Core {
namespace Internal {
@@ -86,7 +86,7 @@ class ExternalToolConfig : public QWidget
Q_OBJECT
public:
- explicit ExternalToolConfig(QWidget *parent = nullptr);
+ ExternalToolConfig();
~ExternalToolConfig() override;
void setTools(const QMap<QString, QList<ExternalTool *> > &tools);
@@ -108,9 +108,9 @@ private:
void updateEnvironmentLabel();
Ui::ExternalToolConfig *ui;
- QList<Utils::EnvironmentItem> m_environment;
+ Utils::EnvironmentItems m_environment;
ExternalToolModel *m_model;
};
} // Internal
-} // Core
+} // namespace Core
diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp
index 8057a9e48a..302a504217 100644
--- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp
+++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp
@@ -550,7 +550,7 @@ void SettingsDialog::createGui()
headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
headerHLayout->addWidget(m_headerLabel);
- m_stackedLayout->setMargin(0);
+ m_stackedLayout->setContentsMargins(0, 0, 0, 0);
QWidget *emptyWidget = new QWidget(this);
m_stackedLayout->addWidget(emptyWidget); // no category selected, for example when filtering
diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
index d740b6ca20..86ee6146da 100644
--- a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
+++ b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
@@ -283,8 +283,7 @@ ShortcutSettingsWidget::~ShortcutSettingsWidget()
qDeleteAll(m_scitems);
}
-ShortcutSettings::ShortcutSettings(QObject *parent)
- : IOptionsPage(parent)
+ShortcutSettings::ShortcutSettings()
{
setId(Constants::SETTINGS_ID_SHORTCUTS);
setDisplayName(tr("Keyboard"));
diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.h b/src/plugins/coreplugin/dialogs/shortcutsettings.h
index f54206cd3e..6c10c14463 100644
--- a/src/plugins/coreplugin/dialogs/shortcutsettings.h
+++ b/src/plugins/coreplugin/dialogs/shortcutsettings.h
@@ -116,7 +116,7 @@ class ShortcutSettings : public IOptionsPage
Q_OBJECT
public:
- ShortcutSettings(QObject *parent = nullptr);
+ ShortcutSettings();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp
index aba6484de5..43760ed547 100644
--- a/src/plugins/coreplugin/documentmanager.cpp
+++ b/src/plugins/coreplugin/documentmanager.cpp
@@ -154,7 +154,6 @@ public:
QSet<QString> m_expectedFileNames; // set of file names without normalization
QList<DocumentManager::RecentFile> m_recentFiles;
- static const int m_maxRecentFiles = 7;
bool m_postponeAutoReload = false;
bool m_blockActivated = false;
@@ -428,9 +427,8 @@ void DocumentManager::renamedFile(const QString &from, const QString &to)
// gather the list of IDocuments
QList<IDocument *> documentsToRename;
- QMapIterator<IDocument *, QStringList> it(d->m_documentsWithWatch);
- while (it.hasNext()) {
- it.next();
+ for (auto it = d->m_documentsWithWatch.cbegin(), end = d->m_documentsWithWatch.cend();
+ it != end; ++it) {
if (it.value().contains(fromKey))
documentsToRename.append(it.key());
}
@@ -1248,9 +1246,7 @@ void DocumentManager::checkForReload()
// handle deleted files
EditorManager::closeDocuments(documentsToClose, false);
- QHashIterator<IDocument *, QString> it(documentsToSave);
- while (it.hasNext()) {
- it.next();
+ for (auto it = documentsToSave.cbegin(), end = documentsToSave.cend(); it != end; ++it) {
saveDocument(it.key(), it.value());
it.key()->checkPermissions();
}
@@ -1271,15 +1267,11 @@ void DocumentManager::addToRecentFiles(const QString &fileName, Id editorId)
{
if (fileName.isEmpty())
return;
- QString fileKey = filePathKey(fileName, KeepLinks);
- QMutableListIterator<RecentFile > it(d->m_recentFiles);
- while (it.hasNext()) {
- RecentFile file = it.next();
- QString recentFileKey(filePathKey(file.first, DocumentManager::KeepLinks));
- if (fileKey == recentFileKey)
- it.remove();
- }
- if (d->m_recentFiles.count() > d->m_maxRecentFiles)
+ const QString fileKey = filePathKey(fileName, KeepLinks);
+ Utils::erase(d->m_recentFiles, [fileKey](const RecentFile &file) {
+ return fileKey == filePathKey(file.first, DocumentManager::KeepLinks);
+ });
+ while (d->m_recentFiles.count() >= EditorManagerPrivate::maxRecentFiles())
d->m_recentFiles.removeLast();
d->m_recentFiles.prepend(RecentFile(fileName, editorId));
}
@@ -1326,15 +1318,15 @@ void readSettings()
QSettings *s = ICore::settings();
d->m_recentFiles.clear();
s->beginGroup(QLatin1String(settingsGroupC));
- QStringList recentFiles = s->value(QLatin1String(filesKeyC)).toStringList();
- QStringList recentEditorIds = s->value(QLatin1String(editorsKeyC)).toStringList();
+ const QStringList recentFiles = s->value(QLatin1String(filesKeyC)).toStringList();
+ const QStringList recentEditorIds = s->value(QLatin1String(editorsKeyC)).toStringList();
s->endGroup();
// clean non-existing files
- QStringListIterator ids(recentEditorIds);
- foreach (const QString &fileName, recentFiles) {
+ for (int i = 0, n = recentFiles.size(); i < n; ++i) {
+ const QString &fileName = recentFiles.at(i);
QString editorId;
- if (ids.hasNext()) // guard against old or weird settings
- editorId = ids.next();
+ if (i < recentEditorIds.size()) // guard against old or weird settings
+ editorId = recentEditorIds.at(i);
if (QFileInfo(fileName).isFile())
d->m_recentFiles.append(DocumentManager::RecentFile(QDir::fromNativeSeparators(fileName), // from native to guard against old settings
Id::fromString(editorId)));
@@ -1343,7 +1335,7 @@ void readSettings()
s->beginGroup(QLatin1String(directoryGroupC));
const FilePath settingsProjectDir = FilePath::fromString(s->value(QLatin1String(projectDirectoryKeyC),
QString()).toString());
- if (!settingsProjectDir.isEmpty() && settingsProjectDir.toFileInfo().isDir())
+ if (!settingsProjectDir.isEmpty() && settingsProjectDir.isDir())
d->m_projectsDirectory = settingsProjectDir;
else
d->m_projectsDirectory = FilePath::fromString(PathChooser::homePath());
diff --git a/src/plugins/coreplugin/editmode.cpp b/src/plugins/coreplugin/editmode.cpp
index c3d47d291c..d53d76e46d 100644
--- a/src/plugins/coreplugin/editmode.cpp
+++ b/src/plugins/coreplugin/editmode.cpp
@@ -55,7 +55,7 @@ EditMode::EditMode() :
setId(Constants::MODE_EDIT);
m_rightSplitWidgetLayout->setSpacing(0);
- m_rightSplitWidgetLayout->setMargin(0);
+ m_rightSplitWidgetLayout->setContentsMargins(0, 0, 0, 0);
QWidget *rightSplitWidget = new QWidget;
rightSplitWidget->setLayout(m_rightSplitWidgetLayout);
auto editorPlaceHolder = new EditorManagerPlaceHolder;
diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp
index b3cec42210..c51dc81a67 100644
--- a/src/plugins/coreplugin/editormanager/documentmodel.cpp
+++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp
@@ -504,7 +504,8 @@ DocumentModel::Entry *DocumentModelPrivate::DynamicEntry::operator->() const
void DocumentModelPrivate::DynamicEntry::disambiguate()
{
- entry->document->setUniqueDisplayName(entry->fileName().fileName(++pathComponents));
+ const QString display = entry->fileName().fileNameWithPathComponents(++pathComponents);
+ entry->document->setUniqueDisplayName(display);
}
void DocumentModelPrivate::DynamicEntry::setNumberedName(int number)
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 954e5401b8..0be92efe8a 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -121,6 +121,7 @@ static const char autoSuspendEnabledKey[] = "EditorManager/AutoSuspendEnabled";
static const char autoSuspendMinDocumentCountKey[] = "EditorManager/AutoSuspendMinDocuments";
static const char warnBeforeOpeningBigTextFilesKey[] = "EditorManager/WarnBeforeOpeningBigTextFiles";
static const char bigTextFileSizeLimitKey[] = "EditorManager/BigTextFileSizeLimitInMB";
+static const char maxRecentFilesKey[] = "EditorManager/MaxRecentFiles";
static const char fileSystemCaseSensitivityKey[] = "Core/FileSystemCaseSensitivity";
static const char preferredEditorFactoriesKey[] = "EditorManager/PreferredEditorFactories";
@@ -136,7 +137,7 @@ EditorManagerPlaceHolder::EditorManagerPlaceHolder(QWidget *parent)
: QWidget(parent)
{
setLayout(new QVBoxLayout);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
setFocusProxy(EditorManagerPrivate::mainEditorArea());
}
@@ -1020,6 +1021,7 @@ void EditorManagerPrivate::saveSettings()
qsettings->setValue(warnBeforeOpeningBigTextFilesKey,
d->m_warnBeforeOpeningBigFilesEnabled);
qsettings->setValue(bigTextFileSizeLimitKey, d->m_bigFileSizeLimitInMB);
+ qsettings->setValue(maxRecentFilesKey, d->m_maxRecentFiles);
Qt::CaseSensitivity defaultSensitivity
= OsSpecificAspects::fileNameCaseSensitivity(HostOsInfo::hostOs());
@@ -1040,6 +1042,10 @@ void EditorManagerPrivate::readSettings()
d->m_bigFileSizeLimitInMB = qs->value(bigTextFileSizeLimitKey).toInt();
}
+ const int maxRecentFiles = qs->value(maxRecentFilesKey).toInt();
+ if (maxRecentFiles > 0)
+ d->m_maxRecentFiles = maxRecentFiles;
+
if (qs->contains(fileSystemCaseSensitivityKey)) {
Qt::CaseSensitivity defaultSensitivity
= OsSpecificAspects::fileNameCaseSensitivity(HostOsInfo::hostOs());
@@ -1155,6 +1161,16 @@ int EditorManagerPrivate::bigFileSizeLimit()
return d->m_bigFileSizeLimitInMB;
}
+void EditorManagerPrivate::setMaxRecentFiles(int count)
+{
+ d->m_maxRecentFiles = count;
+}
+
+int EditorManagerPrivate::maxRecentFiles()
+{
+ return d->m_maxRecentFiles;
+}
+
void EditorManagerPrivate::setBigFileSizeLimit(int limitInMB)
{
d->m_bigFileSizeLimitInMB = limitInMB;
@@ -2308,7 +2324,7 @@ void EditorManagerPrivate::findInDirectory()
return;
const FilePath path = d->m_contextMenuEntry->fileName();
emit m_instance->findOnFileSystemRequest(
- (path.toFileInfo().isDir() ? path : path.parentDir()).toString());
+ (path.isDir() ? path : path.parentDir()).toString());
}
void EditorManagerPrivate::togglePinned()
diff --git a/src/plugins/coreplugin/editormanager/editormanager_p.h b/src/plugins/coreplugin/editormanager/editormanager_p.h
index 4dd7f62e31..ac6ac6f7f8 100644
--- a/src/plugins/coreplugin/editormanager/editormanager_p.h
+++ b/src/plugins/coreplugin/editormanager/editormanager_p.h
@@ -124,6 +124,8 @@ public:
static bool warnBeforeOpeningBigFilesEnabled();
static void setBigFileSizeLimit(int limitInMB);
static int bigFileSizeLimit();
+ static void setMaxRecentFiles(int count);
+ static int maxRecentFiles();
static EditorWindow *createEditorWindow();
static void splitNewWindow(Internal::EditorView *view);
@@ -276,6 +278,7 @@ private:
bool m_warnBeforeOpeningBigFilesEnabled = true;
int m_bigFileSizeLimitInMB = 5;
+ int m_maxRecentFiles = 8;
QString m_placeholderText;
QList<std::function<bool(IEditor *)>> m_closeEditorListeners;
diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp
index d38923be38..c9adba0206 100644
--- a/src/plugins/coreplugin/editormanager/editorview.cpp
+++ b/src/plugins/coreplugin/editormanager/editorview.cpp
@@ -72,7 +72,7 @@ EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) :
{
auto tl = new QVBoxLayout(this);
tl->setSpacing(0);
- tl->setMargin(0);
+ tl->setContentsMargins(0, 0, 0, 0);
{
connect(m_toolBar, &EditorToolBar::goBackClicked,
this, &EditorView::goBackInNavigationHistory);
diff --git a/src/plugins/coreplugin/editormanager/editorwindow.cpp b/src/plugins/coreplugin/editormanager/editorwindow.cpp
index 83b8707131..02da562e5a 100644
--- a/src/plugins/coreplugin/editormanager/editorwindow.cpp
+++ b/src/plugins/coreplugin/editormanager/editorwindow.cpp
@@ -50,7 +50,7 @@ EditorWindow::EditorWindow(QWidget *parent) :
{
m_area = new EditorArea;
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
setLayout(layout);
layout->addWidget(m_area);
diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp
index ad1775f9d2..d7af47f372 100644
--- a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp
+++ b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp
@@ -73,7 +73,7 @@ OpenEditorsWindow::OpenEditorsWindow(QWidget *parent) :
m_editorList->setFrameStyle(QFrame::NoFrame);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_editorList);
connect(m_editorList, &QTreeWidget::itemClicked,
diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp
index 9d19415e45..99dfab9182 100644
--- a/src/plugins/coreplugin/editortoolbar.cpp
+++ b/src/plugins/coreplugin/editortoolbar.cpp
@@ -119,7 +119,7 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
Utils::StyledBar(parent), d(new EditorToolBarPrivate(parent, this))
{
auto toolBarLayout = new QHBoxLayout(this);
- toolBarLayout->setMargin(0);
+ toolBarLayout->setContentsMargins(0, 0, 0, 0);
toolBarLayout->setSpacing(0);
toolBarLayout->addWidget(d->m_defaultToolBar);
d->m_toolBarPlaceholder->setLayout(toolBarLayout);
@@ -172,7 +172,7 @@ EditorToolBar::EditorToolBar(QWidget *parent) :
auto toplayout = new QHBoxLayout(this);
toplayout->setSpacing(0);
- toplayout->setMargin(0);
+ toplayout->setContentsMargins(0, 0, 0, 0);
toplayout->addWidget(d->m_backButton);
toplayout->addWidget(d->m_forwardButton);
toplayout->addWidget(d->m_lockButton);
diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index b339dddd3d..97e0e003be 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -190,7 +190,7 @@ Environment ExternalTool::baseEnvironment() const
return Environment::systemEnvironment();
}
-QList<EnvironmentItem> ExternalTool::environmentUserChanges() const
+EnvironmentItems ExternalTool::environmentUserChanges() const
{
return m_environment;
}
@@ -297,7 +297,7 @@ void ExternalTool::setBaseEnvironmentProviderId(Id id)
m_baseEnvironmentProviderId = id;
}
-void ExternalTool::setEnvironmentUserChanges(const QList<EnvironmentItem> &items)
+void ExternalTool::setEnvironmentUserChanges(const EnvironmentItems &items)
{
m_environment = items;
}
@@ -600,10 +600,10 @@ bool ExternalToolRunner::resolve()
m_resolvedEnvironment = m_tool->baseEnvironment();
MacroExpander *expander = globalMacroExpander();
- QList<EnvironmentItem> expandedEnvironment
- = Utils::transform(m_tool->environmentUserChanges(), [expander](const EnvironmentItem &item) {
- return EnvironmentItem(item.name, expander->expand(item.value), item.operation);
- });
+ EnvironmentItems expandedEnvironment = Utils::transform(
+ m_tool->environmentUserChanges(), [expander](const EnvironmentItem &item) {
+ return EnvironmentItem(item.name, expander->expand(item.value), item.operation);
+ });
m_resolvedEnvironment.modify(expandedEnvironment);
{
@@ -663,11 +663,11 @@ void ExternalToolRunner::run()
this, &ExternalToolRunner::readStandardError);
if (!m_resolvedWorkingDirectory.isEmpty())
m_process->setWorkingDirectory(m_resolvedWorkingDirectory);
- m_process->setCommand(CommandLine(m_resolvedExecutable, m_resolvedArguments));
+ const CommandLine cmd{m_resolvedExecutable, m_resolvedArguments, CommandLine::Raw};
+ m_process->setCommand(cmd);
m_process->setEnvironment(m_resolvedEnvironment);
- MessageManager::write(tr("Starting external tool \"%1\" %2")
- .arg(m_resolvedExecutable.toUserOutput(), m_resolvedArguments),
- MessageManager::Silent);
+ MessageManager::write(tr("Starting external tool \"%1\"")
+ .arg(cmd.toUserOutput()), MessageManager::Silent);
m_process->start();
}
@@ -697,7 +697,7 @@ void ExternalToolRunner::error(QProcess::ProcessError error)
if (m_tool->modifiesCurrentDocument())
DocumentManager::unexpectFileChange(m_expectedFileName);
// TODO inform about errors
- Q_UNUSED(error);
+ Q_UNUSED(error)
deleteLater();
}
diff --git a/src/plugins/coreplugin/externaltool.h b/src/plugins/coreplugin/externaltool.h
index 394ee091a5..4294615cb9 100644
--- a/src/plugins/coreplugin/externaltool.h
+++ b/src/plugins/coreplugin/externaltool.h
@@ -71,7 +71,7 @@ public:
QString workingDirectory() const;
Id baseEnvironmentProviderId() const;
Utils::Environment baseEnvironment() const;
- QList<Utils::EnvironmentItem> environmentUserChanges() const;
+ Utils::EnvironmentItems environmentUserChanges() const;
void setFileName(const QString &fileName);
void setPreset(QSharedPointer<ExternalTool> preset);
@@ -101,7 +101,7 @@ public:
void setInput(const QString &input);
void setWorkingDirectory(const QString &workingDirectory);
void setBaseEnvironmentProviderId(Id id);
- void setEnvironmentUserChanges(const QList<Utils::EnvironmentItem> &items);
+ void setEnvironmentUserChanges(const Utils::EnvironmentItems &items);
private:
QString m_id;
@@ -114,7 +114,7 @@ private:
QString m_input;
QString m_workingDirectory;
Id m_baseEnvironmentProviderId;
- QList<Utils::EnvironmentItem> m_environment;
+ Utils::EnvironmentItems m_environment;
OutputHandling m_outputHandling = ShowInPane;
OutputHandling m_errorHandling = ShowInPane;
bool m_modifiesCurrentDocument = false;
diff --git a/src/plugins/coreplugin/externaltoolmanager.cpp b/src/plugins/coreplugin/externaltoolmanager.cpp
index d2b37bf4ef..67f2dc1374 100644
--- a/src/plugins/coreplugin/externaltoolmanager.cpp
+++ b/src/plugins/coreplugin/externaltoolmanager.cpp
@@ -98,11 +98,8 @@ ExternalToolManager::ExternalToolManager()
true);
QMap<QString, QList<ExternalTool *> > categoryMap;
- QMapIterator<QString, QMultiMap<int, ExternalTool*> > it(categoryPriorityMap);
- while (it.hasNext()) {
- it.next();
+ for (auto it = categoryPriorityMap.cbegin(), end = categoryPriorityMap.cend(); it != end; ++it)
categoryMap.insert(it.key(), it.value().values());
- }
// read renamed categories and custom order
readSettings(tools, &categoryMap);
@@ -177,9 +174,7 @@ void ExternalToolManager::setToolsByCategory(const QMap<QString, QList<ExternalT
// delete old tools and create list of new ones
QMap<QString, ExternalTool *> newTools;
QMap<QString, QAction *> newActions;
- QMapIterator<QString, QList<ExternalTool *> > it(tools);
- while (it.hasNext()) {
- it.next();
+ for (auto it = tools.cbegin(), end = tools.cend(); it != end; ++it) {
foreach (ExternalTool *tool, it.value()) {
const QString id = tool->id();
if (d->m_tools.value(id) == tool) {
@@ -192,10 +187,9 @@ void ExternalToolManager::setToolsByCategory(const QMap<QString, QList<ExternalT
}
}
qDeleteAll(d->m_tools);
- QMapIterator<QString, QAction *> remainingActions(d->m_actions);
const Id externalToolsPrefix = "Tools.External.";
- while (remainingActions.hasNext()) {
- remainingActions.next();
+ for (auto remainingActions = d->m_actions.cbegin(), end = d->m_actions.cend();
+ remainingActions != end; ++remainingActions) {
ActionManager::unregisterAction(remainingActions.value(),
externalToolsPrefix.withSuffix(remainingActions.key()));
delete remainingActions.value();
@@ -208,9 +202,7 @@ void ExternalToolManager::setToolsByCategory(const QMap<QString, QList<ExternalT
// create menu structure and remove no-longer used containers
// add all the category menus, QMap is nicely sorted
QMap<QString, ActionContainer *> newContainers;
- it.toFront();
- while (it.hasNext()) {
- it.next();
+ for (auto it = tools.cbegin(), end = tools.cend(); it != end; ++it) {
ActionContainer *container = nullptr;
const QString &containerName = it.key();
if (containerName.isEmpty()) { // no displayCategory, so put into external tools menu directly
@@ -302,9 +294,7 @@ static void writeSettings()
settings->remove(QLatin1String(""));
settings->beginGroup(QLatin1String("OverrideCategories"));
- QMapIterator<QString, QList<ExternalTool *> > it(d->m_categoryMap);
- while (it.hasNext()) {
- it.next();
+ for (auto it = d->m_categoryMap.cbegin(), end = d->m_categoryMap.cend(); it != end; ++it) {
QString category = it.key();
if (category.isEmpty())
category = QLatin1String(kSpecialUncategorizedSetting);
diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp
index d332817f62..03f28778f6 100644
--- a/src/plugins/coreplugin/fancyactionbar.cpp
+++ b/src/plugins/coreplugin/fancyactionbar.cpp
@@ -359,7 +359,7 @@ FancyActionBar::FancyActionBar(QWidget *parent)
{
setObjectName("actionbar");
m_actionsLayout = new QVBoxLayout;
- m_actionsLayout->setMargin(0);
+ m_actionsLayout->setContentsMargins(0, 0, 0, 0);
m_actionsLayout->setSpacing(0);
setLayout(m_actionsLayout);
setContentsMargins(0, 2, 0, 8);
diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp
index 684b47bd15..1bc2ab5089 100644
--- a/src/plugins/coreplugin/fancytabwidget.cpp
+++ b/src/plugins/coreplugin/fancytabwidget.cpp
@@ -479,11 +479,11 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
m_selectionWidget = new QWidget(this);
auto selectionLayout = new QVBoxLayout;
selectionLayout->setSpacing(0);
- selectionLayout->setMargin(0);
+ selectionLayout->setContentsMargins(0, 0, 0, 0);
auto bar = new StyledBar;
auto layout = new QHBoxLayout(bar);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
auto fancyButton = new FancyColorButton(this);
connect(fancyButton, &FancyColorButton::clicked, this, &FancyTabWidget::topAreaClicked);
@@ -501,7 +501,7 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
auto cornerWidgetLayout = new QVBoxLayout;
cornerWidgetLayout->setSpacing(0);
- cornerWidgetLayout->setMargin(0);
+ cornerWidgetLayout->setContentsMargins(0, 0, 0, 0);
cornerWidgetLayout->addStretch();
m_cornerWidgetContainer->setLayout(cornerWidgetLayout);
@@ -512,13 +512,16 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
m_statusBar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
auto vlayout = new QVBoxLayout;
- vlayout->setMargin(0);
+ vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setSpacing(0);
vlayout->addLayout(m_modesStack);
vlayout->addWidget(m_statusBar);
+ m_infoBarDisplay.setTarget(vlayout, 1);
+ m_infoBarDisplay.setStyle(QFrame::Sunken);
+
auto mainLayout = new QHBoxLayout;
- mainLayout->setMargin(0);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(1);
mainLayout->addWidget(m_selectionWidget);
mainLayout->addLayout(vlayout);
@@ -611,6 +614,13 @@ QStatusBar *FancyTabWidget::statusBar() const
return m_statusBar;
}
+InfoBar *FancyTabWidget::infoBar()
+{
+ if (!m_infoBarDisplay.infoBar())
+ m_infoBarDisplay.setInfoBar(&m_infoBar);
+ return &m_infoBar;
+}
+
void FancyTabWidget::setCurrentIndex(int index)
{
m_tabBar->setCurrentIndex(index);
diff --git a/src/plugins/coreplugin/fancytabwidget.h b/src/plugins/coreplugin/fancytabwidget.h
index c9a7264d80..00d04f376b 100644
--- a/src/plugins/coreplugin/fancytabwidget.h
+++ b/src/plugins/coreplugin/fancytabwidget.h
@@ -25,6 +25,8 @@
#pragma once
+#include "infobar.h"
+
#include <QIcon>
#include <QWidget>
@@ -157,6 +159,7 @@ public:
int currentIndex() const;
QStatusBar *statusBar() const;
+ InfoBar *infoBar();
void setTabEnabled(int index, bool enable);
bool isTabEnabled(int index) const;
@@ -183,6 +186,8 @@ private:
QStackedLayout *m_modesStack;
QWidget *m_selectionWidget;
QStatusBar *m_statusBar;
+ InfoBarDisplay m_infoBarDisplay;
+ InfoBar m_infoBar;
};
} // namespace Internal
diff --git a/src/plugins/coreplugin/find/findtoolwindow.cpp b/src/plugins/coreplugin/find/findtoolwindow.cpp
index 0490e8481f..e25a0d33c6 100644
--- a/src/plugins/coreplugin/find/findtoolwindow.cpp
+++ b/src/plugins/coreplugin/find/findtoolwindow.cpp
@@ -93,7 +93,7 @@ FindToolWindow::FindToolWindow(QWidget *parent)
this, &FindToolWindow::updateButtonStates);
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
m_ui.configWidget->setLayout(layout);
updateButtonStates();
diff --git a/src/plugins/coreplugin/find/itemviewfind.cpp b/src/plugins/coreplugin/find/itemviewfind.cpp
index 87f1160e97..3f07dff596 100644
--- a/src/plugins/coreplugin/find/itemviewfind.cpp
+++ b/src/plugins/coreplugin/find/itemviewfind.cpp
@@ -139,7 +139,7 @@ static QFrame *createHelper(QAbstractItemView *treeView,
placeHolder->setLightColored(colorOption);
auto vbox = new QVBoxLayout(widget);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
vbox->setSpacing(0);
vbox->addWidget(treeView);
vbox->addWidget(placeHolder);
diff --git a/src/plugins/coreplugin/find/searchresulttreemodel.cpp b/src/plugins/coreplugin/find/searchresulttreemodel.cpp
index 3fba0f899d..854bb94ed3 100644
--- a/src/plugins/coreplugin/find/searchresulttreemodel.cpp
+++ b/src/plugins/coreplugin/find/searchresulttreemodel.cpp
@@ -247,7 +247,7 @@ QVariant SearchResultTreeModel::data(const SearchResultTreeItem *row, int role)
else
result = QVariant();
break;
- case Qt::TextColorRole:
+ case Qt::ForegroundRole:
result = m_color.textForeground;
break;
case Qt::BackgroundRole:
diff --git a/src/plugins/coreplugin/find/searchresultwidget.cpp b/src/plugins/coreplugin/find/searchresultwidget.cpp
index 5827885802..23b894ef9a 100644
--- a/src/plugins/coreplugin/find/searchresultwidget.cpp
+++ b/src/plugins/coreplugin/find/searchresultwidget.cpp
@@ -82,7 +82,7 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
QWidget(parent)
{
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
setLayout(layout);
@@ -104,13 +104,13 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
auto topFindWidget = new QWidget(topWidget);
auto topFindLayout = new QHBoxLayout(topFindWidget);
- topFindLayout->setMargin(0);
+ topFindLayout->setContentsMargins(0, 0, 0, 0);
topFindWidget->setLayout(topFindLayout);
topLayout->addWidget(topFindWidget);
m_topReplaceWidget = new QWidget(topWidget);
auto topReplaceLayout = new QHBoxLayout(m_topReplaceWidget);
- topReplaceLayout->setMargin(0);
+ topReplaceLayout->setContentsMargins(0, 0, 0, 0);
m_topReplaceWidget->setLayout(topReplaceLayout);
topLayout->addWidget(m_topReplaceWidget);
@@ -123,7 +123,7 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
}
m_messageWidget->setAutoFillBackground(true);
auto messageLayout = new QHBoxLayout(m_messageWidget);
- messageLayout->setMargin(2);
+ messageLayout->setContentsMargins(2, 2, 2, 2);
m_messageWidget->setLayout(messageLayout);
QLabel *messageLabel = new QLabel(tr("Search was canceled."));
messageLabel->setPalette(pal);
@@ -146,7 +146,7 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
m_descriptionContainer = new QWidget(topFindWidget);
auto descriptionLayout = new QHBoxLayout(m_descriptionContainer);
m_descriptionContainer->setLayout(descriptionLayout);
- descriptionLayout->setMargin(0);
+ descriptionLayout->setContentsMargins(0, 0, 0, 0);
m_descriptionContainer->setMinimumWidth(200);
m_descriptionContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
m_label = new QLabel(m_descriptionContainer);
@@ -257,7 +257,7 @@ void SearchResultWidget::addResults(const QList<SearchResultItem> &items, Search
Id undoWarningId = Id("warninglabel/").withSuffix(m_dontAskAgainGroup);
if (m_infoBar.canInfoBeAdded(undoWarningId)) {
InfoBarEntry info(undoWarningId, tr("This change cannot be undone."),
- InfoBarEntry::GlobalSuppressionEnabled);
+ InfoBarEntry::GlobalSuppression::Enabled);
m_infoBar.addInfo(info);
}
}
diff --git a/src/plugins/coreplugin/findplaceholder.cpp b/src/plugins/coreplugin/findplaceholder.cpp
index 101ccf87df..13a5b243fb 100644
--- a/src/plugins/coreplugin/findplaceholder.cpp
+++ b/src/plugins/coreplugin/findplaceholder.cpp
@@ -40,7 +40,7 @@ FindToolBarPlaceHolder::FindToolBarPlaceHolder(QWidget *owner, QWidget *parent)
g_findToolBarPlaceHolders.append(this);
setLayout(new QVBoxLayout);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
}
FindToolBarPlaceHolder::~FindToolBarPlaceHolder()
diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp
index 27788d5711..f0db3135e9 100644
--- a/src/plugins/coreplugin/generalsettings.cpp
+++ b/src/plugins/coreplugin/generalsettings.cpp
@@ -37,6 +37,7 @@
#include <QLibraryInfo>
#include <QMessageBox>
#include <QSettings>
+#include <QStyleHints>
#include "ui_generalsettings.h"
@@ -46,6 +47,7 @@ namespace Core {
namespace Internal {
const char settingsKeyDPI[] = "Core/EnableHighDpiScaling";
+const char settingsKeyShortcutsInContextMenu[] = "General/ShowShortcutsInContextMenu";
GeneralSettings::GeneralSettings()
: m_page(nullptr), m_dialog(nullptr)
@@ -56,6 +58,8 @@ GeneralSettings::GeneralSettings()
setDisplayCategory(QCoreApplication::translate("Core", "Environment"));
setCategoryIcon(Utils::Icon({{":/core/images/settingscategory_core.png",
Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint));
+ m_defaultShowShortcutsInContextMenu = QGuiApplication::styleHints()
+ ->showShortcutsInContextMenus();
}
static bool hasQmFilesForLocale(const QString &locale, const QString &creatorTrPath)
@@ -107,8 +111,15 @@ QWidget *GeneralSettings::widget()
m_page->colorButton->setColor(StyleHelper::requestedBaseColor());
m_page->resetWarningsButton->setEnabled(canResetWarnings());
+ m_page->showShortcutsInContextMenus->setText(
+ tr("Show keyboard shortcuts in context menus (default: %1)")
+ .arg(QLatin1String(m_defaultShowShortcutsInContextMenu ? "on" : "off")));
+ m_page->showShortcutsInContextMenus->setChecked(showShortcutsInContextMenu());
+#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
+ m_page->showShortcutsInContextMenus->setVisible(false);
+#endif
+
if (Utils::HostOsInfo().isMacHost()) {
- m_page->dpiLabel->setVisible(false);
m_page->dpiCheckbox->setVisible(false);
} else {
const bool defaultValue = Utils::HostOsInfo().isWindowsHost();
@@ -134,6 +145,7 @@ void GeneralSettings::apply()
return;
int currentIndex = m_page->languageBox->currentIndex();
setLanguage(m_page->languageBox->itemData(currentIndex, Qt::UserRole).toString());
+ setShowShortcutsInContextMenu(m_page->showShortcutsInContextMenus->isChecked());
// Apply the new base color if accepted
StyleHelper::setBaseColor(m_page->colorButton->color());
m_page->themeChooser->apply();
@@ -146,6 +158,14 @@ void GeneralSettings::finish()
m_page = nullptr;
}
+bool GeneralSettings::showShortcutsInContextMenu() const
+{
+ return ICore::settings()
+ ->value(settingsKeyShortcutsInContextMenu,
+ QGuiApplication::styleHints()->showShortcutsInContextMenus())
+ .toBool();
+}
+
void GeneralSettings::resetInterfaceColor()
{
m_page->colorButton->setColor(StyleHelper::DEFAULT_BASE_COLOR);
@@ -189,5 +209,16 @@ void GeneralSettings::setLanguage(const QString &locale)
settings->setValue(QLatin1String("General/OverrideLanguage"), locale);
}
+void GeneralSettings::setShowShortcutsInContextMenu(bool show)
+{
+ if (show == m_defaultShowShortcutsInContextMenu)
+ ICore::settings()->remove(settingsKeyShortcutsInContextMenu);
+ else
+ ICore::settings()->setValue(settingsKeyShortcutsInContextMenu, show);
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
+ QGuiApplication::styleHints()->setShowShortcutsInContextMenus(show);
+#endif
+}
+
} // namespace Internal
} // namespace Core
diff --git a/src/plugins/coreplugin/generalsettings.h b/src/plugins/coreplugin/generalsettings.h
index ed0f177532..bdd6597755 100644
--- a/src/plugins/coreplugin/generalsettings.h
+++ b/src/plugins/coreplugin/generalsettings.h
@@ -48,6 +48,9 @@ public:
void apply() override;
void finish() override;
+ bool showShortcutsInContextMenu() const;
+ void setShowShortcutsInContextMenu(bool show);
+
private:
void resetInterfaceColor();
void resetWarnings();
@@ -57,9 +60,11 @@ private:
void fillLanguageBox() const;
QString language() const;
void setLanguage(const QString&);
+
Ui::GeneralSettings *m_page;
QPointer<QMessageBox> m_dialog;
QPointer<QWidget> m_widget;
+ bool m_defaultShowShortcutsInContextMenu;
};
} // namespace Internal
diff --git a/src/plugins/coreplugin/generalsettings.ui b/src/plugins/coreplugin/generalsettings.ui
index 0302314d64..93edf24536 100644
--- a/src/plugins/coreplugin/generalsettings.ui
+++ b/src/plugins/coreplugin/generalsettings.ui
@@ -16,21 +16,7 @@
<property name="title">
<string>User Interface</string>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="colorLabel">
- <property name="text">
- <string>Color:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="languageLabel">
- <property name="text">
- <string>Language:</string>
- </property>
- </widget>
- </item>
+ <layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="themeLabel">
<property name="text">
@@ -38,6 +24,9 @@
</property>
</widget>
</item>
+ <item row="1" column="1">
+ <widget class="Core::Internal::ThemeChooser" name="themeChooser" native="true"/>
+ </item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@@ -84,16 +73,6 @@
</item>
</layout>
</item>
- <item row="4" column="0">
- <widget class="QPushButton" name="resetWarningsButton">
- <property name="toolTip">
- <string>Re-enable warnings that were suppressed by selecting &quot;Do Not Show Again&quot; (for example, missing highlighter).</string>
- </property>
- <property name="text">
- <string comment="Button text">Reset Warnings</string>
- </property>
- </widget>
- </item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
@@ -121,37 +100,41 @@
</item>
</layout>
</item>
- <item row="1" column="1">
- <widget class="Core::Internal::ThemeChooser" name="themeChooser" native="true"/>
+ <item row="0" column="0">
+ <widget class="QLabel" name="colorLabel">
+ <property name="text">
+ <string>Color:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QPushButton" name="resetWarningsButton">
+ <property name="toolTip">
+ <string>Re-enable warnings that were suppressed by selecting &quot;Do Not Show Again&quot; (for example, missing highlighter).</string>
+ </property>
+ <property name="text">
+ <string comment="Button text">Reset Warnings</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="languageLabel">
+ <property name="text">
+ <string>Language:</string>
+ </property>
+ </widget>
</item>
<item row="3" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QCheckBox" name="dpiCheckbox">
- <property name="text">
- <string>Enable high DPI scaling</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>285</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ <widget class="QCheckBox" name="dpiCheckbox">
+ <property name="text">
+ <string>Enable high DPI scaling</string>
+ </property>
+ </widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="dpiLabel">
+ <item row="4" column="1">
+ <widget class="QCheckBox" name="showShortcutsInContextMenus">
<property name="text">
- <string>High DPI scaling:</string>
+ <string/>
</property>
</widget>
</item>
diff --git a/src/plugins/coreplugin/helpitem.cpp b/src/plugins/coreplugin/helpitem.cpp
index d63bd883de..6349ad17cd 100644
--- a/src/plugins/coreplugin/helpitem.cpp
+++ b/src/plugins/coreplugin/helpitem.cpp
@@ -222,11 +222,8 @@ const HelpItem::Links &HelpItem::links() const
}
}
}
- QMapIterator<QString, QUrl> it(helpLinks);
- while (it.hasNext()) {
- it.next();
+ for (auto it = helpLinks.cbegin(), end = helpLinks.cend(); it != end; ++it)
m_helpLinks->emplace_back(it.key(), it.value());
- }
}
Utils::sort(*m_helpLinks, linkLessThan);
}
diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp
index 63eba664cc..d8ba245020 100644
--- a/src/plugins/coreplugin/icore.cpp
+++ b/src/plugins/coreplugin/icore.cpp
@@ -476,15 +476,30 @@ QString ICore::clangIncludeDirectory(const QString &clangVersion, const QString
return QDir::toNativeSeparators(dir.canonicalPath());
}
-QString ICore::clangExecutable(const QString &clangBinDirectory)
+static QString clangBinary(const QString &binaryBaseName, const QString &clangBinDirectory)
{
const QString hostExeSuffix(QTC_HOST_EXE_SUFFIX);
- QFileInfo executable(libexecPath() + "/clang/bin/clang" + hostExeSuffix);
+ QFileInfo executable(ICore::libexecPath() + "/clang/bin/" + binaryBaseName + hostExeSuffix);
if (!executable.exists())
- executable = QFileInfo(clangBinDirectory + "/clang" + hostExeSuffix);
+ executable = QFileInfo(clangBinDirectory + "/" + binaryBaseName + hostExeSuffix);
return QDir::toNativeSeparators(executable.canonicalFilePath());
}
+QString ICore::clangExecutable(const QString &clangBinDirectory)
+{
+ return clangBinary("clang", clangBinDirectory);
+}
+
+QString ICore::clangTidyExecutable(const QString &clangBinDirectory)
+{
+ return clangBinary("clang-tidy", clangBinDirectory);
+}
+
+QString ICore::clazyStandaloneExecutable(const QString &clangBinDirectory)
+{
+ return clangBinary("clazy-standalone", clangBinDirectory);
+}
+
static QString compilerString()
{
#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
@@ -561,6 +576,11 @@ QStatusBar *ICore::statusBar()
return m_mainwindow->statusBar();
}
+InfoBar *ICore::infoBar()
+{
+ return m_mainwindow->infoBar();
+}
+
void ICore::raiseWindow(QWidget *widget)
{
if (!widget)
diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h
index 04d501e134..b338839110 100644
--- a/src/plugins/coreplugin/icore.h
+++ b/src/plugins/coreplugin/icore.h
@@ -43,9 +43,10 @@ template <typename T> class QList;
QT_END_NAMESPACE
namespace Core {
-class IWizardFactory;
class Context;
class IContext;
+class InfoBar;
+class IWizardFactory;
class SettingsDatabase;
namespace Internal { class MainWindow; }
@@ -98,6 +99,8 @@ public:
static QString installerResourcePath();
static QString libexecPath();
static QString clangExecutable(const QString &clangBinDirectory);
+ static QString clangTidyExecutable(const QString &clangBinDirectory);
+ static QString clazyStandaloneExecutable(const QString &clangBinDirectory);
static QString clangIncludeDirectory(const QString &clangVersion,
const QString &clangResourceDirectory);
@@ -107,6 +110,8 @@ public:
static QMainWindow *mainWindow();
static QWidget *dialogParent();
static QStatusBar *statusBar();
+ static InfoBar *infoBar();
+
/* Raises and activates the window for the widget. This contains workarounds for X11. */
static void raiseWindow(QWidget *widget);
diff --git a/src/plugins/coreplugin/infobar.cpp b/src/plugins/coreplugin/infobar.cpp
index a81a8834d5..93f051e158 100644
--- a/src/plugins/coreplugin/infobar.cpp
+++ b/src/plugins/coreplugin/infobar.cpp
@@ -30,7 +30,6 @@
#include <utils/theme/theme.h>
#include <utils/utilsicons.h>
-#include <QFrame>
#include <QHBoxLayout>
#include <QSettings>
#include <QVBoxLayout>
@@ -48,7 +47,7 @@ QSet<Id> InfoBar::globallySuppressed;
QSettings *InfoBar::m_settings = nullptr;
Utils::Theme *InfoBar::m_theme = nullptr;
-InfoBarEntry::InfoBarEntry(Id _id, const QString &_infoText, GlobalSuppressionMode _globalSuppression)
+InfoBarEntry::InfoBarEntry(Id _id, const QString &_infoText, GlobalSuppression _globalSuppression)
: m_id(_id)
, m_infoText(_infoText)
, m_globalSuppression(_globalSuppression)
@@ -207,6 +206,17 @@ void InfoBarDisplay::setInfoBar(InfoBar *infoBar)
update();
}
+void InfoBarDisplay::setStyle(QFrame::Shadow style)
+{
+ m_style = style;
+ update();
+}
+
+InfoBar *InfoBarDisplay::infoBar() const
+{
+ return m_infoBar;
+}
+
void InfoBarDisplay::infoBarDestroyed()
{
m_infoBar = nullptr;
@@ -236,15 +246,15 @@ void InfoBarDisplay::update()
}
infoWidget->setPalette(pal);
- infoWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
+ infoWidget->setFrameStyle(QFrame::Panel | m_style);
infoWidget->setLineWidth(1);
infoWidget->setAutoFillBackground(true);
auto hbox = new QHBoxLayout;
- hbox->setMargin(2);
+ hbox->setContentsMargins(2, 2, 2, 2);
auto vbox = new QVBoxLayout(infoWidget);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
vbox->addLayout(hbox);
QLabel *infoWidgetLabel = new QLabel(info.m_infoText);
@@ -297,7 +307,7 @@ void InfoBarDisplay::update()
const Id id = info.m_id;
QToolButton *infoWidgetSuppressButton = nullptr;
- if (info.m_globalSuppression == InfoBarEntry::GlobalSuppressionEnabled) {
+ if (info.m_globalSuppression == InfoBarEntry::GlobalSuppression::Enabled) {
infoWidgetSuppressButton = new QToolButton;
infoWidgetSuppressButton->setText(tr("Do Not Show Again"));
connect(infoWidgetSuppressButton, &QAbstractButton::clicked, this, [this, id] {
diff --git a/src/plugins/coreplugin/infobar.h b/src/plugins/coreplugin/infobar.h
index 74a0f8136f..5f0a7472bd 100644
--- a/src/plugins/coreplugin/infobar.h
+++ b/src/plugins/coreplugin/infobar.h
@@ -28,6 +28,7 @@
#include "core_global.h"
#include <coreplugin/id.h>
+#include <QFrame>
#include <QObject>
#include <QSet>
@@ -48,13 +49,13 @@ class InfoBarDisplay;
class CORE_EXPORT InfoBarEntry
{
public:
- enum GlobalSuppressionMode
+ enum class GlobalSuppression
{
- GlobalSuppressionDisabled,
- GlobalSuppressionEnabled
+ Disabled,
+ Enabled
};
- InfoBarEntry(Id _id, const QString &_infoText, GlobalSuppressionMode _globalSuppression = GlobalSuppressionDisabled);
+ InfoBarEntry(Id _id, const QString &_infoText, GlobalSuppression _globalSuppression = GlobalSuppression::Disabled);
using CallBack = std::function<void()>;
void setCustomButtonInfo(const QString &_buttonText, CallBack callBack);
@@ -74,7 +75,7 @@ private:
CallBack m_buttonCallBack;
QString m_cancelButtonText;
CallBack m_cancelButtonCallBack;
- GlobalSuppressionMode m_globalSuppression;
+ GlobalSuppression m_globalSuppression;
DetailsWidgetCreator m_detailsWidgetCreator;
bool m_useCancelButton = true;
ComboCallBack m_comboCallBack;
@@ -127,6 +128,9 @@ public:
InfoBarDisplay(QObject *parent = nullptr);
void setTarget(QBoxLayout *layout, int index);
void setInfoBar(InfoBar *infoBar);
+ void setStyle(QFrame::Shadow style);
+
+ InfoBar *infoBar() const;
private:
void update();
@@ -136,6 +140,7 @@ private:
QList<QWidget *> m_infoWidgets;
InfoBar *m_infoBar = nullptr;
QBoxLayout *m_boxLayout = nullptr;
+ QFrame::Shadow m_style = QFrame::Raised;
int m_boxIndex = 0;
bool m_isShowingDetailsWidget = false;
};
diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp
index 3bc7ddd6f8..b8d9582834 100644
--- a/src/plugins/coreplugin/iversioncontrol.cpp
+++ b/src/plugins/coreplugin/iversioncontrol.cpp
@@ -26,9 +26,12 @@
#include "iversioncontrol.h"
#include "vcsmanager.h"
+#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
+#include <QDir>
#include <QFileInfo>
+#include <QRegularExpression>
#include <QStringList>
/*!
@@ -83,13 +86,57 @@ ShellCommand *IVersionControl::createInitialCheckoutCommand(const QString &url,
const QString &localName,
const QStringList &extraArgs)
{
- Q_UNUSED(url);
- Q_UNUSED(baseDirectory);
- Q_UNUSED(localName);
- Q_UNUSED(extraArgs);
+ Q_UNUSED(url)
+ Q_UNUSED(baseDirectory)
+ Q_UNUSED(localName)
+ Q_UNUSED(extraArgs)
return nullptr;
}
+IVersionControl::RepoUrl::RepoUrl(const QString &location)
+{
+ if (location.isEmpty())
+ return;
+
+ // Check for local remotes (refer to the root or relative path)
+ // On Windows, local paths typically starts with <drive>:
+ auto locationIsOnWindowsDrive = [&location] {
+ if (!Utils::HostOsInfo::isWindowsHost() || location.size() < 2)
+ return false;
+ const QChar drive = location.at(0).toLower();
+ return drive >= 'a' && drive <= 'z' && location.at(1) == ':';
+ };
+ if (location.startsWith("file://") || location.startsWith('/') || location.startsWith('.')
+ || locationIsOnWindowsDrive()) {
+ protocol = "file";
+ path = QDir::fromNativeSeparators(location.startsWith("file://")
+ ? location.mid(7) : location);
+ isValid = true;
+ return;
+ }
+
+ // TODO: Why not use QUrl?
+ static const QRegularExpression remotePattern(
+ "^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)"
+ "(?::(?<port>\\d+))?:?(?<path>.*)$");
+ const QRegularExpressionMatch match = remotePattern.match(location);
+ if (!match.hasMatch())
+ return;
+
+ bool ok = false;
+ protocol = match.captured("protocol");
+ userName = match.captured("user");
+ host = match.captured("host");
+ port = match.captured("port").toUShort(&ok);
+ path = match.captured("path");
+ isValid = !host.isEmpty() && (ok || match.captured("port").isEmpty());
+}
+
+IVersionControl::RepoUrl IVersionControl::getRepoUrl(const QString &location) const
+{
+ return RepoUrl(location);
+}
+
QString IVersionControl::vcsTopic(const QString &topLevel)
{
return m_topicCache ? m_topicCache->topic(topLevel) : QString();
@@ -102,7 +149,7 @@ IVersionControl::~IVersionControl()
IVersionControl::OpenSupportMode IVersionControl::openSupportMode(const QString &fileName) const
{
- Q_UNUSED(fileName);
+ Q_UNUSED(fileName)
return NoOpen;
}
diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h
index 0846793b5a..5838a03e39 100644
--- a/src/plugins/coreplugin/iversioncontrol.h
+++ b/src/plugins/coreplugin/iversioncontrol.h
@@ -217,6 +217,19 @@ public:
const QString &localName,
const QStringList &extraArgs);
+ class CORE_EXPORT RepoUrl {
+ public:
+ RepoUrl(const QString &location);
+
+ QString protocol;
+ QString userName;
+ QString host;
+ QString path;
+ quint16 port = 0;
+ bool isValid = false;
+ };
+ virtual RepoUrl getRepoUrl(const QString &location) const;
+
signals:
void repositoryChanged(const QString &repository);
void filesChanged(const QStringList &files);
@@ -246,7 +259,7 @@ public:
~TestVersionControl() override;
bool isVcsFileOrDirectory(const Utils::FilePath &fileName) const final
- { Q_UNUSED(fileName); return false; }
+ { Q_UNUSED(fileName) return false; }
void setManagedDirectories(const QHash<QString, QString> &dirs);
void setManagedFiles(const QSet<QString> &files);
diff --git a/src/plugins/coreplugin/iwelcomepage.cpp b/src/plugins/coreplugin/iwelcomepage.cpp
index 0f93bb1f3b..3858294133 100644
--- a/src/plugins/coreplugin/iwelcomepage.cpp
+++ b/src/plugins/coreplugin/iwelcomepage.cpp
@@ -64,31 +64,28 @@ static QPalette buttonPalette(bool isActive, bool isCursorInside, bool forText)
Theme *theme = Utils::creatorTheme();
if (isActive) {
if (forText) {
- pal.setColor(QPalette::Background, theme->color(Theme::Welcome_ForegroundPrimaryColor));
- pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundPrimaryColor));
+ pal.setColor(QPalette::Window, theme->color(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_BackgroundColor));
} else {
- pal.setColor(QPalette::Background, theme->color(Theme::Welcome_ForegroundPrimaryColor));
- pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundPrimaryColor));
+ pal.setColor(QPalette::Window, theme->color(Theme::Welcome_ForegroundPrimaryColor));
+ pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_ForegroundPrimaryColor));
}
} else {
if (isCursorInside) {
if (forText) {
- pal.setColor(QPalette::Background, theme->color(Theme::Welcome_HoverColor));
- pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_HoverColor));
+ pal.setColor(QPalette::Window, theme->color(Theme::Welcome_HoverColor));
pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_TextColor));
} else {
- pal.setColor(QPalette::Background, theme->color(Theme::Welcome_HoverColor));
- pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundSecondaryColor));
+ pal.setColor(QPalette::Window, theme->color(Theme::Welcome_HoverColor));
+ pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_ForegroundSecondaryColor));
}
} else {
if (forText) {
- pal.setColor(QPalette::Background, theme->color(Theme::Welcome_ForegroundPrimaryColor));
- pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_BackgroundColor));
+ pal.setColor(QPalette::Window, theme->color(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_TextColor));
} else {
- pal.setColor(QPalette::Background, theme->color(Theme::Welcome_BackgroundColor));
- pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundSecondaryColor));
+ pal.setColor(QPalette::Window, theme->color(Theme::Welcome_BackgroundColor));
+ pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_ForegroundSecondaryColor));
}
}
}
diff --git a/src/plugins/coreplugin/locator/basefilefilter.cpp b/src/plugins/coreplugin/locator/basefilefilter.cpp
index e2b26b57ae..9f900b7500 100644
--- a/src/plugins/coreplugin/locator/basefilefilter.cpp
+++ b/src/plugins/coreplugin/locator/basefilefilter.cpp
@@ -34,7 +34,6 @@
#include <QRegularExpression>
#include <QTimer>
-using namespace Core;
using namespace Utils;
namespace Core {
@@ -47,13 +46,11 @@ public:
{
iterator.clear();
previousResultPaths.clear();
- previousResultNames.clear();
previousEntry.clear();
}
QSharedPointer<BaseFileFilter::Iterator> iterator;
- QStringList previousResultPaths;
- QStringList previousResultNames;
+ FilePathList previousResultPaths;
bool forceNewSearchList;
QString previousEntry;
};
@@ -66,7 +63,6 @@ public:
};
} // Internal
-} // Core
BaseFileFilter::Iterator::~Iterator() = default;
@@ -74,7 +70,7 @@ BaseFileFilter::BaseFileFilter()
: d(new Internal::BaseFileFilterPrivate)
{
d->m_data.forceNewSearchList = true;
- setFileIterator(new ListIterator(QStringList()));
+ setFileIterator(new ListIterator({}));
}
BaseFileFilter::~BaseFileFilter()
@@ -87,53 +83,55 @@ void BaseFileFilter::prepareSearch(const QString &entry)
Q_UNUSED(entry)
d->m_current.iterator = d->m_data.iterator;
d->m_current.previousResultPaths = d->m_data.previousResultPaths;
- d->m_current.previousResultNames = d->m_data.previousResultNames;
d->m_current.forceNewSearchList = d->m_data.forceNewSearchList;
d->m_current.previousEntry = d->m_data.previousEntry;
d->m_data.forceNewSearchList = false;
}
-static int matchLevelFor(const QRegularExpressionMatch &match, const QString &matchText)
+ILocatorFilter::MatchLevel BaseFileFilter::matchLevelFor(const QRegularExpressionMatch &match,
+ const QString &matchText) const
{
const int consecutivePos = match.capturedStart(1);
if (consecutivePos == 0)
- return 0;
+ return MatchLevel::Best;
if (consecutivePos > 0) {
const QChar prevChar = matchText.at(consecutivePos - 1);
if (prevChar == '_' || prevChar == '.')
- return 1;
+ return MatchLevel::Better;
}
if (match.capturedStart() == 0)
- return 2;
- return 3;
+ return MatchLevel::Good;
+ return MatchLevel::Normal;
}
QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &origEntry)
{
- QList<LocatorFilterEntry> entries[4];
- const QString entry = QDir::fromNativeSeparators(origEntry);
+ QList<LocatorFilterEntry> entries[int(MatchLevel::Count)];
+ // If search string contains spaces, treat them as wildcard '*' and search in full path
+ const QString entry = QDir::fromNativeSeparators(origEntry).replace(' ', '*');
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
const QRegularExpression regexp = createRegExp(fp.filePath);
if (!regexp.isValid()) {
d->m_current.clear(); // free memory
- return entries[0];
+ return {};
}
- const QChar pathSeparator('/');
- const bool hasPathSeparator = fp.filePath.contains(pathSeparator);
+ auto containsPathSeparator = [](const QString &candidate) {
+ return candidate.contains('/') || candidate.contains('*');
+ };
+
+ const bool hasPathSeparator = containsPathSeparator(fp.filePath);
const bool containsPreviousEntry = !d->m_current.previousEntry.isEmpty()
&& fp.filePath.contains(d->m_current.previousEntry);
- const bool pathSeparatorAdded = !d->m_current.previousEntry.contains(pathSeparator)
- && fp.filePath.contains(pathSeparator);
+ const bool pathSeparatorAdded = !containsPathSeparator(d->m_current.previousEntry)
+ && hasPathSeparator;
const bool searchInPreviousResults = !d->m_current.forceNewSearchList && containsPreviousEntry
&& !pathSeparatorAdded;
if (searchInPreviousResults)
- d->m_current.iterator.reset(new ListIterator(d->m_current.previousResultPaths,
- d->m_current.previousResultNames));
+ d->m_current.iterator.reset(new ListIterator(d->m_current.previousResultPaths));
QTC_ASSERT(d->m_current.iterator.data(), return QList<LocatorFilterEntry>());
d->m_current.previousResultPaths.clear();
- d->m_current.previousResultNames.clear();
d->m_current.previousEntry = fp.filePath;
d->m_current.iterator->toFront();
bool canceled = false;
@@ -144,18 +142,17 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
}
d->m_current.iterator->next();
- QString path = d->m_current.iterator->filePath();
- QString name = d->m_current.iterator->fileName();
- QString matchText = hasPathSeparator ? path : name;
+ FilePath path = d->m_current.iterator->filePath();
+ QString matchText = hasPathSeparator ? path.toString() : path.fileName();
QRegularExpressionMatch match = regexp.match(matchText);
if (match.hasMatch()) {
- QFileInfo fi(path);
- LocatorFilterEntry filterEntry(this, fi.fileName(), QString(path + fp.postfix));
- filterEntry.fileName = path;
+ QFileInfo fi(path.toString());
+ LocatorFilterEntry filterEntry(this, fi.fileName(), QString(path.toString() + fp.postfix));
+ filterEntry.fileName = path.toString();
filterEntry.extraInfo = FilePath::fromFileInfo(fi).shortNativePath();
- const int matchLevel = matchLevelFor(match, matchText);
+ const MatchLevel matchLevel = matchLevelFor(match, matchText);
if (hasPathSeparator) {
match = regexp.match(filterEntry.extraInfo);
filterEntry.highlightInfo =
@@ -164,9 +161,8 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
filterEntry.highlightInfo = highlightInfo(match);
}
- entries[matchLevel].append(filterEntry);
+ entries[int(matchLevel)].append(filterEntry);
d->m_current.previousResultPaths.append(path);
- d->m_current.previousResultNames.append(name);
}
}
@@ -185,7 +181,7 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFil
Utils::sort(entry, Core::LocatorFilterEntry::compareLexigraphically);
}
- return entries[0] + entries[1] + entries[2] + entries[3];
+ return std::accumulate(std::begin(entries), std::end(entries), QList<LocatorFilterEntry>());
}
void BaseFileFilter::accept(LocatorFilterEntry selection,
@@ -221,32 +217,18 @@ void BaseFileFilter::updatePreviousResultData()
return; // do not update with the new result list etc
d->m_data.previousEntry = d->m_current.previousEntry;
d->m_data.previousResultPaths = d->m_current.previousResultPaths;
- d->m_data.previousResultNames = d->m_current.previousResultNames;
// forceNewSearchList was already reset in prepareSearch
}
-BaseFileFilter::ListIterator::ListIterator(const QStringList &filePaths)
+BaseFileFilter::ListIterator::ListIterator(const FilePathList &filePaths)
{
m_filePaths = filePaths;
- for (const QString &path : filePaths) {
- QFileInfo fi(path);
- m_fileNames.append(fi.fileName());
- }
- toFront();
-}
-
-BaseFileFilter::ListIterator::ListIterator(const QStringList &filePaths,
- const QStringList &fileNames)
-{
- m_filePaths = filePaths;
- m_fileNames = fileNames;
toFront();
}
void BaseFileFilter::ListIterator::toFront()
{
m_pathPosition = m_filePaths.constBegin() - 1;
- m_namePosition = m_fileNames.constBegin() - 1;
}
bool BaseFileFilter::ListIterator::hasNext() const
@@ -255,25 +237,18 @@ bool BaseFileFilter::ListIterator::hasNext() const
return m_pathPosition + 1 != m_filePaths.constEnd();
}
-QString BaseFileFilter::ListIterator::next()
+FilePath BaseFileFilter::ListIterator::next()
{
- QTC_ASSERT(m_pathPosition != m_filePaths.constEnd(), return QString());
- QTC_ASSERT(m_namePosition != m_fileNames.constEnd(), return QString());
+ QTC_ASSERT(m_pathPosition != m_filePaths.constEnd(), return {});
++m_pathPosition;
- ++m_namePosition;
- QTC_ASSERT(m_pathPosition != m_filePaths.constEnd(), return QString());
- QTC_ASSERT(m_namePosition != m_fileNames.constEnd(), return QString());
+ QTC_ASSERT(m_pathPosition != m_filePaths.constEnd(), return {});
return *m_pathPosition;
}
-QString BaseFileFilter::ListIterator::filePath() const
+FilePath BaseFileFilter::ListIterator::filePath() const
{
- QTC_ASSERT(m_pathPosition != m_filePaths.constEnd(), return QString());
+ QTC_ASSERT(m_pathPosition != m_filePaths.constEnd(), return {});
return *m_pathPosition;
}
-QString BaseFileFilter::ListIterator::fileName() const
-{
- QTC_ASSERT(m_namePosition != m_fileNames.constEnd(), return QString());
- return *m_namePosition;
-}
+} // Core
diff --git a/src/plugins/coreplugin/locator/basefilefilter.h b/src/plugins/coreplugin/locator/basefilefilter.h
index 1f98cd4a5e..9c538037eb 100644
--- a/src/plugins/coreplugin/locator/basefilefilter.h
+++ b/src/plugins/coreplugin/locator/basefilefilter.h
@@ -27,8 +27,9 @@
#include "ilocatorfilter.h"
+#include <utils/fileutils.h>
+
#include <QSharedPointer>
-#include <QStringList>
namespace Core {
@@ -44,27 +45,22 @@ public:
virtual ~Iterator();
virtual void toFront() = 0;
virtual bool hasNext() const = 0;
- virtual QString next() = 0;
- virtual QString filePath() const = 0;
- virtual QString fileName() const = 0;
+ virtual Utils::FilePath next() = 0;
+ virtual Utils::FilePath filePath() const = 0;
};
class CORE_EXPORT ListIterator : public Iterator {
public:
- ListIterator(const QStringList &filePaths);
- ListIterator(const QStringList &filePaths, const QStringList &fileNames);
+ ListIterator(const Utils::FilePathList &filePaths);
void toFront() override;
bool hasNext() const override;
- QString next() override;
- QString filePath() const override;
- QString fileName() const override;
+ Utils::FilePath next() override;
+ Utils::FilePath filePath() const override;
private:
- QStringList m_filePaths;
- QStringList m_fileNames;
- QStringList::const_iterator m_pathPosition;
- QStringList::const_iterator m_namePosition;
+ Utils::FilePathList m_filePaths;
+ Utils::FilePathList::const_iterator m_pathPosition;
};
BaseFileFilter();
@@ -80,6 +76,7 @@ protected:
QSharedPointer<Iterator> fileIterator();
private:
+ MatchLevel matchLevelFor(const QRegularExpressionMatch &match, const QString &matchText) const;
void updatePreviousResultData();
Internal::BaseFileFilterPrivate *d = nullptr;
diff --git a/src/plugins/coreplugin/locator/directoryfilter.cpp b/src/plugins/coreplugin/locator/directoryfilter.cpp
index 02e7e59fe9..559d3de665 100644
--- a/src/plugins/coreplugin/locator/directoryfilter.cpp
+++ b/src/plugins/coreplugin/locator/directoryfilter.cpp
@@ -56,7 +56,7 @@ QByteArray DirectoryFilter::saveState() const
out << m_filters;
out << shortcutString();
out << isIncludedByDefault();
- out << m_files;
+ out << Utils::transform(m_files, &Utils::FilePath::toString);
out << m_exclusionFilters;
return value;
}
@@ -69,6 +69,7 @@ void DirectoryFilter::restoreState(const QByteArray &state)
QStringList directories;
QString shortcut;
bool defaultFilter;
+ QStringList files;
QDataStream in(state);
in >> name;
@@ -76,7 +77,8 @@ void DirectoryFilter::restoreState(const QByteArray &state)
in >> m_filters;
in >> shortcut;
in >> defaultFilter;
- in >> m_files;
+ in >> files;
+ m_files = Utils::transform(files, &Utils::FilePath::fromString);
if (!in.atEnd()) // Qt Creator 4.3 and later
in >> m_exclusionFilters;
else
@@ -231,12 +233,12 @@ void DirectoryFilter::refresh(QFutureInterface<void> &future)
}
Utils::SubDirFileIterator subDirIterator(directories, m_filters, m_exclusionFilters);
future.setProgressRange(0, subDirIterator.maxProgress());
- QStringList filesFound;
+ Utils::FilePathList filesFound;
auto end = subDirIterator.end();
for (auto it = subDirIterator.begin(); it != end; ++it) {
if (future.isCanceled())
break;
- filesFound << (*it).filePath;
+ filesFound << Utils::FilePath::fromString((*it).filePath);
if (future.isProgressUpdateNeeded()
|| future.progressValue() == 0 /*workaround for regression in Qt*/) {
future.setProgressValueAndText(subDirIterator.currentProgress(),
diff --git a/src/plugins/coreplugin/locator/directoryfilter.h b/src/plugins/coreplugin/locator/directoryfilter.h
index 803141afdb..b8a1871ce3 100644
--- a/src/plugins/coreplugin/locator/directoryfilter.h
+++ b/src/plugins/coreplugin/locator/directoryfilter.h
@@ -77,7 +77,7 @@ private:
QDialog *m_dialog = nullptr;
Internal::Ui::DirectoryFilterOptions *m_ui = nullptr;
mutable QMutex m_lock;
- QStringList m_files;
+ Utils::FilePathList m_files;
bool m_isCustomFilter = true;
};
diff --git a/src/plugins/coreplugin/locator/executefilter.cpp b/src/plugins/coreplugin/locator/executefilter.cpp
index bc4a4b65a7..f98beae687 100644
--- a/src/plugins/coreplugin/locator/executefilter.cpp
+++ b/src/plugins/coreplugin/locator/executefilter.cpp
@@ -169,7 +169,7 @@ void ExecuteFilter::runHeadCommand()
}
MessageManager::write(tr("Starting command \"%1\".").arg(headCommand()));
m_process->setWorkingDirectory(d.workingDirectory);
- m_process->setCommand(Utils::CommandLine(fullPath, d.arguments));
+ m_process->setCommand({fullPath, d.arguments, Utils::CommandLine::Raw});
m_process->start();
m_process->closeWriteChannel();
if (!m_process->waitForStarted(1000)) {
diff --git a/src/plugins/coreplugin/locator/filesystemfilter.cpp b/src/plugins/coreplugin/locator/filesystemfilter.cpp
index 0719e9b781..5e04215539 100644
--- a/src/plugins/coreplugin/locator/filesystemfilter.cpp
+++ b/src/plugins/coreplugin/locator/filesystemfilter.cpp
@@ -35,30 +35,27 @@
#include <utils/fileutils.h>
#include <QDir>
+#include <QRegularExpression>
using namespace Core;
using namespace Core::Internal;
-namespace {
-
-QList<LocatorFilterEntry> *categorize(const QString &entry, const QString &candidate,
- Qt::CaseSensitivity caseSensitivity,
- QList<LocatorFilterEntry> *betterEntries, QList<LocatorFilterEntry> *goodEntries,
- int *index)
+ILocatorFilter::MatchLevel FileSystemFilter::matchLevelFor(const QRegularExpressionMatch &match,
+ const QString &matchText) const
{
- const int position = candidate.indexOf(entry, 0, caseSensitivity);
- if (index)
- *index = position;
-
- if (entry.isEmpty() || position == 0)
- return betterEntries;
- if (position >= 0)
- return goodEntries;
- return nullptr;
+ const int consecutivePos = match.capturedStart(1);
+ if (consecutivePos == 0)
+ return MatchLevel::Best;
+ if (consecutivePos > 0) {
+ const QChar prevChar = matchText.at(consecutivePos - 1);
+ if (prevChar == '_' || prevChar == '.')
+ return MatchLevel::Better;
+ }
+ if (match.capturedStart() == 0)
+ return MatchLevel::Good;
+ return MatchLevel::Normal;
}
-} // anynoumous namespace
-
FileSystemFilter::FileSystemFilter()
{
setId("Files in file system");
@@ -76,8 +73,7 @@ void FileSystemFilter::prepareSearch(const QString &entry)
QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry)
{
- QList<LocatorFilterEntry> goodEntries;
- QList<LocatorFilterEntry> betterEntries;
+ QList<LocatorFilterEntry> entries[int(MatchLevel::Count)];
const QFileInfo entryInfo(entry);
const QString entryFileName = entryInfo.fileName();
QString directory = entryInfo.path();
@@ -97,25 +93,28 @@ QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorF
// use only 'name' for case sensitivity decision, because we need to make the path
// match the case on the file system for case-sensitive file systems
const Qt::CaseSensitivity caseSensitivity_ = caseSensitivity(entryFileName);
- QStringList dirs = dirInfo.entryList(dirFilter,
- QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
+ const QStringList dirs = QStringList("..")
+ + dirInfo.entryList(dirFilter, QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
const QStringList files = dirInfo.entryList(fileFilter,
QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
- dirs.prepend("..");
- for (const QString &dir : qAsConst(dirs)) {
+ const QRegularExpression regExp = createRegExp(entryFileName, caseSensitivity_);
+ if (!regExp.isValid())
+ return {};
+
+ for (const QString &dir : dirs) {
if (future.isCanceled())
break;
- int index = -1;
- if (QList<LocatorFilterEntry> *category = categorize(entryFileName, dir, caseSensitivity_,
- &betterEntries, &goodEntries, &index)) {
+
+ const QRegularExpressionMatch match = regExp.match(dir);
+ if (match.hasMatch()) {
+ const MatchLevel level = matchLevelFor(match, dir);
const QString fullPath = dirInfo.filePath(dir);
LocatorFilterEntry filterEntry(this, dir, QVariant());
filterEntry.fileName = fullPath;
- if (index >= 0)
- filterEntry.highlightInfo = {index, entryFileName.length()};
+ filterEntry.highlightInfo = highlightInfo(match);
- category->append(filterEntry);
+ entries[int(level)].append(filterEntry);
}
}
// file names can match with +linenumber or :linenumber
@@ -124,29 +123,29 @@ QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<LocatorF
for (const QString &file : files) {
if (future.isCanceled())
break;
- int index = -1;
- if (QList<LocatorFilterEntry> *category = categorize(fileName, file, caseSensitivity_,
- &betterEntries, &goodEntries, &index)) {
+
+ const QRegularExpressionMatch match = regExp.match(file);
+ if (match.hasMatch()) {
+ const MatchLevel level = matchLevelFor(match, file);
const QString fullPath = dirInfo.filePath(file);
LocatorFilterEntry filterEntry(this, file, QString(fullPath + fp.postfix));
filterEntry.fileName = fullPath;
- if (index >= 0)
- filterEntry.highlightInfo = {index, fileName.length()};
+ filterEntry.highlightInfo = highlightInfo(match);
- category->append(filterEntry);
+ entries[int(level)].append(filterEntry);
}
}
- betterEntries.append(goodEntries);
// "create and open" functionality
const QString fullFilePath = dirInfo.filePath(fileName);
- if (!QFileInfo::exists(fullFilePath) && dirInfo.exists()) {
+ const bool containsWildcard = entry.contains('?') || entry.contains('*');
+ if (!containsWildcard && !QFileInfo::exists(fullFilePath) && dirInfo.exists()) {
LocatorFilterEntry createAndOpen(this, tr("Create and Open \"%1\"").arg(entry), fullFilePath);
createAndOpen.extraInfo = Utils::FilePath::fromString(dirInfo.absolutePath()).shortNativePath();
- betterEntries.append(createAndOpen);
+ entries[int(MatchLevel::Normal)].append(createAndOpen);
}
- return betterEntries;
+ return std::accumulate(std::begin(entries), std::end(entries), QList<LocatorFilterEntry>());
}
void FileSystemFilter::accept(LocatorFilterEntry selection,
diff --git a/src/plugins/coreplugin/locator/filesystemfilter.h b/src/plugins/coreplugin/locator/filesystemfilter.h
index abca3ed67a..a139106083 100644
--- a/src/plugins/coreplugin/locator/filesystemfilter.h
+++ b/src/plugins/coreplugin/locator/filesystemfilter.h
@@ -53,6 +53,8 @@ public:
void refresh(QFutureInterface<void> &) override {}
private:
+ MatchLevel matchLevelFor(const QRegularExpressionMatch &match, const QString &matchText) const;
+
bool m_includeHidden = true;
QString m_currentDocumentDirectory;
};
diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp
index 857f886fb4..df49721d3f 100644
--- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp
+++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp
@@ -207,9 +207,9 @@ Qt::CaseSensitivity ILocatorFilter::caseSensitivity(const QString &str)
return str == str.toLower() ? Qt::CaseInsensitive : Qt::CaseSensitive;
}
-QRegularExpression ILocatorFilter::createRegExp(const QString &text)
+QRegularExpression ILocatorFilter::createRegExp(const QString &text, Qt::CaseSensitivity caseSensitivity)
{
- return FuzzyMatcher::createRegExp(text);
+ return FuzzyMatcher::createRegExp(text, caseSensitivity);
}
LocatorFilterEntry::HighlightInfo ILocatorFilter::highlightInfo(
diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h
index ecb47eaae2..b98e8f9691 100644
--- a/src/plugins/coreplugin/locator/ilocatorfilter.h
+++ b/src/plugins/coreplugin/locator/ilocatorfilter.h
@@ -105,6 +105,14 @@ class CORE_EXPORT ILocatorFilter : public QObject
Q_OBJECT
public:
+ enum class MatchLevel {
+ Best = 0,
+ Better,
+ Good,
+ Normal,
+ Count
+ };
+
enum Priority {Highest = 0, High = 1, Medium = 2, Low = 3};
ILocatorFilter(QObject *parent = nullptr);
@@ -145,7 +153,8 @@ public:
bool isEnabled() const;
static Qt::CaseSensitivity caseSensitivity(const QString &str);
- static QRegularExpression createRegExp(const QString &text);
+ static QRegularExpression createRegExp(const QString &text,
+ Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive);
LocatorFilterEntry::HighlightInfo highlightInfo(const QRegularExpressionMatch &match,
LocatorFilterEntry::HighlightInfo::DataType dataType = LocatorFilterEntry::HighlightInfo::DisplayName);
diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp
index 58a119047b..ab6727b8a2 100644
--- a/src/plugins/coreplugin/locator/javascriptfilter.cpp
+++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp
@@ -59,7 +59,7 @@ JavaScriptFilter::~JavaScriptFilter()
void JavaScriptFilter::prepareSearch(const QString &entry)
{
- Q_UNUSED(entry);
+ Q_UNUSED(entry)
if (!m_engine)
setupEngine();
@@ -70,7 +70,7 @@ void JavaScriptFilter::prepareSearch(const QString &entry)
QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry)
{
- Q_UNUSED(future);
+ Q_UNUSED(future)
QList<LocatorFilterEntry> entries;
if (entry.trimmed().isEmpty()) {
@@ -94,9 +94,9 @@ QList<LocatorFilterEntry> JavaScriptFilter::matchesFor(
void JavaScriptFilter::accept(Core::LocatorFilterEntry selection, QString *newText,
int *selectionStart, int *selectionLength) const
{
- Q_UNUSED(newText);
- Q_UNUSED(selectionStart);
- Q_UNUSED(selectionLength);
+ Q_UNUSED(newText)
+ Q_UNUSED(selectionStart)
+ Q_UNUSED(selectionLength)
if (selection.internalData.isNull())
return;
@@ -112,7 +112,7 @@ void JavaScriptFilter::accept(Core::LocatorFilterEntry selection, QString *newTe
void JavaScriptFilter::refresh(QFutureInterface<void> &future)
{
- Q_UNUSED(future);
+ Q_UNUSED(future)
// Nothing to refresh
}
diff --git a/src/plugins/coreplugin/locator/locator_test.cpp b/src/plugins/coreplugin/locator/locator_test.cpp
index c76a5633ea..a0881d273b 100644
--- a/src/plugins/coreplugin/locator/locator_test.cpp
+++ b/src/plugins/coreplugin/locator/locator_test.cpp
@@ -45,7 +45,7 @@ QTC_DECLARE_MYTESTDATADIR("../../../../tests/locators/")
class MyBaseFileFilter : public Core::BaseFileFilter
{
public:
- MyBaseFileFilter(const QStringList &theFiles)
+ MyBaseFileFilter(const Utils::FilePathList &theFiles)
{
setFileIterator(new BaseFileFilter::ListIterator(theFiles));
}
@@ -74,7 +74,7 @@ void Core::Internal::CorePlugin::test_basefilefilter()
QFETCH(QStringList, testFiles);
QFETCH(QList<ReferenceData>, referenceDataList);
- MyBaseFileFilter filter(testFiles);
+ MyBaseFileFilter filter(Utils::transform(testFiles, &Utils::FilePath::fromString));
BasicLocatorFilterTest test(&filter);
for (const ReferenceData &reference : qAsConst(referenceDataList)) {
diff --git a/src/plugins/coreplugin/locator/locatorfiltertest.cpp b/src/plugins/coreplugin/locator/locatorfiltertest.cpp
index 6e24cc91fc..62108dc9d7 100644
--- a/src/plugins/coreplugin/locator/locatorfiltertest.cpp
+++ b/src/plugins/coreplugin/locator/locatorfiltertest.cpp
@@ -56,21 +56,38 @@ QList<LocatorFilterEntry> BasicLocatorFilterTest::matchesFor(const QString &sear
ResultData::ResultData() = default;
-ResultData::ResultData(const QString &textColumn1, const QString &textColumn2)
- : textColumn1(textColumn1), textColumn2(textColumn2)
+ResultData::ResultData(const QString &textColumn1, const QString &textColumn2,
+ const QString &highlightPositions)
+ : textColumn1(textColumn1), textColumn2(textColumn2), highlight(highlightPositions)
{
}
bool ResultData::operator==(const ResultData &other) const
{
- return textColumn1 == other.textColumn1 && textColumn2 == other.textColumn2;
+ const bool highlightEqual = highlight.isEmpty()
+ || other.highlight.isEmpty()
+ || highlight == other.highlight;
+
+ return textColumn1 == other.textColumn1 && textColumn2 == other.textColumn2 && highlightEqual;
}
ResultData::ResultDataList ResultData::fromFilterEntryList(const QList<LocatorFilterEntry> &entries)
{
ResultDataList result;
- for (const LocatorFilterEntry &entry : entries)
- result << ResultData(entry.displayName, entry.extraInfo);
+ for (const LocatorFilterEntry &entry : entries) {
+ ResultData data(entry.displayName, entry.extraInfo);
+ data.highlight = QString(entry.displayName.size(), QChar(' '));
+ for (int i = 0; i < entry.highlightInfo.starts.size(); ++i) {
+ const int start = entry.highlightInfo.starts.at(i);
+ const int length = entry.highlightInfo.lengths.at(i);
+ if (start < 0 || start + length > data.highlight.size())
+ break;
+ for (int j = 0; j < length; ++j)
+ data.highlight[start + j] = '~';
+ }
+ result << data;
+ }
+
return result;
}
diff --git a/src/plugins/coreplugin/locator/locatorfiltertest.h b/src/plugins/coreplugin/locator/locatorfiltertest.h
index 1b7a074bb7..de543f5e4f 100644
--- a/src/plugins/coreplugin/locator/locatorfiltertest.h
+++ b/src/plugins/coreplugin/locator/locatorfiltertest.h
@@ -54,7 +54,8 @@ public:
using ResultDataList = QList<ResultData>;
ResultData();
- ResultData(const QString &textColumn1, const QString &textColumn2);
+ ResultData(const QString &textColumn1, const QString &textColumn2,
+ const QString &highlightPositions = QString());
bool operator==(const ResultData &other) const;
@@ -65,6 +66,8 @@ public:
QString textColumn1;
QString textColumn2;
+ QString highlight;
+ LocatorFilterEntry::HighlightInfo::DataType dataType;
};
using ResultDataList = ResultData::ResultDataList;
@@ -80,7 +83,8 @@ namespace QTest {
template<> inline char *toString(const Core::Tests::ResultData &data)
{
- QByteArray ba = "\"" + data.textColumn1.toUtf8() + "\", \"" + data.textColumn2.toUtf8() + "\"";
+ const QByteArray ba = "\n\"" + data.textColumn1.toUtf8() + "\", \"" + data.textColumn2.toUtf8()
+ + "\"\n\"" + data.highlight.toUtf8() + "\"";
return qstrdup(ba.data());
}
diff --git a/src/plugins/coreplugin/locator/locatorsettingspage.cpp b/src/plugins/coreplugin/locator/locatorsettingspage.cpp
index 5e35f2058c..68b263a8d5 100644
--- a/src/plugins/coreplugin/locator/locatorsettingspage.cpp
+++ b/src/plugins/coreplugin/locator/locatorsettingspage.cpp
@@ -74,7 +74,7 @@ class CategoryItem : public TreeItem
public:
CategoryItem(const QString &name, int order);
QVariant data(int column, int role) const override;
- Qt::ItemFlags flags(int column) const override { Q_UNUSED(column); return Qt::ItemIsEnabled; }
+ Qt::ItemFlags flags(int column) const override { Q_UNUSED(column) return Qt::ItemIsEnabled; }
private:
QString m_name;
@@ -154,7 +154,7 @@ CategoryItem::CategoryItem(const QString &name, int order)
QVariant CategoryItem::data(int column, int role) const
{
- Q_UNUSED(column);
+ Q_UNUSED(column)
if (role == SortRole)
return m_order;
if (role == Qt::DisplayRole)
diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp
index b21afd2adc..e545b8313c 100644
--- a/src/plugins/coreplugin/locator/locatorwidget.cpp
+++ b/src/plugins/coreplugin/locator/locatorwidget.cpp
@@ -558,7 +558,7 @@ LocatorWidget::LocatorWidget(Locator *locator) :
auto layout = new QHBoxLayout(this);
setLayout(layout);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_fileLineEdit);
const QIcon icon = Utils::Icons::MAGNIFIER.icon();
diff --git a/src/plugins/coreplugin/locator/spotlightlocatorfilter.mm b/src/plugins/coreplugin/locator/spotlightlocatorfilter.mm
index f8cdd8189e..c3c3833a8f 100644
--- a/src/plugins/coreplugin/locator/spotlightlocatorfilter.mm
+++ b/src/plugins/coreplugin/locator/spotlightlocatorfilter.mm
@@ -50,13 +50,12 @@ class SpotlightIterator : public BaseFileFilter::Iterator
{
public:
SpotlightIterator(const QString &expression);
- ~SpotlightIterator();
+ ~SpotlightIterator() override;
- void toFront();
- bool hasNext() const;
- QString next();
- QString filePath() const;
- QString fileName() const;
+ void toFront() override;
+ bool hasNext() const override;
+ Utils::FilePath next() override;
+ Utils::FilePath filePath() const override;
private:
void ensureNext();
@@ -132,24 +131,18 @@ bool SpotlightIterator::hasNext() const
return (m_index + 1 < m_filePaths.size());
}
-QString SpotlightIterator::next()
+Utils::FilePath SpotlightIterator::next()
{
ensureNext();
++m_index;
- QTC_ASSERT(m_index < m_filePaths.size(), return QString());
- return m_filePaths.at(m_index);
+ QTC_ASSERT(m_index < m_filePaths.size(), return Utils::FilePath());
+ return Utils::FilePath::fromString(m_filePaths.at(m_index));
}
-QString SpotlightIterator::filePath() const
+Utils::FilePath SpotlightIterator::filePath() const
{
- QTC_ASSERT(m_index < m_filePaths.size(), return QString());
- return m_filePaths.at(m_index);
-}
-
-QString SpotlightIterator::fileName() const
-{
- QTC_ASSERT(m_index < m_fileNames.size(), return QString());
- return m_fileNames.at(m_index);
+ QTC_ASSERT(m_index < m_filePaths.size(), return Utils::FilePath());
+ return Utils::FilePath::fromString(m_filePaths.at(m_index));
}
void SpotlightIterator::ensureNext()
@@ -183,7 +176,7 @@ void SpotlightLocatorFilter::prepareSearch(const QString &entry)
{
const EditorManager::FilePathInfo fp = EditorManager::splitLineAndColumnNumber(entry);
if (fp.filePath.isEmpty()) {
- setFileIterator(new BaseFileFilter::ListIterator(QStringList()));
+ setFileIterator(new BaseFileFilter::ListIterator(Utils::FilePathList()));
} else {
// only pass the file name part to spotlight to allow searches like "somepath/*foo"
int lastSlash = fp.filePath.lastIndexOf(QLatin1Char('/'));
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index dd724d9f9c..732f485824 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -149,6 +149,8 @@ MainWindow::MainWindow()
}
QApplication::setStyle(new ManhattanStyle(baseName));
+ m_generalSettings->setShowShortcutsInContextMenu(
+ m_generalSettings->showShortcutsInContextMenu());
setDockNestingEnabled(true);
@@ -365,6 +367,11 @@ QStatusBar *MainWindow::statusBar() const
return m_modeStack->statusBar();
}
+InfoBar *MainWindow::infoBar() const
+{
+ return m_modeStack->infoBar();
+}
+
void MainWindow::registerDefaultContainers()
{
ActionContainer *menubar = ActionManager::createMenuBar(Constants::MENU_BAR);
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 8f9939ee8f..26dc607cbe 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -46,6 +46,7 @@ namespace Core {
class EditorManager;
class ExternalToolManager;
class IDocument;
+class InfoBar;
class JsExpander;
class MessageManager;
class ModeManager;
@@ -93,6 +94,7 @@ public:
virtual QPrinter *printer() const;
IContext * currentContextObject() const;
QStatusBar *statusBar() const;
+ InfoBar *infoBar() const;
void updateAdditionalContexts(const Context &remove, const Context &add,
ICore::ContextPriority priority);
diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp
index 76593c18d0..544f57ad3e 100644
--- a/src/plugins/coreplugin/manhattanstyle.cpp
+++ b/src/plugins/coreplugin/manhattanstyle.cpp
@@ -246,14 +246,12 @@ QPalette panelPalette(const QPalette &oldPalette, bool lightColored = false)
QPalette pal = oldPalette;
pal.setBrush(QPalette::All, QPalette::WindowText, color);
pal.setBrush(QPalette::All, QPalette::ButtonText, color);
- pal.setBrush(QPalette::All, QPalette::Foreground, color);
if (lightColored)
color.setAlpha(100);
else
color = creatorTheme()->color(Theme::IconsDisabledColor);
pal.setBrush(QPalette::Disabled, QPalette::WindowText, color);
pal.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
- pal.setBrush(QPalette::Disabled, QPalette::Foreground, color);
return pal;
}
@@ -291,7 +289,7 @@ void ManhattanStyle::polish(QWidget *widget)
const bool isLightColored = lightColored(widget);
QPalette palette = panelPalette(widget->palette(), isLightColored);
if (!isLightColored)
- palette.setBrush(QPalette::All, QPalette::Foreground,
+ palette.setBrush(QPalette::All, QPalette::WindowText,
creatorTheme()->color(Theme::ComboBoxTextColor));
widget->setPalette(palette);
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
@@ -738,7 +736,7 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt
painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text);
}
painter->setPen((option->state & State_Enabled)
- ? option->palette.color(QPalette::Foreground)
+ ? option->palette.color(QPalette::WindowText)
: creatorTheme()->color(Theme::IconsDisabledColor));
painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text);
diff --git a/src/plugins/coreplugin/menubarfilter.cpp b/src/plugins/coreplugin/menubarfilter.cpp
index 7791bb1f1e..dc8de54614 100644
--- a/src/plugins/coreplugin/menubarfilter.cpp
+++ b/src/plugins/coreplugin/menubarfilter.cpp
@@ -71,17 +71,17 @@ static const QList<QAction *> menuBarActions()
QList<LocatorFilterEntry> MenuBarFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry)
{
- Q_UNUSED(future);
- Q_UNUSED(entry);
+ Q_UNUSED(future)
+ Q_UNUSED(entry)
return std::move(m_entries);
}
void MenuBarFilter::accept(LocatorFilterEntry selection, QString *newText,
int *selectionStart, int *selectionLength) const
{
- Q_UNUSED(newText);
- Q_UNUSED(selectionStart);
- Q_UNUSED(selectionLength);
+ Q_UNUSED(newText)
+ Q_UNUSED(selectionStart)
+ Q_UNUSED(selectionLength)
if (auto action = selection.internalData.value<QPointer<QAction>>()) {
QTimer::singleShot(0, action, [action] {
if (action->isEnabled())
@@ -92,7 +92,7 @@ void MenuBarFilter::accept(LocatorFilterEntry selection, QString *newText,
void MenuBarFilter::refresh(QFutureInterface<void> &future)
{
- Q_UNUSED(future);
+ Q_UNUSED(future)
}
QList<LocatorFilterEntry> MenuBarFilter::matchesForAction(QAction *action,
@@ -182,7 +182,7 @@ void MenuBarFilter::updateEnabledActionCache()
void Core::Internal::MenuBarFilter::prepareSearch(const QString &entry)
{
- Q_UNUSED(entry);
+ Q_UNUSED(entry)
static const QString separators = ". >/";
static const QRegularExpression seperatorRegExp(QString("[%1]").arg(separators));
QString normalized = entry;
diff --git a/src/plugins/coreplugin/mimetypesettings.cpp b/src/plugins/coreplugin/mimetypesettings.cpp
index 7b4d891339..83ed2a278b 100644
--- a/src/plugins/coreplugin/mimetypesettings.cpp
+++ b/src/plugins/coreplugin/mimetypesettings.cpp
@@ -632,9 +632,9 @@ void MimeTypeSettingsPrivate::applyUserModifiedMimeTypes(const UserMimeTypeHash
}
// MimeTypeSettingsPage
-MimeTypeSettings::MimeTypeSettings(QObject *parent)
- : IOptionsPage(parent)
- , d(new MimeTypeSettingsPrivate)
+
+MimeTypeSettings::MimeTypeSettings()
+ : d(new MimeTypeSettingsPrivate)
{
setId(Constants::SETTINGS_ID_MIMETYPES);
setDisplayName(tr("MIME Types"));
diff --git a/src/plugins/coreplugin/mimetypesettings.h b/src/plugins/coreplugin/mimetypesettings.h
index 3d9059bbfe..a57fa46ca0 100644
--- a/src/plugins/coreplugin/mimetypesettings.h
+++ b/src/plugins/coreplugin/mimetypesettings.h
@@ -37,7 +37,7 @@ class MimeTypeSettings : public IOptionsPage
Q_OBJECT
public:
- MimeTypeSettings(QObject *parent = nullptr);
+ MimeTypeSettings();
~MimeTypeSettings() override;
QWidget *widget() override;
diff --git a/src/plugins/coreplugin/minisplitter.cpp b/src/plugins/coreplugin/minisplitter.cpp
index 6bac3ffdfc..99de649d18 100644
--- a/src/plugins/coreplugin/minisplitter.cpp
+++ b/src/plugins/coreplugin/minisplitter.cpp
@@ -92,8 +92,8 @@ MiniSplitter::MiniSplitter(QWidget *parent, SplitterStyle style)
setProperty("minisplitter", true);
}
-MiniSplitter::MiniSplitter(Qt::Orientation orientation, SplitterStyle style)
- : QSplitter(orientation),
+MiniSplitter::MiniSplitter(Qt::Orientation orientation, QWidget *parent, SplitterStyle style)
+ : QSplitter(orientation, parent),
m_style(style)
{
setHandleWidth(1);
diff --git a/src/plugins/coreplugin/minisplitter.h b/src/plugins/coreplugin/minisplitter.h
index 712f8f366f..407e3f250b 100644
--- a/src/plugins/coreplugin/minisplitter.h
+++ b/src/plugins/coreplugin/minisplitter.h
@@ -42,7 +42,7 @@ public:
enum SplitterStyle {Dark, Light};
MiniSplitter(QWidget *parent = nullptr, SplitterStyle style = Dark);
- MiniSplitter(Qt::Orientation orientation, SplitterStyle style = Dark);
+ MiniSplitter(Qt::Orientation orientation, QWidget *parent = nullptr, SplitterStyle style = Dark);
protected:
QSplitterHandle *createHandle() override;
diff --git a/src/plugins/coreplugin/navigationsubwidget.cpp b/src/plugins/coreplugin/navigationsubwidget.cpp
index ab4858e388..c839b3b551 100644
--- a/src/plugins/coreplugin/navigationsubwidget.cpp
+++ b/src/plugins/coreplugin/navigationsubwidget.cpp
@@ -65,7 +65,7 @@ NavigationSubWidget::NavigationSubWidget(NavigationWidget *parentWidget, int pos
m_toolBar = new Utils::StyledBar(this);
auto toolBarLayout = new QHBoxLayout;
- toolBarLayout->setMargin(0);
+ toolBarLayout->setContentsMargins(0, 0, 0, 0);
toolBarLayout->setSpacing(0);
m_toolBar->setLayout(toolBarLayout);
toolBarLayout->addWidget(m_navigationComboBox);
@@ -87,7 +87,7 @@ NavigationSubWidget::NavigationSubWidget(NavigationWidget *parentWidget, int pos
toolBarLayout->addWidget(m_closeButton);
auto lay = new QVBoxLayout();
- lay->setMargin(0);
+ lay->setContentsMargins(0, 0, 0, 0);
lay->setSpacing(0);
setLayout(lay);
lay->addWidget(m_toolBar);
diff --git a/src/plugins/coreplugin/navigationwidget.cpp b/src/plugins/coreplugin/navigationwidget.cpp
index aae3a618f9..6cb8fed496 100644
--- a/src/plugins/coreplugin/navigationwidget.cpp
+++ b/src/plugins/coreplugin/navigationwidget.cpp
@@ -70,7 +70,7 @@ NavigationWidgetPlaceHolder::NavigationWidgetPlaceHolder(Id mode, Side side, QWi
:QWidget(parent), m_mode(mode), m_side(side)
{
setLayout(new QVBoxLayout);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
connect(ModeManager::instance(), &ModeManager::currentModeAboutToChange,
this, &NavigationWidgetPlaceHolder::currentModeAboutToChange);
}
@@ -542,7 +542,7 @@ QString NavigationWidget::settingsKey(const QString &key) const
void NavigationWidget::onSubWidgetFactoryIndexChanged(int factoryIndex)
{
- Q_UNUSED(factoryIndex);
+ Q_UNUSED(factoryIndex)
auto subWidget = qobject_cast<Internal::NavigationSubWidget *>(sender());
QTC_ASSERT(subWidget, return);
Id factoryId = subWidget->factory()->id();
diff --git a/src/plugins/coreplugin/outputpane.cpp b/src/plugins/coreplugin/outputpane.cpp
index b6d118d6b6..5043ac8abd 100644
--- a/src/plugins/coreplugin/outputpane.cpp
+++ b/src/plugins/coreplugin/outputpane.cpp
@@ -63,7 +63,7 @@ OutputPanePlaceHolder::OutputPanePlaceHolder(Id mode, QSplitter *parent)
sp.setVerticalPolicy(QSizePolicy::Preferred);
sp.setHorizontalStretch(0);
setSizePolicy(sp);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
connect(ModeManager::instance(), &ModeManager::currentModeChanged,
this, &OutputPanePlaceHolder::currentModeChanged);
// if this is part of a lazily created mode widget,
diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp
index 7cf2ec2c90..b0153eda50 100644
--- a/src/plugins/coreplugin/outputpanemanager.cpp
+++ b/src/plugins/coreplugin/outputpanemanager.cpp
@@ -346,10 +346,10 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) :
auto mainlayout = new QVBoxLayout;
mainlayout->setSpacing(0);
- mainlayout->setMargin(0);
+ mainlayout->setContentsMargins(0, 0, 0, 0);
m_toolBar = new StyledBar;
auto toolLayout = new QHBoxLayout(m_toolBar);
- toolLayout->setMargin(0);
+ toolLayout->setContentsMargins(0, 0, 0, 0);
toolLayout->setSpacing(0);
toolLayout->addWidget(m_titleLabel);
toolLayout->addWidget(new StyledSeparator);
@@ -451,7 +451,7 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) :
QWidget *toolButtonsContainer = new QWidget(m_opToolBarWidgets);
auto toolButtonsLayout = new QHBoxLayout;
- toolButtonsLayout->setMargin(0);
+ toolButtonsLayout->setContentsMargins(0, 0, 0, 0);
toolButtonsLayout->setSpacing(0);
foreach (QWidget *toolButton, outPane->toolBarWidgets())
toolButtonsLayout->addWidget(toolButton);
diff --git a/src/plugins/coreplugin/progressmanager/futureprogress.cpp b/src/plugins/coreplugin/progressmanager/futureprogress.cpp
index 32193fd08b..b39738bed4 100644
--- a/src/plugins/coreplugin/progressmanager/futureprogress.cpp
+++ b/src/plugins/coreplugin/progressmanager/futureprogress.cpp
@@ -128,7 +128,7 @@ FutureProgress::FutureProgress(QWidget *parent) :
auto layout = new QVBoxLayout;
setLayout(layout);
layout->addWidget(d->m_progress);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addLayout(d->m_widgetLayout);
d->m_widgetLayout->setContentsMargins(7, 0, 7, 2);
diff --git a/src/plugins/coreplugin/progressmanager/progressmanager.cpp b/src/plugins/coreplugin/progressmanager/progressmanager.cpp
index d822397b90..84ca73cc30 100644
--- a/src/plugins/coreplugin/progressmanager/progressmanager.cpp
+++ b/src/plugins/coreplugin/progressmanager/progressmanager.cpp
@@ -508,11 +508,9 @@ void ProgressManagerPrivate::updateSummaryProgressBar()
stopFadeOfSummaryProgress();
m_summaryProgressBar->setFinished(false);
- QMapIterator<QFutureWatcher<void> *, Id> it(m_runningTasks);
static const int TASK_RANGE = 100;
int value = 0;
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_runningTasks.cbegin(), end = m_runningTasks.cend(); it != end; ++it) {
QFutureWatcher<void> *watcher = it.key();
int min = watcher->progressMinimum();
int range = watcher->progressMaximum() - min;
diff --git a/src/plugins/coreplugin/rightpane.cpp b/src/plugins/coreplugin/rightpane.cpp
index 403fe4b0c6..6674106396 100644
--- a/src/plugins/coreplugin/rightpane.cpp
+++ b/src/plugins/coreplugin/rightpane.cpp
@@ -49,7 +49,7 @@ RightPanePlaceHolder::RightPanePlaceHolder(Id mode, QWidget *parent)
:QWidget(parent), m_mode(mode)
{
setLayout(new QVBoxLayout);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
connect(ModeManager::instance(), &ModeManager::currentModeChanged,
this, &RightPanePlaceHolder::currentModeChanged);
}
@@ -124,7 +124,7 @@ RightPaneWidget::RightPaneWidget()
m_instance = this;
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
}
diff --git a/src/plugins/coreplugin/settingsdatabase.cpp b/src/plugins/coreplugin/settingsdatabase.cpp
index 9b5054fa57..f3f52317d8 100644
--- a/src/plugins/coreplugin/settingsdatabase.cpp
+++ b/src/plugins/coreplugin/settingsdatabase.cpp
@@ -241,9 +241,8 @@ QStringList SettingsDatabase::childKeys() const
QStringList children;
const QString g = group();
- QMapIterator<QString, QVariant> i(d->m_settings);
- while (i.hasNext()) {
- const QString &key = i.next().key();
+ for (auto i = d->m_settings.cbegin(), end = d->m_settings.cend(); i != end; ++i) {
+ const QString &key = i.key();
if (key.startsWith(g) && key.indexOf(QLatin1Char('/'), g.length() + 1) == -1)
children.append(key.mid(g.length() + 1));
}
diff --git a/src/plugins/coreplugin/sidebar.cpp b/src/plugins/coreplugin/sidebar.cpp
index a5466a597e..f811e1df33 100644
--- a/src/plugins/coreplugin/sidebar.cpp
+++ b/src/plugins/coreplugin/sidebar.cpp
@@ -108,9 +108,7 @@ SideBar::~SideBar()
QString SideBar::idForTitle(const QString &title) const
{
- QMapIterator<QString, QPointer<SideBarItem> > iter(d->m_itemMap);
- while (iter.hasNext()) {
- iter.next();
+ for (auto iter = d->m_itemMap.cbegin(), end = d->m_itemMap.cend(); iter != end; ++iter) {
if (iter.value().data()->title() == title)
return iter.key();
}
@@ -266,11 +264,8 @@ void SideBar::saveSettings(QSettings *settings, const QString &name)
if (!currentItemId.isEmpty())
views.append(currentItemId);
}
- if (views.isEmpty() && d->m_itemMap.size()) {
- QMapIterator<QString, QPointer<SideBarItem> > iter(d->m_itemMap);
- iter.next();
- views.append(iter.key());
- }
+ if (views.isEmpty() && !d->m_itemMap.isEmpty())
+ views.append(d->m_itemMap.cbegin().key());
settings->setValue(prefix + QLatin1String("Views"), views);
settings->setValue(prefix + QLatin1String("Visible"),
diff --git a/src/plugins/coreplugin/sidebarwidget.cpp b/src/plugins/coreplugin/sidebarwidget.cpp
index fd561611c2..2cb1c6539e 100644
--- a/src/plugins/coreplugin/sidebarwidget.cpp
+++ b/src/plugins/coreplugin/sidebarwidget.cpp
@@ -81,7 +81,7 @@ SideBarWidget::SideBarWidget(SideBar *sideBar, const QString &id)
m_toolbar->addAction(m_closeAction);
auto lay = new QVBoxLayout();
- lay->setMargin(0);
+ lay->setContentsMargins(0, 0, 0, 0);
lay->setSpacing(0);
setLayout(lay);
lay->addWidget(m_toolbar);
diff --git a/src/plugins/coreplugin/statusbarmanager.cpp b/src/plugins/coreplugin/statusbarmanager.cpp
index e71e745077..a5d4848981 100644
--- a/src/plugins/coreplugin/statusbarmanager.cpp
+++ b/src/plugins/coreplugin/statusbarmanager.cpp
@@ -63,7 +63,7 @@ static QWidget *createWidget(QWidget *parent)
QWidget *w = new QWidget(parent);
w->setLayout(new QHBoxLayout);
w->setVisible(true);
- w->layout()->setMargin(0);
+ w->layout()->setContentsMargins(0, 0, 0, 0);
return w;
}
diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp
index b6a435d36a..a6199cfd23 100644
--- a/src/plugins/coreplugin/systemsettings.cpp
+++ b/src/plugins/coreplugin/systemsettings.cpp
@@ -118,6 +118,9 @@ QWidget *SystemSettings::widget()
m_page->warnBeforeOpeningBigFiles->setChecked(
EditorManagerPrivate::warnBeforeOpeningBigFilesEnabled());
m_page->bigFilesLimitSpinBox->setValue(EditorManagerPrivate::bigFileSizeLimit());
+ m_page->maxRecentFilesSpinBox->setMinimum(1);
+ m_page->maxRecentFilesSpinBox->setMaximum(99);
+ m_page->maxRecentFilesSpinBox->setValue(EditorManagerPrivate::maxRecentFiles());
if (HostOsInfo::isAnyUnixHost()) {
connect(m_page->resetTerminalButton, &QAbstractButton::clicked,
@@ -183,6 +186,7 @@ void SystemSettings::apply()
EditorManagerPrivate::setWarnBeforeOpeningBigFilesEnabled(
m_page->warnBeforeOpeningBigFiles->isChecked());
EditorManagerPrivate::setBigFileSizeLimit(m_page->bigFilesLimitSpinBox->value());
+ EditorManagerPrivate::setMaxRecentFiles(m_page->maxRecentFilesSpinBox->value());
if (HostOsInfo::isMacHost()) {
Qt::CaseSensitivity defaultSensitivity
diff --git a/src/plugins/coreplugin/systemsettings.ui b/src/plugins/coreplugin/systemsettings.ui
index 172e773657..1aee69e9e3 100644
--- a/src/plugins/coreplugin/systemsettings.ui
+++ b/src/plugins/coreplugin/systemsettings.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>527</width>
- <height>469</height>
+ <width>599</width>
+ <height>545</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -17,7 +17,138 @@
<string>System</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="5" column="0" colspan="4">
+ <item row="0" column="0">
+ <widget class="QLabel" name="terminalLabel">
+ <property name="text">
+ <string>Terminal:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QComboBox" name="terminalComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Ignored" vsizetype="Fixed">
+ <horstretch>3</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="terminalOpenArgs"/>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="terminalExecuteArgs">
+ <property name="toolTip">
+ <string>Command line arguments used for &quot;Run in terminal&quot;.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="resetTerminalButton">
+ <property name="toolTip">
+ <string comment="Terminal">Reset to default.</string>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="externalFileBrowserLabel">
+ <property name="text">
+ <string>External file browser:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="externalFileBrowserEdit"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="resetFileBrowserButton">
+ <property name="toolTip">
+ <string comment="File Browser">Reset to default.</string>
+ </property>
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QToolButton" name="helpExternalFileBrowserButton">
+ <property name="text">
+ <string>?</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="patchCommandLabel">
+ <property name="text">
+ <string>Patch command:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="Utils::PathChooser" name="patchChooser" native="true"/>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QWidget" name="fileSystemCaseSensitivityWidget" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="toolTip">
+ <string>Influences how file names are matched to decide if they are the same.</string>
+ </property>
+ <property name="text">
+ <string>File system case sensitivity:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="fileSystemCaseSensitivityChooser"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="modifiedLabel">
@@ -63,21 +194,7 @@
</item>
</layout>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="externalFileBrowserLabel">
- <property name="text">
- <string>External file browser:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="QToolButton" name="helpExternalFileBrowserButton">
- <property name="text">
- <string>?</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0" colspan="4">
+ <item row="5" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QCheckBox" name="autoSaveCheckBox">
@@ -137,17 +254,7 @@
</item>
</layout>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="patchCommandLabel">
- <property name="text">
- <string>Patch command:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="externalFileBrowserEdit"/>
- </item>
- <item row="7" column="0" colspan="4">
+ <item row="6" column="0" colspan="4">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="autoSuspendCheckBox">
@@ -213,17 +320,7 @@
</item>
</layout>
</item>
- <item row="2" column="2">
- <widget class="QPushButton" name="resetFileBrowserButton">
- <property name="toolTip">
- <string comment="File Browser">Reset to default.</string>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0" colspan="4">
+ <item row="7" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QCheckBox" name="warnBeforeOpeningBigFiles">
@@ -266,100 +363,30 @@
</item>
</layout>
</item>
- <item row="3" column="1" colspan="2">
- <widget class="Utils::PathChooser" name="patchChooser" native="true"/>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="resetTerminalButton">
- <property name="toolTip">
- <string comment="Terminal">Reset to default.</string>
- </property>
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="4">
- <widget class="QWidget" name="fileSystemCaseSensitivityWidget" native="true">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label">
- <property name="toolTip">
- <string>Influences how file names are matched to decide if they are the same.</string>
- </property>
- <property name="text">
- <string>File system case sensitivity:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="fileSystemCaseSensitivityChooser"/>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="terminalLabel">
- <property name="text">
- <string>Terminal:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item row="8" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
- <widget class="QComboBox" name="terminalComboBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Ignored" vsizetype="Fixed">
- <horstretch>3</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="editable">
- <bool>true</bool>
+ <widget class="QLabel" name="maxRecentFilesLabel">
+ <property name="text">
+ <string>Maximum number of entries in &quot;Recent Files&quot;:</string>
</property>
</widget>
</item>
<item>
- <widget class="QLineEdit" name="terminalOpenArgs"/>
+ <widget class="QSpinBox" name="maxRecentFilesSpinBox"/>
</item>
<item>
- <widget class="QLineEdit" name="terminalExecuteArgs">
- <property name="toolTip">
- <string>Command line arguments used for &quot;Run in terminal&quot;.</string>
+ <spacer name="horizontalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </widget>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
</item>
</layout>
</item>
diff --git a/src/plugins/coreplugin/textdocument.cpp b/src/plugins/coreplugin/textdocument.cpp
index bac68c731e..d053464f1e 100644
--- a/src/plugins/coreplugin/textdocument.cpp
+++ b/src/plugins/coreplugin/textdocument.cpp
@@ -101,6 +101,11 @@ void BaseTextDocument::setSupportsUtf8Bom(bool value)
d->m_supportsUtf8Bom = value;
}
+void BaseTextDocument::setLineTerminationMode(Utils::TextFileFormat::LineTerminationMode mode)
+{
+ d->m_format.lineTerminationMode = mode;
+}
+
/*!
Autodetects format and reads in the text file specified by \a fileName.
*/
@@ -149,6 +154,11 @@ bool BaseTextDocument::supportsUtf8Bom() const
return d->m_supportsUtf8Bom;
}
+Utils::TextFileFormat::LineTerminationMode BaseTextDocument::lineTerminationMode() const
+{
+ return d->m_format.lineTerminationMode;
+}
+
/*!
Returns the format obtained from the last call to \c read().
*/
diff --git a/src/plugins/coreplugin/textdocument.h b/src/plugins/coreplugin/textdocument.h
index 9b498124aa..f1b1b4fc85 100644
--- a/src/plugins/coreplugin/textdocument.h
+++ b/src/plugins/coreplugin/textdocument.h
@@ -48,6 +48,7 @@ public:
void setCodec(const QTextCodec *);
void switchUtf8Bom();
bool supportsUtf8Bom() const;
+ Utils::TextFileFormat::LineTerminationMode lineTerminationMode() const;
ReadResult read(const QString &fileName, QStringList *plainTextList, QString *errorString);
ReadResult read(const QString &fileName, QString *plainText, QString *errorString);
@@ -59,6 +60,7 @@ public:
bool write(const QString &fileName, const Utils::TextFileFormat &format, const QString &data, QString *errorMessage) const;
void setSupportsUtf8Bom(bool value);
+ void setLineTerminationMode(Utils::TextFileFormat::LineTerminationMode mode);
private:
Internal::TextDocumentPrivate *d;
diff --git a/src/plugins/coreplugin/themechooser.cpp b/src/plugins/coreplugin/themechooser.cpp
index 7fedfea06f..0c01084f4c 100644
--- a/src/plugins/coreplugin/themechooser.cpp
+++ b/src/plugins/coreplugin/themechooser.cpp
@@ -141,7 +141,7 @@ ThemeChooserPrivate::ThemeChooserPrivate(QWidget *widget)
overriddenLabel->setText(ThemeChooser::tr("Current theme: %1")
.arg(creatorTheme()->displayName()));
layout->addWidget(overriddenLabel);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
auto horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
layout->addSpacerItem(horizontalSpacer);
m_themeComboBox->setModel(m_themeListModel);
diff --git a/src/plugins/coreplugin/toolsettings.cpp b/src/plugins/coreplugin/toolsettings.cpp
index 200e425140..8106c2f485 100644
--- a/src/plugins/coreplugin/toolsettings.cpp
+++ b/src/plugins/coreplugin/toolsettings.cpp
@@ -42,8 +42,7 @@
using namespace Core;
using namespace Core::Internal;
-ToolSettings::ToolSettings(QObject *parent) :
- IOptionsPage(parent)
+ToolSettings::ToolSettings()
{
setId(Constants::SETTINGS_ID_TOOLS);
setDisplayName(tr("External Tools"));
@@ -103,9 +102,7 @@ static QString findUnusedId(const QString &proposal, const QMap<QString, QList<E
result = proposal + (number > 0 ? QString::number(number) : QString::fromLatin1(""));
++number;
found = false;
- QMapIterator<QString, QList<ExternalTool *> > it(tools);
- while (!found && it.hasNext()) {
- it.next();
+ for (auto it = tools.cbegin(), end = tools.cend(); it != end; ++it) {
foreach (ExternalTool *tool, it.value()) {
if (tool->id() == result) {
found = true;
@@ -125,9 +122,7 @@ void ToolSettings::apply()
QMap<QString, ExternalTool *> originalTools = ExternalToolManager::toolsById();
QMap<QString, QList<ExternalTool *> > newToolsMap = m_widget->tools();
QMap<QString, QList<ExternalTool *> > resultMap;
- QMapIterator<QString, QList<ExternalTool *> > it(newToolsMap);
- while (it.hasNext()) {
- it.next();
+ for (auto it = newToolsMap.cbegin(), end = newToolsMap.cend(); it != end; ++it) {
QList<ExternalTool *> items;
foreach (ExternalTool *tool, it.value()) {
ExternalTool *toolToAdd = nullptr;
diff --git a/src/plugins/coreplugin/toolsettings.h b/src/plugins/coreplugin/toolsettings.h
index 28972bc213..6e20ff0706 100644
--- a/src/plugins/coreplugin/toolsettings.h
+++ b/src/plugins/coreplugin/toolsettings.h
@@ -39,7 +39,7 @@ class ToolSettings : public IOptionsPage
Q_OBJECT
public:
- explicit ToolSettings(QObject *parent = nullptr);
+ ToolSettings();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/coreplugin/variablechooser.cpp b/src/plugins/coreplugin/variablechooser.cpp
index f2e0edef02..46466623c4 100644
--- a/src/plugins/coreplugin/variablechooser.cpp
+++ b/src/plugins/coreplugin/variablechooser.cpp
@@ -466,7 +466,7 @@ void VariableChooserPrivate::updateButtonGeometry()
void VariableChooserPrivate::updateCurrentEditor(QWidget *old, QWidget *widget)
{
- Q_UNUSED(old);
+ Q_UNUSED(old)
if (!widget) // we might loose focus, but then keep the previous state
return;
// prevent children of the chooser itself, and limit to children of chooser's parent
diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp
index fc9388aa1e..0de226c5cf 100644
--- a/src/plugins/coreplugin/vcsmanager.cpp
+++ b/src/plugins/coreplugin/vcsmanager.cpp
@@ -301,7 +301,7 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input
InfoBarEntry info(vcsWarning,
tr("%1 repository was detected but %1 is not configured.")
.arg(versionControl->displayName()),
- InfoBarEntry::GlobalSuppressionEnabled);
+ InfoBarEntry::GlobalSuppression::Enabled);
d->m_unconfiguredVcs = versionControl;
info.setCustomButtonInfo(ICore::msgShowOptionsDialog(), []() {
QTC_ASSERT(d->m_unconfiguredVcs, return);
diff --git a/src/plugins/cpaster/columnindicatortextedit.cpp b/src/plugins/cpaster/columnindicatortextedit.cpp
index cfbe8b2489..721ade51c1 100644
--- a/src/plugins/cpaster/columnindicatortextedit.cpp
+++ b/src/plugins/cpaster/columnindicatortextedit.cpp
@@ -41,9 +41,8 @@ ColumnIndicatorTextEdit::ColumnIndicatorTextEdit(QWidget *parent) :
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy.setVerticalStretch(3);
setSizePolicy(sizePolicy);
- int cmx = 0, cmy = 0, cmw = 0, cmh = 0;
- getContentsMargins(&cmx, &cmy, &cmw, &cmh);
- m_columnIndicator = QFontMetrics(font).horizontalAdvance(QLatin1Char('W')) * 100 + cmx + 1;
+ m_columnIndicator = QFontMetrics(font).horizontalAdvance(QLatin1Char('W')) * 100
+ + contentsMargins().left() + 1;
m_columnIndicatorFont.setFamily(QLatin1String("Times"));
m_columnIndicatorFont.setPointSizeF(7.0);
}
diff --git a/src/plugins/cpaster/fileshareprotocolsettingspage.cpp b/src/plugins/cpaster/fileshareprotocolsettingspage.cpp
index 51b254ecba..a0b160176b 100644
--- a/src/plugins/cpaster/fileshareprotocolsettingspage.cpp
+++ b/src/plugins/cpaster/fileshareprotocolsettingspage.cpp
@@ -65,8 +65,7 @@ bool FileShareProtocolSettings::equals(const FileShareProtocolSettings &rhs) con
return displayCount == rhs.displayCount && path == rhs.path;
}
-FileShareProtocolSettingsWidget::FileShareProtocolSettingsWidget(QWidget *parent) :
- QWidget(parent)
+FileShareProtocolSettingsWidget::FileShareProtocolSettingsWidget()
{
m_ui.setupUi(this);
@@ -91,9 +90,8 @@ FileShareProtocolSettings FileShareProtocolSettingsWidget::settings() const
}
// ----------FileShareProtocolSettingsPage
-FileShareProtocolSettingsPage::FileShareProtocolSettingsPage(const QSharedPointer<FileShareProtocolSettings> &s,
- QObject *parent) :
- Core::IOptionsPage(parent), m_settings(s), m_widget(nullptr)
+FileShareProtocolSettingsPage::FileShareProtocolSettingsPage(const QSharedPointer<FileShareProtocolSettings> &s)
+ : m_settings(s), m_widget(nullptr)
{
setId("X.CodePaster.FileSharePaster");
setDisplayName(tr("Fileshare"));
diff --git a/src/plugins/cpaster/fileshareprotocolsettingspage.h b/src/plugins/cpaster/fileshareprotocolsettingspage.h
index 491c4fe621..aecd5d475c 100644
--- a/src/plugins/cpaster/fileshareprotocolsettingspage.h
+++ b/src/plugins/cpaster/fileshareprotocolsettingspage.h
@@ -54,10 +54,12 @@ inline bool operator==(const FileShareProtocolSettings &s1, const FileShareProto
inline bool operator!=(const FileShareProtocolSettings &s1, const FileShareProtocolSettings &s2)
{ return !s1.equals(s2); }
-class FileShareProtocolSettingsWidget : public QWidget {
+class FileShareProtocolSettingsWidget : public QWidget
+{
Q_OBJECT
+
public:
- explicit FileShareProtocolSettingsWidget(QWidget *parent = nullptr);
+ FileShareProtocolSettingsWidget();
void setSettings(const FileShareProtocolSettings &);
FileShareProtocolSettings settings() const;
@@ -71,8 +73,7 @@ class FileShareProtocolSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit FileShareProtocolSettingsPage(const QSharedPointer<FileShareProtocolSettings> &s,
- QObject *parent = nullptr);
+ explicit FileShareProtocolSettingsPage(const QSharedPointer<FileShareProtocolSettings> &s);
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/cpaster/pastebindotcomprotocol.cpp b/src/plugins/cpaster/pastebindotcomprotocol.cpp
index 86ae8f3f97..fb3d60ba92 100644
--- a/src/plugins/cpaster/pastebindotcomprotocol.cpp
+++ b/src/plugins/cpaster/pastebindotcomprotocol.cpp
@@ -105,8 +105,8 @@ void PasteBinDotComProtocol::paste(const QString &text,
const QString &comment,
const QString &description)
{
- Q_UNUSED(comment);
- Q_UNUSED(description);
+ Q_UNUSED(comment)
+ Q_UNUSED(description)
QTC_ASSERT(!m_pasteReply, return);
// Format body
diff --git a/src/plugins/cpaster/pastecodedotxyzprotocol.cpp b/src/plugins/cpaster/pastecodedotxyzprotocol.cpp
index 5bd2b869ad..8ca7d5c547 100644
--- a/src/plugins/cpaster/pastecodedotxyzprotocol.cpp
+++ b/src/plugins/cpaster/pastecodedotxyzprotocol.cpp
@@ -86,7 +86,7 @@ void PasteCodeDotXyzProtocol::paste(const QString &text, Protocol::ContentType c
return QByteArray(); // Crutch for compiler.
};
data += "&lang=" + langValue(ct);
- Q_UNUSED(comment);
+ Q_UNUSED(comment)
QNetworkReply * const reply = httpPost(apiUrl() + "/create", data);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
diff --git a/src/plugins/cpaster/stickynotespasteprotocol.cpp b/src/plugins/cpaster/stickynotespasteprotocol.cpp
index 3ec958d99c..9c8ad232eb 100644
--- a/src/plugins/cpaster/stickynotespasteprotocol.cpp
+++ b/src/plugins/cpaster/stickynotespasteprotocol.cpp
@@ -106,7 +106,7 @@ void StickyNotesPasteProtocol::paste(const QString &text,
enum { maxDescriptionLength = 30 }; // Length of description is limited.
Q_UNUSED(username)
- Q_UNUSED(comment);
+ Q_UNUSED(comment)
QTC_ASSERT(!m_pasteReply, return);
// Format body
diff --git a/src/plugins/cppcheck/cppcheckplugin.cpp b/src/plugins/cppcheck/cppcheckplugin.cpp
index 983955ef39..5b96452f4e 100644
--- a/src/plugins/cppcheck/cppcheckplugin.cpp
+++ b/src/plugins/cppcheck/cppcheckplugin.cpp
@@ -55,8 +55,8 @@ CppcheckPlugin::~CppcheckPlugin() = default;
bool CppcheckPlugin::initialize(const QStringList &arguments, QString *errorString)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorString);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
d.reset(new CppcheckPluginPrivate);
diff --git a/src/plugins/cppcheck/cppcheckrunner.cpp b/src/plugins/cppcheck/cppcheckrunner.cpp
index 9b9872097a..bf0a85a6e1 100644
--- a/src/plugins/cppcheck/cppcheckrunner.cpp
+++ b/src/plugins/cppcheck/cppcheckrunner.cpp
@@ -155,7 +155,7 @@ void CppcheckRunner::checkQueued()
else
m_queue.begin().value() = files;
- m_process->setCommand(CommandLine(FilePath::fromString(m_binary), arguments));
+ m_process->setCommand(CommandLine(FilePath::fromString(m_binary), arguments, CommandLine::Raw));
m_process->start();
}
diff --git a/src/plugins/cppcheck/cppchecktool.cpp b/src/plugins/cppcheck/cppchecktool.cpp
index 0c95f30fbd..02cb1d68de 100644
--- a/src/plugins/cppcheck/cppchecktool.cpp
+++ b/src/plugins/cppcheck/cppchecktool.cpp
@@ -169,8 +169,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
break;
}
- using QtVersion = CppTools::ProjectPart::QtVersion;
- if (part.qtVersion != QtVersion::NoQt)
+ if (part.qtVersion != Utils::QtVersion::None)
result.push_back("--library=qt");
return result;
diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
index 6b26cd8185..3da5501302 100644
--- a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
+++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp
@@ -902,7 +902,7 @@ QModelIndex SymbolsModel::index(int row, int column, const QModelIndex &parent)
scope = m_document->globalNamespace();
if (scope) {
- if ((unsigned)row < scope->memberCount())
+ if (row < scope->memberCount())
return createIndex(row, column, scope->memberAt(row));
}
@@ -997,8 +997,8 @@ public:
private:
struct TokenInfo {
Token token;
- unsigned line;
- unsigned column;
+ int line;
+ int column;
};
QList<TokenInfo> m_tokenInfos;
};
@@ -1254,9 +1254,8 @@ void WorkingCopyModel::configure(const WorkingCopy &workingCopy)
{
emit layoutAboutToBeChanged();
m_workingCopyList.clear();
- QHashIterator<Utils::FilePath, QPair<QByteArray, unsigned> > it = workingCopy.iterator();
- while (it.hasNext()) {
- it.next();
+ const WorkingCopy::Table &elements = workingCopy.elements();
+ for (auto it = elements.cbegin(), end = elements.cend(); it != end; ++it) {
m_workingCopyList << WorkingCopyEntry(it.key().toString(), it.value().first,
it.value().second);
}
diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp
index f09e3807d3..5d85bd638c 100644
--- a/src/plugins/cppeditor/cppeditordocument.cpp
+++ b/src/plugins/cppeditor/cppeditordocument.cpp
@@ -176,15 +176,8 @@ QByteArray CppEditorDocument::contentsText() const
void CppEditorDocument::applyFontSettings()
{
- if (TextEditor::SyntaxHighlighter *highlighter = syntaxHighlighter()) {
- // Clear all additional formats since they may have changed
- QTextBlock b = document()->firstBlock();
- while (b.isValid()) {
- QVector<QTextLayout::FormatRange> noFormats;
- highlighter->setExtraFormats(b, noFormats);
- b = b.next();
- }
- }
+ if (TextEditor::SyntaxHighlighter *highlighter = syntaxHighlighter())
+ highlighter->clearAllExtraFormats(); // Clear all additional formats since they may have changed
TextDocument::applyFontSettings(); // rehighlights and updates additional formats
if (m_processor)
m_processor->semanticRehighlight();
@@ -241,7 +234,7 @@ void CppEditorDocument::reparseWithPreferredParseContext(const QString &parseCon
void CppEditorDocument::onFilePathChanged(const Utils::FilePath &oldPath,
const Utils::FilePath &newPath)
{
- Q_UNUSED(oldPath);
+ Q_UNUSED(oldPath)
if (!newPath.isEmpty()) {
indenter()->setFileName(newPath);
@@ -364,7 +357,7 @@ void CppEditorDocument::showHideInfoBarAboutMultipleParseContexts(bool show)
Core::InfoBarEntry info(id,
tr("Note: Multiple parse contexts are available for this file. "
"Choose the preferred one from the editor toolbar."),
- Core::InfoBarEntry::GlobalSuppressionEnabled);
+ Core::InfoBarEntry::GlobalSuppression::Enabled);
info.removeCancelButton();
if (infoBar()->canInfoBeAdded(id))
infoBar()->addInfo(info);
diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp
index 6877497884..678d529965 100644
--- a/src/plugins/cppeditor/cppeditorwidget.cpp
+++ b/src/plugins/cppeditor/cppeditorwidget.cpp
@@ -346,18 +346,16 @@ void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show)
action->setVisible(show);
}
-static QString getDocumentLine(const QTextDocument &document, int line)
+static QString getDocumentLine(QTextDocument *document, int line)
{
- return document.findBlockByNumber(line - 1).text();
+ if (document)
+ return document->findBlockByNumber(line - 1).text();
+
+ return {};
}
-static QString getFileLine(const QString &path, int line)
+static std::unique_ptr<QTextDocument> getCurrentDocument(const QString &path)
{
- const IDocument *document = DocumentModel::documentForFilePath(path);
- const auto textDocument = qobject_cast<const TextDocument *>(document);
- if (textDocument)
- return getDocumentLine(*textDocument->document(), line);
-
const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec();
QString contents;
Utils::TextFileFormat format;
@@ -365,11 +363,10 @@ static QString getFileLine(const QString &path, int line)
if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error)
!= Utils::TextFileFormat::ReadSuccess) {
qWarning() << "Error reading file " << path << " : " << error;
- return QString();
+ return {};
}
- const QTextDocument tmpDocument{contents};
- return getDocumentLine(tmpDocument, line);
+ return std::make_unique<QTextDocument>(contents);
}
static void onReplaceUsagesClicked(const QString &text,
@@ -387,6 +384,43 @@ static void onReplaceUsagesClicked(const QString &text,
}
}
+static QTextDocument *getOpenDocument(const QString &path)
+{
+ const IDocument *document = DocumentModel::documentForFilePath(path);
+ if (document)
+ return qobject_cast<const TextDocument *>(document)->document();
+
+ return {};
+}
+
+static void addSearchResults(CppTools::Usages usages, SearchResult &search, const QString &text)
+{
+ std::sort(usages.begin(), usages.end());
+
+ std::unique_ptr<QTextDocument> currentDocument;
+ QString lastPath;
+
+ for (const CppTools::Usage &usage : usages) {
+ QTextDocument *document = getOpenDocument(usage.path);
+
+ if (!document) {
+ if (usage.path != lastPath) {
+ currentDocument = getCurrentDocument(usage.path);
+ lastPath = usage.path;
+ }
+ document = currentDocument.get();
+ }
+
+ const QString lineContent = getDocumentLine(document, usage.line);
+
+ if (lineContent.size()) {
+ Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1),
+ Search::TextPosition(usage.line, usage.column + text.length() - 1)};
+ search.addResult(usage.path, lineContent, range);
+ }
+ }
+}
+
static void findRenameCallback(CppEditorWidget *widget,
const QTextCursor &baseCursor,
const CppTools::Usages &usages,
@@ -413,14 +447,9 @@ static void findRenameCallback(CppEditorWidget *widget,
[widget, rename, replacement, baseCursor]() {
rename ? widget->renameUsages(replacement, baseCursor) : widget->findUsages(baseCursor);
});
- for (const CppTools::Usage &usage : usages) {
- const QString lineStr = getFileLine(usage.path, usage.line);
- if (lineStr.isEmpty())
- continue;
- Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1),
- Search::TextPosition(usage.line, usage.column + text.length() - 1)};
- search->addResult(usage.path, lineStr, range);
- }
+
+ addSearchResults(usages, *search, text);
+
search->finishSearch(false);
QObject::connect(search, &SearchResult::activated,
[](const Core::SearchResultItem& item) {
diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
index 2a53648b31..beb2e2aaf7 100644
--- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
+++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
@@ -878,9 +878,8 @@ ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffse
const LocalSymbols localSymbols(targetFile->cppDocument(), targetDefinition);
const int endOfArguments = targetFile->endOf(targetFunctionDeclarator->rparen_token);
- QHashIterator<Symbol *, QString> it(renamedTargetParameters);
- while (it.hasNext()) {
- it.next();
+ for (auto it = renamedTargetParameters.cbegin(), end = renamedTargetParameters.cend();
+ it != end; ++it) {
const QList<SemanticInfo::Use> &uses = localSymbols.uses.value(it.key());
foreach (const SemanticInfo::Use &use, uses) {
if (use.isInvalid())
diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.h b/src/plugins/cppeditor/cppfunctiondecldeflink.h
index 136e069449..0f11fabc8d 100644
--- a/src/plugins/cppeditor/cppfunctiondecldeflink.h
+++ b/src/plugins/cppeditor/cppfunctiondecldeflink.h
@@ -94,8 +94,8 @@ public:
// The 'target' prefix denotes information about the remote declaration matching
// the 'source' declaration, where we will try to apply the user changes.
// 1-based line and column
- unsigned targetLine = 0;
- unsigned targetColumn = 0;
+ int targetLine = 0;
+ int targetColumn = 0;
QString targetInitial;
CppTools::CppRefactoringFileConstPtr targetFile;
diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp
index a7531acf1e..681ba51ce3 100644
--- a/src/plugins/cppeditor/cpphighlighter.cpp
+++ b/src/plugins/cppeditor/cpphighlighter.cpp
@@ -86,7 +86,7 @@ void CppHighlighter::highlightBlock(const QString &text)
return;
}
- const unsigned firstNonSpace = tokens.first().utf16charsBegin();
+ const int firstNonSpace = tokens.first().utf16charsBegin();
Parentheses parentheses;
parentheses.reserve(5);
@@ -97,7 +97,7 @@ void CppHighlighter::highlightBlock(const QString &text)
for (int i = 0; i < tokens.size(); ++i) {
const Token &tk = tokens.at(i);
- unsigned previousTokenEnd = 0;
+ int previousTokenEnd = 0;
if (i != 0) {
// mark the whitespaces
previousTokenEnd = tokens.at(i - 1).utf16charsBegin() +
diff --git a/src/plugins/cppeditor/cppincludehierarchy.cpp b/src/plugins/cppeditor/cppincludehierarchy.cpp
index eaa1b064c8..41985bd555 100644
--- a/src/plugins/cppeditor/cppincludehierarchy.cpp
+++ b/src/plugins/cppeditor/cppincludehierarchy.cpp
@@ -180,7 +180,7 @@ private:
QVariant CppIncludeHierarchyItem::data(int column, int role) const
{
- Q_UNUSED(column);
+ Q_UNUSED(column)
if (role == Qt::DisplayRole) {
if (isPhony() && childCount() == 0)
return QString(m_fileName + ' ' + CppIncludeHierarchyModel::tr("(none)"));
@@ -409,7 +409,7 @@ CppIncludeHierarchyWidget::CppIncludeHierarchyWidget()
this, &CppIncludeHierarchyWidget::syncFromEditorManager);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_inspectedFile);
layout->addWidget(ItemViewFind::createSearchableWrapper(new IncludeFinder(m_treeView, &m_model)));
diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
index 1f2650ac63..1985203f47 100644
--- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
+++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
@@ -844,7 +844,7 @@ public:
// make target lookup context
Document::Ptr implementationDoc = implementationFile->cppDocument();
- unsigned line, column;
+ int line, column;
implementationDoc->translationUnit()->getPosition(insertPos, &line, &column);
Scope *targetScope = implementationDoc->scopeAt(line, column);
const LookupContext targetContext(implementationDoc, snapshot());
@@ -853,7 +853,7 @@ public:
targetCoN = targetContext.globalNamespace();
// Loop through inserted declarations
- for (unsigned i = targetClass->memberCount(); i < clazz->memberCount(); ++i) {
+ for (int i = targetClass->memberCount(); i < clazz->memberCount(); ++i) {
Declaration *decl = clazz->memberAt(i)->asDeclaration();
if (!decl)
continue;
@@ -1011,7 +1011,7 @@ void InsertVirtualMethodsDialog::initGui()
auto overrideWidgetsLayout = new QHBoxLayout(this);
overrideWidgetsLayout->setSpacing(0);
- overrideWidgetsLayout->setMargin(0);
+ overrideWidgetsLayout->setContentsMargins(0, 0, 0, 0);
overrideWidgetsLayout->addWidget(m_overrideReplacementCheckBox);
overrideWidgetsLayout->addWidget(m_overrideReplacementComboBox);
overrideWidgetsLayout->addWidget(m_clearUserAddedReplacementsButton);
diff --git a/src/plugins/cppeditor/cppoutline.cpp b/src/plugins/cppeditor/cppoutline.cpp
index 55a2e93f19..137e73292a 100644
--- a/src/plugins/cppeditor/cppoutline.cpp
+++ b/src/plugins/cppeditor/cppoutline.cpp
@@ -108,7 +108,7 @@ CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) :
m_proxyModel->setSourceModel(model);
auto *layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_treeView));
setLayout(layout);
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 538c9242b8..7689e960e0 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -131,7 +131,7 @@ InsertionLocation insertLocationForMethodDefinition(Symbol *symbol, const bool u
// ...failed,
// if class member try to get position right after class
CppRefactoringFilePtr file = refactoring.file(fileName);
- unsigned line = 0, column = 0;
+ int line = 0, column = 0;
if (Class *clazz = symbol->enclosingClass()) {
if (symbol->fileName() == fileName.toUtf8()) {
file->cppDocument()->translationUnit()->getPosition(clazz->endOffset(), &line, &column);
@@ -1854,7 +1854,7 @@ bool canLookupDefinition(const CppQuickFixInterface &interface, const NameAST *n
QTC_ASSERT(nameAst && nameAst->name, return false);
// Find the enclosing scope
- unsigned line, column;
+ int line, column;
const Document::Ptr &doc = interface.semanticInfo().doc;
doc->translationUnit()->getTokenStartPosition(nameAst->firstToken(), &line, &column);
Scope *scope = doc->scopeAt(line, column);
@@ -2364,7 +2364,7 @@ void CompleteSwitchCaseStatement::match(const CppQuickFixInterface &interface,
// check the possible enum values
QStringList values;
Overview prettyPrint;
- for (unsigned i = 0; i < e->memberCount(); ++i) {
+ for (int i = 0; i < e->memberCount(); ++i) {
if (Declaration *decl = e->memberAt(i)->asDeclaration())
values << prettyPrint.prettyName(LookupContext::fullyQualifiedName(decl));
}
@@ -2690,7 +2690,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe
if (Symbol *symbol = simpleDecl->symbols->value) {
if (Declaration *decl = symbol->asDeclaration()) {
if (Function *func = decl->type()->asFunctionType()) {
- if (func->isSignal())
+ if (func->isSignal() || func->isPureVirtual())
return;
// Check if there is already a definition
@@ -2752,7 +2752,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe
// Insert Position: Inside Class
// Determine insert location direct after the declaration.
- unsigned line, column;
+ int line, column;
const CppRefactoringFilePtr file = interface.currentFile();
file->lineAndColumn(file->endOf(simpleDecl), &line, &column);
const InsertionLocation loc
@@ -2779,7 +2779,7 @@ bool hasClassMemberWithGetPrefix(const Class *klass)
if (!klass)
return false;
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
const Symbol *symbol = klass->memberAt(i);
if (symbol->isFunction() || symbol->isDeclaration()) {
if (const Name *symbolName = symbol->name()) {
@@ -2872,7 +2872,7 @@ public:
bool hasGetter = false;
bool hasSetter = false;
if (Class *klass = m_classSpecifier->symbol) {
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *symbol = klass->memberAt(i);
if (symbol->isQtPropertyDeclaration())
continue;
@@ -3125,7 +3125,7 @@ public:
// Create and apply changes
ChangeSet currChanges;
- int declInsertPos = currentFile->position(qMax(1u, declLocation.line()),
+ int declInsertPos = currentFile->position(qMax(1, declLocation.line()),
declLocation.column());
currChanges.insert(declInsertPos, declaration);
@@ -3729,10 +3729,8 @@ void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOpera
// Identify what would be parameters for the new function and its return value, if any.
Symbol *funcReturn = nullptr;
QList<QPair<QString, QString> > relevantDecls;
- SemanticInfo::LocalUseIterator it(interface.semanticInfo().localUses);
- while (it.hasNext()) {
- it.next();
-
+ const SemanticInfo::LocalUseMap localUses = interface.semanticInfo().localUses;
+ for (auto it = localUses.cbegin(), end = localUses.cend(); it != end; ++it) {
bool usedBeforeExtraction = false;
bool usedAfterExtraction = false;
bool usedInsideExtraction = false;
@@ -4608,7 +4606,7 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface,
Class *c = klass->symbol;
Overview overview;
- for (unsigned i = 0; i < c->memberCount(); ++i) {
+ for (int i = 0; i < c->memberCount(); ++i) {
Symbol *member = c->memberAt(i);
FullySpecifiedType type = member->type();
if (member->asFunction() || (type.isValid() && type->asFunctionType())) {
diff --git a/src/plugins/cppeditor/cpptypehierarchy.cpp b/src/plugins/cppeditor/cpptypehierarchy.cpp
index 822ec44ff9..081a0c5e98 100644
--- a/src/plugins/cppeditor/cpptypehierarchy.cpp
+++ b/src/plugins/cppeditor/cpptypehierarchy.cpp
@@ -114,7 +114,7 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget()
m_hierarchyWidget = new QWidget(this);
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_inspectedClass);
layout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_treeView));
diff --git a/src/plugins/cppeditor/cppuseselections_test.cpp b/src/plugins/cppeditor/cppuseselections_test.cpp
index 6909c202a8..8eb1700a06 100644
--- a/src/plugins/cppeditor/cppuseselections_test.cpp
+++ b/src/plugins/cppeditor/cppuseselections_test.cpp
@@ -164,7 +164,7 @@ void CppEditorPlugin::test_useSelections_data()
);
QTest::newRow("local use as macro argument 1 - argument expanded")
- << _("#define Q_UNUSED(x) (void)x;\n"
+ << _("#define Q_UNUSED(x) (void)x\n"
"void f(int arg)\n"
"{\n"
" Q_UNUSED(@arg)\n"
diff --git a/src/plugins/cppeditor/fileandtokenactions_test.cpp b/src/plugins/cppeditor/fileandtokenactions_test.cpp
index 02c1314d7d..1c058c0f82 100644
--- a/src/plugins/cppeditor/fileandtokenactions_test.cpp
+++ b/src/plugins/cppeditor/fileandtokenactions_test.cpp
@@ -232,7 +232,7 @@ TestActionsTestCase::TestActionsTestCase(const Actions &tokenActions, const Acti
i = j - 1; // Continue with next not expanded token
} else {
// Position the cursor on the token
- unsigned line, column;
+ int line, column;
translationUnit->getPosition(token.utf16charsBegin(), &line, &column);
editor->gotoLine(line, column - 1);
QApplication::processEvents();
@@ -287,7 +287,7 @@ void TestActionsTestCase::moveWordCamelCaseToToken(TranslationUnit *translationU
CppEditorWidget *editorWidget = dynamic_cast<CppEditorWidget *>(editor->editorWidget());
QVERIFY(editorWidget);
- unsigned line, column;
+ int line, column;
translationUnit->getPosition(token.utf16charsBegin(), &line, &column);
while (editor->currentLine() < (int) line
diff --git a/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp b/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp
index 082c04493d..1b70afa4b0 100644
--- a/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp
+++ b/src/plugins/cppeditor/resourcepreviewhoverhandler.cpp
@@ -26,14 +26,15 @@
#include "resourcepreviewhoverhandler.h"
#include <coreplugin/icore.h>
-#include <utils/tooltip/tooltip.h>
-#include <utils/fileutils.h>
-#include <utils/qtcassert.h>
-#include <utils/mimetypes/mimedatabase.h>
-#include <projectexplorer/projecttree.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/projecttree.h>
#include <texteditor/texteditor.h>
#include <utils/executeondestruction.h>
+#include <utils/fileutils.h>
+#include <utils/mimetypes/mimedatabase.h>
+#include <utils/qtcassert.h>
+#include <utils/tooltip/tooltip.h>
#include <QPoint>
#include <QTextBlock>
@@ -143,10 +144,9 @@ static QString findResourceInProject(const QString &resName)
return QString();
if (auto *project = ProjectExplorer::ProjectTree::currentProject()) {
- const Utils::FilePathList files = project->files(ProjectExplorer::Project::AllFiles);
+ const Utils::FilePathList files = project->files(
+ [](const ProjectExplorer::Node *n) { return n->filePath().endsWith(".qrc"); });
for (const Utils::FilePath &file : files) {
- if (!file.endsWith(".qrc"))
- continue;
const QFileInfo fi = file.toFileInfo();
if (!fi.isReadable())
continue;
diff --git a/src/plugins/cpptools/CMakeLists.txt b/src/plugins/cpptools/CMakeLists.txt
index c99705cbc1..e6e5bc129c 100644
--- a/src/plugins/cpptools/CMakeLists.txt
+++ b/src/plugins/cpptools/CMakeLists.txt
@@ -48,7 +48,6 @@ add_qtc_plugin(CppTools
cpphoverhandler.cpp cpphoverhandler.h
cppincludesfilter.cpp cppincludesfilter.h
cppindexingsupport.cpp cppindexingsupport.h
- cppkitinfo.cpp cppkitinfo.h
cpplocalsymbols.cpp cpplocalsymbols.h
cpplocatordata.cpp cpplocatordata.h
cpplocatorfilter.cpp cpplocatorfilter.h
@@ -62,8 +61,8 @@ add_qtc_plugin(CppTools
cppprojectinfogenerator.cpp cppprojectinfogenerator.h
cppprojectpartchooser.cpp cppprojectpartchooser.h
cppprojectupdater.cpp cppprojectupdater.h
+ cppprojectupdaterinterface.h
cppqtstyleindenter.cpp cppqtstyleindenter.h
- cpprawprojectpart.cpp cpprawprojectpart.h
cpprefactoringchanges.cpp cpprefactoringchanges.h
cpprefactoringengine.cpp cpprefactoringengine.h
cppselectionchanger.cpp cppselectionchanger.h
@@ -71,7 +70,6 @@ add_qtc_plugin(CppTools
cppsemanticinfoupdater.cpp cppsemanticinfoupdater.h
cppsourceprocessor.cpp cppsourceprocessor.h
cppsymbolinfo.h
- cpptools.qrc
cpptools_clangtidychecks.h
cpptools_clazychecks.h
cpptools_global.h
diff --git a/src/plugins/cpptools/baseeditordocumentparser.cpp b/src/plugins/cpptools/baseeditordocumentparser.cpp
index 91c6a3aa79..0616182376 100644
--- a/src/plugins/cpptools/baseeditordocumentparser.cpp
+++ b/src/plugins/cpptools/baseeditordocumentparser.cpp
@@ -55,7 +55,7 @@ BaseEditorDocumentParser::BaseEditorDocumentParser(const QString &filePath)
: m_filePath(filePath)
{
static int meta = qRegisterMetaType<ProjectPartInfo>("CppTools::ProjectPartInfo");
- Q_UNUSED(meta);
+ Q_UNUSED(meta)
}
BaseEditorDocumentParser::~BaseEditorDocumentParser() = default;
diff --git a/src/plugins/cpptools/builtincursorinfo.cpp b/src/plugins/cpptools/builtincursorinfo.cpp
index 486db2c503..c1e4a9c8c7 100644
--- a/src/plugins/cpptools/builtincursorinfo.cpp
+++ b/src/plugins/cpptools/builtincursorinfo.cpp
@@ -55,26 +55,24 @@ CursorInfo::Range toRange(const SemanticInfo::Use &use)
CursorInfo::Range toRange(int tokenIndex, TranslationUnit *translationUnit)
{
- unsigned line, column;
- translationUnit->getTokenPosition(static_cast<unsigned>(tokenIndex), &line, &column);
+ int line, column;
+ translationUnit->getTokenPosition(tokenIndex, &line, &column);
if (column)
--column; // adjust the column position.
return {line,
column + 1,
- translationUnit->tokenAt(static_cast<unsigned>(tokenIndex)).utf16chars()};
+ translationUnit->tokenAt(tokenIndex).utf16chars()};
}
-CursorInfo::Range toRange(const QTextCursor &textCursor,
- unsigned utf16offset,
- unsigned length)
+CursorInfo::Range toRange(const QTextCursor &textCursor, int utf16offset, int length)
{
QTextCursor cursor(textCursor.document());
- cursor.setPosition(static_cast<int>(utf16offset));
+ cursor.setPosition(utf16offset);
const QTextBlock textBlock = cursor.block();
- return {static_cast<unsigned>(textBlock.blockNumber() + 1),
- static_cast<unsigned>(cursor.position() - textBlock.position() + 1),
+ return {textBlock.blockNumber() + 1,
+ cursor.position() - textBlock.position() + 1,
length};
}
@@ -102,8 +100,8 @@ CursorInfo::Ranges toRanges(const QList<int> &tokenIndices, TranslationUnit *tra
class FunctionDefinitionUnderCursor: protected ASTVisitor
{
- unsigned m_line = 0;
- unsigned m_column = 0;
+ int m_line = 0;
+ int m_column = 0;
DeclarationAST *m_functionDefinition = nullptr;
public:
@@ -111,7 +109,7 @@ public:
: ASTVisitor(translationUnit)
{ }
- DeclarationAST *operator()(AST *ast, unsigned line, unsigned column)
+ DeclarationAST *operator()(AST *ast, int line, int column)
{
m_functionDefinition = nullptr;
m_line = line;
@@ -140,8 +138,8 @@ protected:
private:
bool checkDeclaration(DeclarationAST *ast)
{
- unsigned startLine, startColumn;
- unsigned endLine, endColumn;
+ int startLine, startColumn;
+ int endLine, endColumn;
getTokenStartPosition(ast->firstToken(), &startLine, &startColumn);
getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn);
@@ -207,16 +205,13 @@ private:
LookupContext context(m_document, m_snapshot);
- CppTools::SemanticInfo::LocalUseIterator it(uses);
- while (it.hasNext()) {
- it.next();
+ for (auto it = uses.cbegin(), end = uses.cend(); it != end; ++it) {
const SemanticUses &uses = it.value();
bool good = false;
foreach (const CppTools::SemanticInfo::Use &use, uses) {
- const auto l = static_cast<unsigned>(m_line);
- const auto c = static_cast<unsigned>(m_column);
- if (l == use.line && c >= use.column && c <= (use.column + use.length)) {
+ if (m_line == use.line && m_column >= use.column
+ && m_column <= static_cast<int>(use.column + use.length)) {
good = true;
break;
}
@@ -293,7 +288,7 @@ bool handleMacroCase(const Document::Ptr document,
if (!macro)
return false;
- const unsigned length = static_cast<unsigned>(macro->nameToQString().size());
+ const int length = macro->nameToQString().size();
// Macro definition
if (macro->fileName() == document->fileName())
@@ -359,9 +354,7 @@ BuiltinCursorInfo::findLocalUses(const Document::Ptr &document, int line, int co
AST *ast = document->translationUnit()->ast();
FunctionDefinitionUnderCursor functionDefinitionUnderCursor(document->translationUnit());
- DeclarationAST *declaration = functionDefinitionUnderCursor(ast,
- static_cast<unsigned>(line),
- static_cast<unsigned>(column));
+ DeclarationAST *declaration = functionDefinitionUnderCursor(ast, line, column);
return CppTools::LocalSymbols(document, declaration).uses;
}
diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp
index 9232750684..c9f69f644c 100644
--- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp
+++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp
@@ -71,7 +71,7 @@ QList<QTextEdit::ExtraSelection> toTextEditorSelections(
QTextCursor c(textDocument->findBlockByNumber(m.line() - 1));
const QString text = c.block().text();
const int startPos = m.column() > 0 ? m.column() - 1 : 0;
- if (m.length() > 0 && startPos + m.length() <= (unsigned)text.size()) {
+ if (m.length() > 0 && startPos + m.length() <= text.size()) {
c.setPosition(c.position() + startPos);
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, m.length());
} else {
diff --git a/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp
index 7899fcae4c..217ca95cb2 100644
--- a/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp
+++ b/src/plugins/cpptools/clangdiagnosticconfigsselectionwidget.cpp
@@ -45,7 +45,7 @@ ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWi
, m_selectionComboBox(new QComboBox(this))
{
auto *layout = new QHBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
layout->addWidget(m_label);
layout->addWidget(m_selectionComboBox, 1);
@@ -108,7 +108,7 @@ void ClangDiagnosticConfigsSelectionWidget::connectToClangDiagnosticConfigsDialo
{
connect(button, &QPushButton::clicked, [this]() {
ClangDiagnosticConfigsWidget *widget = new ClangDiagnosticConfigsWidget(currentConfigId());
- widget->layout()->setMargin(0);
+ widget->layout()->setContentsMargins(0, 0, 0, 0);
QDialog dialog;
dialog.setWindowTitle(ClangDiagnosticConfigsWidget::tr("Diagnostic Configurations"));
dialog.setLayout(new QVBoxLayout);
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index 3d74ad8d32..e2858fb368 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -656,7 +656,7 @@ void CompilerOptionsBuilder::addWrappedQtHeadersIncludePath(QStringList &list) c
static QString wrappedQtHeadersPath = resourcePath + "/cplusplus/wrappedQtHeaders";
QTC_ASSERT(QDir(wrappedQtHeadersPath).exists(), return;);
- if (m_projectPart.qtVersion != ProjectPart::NoQt) {
+ if (m_projectPart.qtVersion != Utils::QtVersion::None) {
const QString wrappedQtCoreHeaderPath = wrappedQtHeadersPath + "/QtCore";
list.append({includeUserPathOption,
QDir::toNativeSeparators(wrappedQtHeadersPath),
diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp
index ea534531e6..f4458bd059 100644
--- a/src/plugins/cpptools/cppchecksymbols.cpp
+++ b/src/plugins/cpptools/cppchecksymbols.cpp
@@ -314,9 +314,9 @@ CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context, cons
: ASTVisitor(doc->translationUnit()), _doc(doc), _context(context)
, _lineOfLastUsage(0), _macroUses(macroUses)
{
- unsigned line = 0;
+ int line = 0;
getTokenEndPosition(translationUnit()->ast()->lastToken(), &line, nullptr);
- _chunkSize = qMax(50U, line / 200);
+ _chunkSize = qMax(50, line / 200);
_usages.reserve(_chunkSize);
_astStack.reserve(200);
@@ -365,7 +365,7 @@ bool CheckSymbols::warning(AST *ast, const QString &text)
const Token &lastToken = tokenAt(ast->lastToken() - 1);
const unsigned length = lastToken.utf16charsEnd() - firstToken.utf16charsBegin();
- unsigned line = 1, column = 1;
+ int line = 1, column = 1;
getTokenStartPosition(ast->firstToken(), &line, &column);
warning(line, column, text, length);
@@ -478,7 +478,7 @@ bool CheckSymbols::visit(NamespaceAST *ast)
if (ast->identifier_token) {
const Token &tok = tokenAt(ast->identifier_token);
if (!tok.generated()) {
- unsigned line, column;
+ int line, column;
getTokenStartPosition(ast->identifier_token, &line, &column);
Result use(line, column, tok.utf16chars(), SemanticHighlighter::TypeUse);
addUse(use);
@@ -786,7 +786,7 @@ void CheckSymbols::checkNamespace(NameAST *name)
if (!name)
return;
- unsigned line, column;
+ int line, column;
getTokenStartPosition(name->firstToken(), &line, &column);
if (ClassOrNamespace *b = _context.lookupType(name->name, enclosingScope())) {
@@ -1184,7 +1184,7 @@ void CheckSymbols::addUse(unsigned tokenIndex, Kind kind)
if (tok.generated())
return;
- unsigned line, column;
+ int line, column;
getTokenStartPosition(tokenIndex, &line, &column);
const unsigned length = tok.utf16chars();
@@ -1221,7 +1221,7 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast)
if (tok.generated())
return;
- unsigned line, column;
+ int line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
const Result use(line, column, length, SemanticHighlighter::TypeUse);
@@ -1263,7 +1263,7 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
c->isClass() || c->isEnum() || isTemplateClass(c) ||
c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum() != nullptr) {
- unsigned line, column;
+ int line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
@@ -1305,7 +1305,7 @@ bool CheckSymbols::maybeAddField(const QList<LookupItem> &candidates, NameAST *a
else if (c->isTypedef() || (c->type() && c->type()->isFunctionType()))
return false; // shadowed
- unsigned line, column;
+ int line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
@@ -1319,9 +1319,9 @@ bool CheckSymbols::maybeAddField(const QList<LookupItem> &candidates, NameAST *a
}
bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST *ast,
- unsigned argumentCount, FunctionKind functionKind)
+ int argumentCount, FunctionKind functionKind)
{
- unsigned startToken = ast->firstToken();
+ int startToken = ast->firstToken();
bool isDestructor = false;
bool isConstructor = false;
if (DestructorNameAST *dtor = ast->asDestructorName()) {
@@ -1399,7 +1399,7 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
return false;
}
- unsigned line, column;
+ int line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
diff --git a/src/plugins/cpptools/cppchecksymbols.h b/src/plugins/cpptools/cppchecksymbols.h
index 9a686c2995..fa1229977d 100644
--- a/src/plugins/cpptools/cppchecksymbols.h
+++ b/src/plugins/cpptools/cppchecksymbols.h
@@ -132,7 +132,7 @@ protected:
bool maybeAddField(const QList<CPlusPlus::LookupItem> &candidates,
CPlusPlus::NameAST *ast);
bool maybeAddFunction(const QList<CPlusPlus::LookupItem> &candidates,
- CPlusPlus::NameAST *ast, unsigned argumentCount,
+ CPlusPlus::NameAST *ast, int argumentCount,
FunctionKind functionKind);
bool isTemplateClass(CPlusPlus::Symbol *s) const;
@@ -201,7 +201,7 @@ private:
QVector<Result> _usages;
QList<CPlusPlus::Document::DiagnosticMessage> _diagMsgs;
int _chunkSize;
- unsigned _lineOfLastUsage;
+ int _lineOfLastUsage;
QList<Result> _macroUses;
};
diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index 069359d869..fca7998ece 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -1054,6 +1054,8 @@ int CodeFormatter::tokenizeBlock(const QTextBlock &block, bool *endedJoined)
features.qtKeywordsEnabled = true;
features.cxxEnabled = true;
features.objCEnabled = true;
+ features.cxx11Enabled = true;
+ features.cxx14Enabled = true;
SimpleLexer tokenize;
tokenize.setLanguageFeatures(features);
diff --git a/src/plugins/cpptools/cppcodegen_test.cpp b/src/plugins/cpptools/cppcodegen_test.cpp
index 01d8973904..088e55c9de 100644
--- a/src/plugins/cpptools/cppcodegen_test.cpp
+++ b/src/plugins/cpptools/cppcodegen_test.cpp
@@ -45,7 +45,7 @@ using namespace CppTools::Internal;
namespace {
Document::Ptr createDocument(const QString &filePath, const QByteArray &text,
- unsigned expectedGlobalSymbolCount)
+ int expectedGlobalSymbolCount)
{
Document::Ptr document = Document::create(filePath);
document->setUtf8Source(text);
@@ -59,7 +59,7 @@ Document::Ptr createDocument(const QString &filePath, const QByteArray &text,
Document::Ptr createDocumentAndFile(Tests::TemporaryDir *temporaryDir,
const QByteArray relativeFilePath,
const QByteArray text,
- unsigned expectedGlobalSymbolCount)
+ int expectedGlobalSymbolCount)
{
QTC_ASSERT(temporaryDir, return Document::Ptr());
const QString absoluteFilePath = temporaryDir->createFile(relativeFilePath, text);
@@ -80,13 +80,13 @@ void CppToolsPlugin::test_codegen_public_in_empty_class()
"{\n"
"};\n"
"\n";
- Document::Ptr doc = createDocument(QLatin1String("public_in_empty_class"), src, 1U);
+ Document::Ptr doc = createDocument(QLatin1String("public_in_empty_class"), src, 1);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -99,8 +99,8 @@ void CppToolsPlugin::test_codegen_public_in_empty_class()
QVERIFY(loc.isValid());
QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
QVERIFY(loc.suffix().isEmpty());
- QCOMPARE(loc.line(), 3U);
- QCOMPARE(loc.column(), 1U);
+ QCOMPARE(loc.line(), 3);
+ QCOMPARE(loc.column(), 1);
}
/*!
@@ -114,13 +114,13 @@ void CppToolsPlugin::test_codegen_public_in_nonempty_class()
"public:\n" // line 3
"};\n" // line 4
"\n";
- Document::Ptr doc = createDocument(QLatin1String("public_in_nonempty_class"), src, 1U);
+ Document::Ptr doc = createDocument(QLatin1String("public_in_nonempty_class"), src, 1);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -133,8 +133,8 @@ void CppToolsPlugin::test_codegen_public_in_nonempty_class()
QVERIFY(loc.isValid());
QVERIFY(loc.prefix().isEmpty());
QVERIFY(loc.suffix().isEmpty());
- QCOMPARE(loc.line(), 4U);
- QCOMPARE(loc.column(), 1U);
+ QCOMPARE(loc.line(), 4);
+ QCOMPARE(loc.column(), 1);
}
/*!
@@ -148,13 +148,13 @@ void CppToolsPlugin::test_codegen_public_before_protected()
"protected:\n" // line 3
"};\n"
"\n";
- Document::Ptr doc = createDocument(QLatin1String("public_before_protected"), src, 1U);
+ Document::Ptr doc = createDocument(QLatin1String("public_before_protected"), src, 1);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -167,8 +167,8 @@ void CppToolsPlugin::test_codegen_public_before_protected()
QVERIFY(loc.isValid());
QCOMPARE(loc.prefix(), QLatin1String("public:\n"));
QCOMPARE(loc.suffix(), QLatin1String("\n"));
- QCOMPARE(loc.column(), 1U);
- QCOMPARE(loc.line(), 3U);
+ QCOMPARE(loc.column(), 1);
+ QCOMPARE(loc.line(), 3);
}
/*!
@@ -183,13 +183,13 @@ void CppToolsPlugin::test_codegen_private_after_protected()
"protected:\n" // line 3
"};\n"
"\n";
- Document::Ptr doc = createDocument(QLatin1String("private_after_protected"), src, 1U);
+ Document::Ptr doc = createDocument(QLatin1String("private_after_protected"), src, 1);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -202,8 +202,8 @@ void CppToolsPlugin::test_codegen_private_after_protected()
QVERIFY(loc.isValid());
QCOMPARE(loc.prefix(), QLatin1String("private:\n"));
QVERIFY(loc.suffix().isEmpty());
- QCOMPARE(loc.column(), 1U);
- QCOMPARE(loc.line(), 4U);
+ QCOMPARE(loc.column(), 1);
+ QCOMPARE(loc.line(), 4);
}
/*!
@@ -218,13 +218,13 @@ void CppToolsPlugin::test_codegen_protected_in_nonempty_class()
"public:\n" // line 3
"};\n" // line 4
"\n";
- Document::Ptr doc = createDocument(QLatin1String("protected_in_nonempty_class"), src, 1U);
+ Document::Ptr doc = createDocument(QLatin1String("protected_in_nonempty_class"), src, 1);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -237,8 +237,8 @@ void CppToolsPlugin::test_codegen_protected_in_nonempty_class()
QVERIFY(loc.isValid());
QCOMPARE(loc.prefix(), QLatin1String("protected:\n"));
QVERIFY(loc.suffix().isEmpty());
- QCOMPARE(loc.column(), 1U);
- QCOMPARE(loc.line(), 4U);
+ QCOMPARE(loc.column(), 1);
+ QCOMPARE(loc.line(), 4);
}
/*!
@@ -253,13 +253,13 @@ void CppToolsPlugin::test_codegen_protected_between_public_and_private()
"private:\n" // line 4
"};\n" // line 5
"\n";
- Document::Ptr doc = createDocument(QLatin1String("protected_betwee_public_and_private"), src, 1U);
+ Document::Ptr doc = createDocument(QLatin1String("protected_betwee_public_and_private"), src, 1);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -272,8 +272,8 @@ void CppToolsPlugin::test_codegen_protected_between_public_and_private()
QVERIFY(loc.isValid());
QCOMPARE(loc.prefix(), QLatin1String("protected:\n"));
QCOMPARE(loc.suffix(), QLatin1String("\n"));
- QCOMPARE(loc.column(), 1U);
- QCOMPARE(loc.line(), 4U);
+ QCOMPARE(loc.column(), 1);
+ QCOMPARE(loc.line(), 4);
}
/*!
@@ -309,13 +309,13 @@ void CppToolsPlugin::test_codegen_qtdesigner_integration()
"\n"
"#endif // MAINWINDOW_H\n";
- Document::Ptr doc = createDocument(QLatin1String("qtdesigner_integration"), src, 2U);
+ Document::Ptr doc = createDocument(QLatin1String("qtdesigner_integration"), src, 2);
QVERIFY(doc);
Class *foo = doc->globalSymbolAt(1)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 10U);
- QCOMPARE(foo->column(), 7U);
+ QCOMPARE(foo->line(), 10);
+ QCOMPARE(foo->column(), 7);
Snapshot snapshot;
snapshot.insert(doc);
@@ -328,8 +328,8 @@ void CppToolsPlugin::test_codegen_qtdesigner_integration()
QVERIFY(loc.isValid());
QCOMPARE(loc.prefix(), QLatin1String("private slots:\n"));
QCOMPARE(loc.suffix(), QLatin1String("\n"));
- QCOMPARE(loc.line(), 18U);
- QCOMPARE(loc.column(), 1U);
+ QCOMPARE(loc.line(), 18);
+ QCOMPARE(loc.column(), 1);
}
void CppToolsPlugin::test_codegen_definition_empty_class()
@@ -343,13 +343,13 @@ void CppToolsPlugin::test_codegen_definition_empty_class()
"void foo();\n" // line 3
"};\n"
"\n";
- Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1U);
+ Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1);
QVERIFY(headerDocument);
const QByteArray sourceText = "\n"
"int x;\n" // line 1
"\n";
- Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 1U);
+ Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 1);
QVERIFY(sourceDocument);
Snapshot snapshot;
@@ -358,13 +358,13 @@ void CppToolsPlugin::test_codegen_definition_empty_class()
Class *foo = headerDocument->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
- QCOMPARE(foo->memberCount(), 1U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
+ QCOMPARE(foo->memberCount(), 1);
Declaration *decl = foo->memberAt(0)->asDeclaration();
QVERIFY(decl);
- QCOMPARE(decl->line(), 3U);
- QCOMPARE(decl->column(), 6U);
+ QCOMPARE(decl->line(), 3);
+ QCOMPARE(decl->column(), 6);
CppRefactoringChanges changes(snapshot);
InsertionPointLocator find(changes);
@@ -374,8 +374,8 @@ void CppToolsPlugin::test_codegen_definition_empty_class()
QCOMPARE(loc.fileName(), sourceDocument->fileName());
QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
QCOMPARE(loc.suffix(), QString());
- QCOMPARE(loc.line(), 3U);
- QCOMPARE(loc.column(), 1U);
+ QCOMPARE(loc.line(), 3);
+ QCOMPARE(loc.column(), 1);
}
void CppToolsPlugin::test_codegen_definition_first_member()
@@ -390,7 +390,7 @@ void CppToolsPlugin::test_codegen_definition_first_member()
"void bar();\n" // line 4
"};\n"
"\n";
- Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1U);
+ Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1);
QVERIFY(headerDocument);
const QByteArray sourceText = QString::fromLatin1(
@@ -404,7 +404,7 @@ void CppToolsPlugin::test_codegen_definition_first_member()
"}\n"
"\n"
"int y;\n").arg(temporaryDir.path()).toLatin1();
- Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3U);
+ Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3);
QVERIFY(sourceDocument);
sourceDocument->addIncludeFile(Document::Include(QLatin1String("file.h"),
headerDocument->fileName(), 1,
@@ -416,13 +416,13 @@ void CppToolsPlugin::test_codegen_definition_first_member()
Class *foo = headerDocument->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
- QCOMPARE(foo->memberCount(), 2U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
+ QCOMPARE(foo->memberCount(), 2);
Declaration *decl = foo->memberAt(0)->asDeclaration();
QVERIFY(decl);
- QCOMPARE(decl->line(), 3U);
- QCOMPARE(decl->column(), 6U);
+ QCOMPARE(decl->line(), 3);
+ QCOMPARE(decl->column(), 6);
CppRefactoringChanges changes(snapshot);
InsertionPointLocator find(changes);
@@ -430,8 +430,8 @@ void CppToolsPlugin::test_codegen_definition_first_member()
QVERIFY(locList.size() == 1);
InsertionLocation loc = locList.first();
QCOMPARE(loc.fileName(), sourceDocument->fileName());
- QCOMPARE(loc.line(), 4U);
- QCOMPARE(loc.column(), 1U);
+ QCOMPARE(loc.line(), 4);
+ QCOMPARE(loc.column(), 1);
QCOMPARE(loc.suffix(), QLatin1String("\n\n"));
QCOMPARE(loc.prefix(), QString());
}
@@ -448,7 +448,7 @@ void CppToolsPlugin::test_codegen_definition_last_member()
"void bar();\n" // line 4
"};\n"
"\n";
- Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1U);
+ Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1);
QVERIFY(headerDocument);
const QByteArray sourceText = QString::fromLatin1(
@@ -463,7 +463,7 @@ void CppToolsPlugin::test_codegen_definition_last_member()
"\n"
"int y;\n").arg(temporaryDir.path()).toLatin1();
- Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3U);
+ Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3);
QVERIFY(sourceDocument);
sourceDocument->addIncludeFile(Document::Include(QLatin1String("file.h"),
headerDocument->fileName(), 1,
@@ -475,13 +475,13 @@ void CppToolsPlugin::test_codegen_definition_last_member()
Class *foo = headerDocument->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
- QCOMPARE(foo->memberCount(), 2U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
+ QCOMPARE(foo->memberCount(), 2);
Declaration *decl = foo->memberAt(1)->asDeclaration();
QVERIFY(decl);
- QCOMPARE(decl->line(), 4U);
- QCOMPARE(decl->column(), 6U);
+ QCOMPARE(decl->line(), 4);
+ QCOMPARE(decl->column(), 6);
CppRefactoringChanges changes(snapshot);
InsertionPointLocator find(changes);
@@ -489,8 +489,8 @@ void CppToolsPlugin::test_codegen_definition_last_member()
QVERIFY(locList.size() == 1);
InsertionLocation loc = locList.first();
QCOMPARE(loc.fileName(), sourceDocument->fileName());
- QCOMPARE(loc.line(), 7U);
- QCOMPARE(loc.column(), 2U);
+ QCOMPARE(loc.line(), 7);
+ QCOMPARE(loc.column(), 2);
QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
QCOMPARE(loc.suffix(), QString());
}
@@ -509,7 +509,7 @@ void CppToolsPlugin::test_codegen_definition_middle_member()
"};\n"
"\n";
- Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1U);
+ Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1);
QVERIFY(headerDocument);
const QByteArray sourceText = QString::fromLatin1(
@@ -529,7 +529,7 @@ void CppToolsPlugin::test_codegen_definition_middle_member()
"\n"
"int y;\n").arg(Utils::TemporaryDirectory::masterDirectoryPath()).toLatin1();
- Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 4U);
+ Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 4);
QVERIFY(sourceDocument);
sourceDocument->addIncludeFile(Document::Include(QLatin1String("file.h"),
headerDocument->fileName(), 1,
@@ -541,13 +541,13 @@ void CppToolsPlugin::test_codegen_definition_middle_member()
Class *foo = headerDocument->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
- QCOMPARE(foo->memberCount(), 3U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
+ QCOMPARE(foo->memberCount(), 3);
Declaration *decl = foo->memberAt(1)->asDeclaration();
QVERIFY(decl);
- QCOMPARE(decl->line(), 4U);
- QCOMPARE(decl->column(), 6U);
+ QCOMPARE(decl->line(), 4);
+ QCOMPARE(decl->column(), 6);
CppRefactoringChanges changes(snapshot);
InsertionPointLocator find(changes);
@@ -555,8 +555,8 @@ void CppToolsPlugin::test_codegen_definition_middle_member()
QVERIFY(locList.size() == 1);
InsertionLocation loc = locList.first();
QCOMPARE(loc.fileName(), sourceDocument->fileName());
- QCOMPARE(loc.line(), 7U);
- QCOMPARE(loc.column(), 2U);
+ QCOMPARE(loc.line(), 7);
+ QCOMPARE(loc.column(), 2);
QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
QCOMPARE(loc.suffix(), QString());
}
@@ -575,7 +575,7 @@ void CppToolsPlugin::test_codegen_definition_middle_member_surrounded_by_undefin
"void car();\n" // line 6
"};\n"
"\n";
- Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1U);
+ Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 1);
QVERIFY(headerDocument);
const QByteArray sourceText = QString::fromLatin1(
@@ -589,7 +589,7 @@ void CppToolsPlugin::test_codegen_definition_middle_member_surrounded_by_undefin
"}\n"
"\n"
"int y;\n").arg(temporaryDir.path()).toLatin1();
- Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3U);
+ Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3);
QVERIFY(sourceDocument);
sourceDocument->addIncludeFile(Document::Include(QLatin1String("file.h"),
headerDocument->fileName(), 1,
@@ -601,13 +601,13 @@ void CppToolsPlugin::test_codegen_definition_middle_member_surrounded_by_undefin
Class *foo = headerDocument->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
- QCOMPARE(foo->memberCount(), 4U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
+ QCOMPARE(foo->memberCount(), 4);
Declaration *decl = foo->memberAt(1)->asDeclaration();
QVERIFY(decl);
- QCOMPARE(decl->line(), 4U);
- QCOMPARE(decl->column(), 6U);
+ QCOMPARE(decl->line(), 4);
+ QCOMPARE(decl->column(), 6);
CppRefactoringChanges changes(snapshot);
InsertionPointLocator find(changes);
@@ -615,8 +615,8 @@ void CppToolsPlugin::test_codegen_definition_middle_member_surrounded_by_undefin
QVERIFY(locList.size() == 1);
InsertionLocation loc = locList.first();
QCOMPARE(loc.fileName(), sourceDocument->fileName());
- QCOMPARE(loc.line(), 4U);
- QCOMPARE(loc.column(), 1U);
+ QCOMPARE(loc.line(), 4);
+ QCOMPARE(loc.column(), 1);
QCOMPARE(loc.prefix(), QString());
QCOMPARE(loc.suffix(), QLatin1String("\n\n"));
}
@@ -638,7 +638,7 @@ void CppToolsPlugin::test_codegen_definition_member_specific_file()
"{\n"
"\n"
"}\n";
- Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 2U);
+ Document::Ptr headerDocument = createDocumentAndFile(&temporaryDir, "file.h", headerText, 2);
QVERIFY(headerDocument);
const QByteArray sourceText = QString::fromLatin1(
@@ -652,7 +652,7 @@ void CppToolsPlugin::test_codegen_definition_member_specific_file()
"}\n" // line 7
"\n"
"int y;\n").arg(temporaryDir.path()).toLatin1();
- Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3U);
+ Document::Ptr sourceDocument = createDocumentAndFile(&temporaryDir, "file.cpp", sourceText, 3);
QVERIFY(sourceDocument);
sourceDocument->addIncludeFile(Document::Include(QLatin1String("file.h"),
headerDocument->fileName(), 1,
@@ -664,13 +664,13 @@ void CppToolsPlugin::test_codegen_definition_member_specific_file()
Class *foo = headerDocument->globalSymbolAt(0)->asClass();
QVERIFY(foo);
- QCOMPARE(foo->line(), 1U);
- QCOMPARE(foo->column(), 7U);
- QCOMPARE(foo->memberCount(), 3U);
+ QCOMPARE(foo->line(), 1);
+ QCOMPARE(foo->column(), 7);
+ QCOMPARE(foo->memberCount(), 3);
Declaration *decl = foo->memberAt(2)->asDeclaration();
QVERIFY(decl);
- QCOMPARE(decl->line(), 5U);
- QCOMPARE(decl->column(), 6U);
+ QCOMPARE(decl->line(), 5);
+ QCOMPARE(decl->column(), 6);
CppRefactoringChanges changes(snapshot);
InsertionPointLocator find(changes);
@@ -678,8 +678,8 @@ void CppToolsPlugin::test_codegen_definition_member_specific_file()
QVERIFY(locList.size() == 1);
InsertionLocation loc = locList.first();
QCOMPARE(loc.fileName(), sourceDocument->fileName());
- QCOMPARE(loc.line(), 7U);
- QCOMPARE(loc.column(), 2U);
+ QCOMPARE(loc.line(), 7);
+ QCOMPARE(loc.column(), 2);
QCOMPARE(loc.prefix(), QLatin1String("\n\n"));
QCOMPARE(loc.suffix(), QString());
}
diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
index efde14abc4..0907db98c6 100644
--- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
+++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
@@ -53,6 +53,11 @@ QString Utils::toString(bool value)
return value ? QLatin1String("Yes") : QLatin1String("No");
}
+QString Utils::toString(int value)
+{
+ return QString::number(value);
+}
+
QString Utils::toString(unsigned value)
{
return QString::number(value);
@@ -143,23 +148,27 @@ QString Utils::toString(::Utils::LanguageExtensions languageExtension)
return result;
}
-QString Utils::toString(ProjectPart::QtVersion qtVersion)
+QString Utils::toString(::Utils::QtVersion qtVersion)
{
-#define CASE_QTVERSION(x) case ProjectPart::x: return QLatin1String(#x)
+#define CASE_QTVERSION(x) \
+ case ::Utils::QtVersion::x: \
+ return QLatin1String(#x)
switch (qtVersion) {
- CASE_QTVERSION(UnknownQt);
- CASE_QTVERSION(NoQt);
- CASE_QTVERSION(Qt4);
- CASE_QTVERSION(Qt5);
- // no default to get a compiler warning if anything is added
+ CASE_QTVERSION(Unknown);
+ CASE_QTVERSION(None);
+ CASE_QTVERSION(Qt4);
+ CASE_QTVERSION(Qt5);
+ // no default to get a compiler warning if anything is added
}
#undef CASE_QTVERSION
return QString();
}
-QString Utils::toString(ProjectPart::BuildTargetType buildTargetType)
+QString Utils::toString(ProjectExplorer::BuildTargetType buildTargetType)
{
-#define CASE_BUILDTARGETTYPE(x) case ProjectPart::x: return QLatin1String(#x)
+#define CASE_BUILDTARGETTYPE(x) \
+ case ProjectExplorer::BuildTargetType::x: \
+ return QLatin1String(#x)
switch (buildTargetType) {
CASE_BUILDTARGETTYPE(Unknown);
CASE_BUILDTARGETTYPE(Executable);
@@ -613,9 +622,8 @@ void Dumper::dumpWorkingCopy(const WorkingCopy &workingCopy)
m_out << "Working Copy contains " << workingCopy.size() << " entries{{{1\n";
const QByteArray i1 = indent(1);
- QHashIterator< ::Utils::FilePath, QPair<QByteArray, unsigned> > it = workingCopy.iterator();
- while (it.hasNext()) {
- it.next();
+ const WorkingCopy::Table &elements = workingCopy.elements();
+ for (auto it = elements.cbegin(), end = elements.cend(); it != end; ++it) {
const ::Utils::FilePath &filePath = it.key();
unsigned sourcRevision = it.value().second;
m_out << i1 << "rev=" << sourcRevision << ", " << filePath << "\n";
diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.h b/src/plugins/cpptools/cppcodemodelinspectordumper.h
index 41d294e817..c7769315c1 100644
--- a/src/plugins/cpptools/cppcodemodelinspectordumper.h
+++ b/src/plugins/cpptools/cppcodemodelinspectordumper.h
@@ -42,6 +42,7 @@ namespace CppCodeModelInspector {
struct CPPTOOLS_EXPORT Utils
{
static QString toString(bool value);
+ static QString toString(int value);
static QString toString(unsigned value);
static QString toString(const QDateTime &dateTime);
static QString toString(CPlusPlus::Document::CheckMode checkMode);
@@ -49,8 +50,8 @@ struct CPPTOOLS_EXPORT Utils
static QString toString(ProjectExplorer::HeaderPathType type);
static QString toString(::Utils::LanguageVersion languageVersion);
static QString toString(::Utils::LanguageExtensions languageExtension);
- static QString toString(CppTools::ProjectPart::QtVersion qtVersion);
- static QString toString(CppTools::ProjectPart::BuildTargetType buildTargetType);
+ static QString toString(::Utils::QtVersion qtVersion);
+ static QString toString(ProjectExplorer::BuildTargetType buildTargetType);
static QString toString(const QVector<CppTools::ProjectFile> &projectFiles);
static QString toString(CppTools::ProjectFile::Kind kind);
static QString toString(CPlusPlus::Kind kind);
diff --git a/src/plugins/cpptools/cppcodemodelsettingspage.cpp b/src/plugins/cpptools/cppcodemodelsettingspage.cpp
index af5f6b1fd2..0cd52a5228 100644
--- a/src/plugins/cpptools/cppcodemodelsettingspage.cpp
+++ b/src/plugins/cpptools/cppcodemodelsettingspage.cpp
@@ -41,9 +41,8 @@
using namespace CppTools;
using namespace CppTools::Internal;
-CppCodeModelSettingsWidget::CppCodeModelSettingsWidget(QWidget *parent)
- : QWidget(parent)
- , m_ui(new Ui::CppCodeModelSettingsPage)
+CppCodeModelSettingsWidget::CppCodeModelSettingsWidget()
+ : m_ui(new Ui::CppCodeModelSettingsPage)
{
m_ui->setupUi(this);
m_ui->expensiveChecksHintIcon->setPixmap(Utils::Icons::WARNING.pixmap());
@@ -184,17 +183,16 @@ bool CppCodeModelSettingsWidget::applyGeneralWidgetsToSettings() const
return settingsChanged;
}
-CppCodeModelSettingsPage::CppCodeModelSettingsPage(QSharedPointer<CppCodeModelSettings> &settings,
- QObject *parent)
- : Core::IOptionsPage(parent)
- , m_settings(settings)
+CppCodeModelSettingsPage::CppCodeModelSettingsPage(QSharedPointer<CppCodeModelSettings> &settings)
+ : m_settings(settings)
{
setId(Constants::CPP_CODE_MODEL_SETTINGS_ID);
setDisplayName(QCoreApplication::translate("CppTools",Constants::CPP_CODE_MODEL_SETTINGS_NAME));
setCategory(Constants::CPP_SETTINGS_CATEGORY);
setDisplayCategory(QCoreApplication::translate("CppTools", "C++"));
- setCategoryIcon(Utils::Icon({{":/cpptools/images/settingscategory_cpp.png",
- Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint));
+ setCategoryIcon(Utils::Icon({{":/projectexplorer/images/settingscategory_cpp.png",
+ Utils::Theme::PanelTextColorDark}},
+ Utils::Icon::Tint));
}
QWidget *CppCodeModelSettingsPage::widget()
diff --git a/src/plugins/cpptools/cppcodemodelsettingspage.h b/src/plugins/cpptools/cppcodemodelsettingspage.h
index 5ccb5fb37f..4f0722a805 100644
--- a/src/plugins/cpptools/cppcodemodelsettingspage.h
+++ b/src/plugins/cpptools/cppcodemodelsettingspage.h
@@ -46,7 +46,7 @@ class CppCodeModelSettingsWidget: public QWidget
Q_OBJECT
public:
- explicit CppCodeModelSettingsWidget(QWidget *parent = nullptr);
+ CppCodeModelSettingsWidget();
~CppCodeModelSettingsWidget() override;
void setSettings(const QSharedPointer<CppCodeModelSettings> &s);
@@ -67,8 +67,7 @@ private:
class CppCodeModelSettingsPage: public Core::IOptionsPage
{
public:
- explicit CppCodeModelSettingsPage(QSharedPointer<CppCodeModelSettings> &settings,
- QObject *parent = nullptr);
+ explicit CppCodeModelSettingsPage(QSharedPointer<CppCodeModelSettings> &settings);
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp b/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp
index 4c0ca8d9a5..0146af8336 100644
--- a/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp
+++ b/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp
@@ -106,7 +106,7 @@ QWidget *CppCodeStylePreferencesFactory::createEditor(TextEditor::ICodeStylePref
if (!cppPreferences)
return nullptr;
auto widget = new Internal::CppCodeStylePreferencesWidget(parent);
- widget->layout()->setMargin(0);
+ widget->layout()->setContentsMargins(0, 0, 0, 0);
widget->setCodeStyle(cppPreferences);
return widget;
}
diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp
index b51f833afe..0a7624576a 100644
--- a/src/plugins/cpptools/cppcompletionassist.cpp
+++ b/src/plugins/cpptools/cppcompletionassist.cpp
@@ -1203,7 +1203,7 @@ void InternalCppCompletionAssistProcessor::completeObjCMsgSend(ClassOrNamespace
}
foreach (Scope *scope, memberScopes) {
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
Symbol *symbol = scope->memberAt(i);
if (ObjCMethod *method = symbol->type()->asObjCMethodType()) {
@@ -1214,7 +1214,7 @@ void InternalCppCompletionAssistProcessor::completeObjCMsgSend(ClassOrNamespace
QString text;
QString data;
if (selectorName->hasArguments()) {
- for (unsigned i = 0; i < selectorName->nameCount(); ++i) {
+ for (int i = 0; i < selectorName->nameCount(); ++i) {
if (i > 0)
text += QLatin1Char(' ');
Symbol *arg = method->argumentAt(i);
@@ -1320,8 +1320,8 @@ bool InternalCppCompletionAssistProcessor::objcKeywordsWanted() const
}
int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString &fileName,
- unsigned line,
- unsigned positionInBlock,
+ int line,
+ int positionInBlock,
const QString &expr,
int endOfExpression)
{
@@ -1467,7 +1467,7 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope)
for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) {
if (Block *block = scope->asBlock()) {
if (ClassOrNamespace *binding = context.lookupType(scope)) {
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
Symbol *member = scope->memberAt(i);
if (member->isEnum()) {
if (ClassOrNamespace *b = binding->findBlock(block))
@@ -1494,13 +1494,13 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope)
for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) {
if (scope->isBlock()) {
- for (unsigned i = 0; i < scope->memberCount(); ++i)
+ for (int i = 0; i < scope->memberCount(); ++i)
addCompletionItem(scope->memberAt(i), FunctionLocalsOrder);
} else if (Function *fun = scope->asFunction()) {
- for (unsigned i = 0, argc = fun->argumentCount(); i < argc; ++i)
+ for (int i = 0, argc = fun->argumentCount(); i < argc; ++i)
addCompletionItem(fun->argumentAt(i), FunctionArgumentsOrder);
} else if (Template *templ = scope->asTemplate()) {
- for (unsigned i = 0, argc = templ->templateParameterCount(); i < argc; ++i)
+ for (int i = 0, argc = templ->templateParameterCount(); i < argc; ++i)
addCompletionItem(templ->templateParameterAt(i), FunctionArgumentsOrder);
break;
}
@@ -1799,7 +1799,7 @@ bool InternalCppCompletionAssistProcessor::completeQtMethod(const QList<LookupIt
if (!klass)
continue;
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
Symbol *member = scope->memberAt(i);
Function *fun = member->type()->asFunctionType();
if (!fun || fun->isGenerated())
@@ -1809,7 +1809,7 @@ bool InternalCppCompletionAssistProcessor::completeQtMethod(const QList<LookupIt
else if (!wantSignals && type == CompleteQt4Slots && !fun->isSlot())
continue;
- unsigned count = fun->argumentCount();
+ int count = fun->argumentCount();
while (true) {
const QString completionText = wantQt5SignalOrSlot
? createQt5SignalOrSlot(fun, o)
@@ -1937,7 +1937,7 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q
if (!className)
continue; // nothing to do for anonymous classes.
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
const Name *memberName = member->name();
diff --git a/src/plugins/cpptools/cppcompletionassist.h b/src/plugins/cpptools/cppcompletionassist.h
index 7213271263..5afdc43593 100644
--- a/src/plugins/cpptools/cppcompletionassist.h
+++ b/src/plugins/cpptools/cppcompletionassist.h
@@ -111,7 +111,7 @@ private:
bool tryObjCCompletion();
bool objcKeywordsWanted() const;
int startCompletionInternal(const QString &fileName,
- unsigned line, unsigned positionInBlock,
+ int line, int positionInBlock,
const QString &expression,
int endOfExpression);
diff --git a/src/plugins/cpptools/cppcursorinfo.h b/src/plugins/cpptools/cppcursorinfo.h
index d9da2541d3..233fdeac26 100644
--- a/src/plugins/cpptools/cppcursorinfo.h
+++ b/src/plugins/cpptools/cppcursorinfo.h
@@ -46,16 +46,16 @@ class CPPTOOLS_EXPORT CursorInfo
public:
struct Range {
Range() = default;
- Range(unsigned line, unsigned column, unsigned length)
+ Range(int line, int column, int length)
: line(line)
, column(column)
, length(length)
{
}
- unsigned line = 0; // 1-based
- unsigned column = 0; // 1-based
- unsigned length = 0;
+ int line = 0; // 1-based
+ int column = 0; // 1-based
+ int length = 0;
};
using Ranges = QVector<Range>;
diff --git a/src/plugins/cpptools/cppelementevaluator.cpp b/src/plugins/cpptools/cppelementevaluator.cpp
index 88ffc3c075..b59bf3380d 100644
--- a/src/plugins/cpptools/cppelementevaluator.cpp
+++ b/src/plugins/cpptools/cppelementevaluator.cpp
@@ -397,7 +397,7 @@ void CppElementEvaluator::checkDiagnosticMessage(int pos)
}
}
-bool CppElementEvaluator::matchIncludeFile(const Document::Ptr &document, unsigned line)
+bool CppElementEvaluator::matchIncludeFile(const Document::Ptr &document, int line)
{
foreach (const Document::Include &includeFile, document->resolvedIncludes()) {
if (includeFile.line() == line) {
@@ -408,11 +408,11 @@ bool CppElementEvaluator::matchIncludeFile(const Document::Ptr &document, unsign
return false;
}
-bool CppElementEvaluator::matchMacroInUse(const Document::Ptr &document, unsigned pos)
+bool CppElementEvaluator::matchMacroInUse(const Document::Ptr &document, int pos)
{
foreach (const Document::MacroUse &use, document->macroUses()) {
if (use.containsUtf16charOffset(pos)) {
- const unsigned begin = use.utf16charsBegin();
+ const int begin = use.utf16charsBegin();
if (pos < begin + use.macro().nameToQString().size()) {
m_element = QSharedPointer<CppElement>(new CppMacro(use.macro()));
return true;
diff --git a/src/plugins/cpptools/cppelementevaluator.h b/src/plugins/cpptools/cppelementevaluator.h
index 13950a09cc..6ce518a2e1 100644
--- a/src/plugins/cpptools/cppelementevaluator.h
+++ b/src/plugins/cpptools/cppelementevaluator.h
@@ -65,8 +65,8 @@ public:
private:
void clear();
void checkDiagnosticMessage(int pos);
- bool matchIncludeFile(const CPlusPlus::Document::Ptr &document, unsigned line);
- bool matchMacroInUse(const CPlusPlus::Document::Ptr &document, unsigned pos);
+ bool matchIncludeFile(const CPlusPlus::Document::Ptr &document, int line);
+ bool matchMacroInUse(const CPlusPlus::Document::Ptr &document, int pos);
void handleLookupItemMatch(const CPlusPlus::Snapshot &snapshot,
const CPlusPlus::LookupItem &lookupItem,
const CPlusPlus::LookupContext &lookupContext,
diff --git a/src/plugins/cpptools/cppfilesettingspage.cpp b/src/plugins/cpptools/cppfilesettingspage.cpp
index 5ee5ef22cf..b6f7fb5720 100644
--- a/src/plugins/cpptools/cppfilesettingspage.cpp
+++ b/src/plugins/cpptools/cppfilesettingspage.cpp
@@ -252,8 +252,7 @@ QString CppFileSettings::licenseTemplate()
// ------------------ CppFileSettingsWidget
-CppFileSettingsWidget::CppFileSettingsWidget(QWidget *parent) :
- QWidget(parent),
+CppFileSettingsWidget::CppFileSettingsWidget() :
m_ui(new Internal::Ui::CppFileSettingsPage)
{
m_ui->setupUi(this);
@@ -351,9 +350,7 @@ void CppFileSettingsWidget::slotEdit()
}
// --------------- CppFileSettingsPage
-CppFileSettingsPage::CppFileSettingsPage(QSharedPointer<CppFileSettings> &settings,
- QObject *parent) :
- Core::IOptionsPage(parent),
+CppFileSettingsPage::CppFileSettingsPage(QSharedPointer<CppFileSettings> &settings) :
m_settings(settings)
{
setId(Constants::CPP_FILE_SETTINGS_ID);
@@ -363,7 +360,6 @@ CppFileSettingsPage::CppFileSettingsPage(QSharedPointer<CppFileSettings> &settin
QWidget *CppFileSettingsPage::widget()
{
-
if (!m_widget) {
m_widget = new CppFileSettingsWidget;
m_widget->setSettings(*m_settings);
diff --git a/src/plugins/cpptools/cppfilesettingspage.h b/src/plugins/cpptools/cppfilesettingspage.h
index 5375664828..4a88e5af5e 100644
--- a/src/plugins/cpptools/cppfilesettingspage.h
+++ b/src/plugins/cpptools/cppfilesettingspage.h
@@ -70,7 +70,7 @@ class CppFileSettingsWidget : public QWidget
Q_OBJECT
public:
- explicit CppFileSettingsWidget(QWidget *parent = nullptr);
+ CppFileSettingsWidget();
~CppFileSettingsWidget() override;
CppFileSettings settings() const;
@@ -87,8 +87,7 @@ private:
class CppFileSettingsPage : public Core::IOptionsPage
{
public:
- explicit CppFileSettingsPage(QSharedPointer<CppFileSettings> &settings,
- QObject *parent = nullptr);
+ explicit CppFileSettingsPage(QSharedPointer<CppFileSettings> &settings);
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
index 5ec6b572a2..9a66467951 100644
--- a/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
+++ b/src/plugins/cpptools/cppfollowsymbolundercursor.cpp
@@ -353,7 +353,7 @@ Link attemptFuncDeclDef(const QTextCursor &cursor, Snapshot snapshot,
if (target) {
result = target->toLink();
- unsigned startLine, startColumn, endLine, endColumn;
+ int startLine, startColumn, endLine, endColumn;
document->translationUnit()->getTokenStartPosition(name->firstToken(), &startLine,
&startColumn);
document->translationUnit()->getTokenEndPosition(name->lastToken() - 1, &endLine,
@@ -540,8 +540,7 @@ void FollowSymbolUnderCursor::findLink(
for (int i = 0; i < tokens.size(); ++i) {
const Token &tk = tokens.at(i);
- if (static_cast<unsigned>(positionInBlock) >= tk.utf16charsBegin()
- && static_cast<unsigned>(positionInBlock) < tk.utf16charsEnd()) {
+ if (positionInBlock >= tk.utf16charsBegin() && positionInBlock < tk.utf16charsEnd()) {
int closingParenthesisPos = tokens.size();
if (i >= 2 && tokens.at(i).is(T_IDENTIFIER) && tokens.at(i - 1).is(T_LPAREN)
&& (tokens.at(i - 2).is(T_SIGNAL) || tokens.at(i - 2).is(T_SLOT))) {
@@ -583,8 +582,7 @@ void FollowSymbolUnderCursor::findLink(
// In this case we want to look at one token before the current position to recognize
// an operator if the cursor is inside the actual operator: operator[$]
- if (static_cast<unsigned>(positionInBlock) >= tk.utf16charsBegin()
- && static_cast<unsigned>(positionInBlock) <= tk.utf16charsEnd()) {
+ if (positionInBlock >= tk.utf16charsBegin() && positionInBlock <= tk.utf16charsEnd()) {
cursorRegionReached = true;
if (tk.is(T_OPERATOR)) {
link = attemptFuncDeclDef(cursor, theSnapshot,
@@ -633,7 +631,7 @@ void FollowSymbolUnderCursor::findLink(
// Handle include directives
if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) {
- const unsigned lineno = cursor.blockNumber() + 1;
+ const int lineno = cursor.blockNumber() + 1;
foreach (const Document::Include &incl, doc->resolvedIncludes()) {
if (incl.line() == lineno) {
link.targetFileName = incl.resolvedFileName();
@@ -697,8 +695,7 @@ void FollowSymbolUnderCursor::findLink(
if (d->isDeclaration() || d->isFunction()) {
const QString fileName = QString::fromUtf8(d->fileName(), d->fileNameLength());
if (data.filePath().toString() == fileName) {
- if (static_cast<unsigned>(line) == d->line()
- && static_cast<unsigned>(positionInBlock) >= d->column()) {
+ if (line == d->line() && positionInBlock >= d->column()) {
// TODO: check the end
result = r; // take the symbol under cursor.
break;
@@ -709,9 +706,9 @@ void FollowSymbolUnderCursor::findLink(
int tokenBeginColumnNumber = 0;
Utils::Text::convertPosition(document, beginOfToken, &tokenBeginLineNumber,
&tokenBeginColumnNumber);
- if (static_cast<unsigned>(tokenBeginLineNumber) > d->line()
- || (static_cast<unsigned>(tokenBeginLineNumber) == d->line()
- && static_cast<unsigned>(tokenBeginColumnNumber) >= d->column())) {
+ if (tokenBeginLineNumber > d->line()
+ || (tokenBeginLineNumber == d->line()
+ && tokenBeginColumnNumber >= d->column())) {
result = r; // take the symbol under cursor.
break;
}
diff --git a/src/plugins/cpptools/cpphoverhandler.cpp b/src/plugins/cpptools/cpphoverhandler.cpp
index 07617a411f..057a9de73f 100644
--- a/src/plugins/cpptools/cpphoverhandler.cpp
+++ b/src/plugins/cpptools/cpphoverhandler.cpp
@@ -62,7 +62,7 @@ void CppHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, Rep
const QSharedPointer<CppElement> &cppElement = evaluator.cppElement();
const QStringList candidates = cppElement->helpIdCandidates;
const HelpItem helpItem(candidates + fallback, cppElement->helpMark, cppElement->helpCategory);
- setLastHelpItemIdentified(helpItem); // tool tip appended by decorateToolTip
+ setLastHelpItemIdentified(helpItem); // tool tip appended by BaseHoverHandler::decorateToolTip
if (!helpItem.isValid())
tip += cppElement->tooltip;
} else {
diff --git a/src/plugins/cpptools/cppincludesfilter.cpp b/src/plugins/cpptools/cppincludesfilter.cpp
index 8a852fb7a5..f40763e052 100644
--- a/src/plugins/cpptools/cppincludesfilter.cpp
+++ b/src/plugins/cpptools/cppincludesfilter.cpp
@@ -37,9 +37,9 @@
#include <QTimer>
using namespace Core;
-using namespace CppTools;
-using namespace CppTools::Internal;
using namespace ProjectExplorer;
+using namespace Utils;
+
namespace CppTools {
namespace Internal {
@@ -50,9 +50,8 @@ public:
void toFront() override;
bool hasNext() const override;
- QString next() override;
- QString filePath() const override;
- QString fileName() const override;
+ Utils::FilePath next() override;
+ Utils::FilePath filePath() const override;
private:
void fetchMore();
@@ -62,13 +61,9 @@ private:
QSet<QString> m_queuedPaths;
QSet<QString> m_allResultPaths;
QStringList m_resultQueue;
- QString m_currentPath;
+ FilePath m_currentPath;
};
-} // Internal
-} // CppTools
-
-
CppIncludesIterator::CppIncludesIterator(CPlusPlus::Snapshot snapshot,
const QSet<QString> &seedPaths)
: m_snapshot(snapshot),
@@ -90,26 +85,21 @@ bool CppIncludesIterator::hasNext() const
return !m_resultQueue.isEmpty();
}
-QString CppIncludesIterator::next()
+FilePath CppIncludesIterator::next()
{
if (m_resultQueue.isEmpty())
- return QString();
- m_currentPath = m_resultQueue.takeFirst();
+ return {};
+ m_currentPath = FilePath::fromString(m_resultQueue.takeFirst());
if (m_resultQueue.isEmpty())
fetchMore();
return m_currentPath;
}
-QString CppIncludesIterator::filePath() const
+FilePath CppIncludesIterator::filePath() const
{
return m_currentPath;
}
-QString CppIncludesIterator::fileName() const
-{
- return QFileInfo(m_currentPath).fileName();
-}
-
void CppIncludesIterator::fetchMore()
{
while (!m_queuedPaths.isEmpty() && m_resultQueue.isEmpty()) {
@@ -160,7 +150,7 @@ void CppIncludesFilter::prepareSearch(const QString &entry)
m_needsUpdate = false;
QSet<QString> seedPaths;
for (Project *project : SessionManager::projects()) {
- const Utils::FilePathList allFiles = project->files(Project::AllFiles);
+ const Utils::FilePathList allFiles = project->files(Project::SourceFiles);
for (const Utils::FilePath &filePath : allFiles )
seedPaths.insert(filePath.toString());
}
@@ -186,3 +176,7 @@ void CppIncludesFilter::markOutdated()
m_needsUpdate = true;
setFileIterator(nullptr); // clean up
}
+
+} // Internal
+} // CppTools
+
diff --git a/src/plugins/cpptools/cpplocalsymbols.cpp b/src/plugins/cpptools/cpplocalsymbols.cpp
index feec5dc606..36ce87ce49 100644
--- a/src/plugins/cpptools/cpplocalsymbols.cpp
+++ b/src/plugins/cpptools/cpplocalsymbols.cpp
@@ -71,14 +71,14 @@ protected:
{
_scopeStack.append(scope);
- for (unsigned i = 0; i < scope->memberCount(); ++i) {
+ for (int i = 0; i < scope->memberCount(); ++i) {
if (Symbol *member = scope->memberAt(i)) {
if (member->isTypedef())
continue;
if (!member->isGenerated() && (member->isDeclaration() || member->isArgument())) {
if (member->name() && member->name()->isNameId()) {
const Token token = tokenAt(member->sourceLocation());
- unsigned line, column;
+ int line, column;
getPosition(token.utf16charsBegin(), &line, &column);
localUses[member].append(
HighlightingResult(line, column, token.utf16chars(),
@@ -89,7 +89,7 @@ protected:
}
}
- bool checkLocalUse(NameAST *nameAst, unsigned firstToken)
+ bool checkLocalUse(NameAST *nameAst, int firstToken)
{
if (SimpleNameAST *simpleName = nameAst->asSimpleName()) {
const Token token = tokenAt(simpleName->identifier_token);
@@ -102,7 +102,7 @@ protected:
continue;
if (!member->isGenerated() && (member->sourceLocation() < firstToken
|| member->enclosingScope()->isFunction())) {
- unsigned line, column;
+ int line, column;
getTokenStartPosition(simpleName->identifier_token, &line, &column);
localUses[member].append(
HighlightingResult(line, column, token.utf16chars(),
diff --git a/src/plugins/cpptools/cpplocalsymbols_test.cpp b/src/plugins/cpptools/cpplocalsymbols_test.cpp
index 7ee8ad1723..7a21b1bc4d 100644
--- a/src/plugins/cpptools/cpplocalsymbols_test.cpp
+++ b/src/plugins/cpptools/cpplocalsymbols_test.cpp
@@ -93,9 +93,7 @@ struct Result
{
QList<Result> result;
- CppTools::SemanticInfo::LocalUseIterator it(localUses);
- while (it.hasNext()) {
- it.next();
+ for (auto it = localUses.cbegin(), end = localUses.cend(); it != end; ++it) {
const CPlusPlus::Symbol *symbol = it.key();
const QList<CppTools::SemanticInfo::Use> &uses = it.value();
foreach (const CppTools::SemanticInfo::Use &use, uses)
diff --git a/src/plugins/cpptools/cpplocatordata.cpp b/src/plugins/cpptools/cpplocatordata.cpp
index d736736191..b1f0b22db8 100644
--- a/src/plugins/cpptools/cpplocatordata.cpp
+++ b/src/plugins/cpptools/cpplocatordata.cpp
@@ -44,16 +44,18 @@ void CppLocatorData::onDocumentUpdated(const CPlusPlus::Document::Ptr &document)
{
QMutexLocker locker(&m_pendingDocumentsMutex);
- int i = 0, ei = m_pendingDocuments.size();
- for (; i < ei; ++i) {
+ bool isPending = false;
+ for (int i = 0, ei = m_pendingDocuments.size(); i < ei; ++i) {
const CPlusPlus::Document::Ptr &doc = m_pendingDocuments.at(i);
- if (doc->fileName() == document->fileName() && doc->revision() <= document->revision()) {
- m_pendingDocuments[i] = document;
+ if (doc->fileName() == document->fileName()) {
+ isPending = true;
+ if (document->revision() >= doc->revision())
+ m_pendingDocuments[i] = document;
break;
}
}
- if (i == ei && QFileInfo(document->fileName()).suffix() != "moc")
+ if (!isPending && QFileInfo(document->fileName()).suffix() != "moc")
m_pendingDocuments.append(document);
flushPendingDocument(false);
@@ -101,10 +103,7 @@ QList<IndexItem::Ptr> CppLocatorData::allIndexItems(
const QHash<QString, QList<IndexItem::Ptr>> &items) const
{
QList<IndexItem::Ptr> result;
- QHashIterator<QString, QList<IndexItem::Ptr> > it(items);
- while (it.hasNext()) {
- it.next();
- result.append(it.value());
- }
+ for (const QList<IndexItem::Ptr> &subItems : items)
+ result.append(subItems);
return result;
}
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index 39965d3120..000091bde4 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -33,6 +33,7 @@
#include <QRegularExpression>
#include <algorithm>
+#include <numeric>
using namespace CppTools;
using namespace CppTools::Internal;
@@ -68,16 +69,13 @@ void CppLocatorFilter::refresh(QFutureInterface<void> &future)
QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry)
{
- QList<Core::LocatorFilterEntry> normalEntries;
- QList<Core::LocatorFilterEntry> goodEntries;
- QList<Core::LocatorFilterEntry> betterEntries;
- QList<Core::LocatorFilterEntry> bestEntries;
+ QList<Core::LocatorFilterEntry> entries[int(MatchLevel::Count)];
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
const IndexItem::ItemType wanted = matchTypes();
const QRegularExpression regexp = createRegExp(entry);
if (!regexp.isValid())
- return goodEntries;
+ return {};
const bool hasColonColon = entry.contains("::");
const QRegularExpression shortRegexp =
hasColonColon ? createRegExp(entry.mid(entry.lastIndexOf("::") + 2)) : regexp;
@@ -119,13 +117,13 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
}
if (matchInParameterList)
- normalEntries.append(filterEntry);
+ entries[int(MatchLevel::Normal)].append(filterEntry);
else if (filterEntry.displayName.startsWith(entry, caseSensitivityForPrefix))
- bestEntries.append(filterEntry);
+ entries[int(MatchLevel::Best)].append(filterEntry);
else if (filterEntry.displayName.contains(entry, caseSensitivityForPrefix))
- betterEntries.append(filterEntry);
+ entries[int(MatchLevel::Better)].append(filterEntry);
else
- goodEntries.append(filterEntry);
+ entries[int(MatchLevel::Good)].append(filterEntry);
}
}
@@ -135,19 +133,12 @@ QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor(
return IndexItem::Recurse;
});
- if (normalEntries.size() < 1000)
- Utils::sort(normalEntries, Core::LocatorFilterEntry::compareLexigraphically);
- if (goodEntries.size() < 1000)
- Utils::sort(goodEntries, Core::LocatorFilterEntry::compareLexigraphically);
- if (betterEntries.size() < 1000)
- Utils::sort(betterEntries, Core::LocatorFilterEntry::compareLexigraphically);
- if (bestEntries.size() < 1000)
- Utils::sort(bestEntries, Core::LocatorFilterEntry::compareLexigraphically);
-
- bestEntries += betterEntries;
- bestEntries += goodEntries;
- bestEntries += normalEntries;
- return bestEntries;
+ for (auto &entry : entries) {
+ if (entry.size() < 1000)
+ Utils::sort(entry, Core::LocatorFilterEntry::compareLexigraphically);
+ }
+
+ return std::accumulate(std::begin(entries), std::end(entries), QList<Core::LocatorFilterEntry>());
}
void CppLocatorFilter::accept(Core::LocatorFilterEntry selection,
diff --git a/src/plugins/cpptools/cpplocatorfilter_test.cpp b/src/plugins/cpptools/cpplocatorfilter_test.cpp
index 482c89b5b1..1b5e64feca 100644
--- a/src/plugins/cpptools/cpplocatorfilter_test.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter_test.cpp
@@ -54,8 +54,6 @@ const bool debug = qEnvironmentVariable("QTC_DEBUG_CPPLOCATORFILTERTESTCASE") ==
QTC_DECLARE_MYTESTDATADIR("../../../tests/cpplocators/")
-inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); }
-
class CppLocatorFilterTestCase
: public BasicLocatorFilterTest
, public CppTools::Tests::TestCase
@@ -95,14 +93,15 @@ class CppCurrentDocumentFilterTestCase
{
public:
CppCurrentDocumentFilterTestCase(const QString &fileName,
- const ResultDataList &expectedResults)
+ const ResultDataList &expectedResults,
+ const QString &searchText = QString())
: BasicLocatorFilterTest(CppTools::CppModelManager::instance()->currentDocumentFilter())
, m_fileName(fileName)
{
QVERIFY(succeededSoFar());
QVERIFY(!m_fileName.isEmpty());
- ResultDataList results = ResultData::fromFilterEntryList(matchesFor());
+ ResultDataList results = ResultData::fromFilterEntryList(matchesFor(searchText));
if (debug) {
ResultData::printFilterEntries(expectedResults, "Expected:");
ResultData::printFilterEntries(results, "Results:");
@@ -172,153 +171,153 @@ void CppToolsPlugin::test_cpplocatorfilters_CppLocatorFilter_data()
QTest::newRow("CppFunctionsFilter")
<< testFile
<< cppFunctionsFilter
- << _("function")
- << (QList<ResultData>()
- << ResultData(_("functionDefinedInClass(bool, int)"), _("MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("<anonymous namespace>::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"),
- _("<anonymous namespace>::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClassAndNamespace(float)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("myFunction(bool, int)"), testFileShort)
- << ResultData(_("myFunction(bool, int)"), _("MyNamespace (file1.cpp)"))
- << ResultData(_("myFunction(bool, int)"), _("<anonymous namespace> (file1.cpp)"))
- );
+ << "function"
+ << ResultDataList{
+ ResultData("functionDefinedInClass(bool, int)", "MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "<anonymous namespace>::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)", "MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)",
+ "<anonymous namespace>::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClassAndNamespace(float)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("myFunction(bool, int)", testFileShort),
+ ResultData("myFunction(bool, int)", "MyNamespace (file1.cpp)"),
+ ResultData("myFunction(bool, int)", "<anonymous namespace> (file1.cpp)")
+ };
QTest::newRow("CppFunctionsFilter-Sorting")
<< testFile
<< cppFunctionsFilter
- << _("pos")
- << (QList<ResultData>()
- << ResultData(_("positiveNumber()"), testFileShort)
- << ResultData(_("somePositionWithin()"), testFileShort)
- << ResultData(_("pointOfService()"), testFileShort)
- << ResultData(_("matchArgument(Pos)"), testFileShort)
- );
+ << "pos"
+ << ResultDataList{
+ ResultData("positiveNumber()", testFileShort),
+ ResultData("somePositionWithin()", testFileShort),
+ ResultData("pointOfService()", testFileShort),
+ ResultData("matchArgument(Pos)", testFileShort)
+ };
QTest::newRow("CppFunctionsFilter-arguments")
- << testFile
- << cppFunctionsFilter
- << _("function*bool")
- << (QList<ResultData>()
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("<anonymous namespace>::MyClass (file1.cpp)"))
- << ResultData(_("myFunction(bool, int)"), testFileShort)
- << ResultData(_("myFunction(bool, int)"), _("MyNamespace (file1.cpp)"))
- << ResultData(_("myFunction(bool, int)"), _("<anonymous namespace> (file1.cpp)"))
- );
+ << testFile
+ << cppFunctionsFilter
+ << "function*bool"
+ << ResultDataList{
+ ResultData("functionDefinedInClass(bool, int)",
+ "MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "<anonymous namespace>::MyClass (file1.cpp)"),
+ ResultData("myFunction(bool, int)", testFileShort),
+ ResultData("myFunction(bool, int)", "MyNamespace (file1.cpp)"),
+ ResultData("myFunction(bool, int)", "<anonymous namespace> (file1.cpp)")
+ };
QTest::newRow("CppFunctionsFilter-WithNamespacePrefix")
<< testFile
<< cppFunctionsFilter
- << _("mynamespace::")
- << (QList<ResultData>()
- << ResultData(_("MyClass()"), _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClassAndNamespace(float)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("myFunction(bool, int)"), _("MyNamespace (file1.cpp)"))
- );
+ << "mynamespace::"
+ << ResultDataList{
+ ResultData("MyClass()", "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClassAndNamespace(float)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("myFunction(bool, int)", "MyNamespace (file1.cpp)"),
+ };
QTest::newRow("CppFunctionsFilter-WithClassPrefix")
- << testFile
- << cppFunctionsFilter
- << _("MyClass::func")
- << (QList<ResultData>()
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedInClass(bool, int)"),
- _("<anonymous namespace>::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"),
- _("MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClass(char)"),
- _("<anonymous namespace>::MyClass (file1.cpp)"))
- << ResultData(_("functionDefinedOutSideClassAndNamespace(float)"),
- _("MyNamespace::MyClass (file1.cpp)"))
- );
+ << testFile
+ << cppFunctionsFilter
+ << "MyClass::func"
+ << ResultDataList{
+ ResultData("functionDefinedInClass(bool, int)",
+ "MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedInClass(bool, int)",
+ "<anonymous namespace>::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)",
+ "MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClass(char)",
+ "<anonymous namespace>::MyClass (file1.cpp)"),
+ ResultData("functionDefinedOutSideClassAndNamespace(float)",
+ "MyNamespace::MyClass (file1.cpp)"),
+ };
QTest::newRow("CppClassesFilter")
<< testFile
<< cppClassesFilter
- << _("myclass")
- << (QList<ResultData>()
- << ResultData(_("MyClass"), testFileShort)
- << ResultData(_("MyClass"), _("MyNamespace"))
- << ResultData(_("MyClass"), _("<anonymous namespace>"))
- );
+ << "myclass"
+ << ResultDataList{
+ ResultData("MyClass", testFileShort),
+ ResultData("MyClass", "MyNamespace"),
+ ResultData("MyClass", "<anonymous namespace>")
+ };
QTest::newRow("CppClassesFilter-WithNamespacePrefix")
<< testFile
<< cppClassesFilter
- << _("mynamespace::")
- << (QList<ResultData>()
- << ResultData(_("MyClass"), _("MyNamespace"))
- );
+ << "mynamespace::"
+ << ResultDataList{
+ ResultData("MyClass", "MyNamespace")
+ };
// all symbols in the left column are expected to be fully qualified.
QTest::newRow("CppLocatorFilter-filtered")
<< testFile
<< cppLocatorFilter
- << _("my")
- << (QList<ResultData>()
- << ResultData(_("MyClass"), testFileShort)
- << ResultData(_("MyClass::MyClass"), _("()"))
- << ResultData(_("MyClass::functionDefinedOutSideClass"), _("(char)"))
- << ResultData(_("MyEnum"), testFileShort)
- << ResultData(_("MyNamespace::MyClass"), testFileShort)
- << ResultData(_("MyNamespace::MyClass::MyClass"), _("()"))
- << ResultData(_("MyNamespace::MyClass::functionDefinedOutSideClass"),
- _("(char)"))
- << ResultData(_("MyNamespace::MyClass::functionDefinedOutSideClassAndNamespace"),
- _("(float)"))
- << ResultData(_("MyNamespace::MyEnum"), testFileShort)
- << ResultData(_("MyNamespace::myFunction"), _("(bool, int)"))
- << ResultData(_("myFunction"), _("(bool, int)"))
- << ResultData(_("<anonymous namespace>::MyClass"), testFileShort)
- << ResultData(_("<anonymous namespace>::MyClass::MyClass"), _("()"))
- << ResultData(_("<anonymous namespace>::MyClass::functionDefinedOutSideClass"),
- _("(char)"))
- << ResultData(_("<anonymous namespace>::MyEnum"), testFileShort)
- << ResultData(_("<anonymous namespace>::myFunction"), _("(bool, int)"))
- );
+ << "my"
+ << ResultDataList{
+ ResultData("MyClass", testFileShort),
+ ResultData("MyClass::MyClass", "()"),
+ ResultData("MyClass::functionDefinedOutSideClass", "(char)"),
+ ResultData("MyEnum", testFileShort),
+ ResultData("MyNamespace::MyClass", testFileShort),
+ ResultData("MyNamespace::MyClass::MyClass", "()"),
+ ResultData("MyNamespace::MyClass::functionDefinedOutSideClass",
+ "(char)"),
+ ResultData("MyNamespace::MyClass::functionDefinedOutSideClassAndNamespace",
+ "(float)"),
+ ResultData("MyNamespace::MyEnum", testFileShort),
+ ResultData("MyNamespace::myFunction", "(bool, int)"),
+ ResultData("myFunction", "(bool, int)"),
+ ResultData("<anonymous namespace>::MyClass", testFileShort),
+ ResultData("<anonymous namespace>::MyClass::MyClass", "()"),
+ ResultData("<anonymous namespace>::MyClass::functionDefinedOutSideClass",
+ "(char)"),
+ ResultData("<anonymous namespace>::MyEnum", testFileShort),
+ ResultData("<anonymous namespace>::myFunction", "(bool, int)")
+ };
QTest::newRow("CppClassesFilter-ObjC")
- << objTestFile
- << cppClassesFilter
- << _("M")
- << (QList<ResultData>()
- << ResultData(_("MyClass"), objTestFileShort)
- << ResultData(_("MyClass"), objTestFileShort)
- << ResultData(_("MyClass"), objTestFileShort)
- << ResultData(_("MyProtocol"), objTestFileShort)
- );
+ << objTestFile
+ << cppClassesFilter
+ << "M"
+ << ResultDataList{
+ ResultData("MyClass", objTestFileShort),
+ ResultData("MyClass", objTestFileShort),
+ ResultData("MyClass", objTestFileShort),
+ ResultData("MyProtocol", objTestFileShort),
+ };
QTest::newRow("CppFunctionsFilter-ObjC")
<< objTestFile
<< cppFunctionsFilter
- << _("M")
- << (QList<ResultData>()
- << ResultData(_("anotherMethod"), _("MyClass (file1.mm)"))
- << ResultData(_("anotherMethod:"), _("MyClass (file1.mm)"))
- << ResultData(_("someMethod"), _("MyClass (file1.mm)"))
- );
+ << "M"
+ << ResultDataList{
+ ResultData("anotherMethod", "MyClass (file1.mm)"),
+ ResultData("anotherMethod:", "MyClass (file1.mm)"),
+ ResultData("someMethod", "MyClass (file1.mm)")
+ };
}
void CppToolsPlugin::test_cpplocatorfilters_CppCurrentDocumentFilter()
@@ -326,51 +325,101 @@ void CppToolsPlugin::test_cpplocatorfilters_CppCurrentDocumentFilter()
MyTestDataDir testDirectory("testdata_basic");
const QString testFile = testDirectory.file("file1.cpp");
- QList<ResultData> expectedResults = QList<ResultData>()
- << ResultData(_("int myVariable"), _(""))
- << ResultData(_("myFunction(bool, int)"), _(""))
- << ResultData(_("Pos"), _(""))
- << ResultData(_("somePositionWithin()"), _(""))
- << ResultData(_("pointOfService()"), _(""))
- << ResultData(_("matchArgument(Pos)"), _(""))
- << ResultData(_("positiveNumber()"), _(""))
- << ResultData(_("MyEnum"), _(""))
- << ResultData(_("int V1"), _("MyEnum"))
- << ResultData(_("int V2"), _("MyEnum"))
- << ResultData(_("MyClass"), _(""))
- << ResultData(_("MyClass()"), _("MyClass"))
- << ResultData(_("functionDeclaredOnly()"), _("MyClass"))
- << ResultData(_("functionDefinedInClass(bool, int)"), _("MyClass"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("MyClass"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("MyClass"))
- << ResultData(_("int myVariable"), _("MyNamespace"))
- << ResultData(_("myFunction(bool, int)"), _("MyNamespace"))
- << ResultData(_("MyEnum"), _("MyNamespace"))
- << ResultData(_("int V1"), _("MyNamespace::MyEnum"))
- << ResultData(_("int V2"), _("MyNamespace::MyEnum"))
- << ResultData(_("MyClass"), _("MyNamespace"))
- << ResultData(_("MyClass()"), _("MyNamespace::MyClass"))
- << ResultData(_("functionDeclaredOnly()"), _("MyNamespace::MyClass"))
- << ResultData(_("functionDefinedInClass(bool, int)"), _("MyNamespace::MyClass"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("MyNamespace::MyClass"))
- << ResultData(_("functionDefinedOutSideClassAndNamespace(float)"),
- _("MyNamespace::MyClass"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("MyNamespace::MyClass"))
- << ResultData(_("functionDefinedOutSideClassAndNamespace(float)"),
- _("MyNamespace::MyClass"))
- << ResultData(_("int myVariable"), _("<anonymous namespace>"))
- << ResultData(_("myFunction(bool, int)"), _("<anonymous namespace>"))
- << ResultData(_("MyEnum"), _("<anonymous namespace>"))
- << ResultData(_("int V1"), _("<anonymous namespace>::MyEnum"))
- << ResultData(_("int V2"), _("<anonymous namespace>::MyEnum"))
- << ResultData(_("MyClass"), _("<anonymous namespace>"))
- << ResultData(_("MyClass()"), _("<anonymous namespace>::MyClass"))
- << ResultData(_("functionDeclaredOnly()"), _("<anonymous namespace>::MyClass"))
- << ResultData(_("functionDefinedInClass(bool, int)"), _("<anonymous namespace>::MyClass"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("<anonymous namespace>::MyClass"))
- << ResultData(_("functionDefinedOutSideClass(char)"), _("<anonymous namespace>::MyClass"))
- << ResultData(_("main()"), _(""))
- ;
+ auto expectedResults = ResultDataList{
+ ResultData("int myVariable", ""),
+ ResultData("myFunction(bool, int)", ""),
+ ResultData("Pos", ""),
+ ResultData("somePositionWithin()", ""),
+ ResultData("pointOfService()", ""),
+ ResultData("matchArgument(Pos)", ""),
+ ResultData("positiveNumber()", ""),
+ ResultData("MyEnum", ""),
+ ResultData("int V1", "MyEnum"),
+ ResultData("int V2", "MyEnum"),
+ ResultData("MyClass", ""),
+ ResultData("MyClass()", "MyClass"),
+ ResultData("functionDeclaredOnly()", "MyClass"),
+ ResultData("functionDefinedInClass(bool, int)", "MyClass"),
+ ResultData("functionDefinedOutSideClass(char)", "MyClass"),
+ ResultData("functionDefinedOutSideClass(char)", "MyClass"),
+ ResultData("int myVariable", "MyNamespace"),
+ ResultData("myFunction(bool, int)", "MyNamespace"),
+ ResultData("MyEnum", "MyNamespace"),
+ ResultData("int V1", "MyNamespace::MyEnum"),
+ ResultData("int V2", "MyNamespace::MyEnum"),
+ ResultData("MyClass", "MyNamespace"),
+ ResultData("MyClass()", "MyNamespace::MyClass"),
+ ResultData("functionDeclaredOnly()", "MyNamespace::MyClass"),
+ ResultData("functionDefinedInClass(bool, int)", "MyNamespace::MyClass"),
+ ResultData("functionDefinedOutSideClass(char)", "MyNamespace::MyClass"),
+ ResultData("functionDefinedOutSideClassAndNamespace(float)",
+ "MyNamespace::MyClass"),
+ ResultData("functionDefinedOutSideClass(char)", "MyNamespace::MyClass"),
+ ResultData("functionDefinedOutSideClassAndNamespace(float)",
+ "MyNamespace::MyClass"),
+ ResultData("int myVariable", "<anonymous namespace>"),
+ ResultData("myFunction(bool, int)", "<anonymous namespace>"),
+ ResultData("MyEnum", "<anonymous namespace>"),
+ ResultData("int V1", "<anonymous namespace>::MyEnum"),
+ ResultData("int V2", "<anonymous namespace>::MyEnum"),
+ ResultData("MyClass", "<anonymous namespace>"),
+ ResultData("MyClass()", "<anonymous namespace>::MyClass"),
+ ResultData("functionDeclaredOnly()", "<anonymous namespace>::MyClass"),
+ ResultData("functionDefinedInClass(bool, int)", "<anonymous namespace>::MyClass"),
+ ResultData("functionDefinedOutSideClass(char)", "<anonymous namespace>::MyClass"),
+ ResultData("functionDefinedOutSideClass(char)", "<anonymous namespace>::MyClass"),
+ ResultData("main()", ""),
+ };
CppCurrentDocumentFilterTestCase(testFile, expectedResults);
}
+
+void CppToolsPlugin::test_cpplocatorfilters_CppCurrentDocumentHighlighting()
+{
+ MyTestDataDir testDirectory("testdata_basic");
+ const QString testFile = testDirectory.file("file1.cpp");
+
+ const QString searchText = "pos";
+ const ResultDataList expectedResults{
+ ResultData("Pos", "",
+ "~~~"),
+ ResultData("pointOfService()", "",
+ "~ ~ ~ "),
+ ResultData("positiveNumber()", "",
+ "~~~ "),
+ ResultData("somePositionWithin()", "",
+ " ~~~ "),
+ ResultData("matchArgument(Pos)", "",
+ " ~~~ ")
+ };
+
+ Tests::VerifyCleanCppModelManager verify;
+
+ CppCurrentDocumentFilterTestCase(testFile, expectedResults, searchText);
+}
+
+void CppToolsPlugin::test_cpplocatorfilters_CppFunctionsFilterHighlighting()
+{
+ MyTestDataDir testDirectory("testdata_basic");
+ const QString testFile = testDirectory.file("file1.cpp");
+ const QString testFileShort = FilePath::fromString(testFile).shortNativePath();
+
+ const QString searchText = "pos";
+ const ResultDataList expectedResults{
+ ResultData("positiveNumber()", testFileShort,
+ "~~~ "),
+ ResultData("somePositionWithin()", testFileShort,
+ " ~~~ "),
+ ResultData("pointOfService()", testFileShort,
+ "~ ~ ~ "),
+ ResultData("matchArgument(Pos)", testFileShort,
+ " ~~~ ")
+ };
+
+ CppModelManager *cppModelManager = CppModelManager::instance();
+ ILocatorFilter *filter = cppModelManager->functionsFilter();
+
+ Tests::VerifyCleanCppModelManager verify;
+
+ CppLocatorFilterTestCase(filter, testFile, searchText, expectedResults);
+}
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index ea083c8eb6..47c7df5bf9 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -52,15 +52,16 @@
#include "followsymbolinterface.h"
#include <coreplugin/documentmanager.h>
+#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
-#include <coreplugin/vcsmanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
-#include <coreplugin/editormanager/editormanager.h>
-#include <texteditor/textdocument.h>
+#include <coreplugin/vcsmanager.h>
+#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectmacro.h>
#include <projectexplorer/session.h>
+#include <texteditor/textdocument.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
@@ -511,6 +512,10 @@ CppModelManager::CppModelManager()
: CppModelManagerBase(nullptr)
, d(new CppModelManagerPrivate)
{
+ // Used for weak dependency in VcsBaseSubmitEditor
+ setObjectName("CppModelManager");
+ ExtensionSystem::PluginManager::addObject(this);
+
d->m_indexingSupporter = nullptr;
d->m_enableGC = true;
@@ -561,6 +566,8 @@ CppModelManager::CppModelManager()
CppModelManager::~CppModelManager()
{
+ ExtensionSystem::PluginManager::removeObject(this);
+
delete d->m_internalIndexingSupport;
delete d;
}
@@ -608,10 +615,7 @@ void CppModelManager::ensureUpdated()
QStringList CppModelManager::internalProjectFiles() const
{
QStringList files;
- QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(d->m_projectToProjectsInfo);
- while (it.hasNext()) {
- it.next();
- const ProjectInfo pinfo = it.value();
+ for (const ProjectInfo &pinfo : d->m_projectToProjectsInfo) {
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
foreach (const ProjectFile &file, part->files)
files += file.path;
@@ -624,10 +628,7 @@ QStringList CppModelManager::internalProjectFiles() const
ProjectExplorer::HeaderPaths CppModelManager::internalHeaderPaths() const
{
ProjectExplorer::HeaderPaths headerPaths;
- QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(d->m_projectToProjectsInfo);
- while (it.hasNext()) {
- it.next();
- const ProjectInfo pinfo = it.value();
+ for (const ProjectInfo &pinfo : d->m_projectToProjectsInfo) {
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
foreach (const ProjectExplorer::HeaderPath &path, part->headerPaths) {
ProjectExplorer::HeaderPath hp(QDir::cleanPath(path.path), path.type);
@@ -655,10 +656,7 @@ ProjectExplorer::Macros CppModelManager::internalDefinedMacros() const
{
ProjectExplorer::Macros macros;
QSet<ProjectExplorer::Macro> alreadyIn;
- QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(d->m_projectToProjectsInfo);
- while (it.hasNext()) {
- it.next();
- const ProjectInfo pinfo = it.value();
+ for (const ProjectInfo &pinfo : d->m_projectToProjectsInfo) {
for (const ProjectPart::Ptr &part : pinfo.projectParts()) {
addUnique(part->toolChainMacros, macros, alreadyIn);
addUnique(part->projectMacros, macros, alreadyIn);
@@ -783,11 +781,8 @@ WorkingCopy CppModelManager::buildWorkingCopyList()
cppEditorDocument->revision());
}
- QSetIterator<AbstractEditorSupport *> it(d->m_extraEditorSupports);
- while (it.hasNext()) {
- AbstractEditorSupport *es = it.next();
+ for (AbstractEditorSupport *es : qAsConst(d->m_extraEditorSupports))
workingCopy.insert(es->fileName(), es->contents(), es->revision());
- }
// Add the project configuration file
QByteArray conf = codeModelConfiguration();
@@ -815,9 +810,7 @@ static QSet<QString> tooBigFilesRemoved(const QSet<QString> &files, int fileSize
QSet<QString> result;
QFileInfo fileInfo;
- QSetIterator<QString> i(files);
- while (i.hasNext()) {
- const QString filePath = i.next();
+ for (const QString &filePath : files) {
fileInfo.setFile(filePath);
if (fileSizeExceedsLimit(fileInfo, fileSizeLimitInMb))
continue;
@@ -887,9 +880,8 @@ QList<CppEditorDocumentHandle *> CppModelManager::cppEditorDocuments() const
void CppModelManager::removeFilesFromSnapshot(const QSet<QString> &filesToRemove)
{
QMutexLocker snapshotLocker(&d->m_snapshotMutex);
- QSetIterator<QString> i(filesToRemove);
- while (i.hasNext())
- d->m_snapshot.remove(i.next());
+ for (const QString &file : filesToRemove)
+ d->m_snapshot.remove(file);
}
class ProjectInfoComparer
@@ -935,9 +927,7 @@ public:
commonSourceFiles.intersect(m_oldSourceFiles);
QList<Document::Ptr> documentsToCheck;
- QSetIterator<QString> i(commonSourceFiles);
- while (i.hasNext()) {
- const QString file = i.next();
+ for (const QString &file : commonSourceFiles) {
if (Document::Ptr document = snapshot.document(file))
documentsToCheck << document;
}
@@ -1169,7 +1159,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart()
part->languageExtensions &= ~Utils::LanguageExtensions(
Utils::LanguageExtension::ObjectiveC);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->updateLanguageFeatures();
return part;
@@ -1322,6 +1312,60 @@ void CppModelManager::renameIncludes(const QString &oldFileName, const QString &
}
}
+// Return the class name which function belongs to
+static const char *belongingClassName(const Function *function)
+{
+ if (!function)
+ return nullptr;
+
+ if (auto funcName = function->name()) {
+ if (auto qualifiedNameId = funcName->asQualifiedNameId()) {
+ if (const Name *funcBaseName = qualifiedNameId->base()) {
+ if (auto identifier = funcBaseName->identifier())
+ return identifier->chars();
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+QSet<QString> CppModelManager::symbolsInFiles(const QSet<Utils::FilePath> &files) const
+{
+ QSet<QString> uniqueSymbols;
+ const Snapshot cppSnapShot = snapshot();
+
+ // Iterate over the files and get interesting symbols
+ for (const Utils::FilePath &file : files) {
+ // Add symbols from the C++ code model
+ const CPlusPlus::Document::Ptr doc = cppSnapShot.document(file);
+ if (!doc.isNull() && doc->control()) {
+ const CPlusPlus::Control *ctrl = doc->control();
+ CPlusPlus::Symbol **symPtr = ctrl->firstSymbol(); // Read-only
+ while (symPtr != ctrl->lastSymbol()) {
+ const CPlusPlus::Symbol *sym = *symPtr;
+
+ const CPlusPlus::Identifier *symId = sym->identifier();
+ // Add any class, function or namespace identifiers
+ if ((sym->isClass() || sym->isFunction() || sym->isNamespace()) && symId
+ && symId->chars()) {
+ uniqueSymbols.insert(QString::fromUtf8(symId->chars()));
+ }
+
+ // Handle specific case : get "Foo" in "void Foo::function() {}"
+ if (sym->isFunction() && !sym->asFunction()->isDeclaration()) {
+ const char *className = belongingClassName(sym->asFunction());
+ if (className)
+ uniqueSymbols.insert(QString::fromUtf8(className));
+ }
+
+ ++symPtr;
+ }
+ }
+ }
+ return uniqueSymbols;
+}
+
void CppModelManager::onCoreAboutToClose()
{
Core::ProgressManager::cancelTasks(CppTools::Constants::TASK_INDEX);
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 9deaa2e392..8567de9c30 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -230,6 +230,9 @@ public:
void renameIncludes(const QString &oldFileName, const QString &newFileName);
+ // for VcsBaseSubmitEditor
+ Q_INVOKABLE QSet<QString> symbolsInFiles(const QSet<Utils::FilePath> &files) const;
+
signals:
/// Project data might be locked while this is emitted.
void aboutToRemoveFiles(const QStringList &files);
diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp
index 02586943da..73da04531f 100644
--- a/src/plugins/cpptools/cppmodelmanager_test.cpp
+++ b/src/plugins/cpptools/cppmodelmanager_test.cpp
@@ -108,7 +108,7 @@ public:
projectInfo = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
foreach (const QString &file, projectFiles) {
ProjectFile projectFile(file, ProjectFile::classify(file));
part->files.append(projectFile);
@@ -184,7 +184,7 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean()
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->projectMacros = {ProjectExplorer::Macro("OH_BEHAVE", "-1")};
part->headerPaths = {{testDataDir.includeDir(false), HeaderPathType::User},
{testDataDir.frameworksDir(false), HeaderPathType::Framework}};
@@ -214,7 +214,7 @@ void CppToolsPlugin::test_modelmanager_framework_headers()
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->projectMacros = {{"OH_BEHAVE", "-1"}};
part->headerPaths = {{testDataDir.includeDir(false), HeaderPathType::User},
{testDataDir.frameworksDir(false), HeaderPathType::Framework}};
@@ -262,7 +262,7 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->projectMacros = {{"OH_BEHAVE", "-1"}};
part->headerPaths = {{testDataDir.includeDir(false), HeaderPathType::User}};
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
@@ -318,7 +318,7 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
@@ -337,7 +337,7 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
// Simulate project configuration change by having different defines each time.
macros += {"ANOTHER_DEFINE"};
part->projectMacros = macros;
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
@@ -381,7 +381,7 @@ void CppToolsPlugin::test_modelmanager_refresh_test_for_changes()
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
@@ -417,7 +417,7 @@ void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed()
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
pi.appendProjectPart(part);
@@ -438,7 +438,7 @@ void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed()
// Now add testHeader2 and remove testHeader1
pi = ProjectInfo(project);
ProjectPart::Ptr newPart(new ProjectPart);
- newPart->qtVersion = ProjectPart::Qt5;
+ newPart->qtVersion = Utils::QtVersion::Qt5;
newPart->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
newPart->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
pi.appendProjectPart(newPart);
@@ -477,7 +477,7 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
- part->qtVersion = ProjectPart::Qt5;
+ part->qtVersion = Utils::QtVersion::Qt5;
foreach (const QString &file, initialProjectFiles)
part->files.append(ProjectFile(file, ProjectFile::CXXSource));
pi = ProjectInfo(project);
@@ -498,7 +498,7 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
document = snapshot.document(fileToChange);
const QDateTime lastModifiedBefore = document->lastModified();
- QCOMPARE(document->globalSymbolCount(), 1U);
+ QCOMPARE(document->globalSymbolCount(), 1);
QCOMPARE(document->globalSymbolAt(0)->name()->identifier()->chars(), "someGlobal");
// Modify the file
@@ -527,7 +527,7 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
document = snapshot.document(fileToChange);
const QDateTime lastModifiedAfter = document->lastModified();
QVERIFY(lastModifiedAfter > lastModifiedBefore);
- QCOMPARE(document->globalSymbolCount(), 2U);
+ QCOMPARE(document->globalSymbolCount(), 2);
QCOMPARE(document->globalSymbolAt(0)->name()->identifier()->chars(), "someGlobal");
QCOMPARE(document->globalSymbolAt(1)->name()->identifier()->chars(), "addedOtherGlobal");
}
@@ -618,11 +618,10 @@ void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles()
QCOMPARE(workingCopy.size(), 2); // mm->configurationFileName() and "ui_*.h"
QStringList fileNamesInWorkinCopy;
- QHashIterator<Utils::FilePath, QPair<QByteArray, unsigned> > it = workingCopy.iterator();
- while (it.hasNext()) {
- it.next();
+ const WorkingCopy::Table &elements = workingCopy.elements();
+ for (auto it = elements.cbegin(), end = elements.cend(); it != end; ++it)
fileNamesInWorkinCopy << Utils::FilePath::fromString(it.key().toString()).fileName();
- }
+
fileNamesInWorkinCopy.sort();
const QString expectedUiHeaderFileName = _("ui_mainwindow.h");
QCOMPARE(fileNamesInWorkinCopy.at(0), mm->configurationFileName());
@@ -756,7 +755,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
part1->projectFile = QLatin1String("project1.projectfile");
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
- part1->qtVersion = ProjectPart::NoQt;
+ part1->qtVersion = Utils::QtVersion::None;
part1->projectMacros = {{"SUB1"}};
part1->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
@@ -764,7 +763,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
part2->projectFile = QLatin1String("project1.projectfile");
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
- part2->qtVersion = ProjectPart::NoQt;
+ part2->qtVersion = Utils::QtVersion::None;
part2->projectMacros = {{"SUB2"}};
part2->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
@@ -820,7 +819,7 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
part1->projectFile = QLatin1String("project1.projectfile");
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
- part1->qtVersion = ProjectPart::NoQt;
+ part1->qtVersion = Utils::QtVersion::None;
part1->precompiledHeaders.append(pch1File);
part1->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
part1->updateLanguageFeatures();
@@ -829,7 +828,7 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
part2->projectFile = QLatin1String("project2.projectfile");
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
- part2->qtVersion = ProjectPart::NoQt;
+ part2->qtVersion = Utils::QtVersion::None;
part2->precompiledHeaders.append(pch2File);
part2->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
part2->updateLanguageFeatures();
@@ -901,13 +900,13 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
ProjectPart::Ptr part1(new ProjectPart);
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
- part1->qtVersion = ProjectPart::NoQt;
+ part1->qtVersion = Utils::QtVersion::None;
part1->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
ProjectPart::Ptr part2(new ProjectPart);
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
- part2->qtVersion = ProjectPart::NoQt;
+ part2->qtVersion = Utils::QtVersion::None;
part2->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
ProjectInfo pi = ProjectInfo(project);
@@ -986,7 +985,7 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
part->project = project;
part->files.append(ProjectFile(fileA, ProjectFile::CXXSource));
part->files.append(ProjectFile(fileB, ProjectFile::CXXSource));
- part->qtVersion = ProjectPart::NoQt;
+ part->qtVersion = Utils::QtVersion::None;
ProjectInfo pi = ProjectInfo(project);
pi.appendProjectPart(part);
@@ -1009,7 +1008,7 @@ void CppToolsPlugin::test_modelmanager_renameIncludes()
struct ModelManagerGCHelper {
~ModelManagerGCHelper() { CppModelManager::instance()->GC(); }
} GCHelper;
- Q_UNUSED(GCHelper); // do not warn about being unused
+ Q_UNUSED(GCHelper) // do not warn about being unused
TemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
@@ -1055,7 +1054,7 @@ void CppToolsPlugin::test_modelmanager_renameIncludesInEditor()
struct ModelManagerGCHelper {
~ModelManagerGCHelper() { CppModelManager::instance()->GC(); }
} GCHelper;
- Q_UNUSED(GCHelper); // do not warn about being unused
+ Q_UNUSED(GCHelper) // do not warn about being unused
TemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
diff --git a/src/plugins/cpptools/cppoverviewmodel.cpp b/src/plugins/cpptools/cppoverviewmodel.cpp
index e0fc805698..6fd9b161dc 100644
--- a/src/plugins/cpptools/cppoverviewmodel.cpp
+++ b/src/plugins/cpptools/cppoverviewmodel.cpp
@@ -82,8 +82,8 @@ QVariant SymbolItem::data(int /*column*/, int role) const
if (Template *t = symbl->asTemplate())
if (Symbol *templateDeclaration = t->declaration()) {
QStringList parameters;
- parameters.reserve(static_cast<int>(t->templateParameterCount()));
- for (unsigned i = 0; i < t->templateParameterCount(); ++i) {
+ parameters.reserve(t->templateParameterCount());
+ for (int i = 0; i < t->templateParameterCount(); ++i) {
parameters.append(overviewModel->_overview.prettyName(
t->templateParameterAt(i)->name()));
}
@@ -119,7 +119,7 @@ QVariant SymbolItem::data(int /*column*/, int role) const
return Icons::iconForSymbol(symbol);
case AbstractOverviewModel::FileNameRole:
- return QString::fromUtf8(symbol->fileName(), static_cast<int>(symbol->fileNameLength()));
+ return QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
case AbstractOverviewModel::LineNumberRole:
return symbol->line();
@@ -135,15 +135,15 @@ bool OverviewModel::hasDocument() const
return _cppDocument;
}
-unsigned OverviewModel::globalSymbolCount() const
+int OverviewModel::globalSymbolCount() const
{
- unsigned count = 0;
+ int count = 0;
if (_cppDocument)
count += _cppDocument->globalSymbolCount();
return count;
}
-Symbol *OverviewModel::globalSymbolAt(unsigned index) const
+Symbol *OverviewModel::globalSymbolAt(int index) const
{ return _cppDocument->globalSymbolAt(index); }
Symbol *OverviewModel::symbolFromIndex(const QModelIndex &index) const
@@ -185,8 +185,8 @@ Utils::LineColumn OverviewModel::lineColumnFromIndex(const QModelIndex &sourceIn
CPlusPlus::Symbol *symbol = symbolFromIndex(sourceIndex);
if (!symbol)
return lineColumn;
- lineColumn.line = static_cast<int>(symbol->line());
- lineColumn.column = static_cast<int>(symbol->column());
+ lineColumn.line = symbol->line();
+ lineColumn.column = symbol->column();
return lineColumn;
}
@@ -202,8 +202,8 @@ void OverviewModel::buildTree(SymbolItem *root, bool isRoot)
return;
if (isRoot) {
- unsigned rows = globalSymbolCount();
- for (unsigned row = 0; row < rows; ++row) {
+ int rows = globalSymbolCount();
+ for (int row = 0; row < rows; ++row) {
Symbol *symbol = globalSymbolAt(row);
auto currentItem = new SymbolItem(symbol);
buildTree(currentItem, false);
diff --git a/src/plugins/cpptools/cppoverviewmodel.h b/src/plugins/cpptools/cppoverviewmodel.h
index 44a45ace36..4d06427395 100644
--- a/src/plugins/cpptools/cppoverviewmodel.h
+++ b/src/plugins/cpptools/cppoverviewmodel.h
@@ -59,8 +59,8 @@ public:
private:
CPlusPlus::Symbol *symbolFromIndex(const QModelIndex &index) const;
bool hasDocument() const;
- unsigned globalSymbolCount() const;
- CPlusPlus::Symbol *globalSymbolAt(unsigned index) const;
+ int globalSymbolCount() const;
+ CPlusPlus::Symbol *globalSymbolAt(int index) const;
void buildTree(SymbolItem *root, bool isRoot);
private:
diff --git a/src/plugins/cpptools/cpppointerdeclarationformatter.cpp b/src/plugins/cpptools/cpppointerdeclarationformatter.cpp
index 853e563424..82df823af1 100644
--- a/src/plugins/cpptools/cpppointerdeclarationformatter.cpp
+++ b/src/plugins/cpptools/cpppointerdeclarationformatter.cpp
@@ -377,7 +377,7 @@ void PointerDeclarationFormatter::checkAndRewrite(DeclaratorAST *declarator,
CHECK_R(symbol, "No symbol");
// Check for expanded tokens
- for (unsigned token = tokenRange.start; token <= tokenRange.end; ++token)
+ for (int token = tokenRange.start; token <= tokenRange.end; ++token)
CHECK_R(!tokenAt(token).expanded(), "Token is expanded");
Utils::ChangeSet::Range range(m_cppRefactoringFile->startOf(tokenRange.start),
@@ -455,7 +455,7 @@ void PointerDeclarationFormatter::printCandidate(AST *ast)
{
#if DEBUG_OUTPUT
QString tokens;
- for (unsigned token = ast->firstToken(); token < ast->lastToken(); token++)
+ for (int token = ast->firstToken(); token < ast->lastToken(); token++)
tokens += QString::fromLatin1(tokenAt(token).spell()) + QLatin1Char(' ');
# ifdef __GNUC__
diff --git a/src/plugins/cpptools/cpppointerdeclarationformatter.h b/src/plugins/cpptools/cpppointerdeclarationformatter.h
index 20ed9557bc..e965d89774 100644
--- a/src/plugins/cpptools/cpppointerdeclarationformatter.h
+++ b/src/plugins/cpptools/cpppointerdeclarationformatter.h
@@ -101,9 +101,9 @@ private:
class TokenRange {
public:
TokenRange() = default;
- TokenRange(unsigned start, unsigned end) : start(start), end(end) {}
- unsigned start = 0;
- unsigned end = 0;
+ TokenRange(int start, int end) : start(start), end(end) {}
+ int start = 0;
+ int end = 0;
};
void processIfWhileForStatement(ExpressionAST *expression, Symbol *symbol);
diff --git a/src/plugins/cpptools/cppprojectfile.cpp b/src/plugins/cpptools/cppprojectfile.cpp
index 52c599d10b..3f1e590619 100644
--- a/src/plugins/cpptools/cppprojectfile.cpp
+++ b/src/plugins/cpptools/cppprojectfile.cpp
@@ -47,32 +47,38 @@ bool ProjectFile::operator==(const ProjectFile &other) const
&& path == other.path;
}
-ProjectFile::Kind ProjectFile::classify(const QString &filePath)
+ProjectFile::Kind ProjectFile::classifyByMimeType(const QString &mt)
{
- if (isAmbiguousHeader(filePath))
- return AmbiguousHeader;
-
- const Utils::MimeType mimeType = Utils::mimeTypeForFile(filePath);
- const QString mt = mimeType.name();
- if (mt == QLatin1String(CppTools::Constants::C_SOURCE_MIMETYPE))
+ if (mt == CppTools::Constants::C_SOURCE_MIMETYPE)
return CSource;
- if (mt == QLatin1String(CppTools::Constants::C_HEADER_MIMETYPE))
+ if (mt == CppTools::Constants::C_HEADER_MIMETYPE)
return CHeader;
- if (mt == QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE))
+ if (mt == CppTools::Constants::CPP_SOURCE_MIMETYPE)
return CXXSource;
- if (mt == QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE))
+ if (mt == CppTools::Constants::CPP_HEADER_MIMETYPE)
return CXXHeader;
- if (mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE))
+ if (mt == CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)
return ObjCSource;
- if (mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE))
+ if (mt == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)
return ObjCXXSource;
- if (mt == QLatin1String(CppTools::Constants::QDOC_MIMETYPE))
+ if (mt == CppTools::Constants::QDOC_MIMETYPE)
return CXXSource;
- if (mt == QLatin1String(CppTools::Constants::MOC_MIMETYPE))
+ if (mt == CppTools::Constants::MOC_MIMETYPE)
return CXXSource;
+ if (mt == CppTools::Constants::AMBIGUOUS_HEADER_MIMETYPE)
+ return AmbiguousHeader;
return Unsupported;
}
+ProjectFile::Kind ProjectFile::classify(const QString &filePath)
+{
+ if (isAmbiguousHeader(filePath))
+ return AmbiguousHeader;
+
+ const Utils::MimeType mimeType = Utils::mimeTypeForFile(filePath);
+ return classifyByMimeType(mimeType.name());
+}
+
bool ProjectFile::isAmbiguousHeader(const QString &filePath)
{
return filePath.endsWith(".h");
diff --git a/src/plugins/cpptools/cppprojectfile.h b/src/plugins/cpptools/cppprojectfile.h
index 4cfda1be49..942cf66f3b 100644
--- a/src/plugins/cpptools/cppprojectfile.h
+++ b/src/plugins/cpptools/cppprojectfile.h
@@ -50,6 +50,7 @@ public:
OpenCLSource,
};
+ static Kind classifyByMimeType(const QString &mt);
static Kind classify(const QString &filePath);
static bool isSource(Kind kind);
diff --git a/src/plugins/cpptools/cppprojectfilecategorizer.cpp b/src/plugins/cpptools/cppprojectfilecategorizer.cpp
index 35ec2d9263..036022bb43 100644
--- a/src/plugins/cpptools/cppprojectfilecategorizer.cpp
+++ b/src/plugins/cpptools/cppprojectfilecategorizer.cpp
@@ -31,10 +31,11 @@ namespace CppTools {
ProjectFileCategorizer::ProjectFileCategorizer(const QString &projectPartName,
const QStringList &filePaths,
- const FileClassifier &fileClassifier)
+ const FileIsActive &fileIsActive,
+ const GetMimeType &getMimeType)
: m_partName(projectPartName)
{
- const ProjectFiles ambiguousHeaders = classifyFiles(filePaths, fileClassifier);
+ const ProjectFiles ambiguousHeaders = classifyFiles(filePaths, fileIsActive, getMimeType);
expandSourcesWithAmbiguousHeaders(ambiguousHeaders);
m_partCount = (m_cSources.isEmpty() ? 0 : 1)
@@ -53,14 +54,17 @@ QString ProjectFileCategorizer::partName(const QString &languageName) const
}
ProjectFiles ProjectFileCategorizer::classifyFiles(const QStringList &filePaths,
- const FileClassifier &fileClassifier)
+ const FileIsActive &fileIsActive,
+ const GetMimeType &getMimeType)
{
ProjectFiles ambiguousHeaders;
foreach (const QString &filePath, filePaths) {
- const ProjectFile projectFile = fileClassifier
- ? fileClassifier(filePath)
- : ProjectFile(filePath, ProjectFile::classify(filePath));
+ const ProjectFile projectFile(filePath,
+ getMimeType
+ ? ProjectFile::classifyByMimeType(getMimeType(filePath))
+ : ProjectFile::classify(filePath),
+ fileIsActive ? fileIsActive(filePath) : true);
switch (projectFile.kind) {
case ProjectFile::AmbiguousHeader:
diff --git a/src/plugins/cpptools/cppprojectfilecategorizer.h b/src/plugins/cpptools/cppprojectfilecategorizer.h
index 48cd2438c6..bd82ee2ca0 100644
--- a/src/plugins/cpptools/cppprojectfilecategorizer.h
+++ b/src/plugins/cpptools/cppprojectfilecategorizer.h
@@ -26,7 +26,8 @@
#pragma once
#include "cppprojectfile.h"
-#include "cpprawprojectpart.h"
+
+#include <projectexplorer/rawprojectpart.h>
#include <QString>
#include <QVector>
@@ -36,12 +37,14 @@ namespace CppTools {
class ProjectFileCategorizer
{
public:
- using FileClassifier = RawProjectPart::FileClassifier;
+ using FileIsActive = ProjectExplorer::RawProjectPart::FileIsActive;
+ using GetMimeType = ProjectExplorer::RawProjectPart::GetMimeType;
public:
ProjectFileCategorizer(const QString &projectPartName,
const QStringList &filePaths,
- const FileClassifier &fileClassifier = FileClassifier());
+ const FileIsActive &fileIsActive = {},
+ const GetMimeType &getMimeType = {});
bool hasCSources() const { return !m_cSources.isEmpty(); }
bool hasCxxSources() const { return !m_cxxSources.isEmpty(); }
@@ -59,7 +62,9 @@ public:
QString partName(const QString &languageName) const;
private:
- ProjectFiles classifyFiles(const QStringList &filePaths, const FileClassifier &fileClassifier);
+ ProjectFiles classifyFiles(const QStringList &filePaths,
+ const FileIsActive &fileIsActive,
+ const GetMimeType &getMimeType);
void expandSourcesWithAmbiguousHeaders(const ProjectFiles &ambiguousHeaders);
private:
diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp
index 18c7d4fb76..c013e62566 100644
--- a/src/plugins/cpptools/cppprojectinfogenerator.cpp
+++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp
@@ -35,8 +35,9 @@
namespace CppTools {
namespace Internal {
-ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<void> &futureInterface,
- const ProjectUpdateInfo &projectUpdateInfo)
+ProjectInfoGenerator::ProjectInfoGenerator(
+ const QFutureInterface<void> &futureInterface,
+ const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo)
: m_futureInterface(futureInterface)
, m_projectUpdateInfo(projectUpdateInfo)
{
@@ -46,7 +47,7 @@ ProjectInfo ProjectInfoGenerator::generate()
{
ProjectInfo projectInfo(m_projectUpdateInfo.project);
- for (const RawProjectPart &rpp : m_projectUpdateInfo.rawProjectParts) {
+ for (const ProjectExplorer::RawProjectPart &rpp : m_projectUpdateInfo.rawProjectParts) {
if (m_futureInterface.isCanceled())
return ProjectInfo();
@@ -57,8 +58,8 @@ ProjectInfo ProjectInfoGenerator::generate()
return projectInfo;
}
-static ProjectPart::Ptr projectPartFromRawProjectPart(const RawProjectPart &rawProjectPart,
- ProjectExplorer::Project *project)
+static ProjectPart::Ptr projectPartFromRawProjectPart(
+ const ProjectExplorer::RawProjectPart &rawProjectPart, ProjectExplorer::Project *project)
{
ProjectPart::Ptr part(new ProjectPart);
part->project = project;
@@ -80,14 +81,15 @@ static ProjectPart::Ptr projectPartFromRawProjectPart(const RawProjectPart &rawP
return part;
}
-QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProjectPart &rawProjectPart)
+QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
+ const ProjectExplorer::RawProjectPart &rawProjectPart)
{
using Utils::LanguageExtension;
QVector<ProjectPart::Ptr> result;
ProjectFileCategorizer cat(rawProjectPart.displayName,
rawProjectPart.files,
- rawProjectPart.fileClassifier);
+ rawProjectPart.fileIsActive);
if (!cat.hasParts())
return result;
@@ -138,15 +140,15 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
}
ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
- const RawProjectPart &rawProjectPart,
+ const ProjectExplorer::RawProjectPart &rawProjectPart,
const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
Language language,
Utils::LanguageExtensions languageExtensions)
{
- RawProjectPartFlags flags;
- ToolChainInfo tcInfo;
+ ProjectExplorer::RawProjectPartFlags flags;
+ ProjectExplorer::ToolChainInfo tcInfo;
if (language == Language::C) {
flags = rawProjectPart.flagsForC;
tcInfo = m_projectUpdateInfo.cToolChainInfo;
diff --git a/src/plugins/cpptools/cppprojectinfogenerator.h b/src/plugins/cpptools/cppprojectinfogenerator.h
index bb73fdd0e0..2dbc4cd2fa 100644
--- a/src/plugins/cpptools/cppprojectinfogenerator.h
+++ b/src/plugins/cpptools/cppprojectinfogenerator.h
@@ -37,13 +37,14 @@ class ProjectInfoGenerator
{
public:
ProjectInfoGenerator(const QFutureInterface<void> &futureInterface,
- const ProjectUpdateInfo &projectUpdateInfo);
+ const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo);
ProjectInfo generate();
private:
- QVector<ProjectPart::Ptr> createProjectParts(const RawProjectPart &rawProjectPart);
- ProjectPart::Ptr createProjectPart(const RawProjectPart &rawProjectPart,
+ QVector<ProjectPart::Ptr> createProjectParts(
+ const ProjectExplorer::RawProjectPart &rawProjectPart);
+ ProjectPart::Ptr createProjectPart(const ProjectExplorer::RawProjectPart &rawProjectPart,
const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
@@ -52,7 +53,7 @@ private:
private:
const QFutureInterface<void> m_futureInterface;
- const ProjectUpdateInfo &m_projectUpdateInfo;
+ const ProjectExplorer::ProjectUpdateInfo &m_projectUpdateInfo;
};
} // namespace Internal
} // namespace CppTools
diff --git a/src/plugins/cpptools/cppprojectupdater.cpp b/src/plugins/cpptools/cppprojectupdater.cpp
index 23842f15f3..f89f8e9fc8 100644
--- a/src/plugins/cpptools/cppprojectupdater.cpp
+++ b/src/plugins/cpptools/cppprojectupdater.cpp
@@ -46,7 +46,7 @@ CppProjectUpdater::~CppProjectUpdater()
cancelAndWaitForFinished();
}
-void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo)
+void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo)
{
// Stop previous update.
cancelAndWaitForFinished();
@@ -101,4 +101,14 @@ void CppProjectUpdater::onProjectInfoGenerated()
QTC_CHECK(future != QFuture<void>());
}
+CppProjectUpdaterFactory::CppProjectUpdaterFactory()
+{
+ setObjectName("CppProjectUpdaterFactory");
+}
+
+CppProjectUpdaterInterface *CppProjectUpdaterFactory::create()
+{
+ return new CppProjectUpdater;
+}
+
} // namespace CppTools
diff --git a/src/plugins/cpptools/cppprojectupdater.h b/src/plugins/cpptools/cppprojectupdater.h
index 65eb1522a1..5d95fa087c 100644
--- a/src/plugins/cpptools/cppprojectupdater.h
+++ b/src/plugins/cpptools/cppprojectupdater.h
@@ -25,6 +25,7 @@
#pragma once
+#include "cppprojectupdaterinterface.h"
#include "cpptools_global.h"
#include "projectinfo.h"
@@ -34,9 +35,19 @@
namespace CppTools {
class ProjectInfo;
-class ProjectUpdateInfo;
-class CPPTOOLS_EXPORT CppProjectUpdater : public QObject
+// registered in extensionsystem's object pool for plugins with weak dependency to CppTools
+class CPPTOOLS_EXPORT CppProjectUpdaterFactory : public QObject
+{
+ Q_OBJECT
+public:
+ CppProjectUpdaterFactory();
+
+ // keep the namespace, for the type name in the invokeMethod call
+ Q_INVOKABLE CppTools::CppProjectUpdaterInterface *create();
+};
+
+class CPPTOOLS_EXPORT CppProjectUpdater : public QObject, public CppProjectUpdaterInterface
{
Q_OBJECT
@@ -44,8 +55,8 @@ public:
CppProjectUpdater();
~CppProjectUpdater() override;
- void update(const ProjectUpdateInfo &projectUpdateInfo);
- void cancel();
+ void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) override;
+ void cancel() override;
private:
void cancelAndWaitForFinished();
@@ -54,7 +65,7 @@ private:
void onProjectInfoGenerated();
private:
- ProjectUpdateInfo m_projectUpdateInfo;
+ ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
QFutureInterface<void> m_futureInterface;
QFutureWatcher<ProjectInfo> m_generateFutureWatcher;
diff --git a/src/plugins/cpptools/cppprojectupdaterinterface.h b/src/plugins/cpptools/cppprojectupdaterinterface.h
new file mode 100644
index 0000000000..2a9f44db48
--- /dev/null
+++ b/src/plugins/cpptools/cppprojectupdaterinterface.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/rawprojectpart.h>
+
+namespace CppTools {
+
+class CppProjectUpdaterInterface
+{
+public:
+ virtual ~CppProjectUpdaterInterface() = default;
+
+ virtual void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) = 0;
+ virtual void cancel() = 0;
+};
+
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cpprawprojectpart.cpp b/src/plugins/cpptools/cpprawprojectpart.cpp
deleted file mode 100644
index ee18166c05..0000000000
--- a/src/plugins/cpptools/cpprawprojectpart.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "cpprawprojectpart.h"
-
-#include <projectexplorer/abi.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/kitinformation.h>
-
-namespace CppTools {
-
-RawProjectPartFlags::RawProjectPartFlags(const ProjectExplorer::ToolChain *toolChain,
- const QStringList &commandLineFlags)
-{
- // Keep the following cheap/non-blocking for the ui thread. Expensive
- // operations are encapsulated in ToolChainInfo as "runners".
- this->commandLineFlags = commandLineFlags;
- if (toolChain) {
- warningFlags = toolChain->warningFlags(commandLineFlags);
- languageExtensions = toolChain->languageExtensions(commandLineFlags);
- }
-}
-
-void RawProjectPart::setDisplayName(const QString &displayName)
-{
- this->displayName = displayName;
-}
-
-void RawProjectPart::setFiles(const QStringList &files, const FileClassifier &fileClassifier)
-{
- this->files = files;
- this->fileClassifier = fileClassifier;
-}
-
-void RawProjectPart::setProjectFileLocation(const QString &projectFile, int line, int column)
-{
- this->projectFile = projectFile;
- projectFileLine = line;
- projectFileColumn = column;
-}
-
-void RawProjectPart::setConfigFileName(const QString &configFileName)
-{
- this->projectConfigFile = configFileName;
-}
-
-void RawProjectPart::setBuildSystemTarget(const QString &target)
-{
- buildSystemTarget = target;
-}
-
-void RawProjectPart::setCallGroupId(const QString &id)
-{
- callGroupId = id;
-}
-
-void RawProjectPart::setQtVersion(ProjectPart::QtVersion qtVersion)
-{
- this->qtVersion = qtVersion;
-}
-
-void RawProjectPart::setMacros(const ProjectExplorer::Macros &macros)
-{
- this->projectMacros = macros;
-}
-
-void RawProjectPart::setHeaderPaths(const ProjectExplorer::HeaderPaths &headerPaths)
-{
- this->headerPaths = headerPaths;
-}
-
-void RawProjectPart::setIncludePaths(const QStringList &includePaths)
-{
- headerPaths.clear();
-
- foreach (const QString &includeFile, includePaths) {
- ProjectExplorer::HeaderPath hp(includeFile, ProjectExplorer::HeaderPathType::User);
-
- // The simple project managers are utterly ignorant of frameworks on macOS, and won't report
- // framework paths. The work-around is to check if the include path ends in ".framework",
- // and if so, add the parent directory as framework path.
- if (includeFile.endsWith(QLatin1String(".framework"))) {
- const int slashIdx = includeFile.lastIndexOf(QLatin1Char('/'));
- if (slashIdx != -1) {
- hp = {includeFile.left(slashIdx), ProjectExplorer::HeaderPathType::Framework};
- }
- }
-
- headerPaths.push_back(std::move(hp));
- }
-}
-
-void RawProjectPart::setPreCompiledHeaders(const QStringList &preCompiledHeaders)
-{
- this->precompiledHeaders = preCompiledHeaders;
-}
-
-void RawProjectPart::setSelectedForBuilding(bool yesno)
-{
- this->selectedForBuilding = yesno;
-}
-
-void RawProjectPart::setFlagsForC(const RawProjectPartFlags &flags)
-{
- flagsForC = flags;
-}
-
-void RawProjectPart::setFlagsForCxx(const RawProjectPartFlags &flags)
-{
- flagsForCxx = flags;
-}
-
-void RawProjectPart::setBuildTargetType(ProjectPart::BuildTargetType type)
-{
- buildTargetType = type;
-}
-
-} // namespace CppTools
diff --git a/src/plugins/cpptools/cpprawprojectpart.h b/src/plugins/cpptools/cpprawprojectpart.h
deleted file mode 100644
index 43e3067753..0000000000
--- a/src/plugins/cpptools/cpprawprojectpart.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "cpptools_global.h"
-#include "projectpart.h"
-
-#include <projectexplorer/toolchain.h>
-#include <utils/cpplanguage_details.h>
-
-#include <functional>
-
-namespace CppTools {
-
-class CPPTOOLS_EXPORT RawProjectPartFlags
-{
-public:
- RawProjectPartFlags() = default;
- RawProjectPartFlags(const ProjectExplorer::ToolChain *toolChain,
- const QStringList &commandLineFlags);
-
-public:
- QStringList commandLineFlags;
- // The following are deduced from commandLineFlags.
- ProjectExplorer::WarningFlags warningFlags = ProjectExplorer::WarningFlags::Default;
- Utils::LanguageExtensions languageExtensions = Utils::LanguageExtension::None;
-};
-
-class CPPTOOLS_EXPORT RawProjectPart
-{
-public:
- void setDisplayName(const QString &displayName);
-
- void setProjectFileLocation(const QString &projectFile, int line = -1, int column = -1);
- void setConfigFileName(const QString &configFileName);
- void setCallGroupId(const QString &id);
-
- // FileClassifier must be thread-safe.
- using FileClassifier = std::function<ProjectFile(const QString &filePath)>;
- void setFiles(const QStringList &files, const FileClassifier &fileClassifier = FileClassifier());
- void setHeaderPaths(const ProjectExplorer::HeaderPaths &headerPaths);
- void setIncludePaths(const QStringList &includePaths);
- void setPreCompiledHeaders(const QStringList &preCompiledHeaders);
-
- void setBuildSystemTarget(const QString &target);
- void setBuildTargetType(ProjectPart::BuildTargetType type);
- void setSelectedForBuilding(bool yesno);
-
- void setFlagsForC(const RawProjectPartFlags &flags);
- void setFlagsForCxx(const RawProjectPartFlags &flags);
-
- void setMacros(const ProjectExplorer::Macros &macros);
- void setQtVersion(ProjectPart::QtVersion qtVersion);
-
-public:
- QString displayName;
-
- QString projectFile;
- int projectFileLine = -1;
- int projectFileColumn = -1;
- QString callGroupId;
-
- // Files
- QStringList files;
- FileClassifier fileClassifier;
- QStringList precompiledHeaders;
- ProjectExplorer::HeaderPaths headerPaths;
- QString projectConfigFile; // Generic Project Manager only
-
- // Build system
- QString buildSystemTarget;
- ProjectPart::BuildTargetType buildTargetType = ProjectPart::BuildTargetType::Unknown;
- bool selectedForBuilding = true;
-
- // Flags
- RawProjectPartFlags flagsForC;
- RawProjectPartFlags flagsForCxx;
-
- // Misc
- ProjectExplorer::Macros projectMacros;
- ProjectPart::QtVersion qtVersion = ProjectPart::UnknownQt;
-};
-
-using RawProjectParts = QVector<RawProjectPart>;
-
-} // namespace CppTools
diff --git a/src/plugins/cpptools/cpprefactoringchanges.cpp b/src/plugins/cpptools/cpprefactoringchanges.cpp
index f3c27073a9..4d16dd4813 100644
--- a/src/plugins/cpptools/cpprefactoringchanges.cpp
+++ b/src/plugins/cpptools/cpprefactoringchanges.cpp
@@ -159,7 +159,7 @@ void CppRefactoringFile::setCppDocument(Document::Ptr document)
Scope *CppRefactoringFile::scopeAt(unsigned index) const
{
- unsigned line, column;
+ int line, column;
cppDocument()->translationUnit()->getTokenStartPosition(index, &line, &column);
return cppDocument()->scopeAt(line, column);
}
@@ -195,10 +195,10 @@ bool CppRefactoringFile::isCursorOn(const AST *ast) const
Utils::ChangeSet::Range CppRefactoringFile::range(unsigned tokenIndex) const
{
const Token &token = tokenAt(tokenIndex);
- unsigned line, column;
+ int line, column;
cppDocument()->translationUnit()->getPosition(token.utf16charsBegin(), &line, &column);
const int start = document()->findBlockByNumber(line - 1).position() + column - 1;
- return {start, static_cast<int>(start + token.utf16chars())};
+ return {start, start + token.utf16chars()};
}
Utils::ChangeSet::Range CppRefactoringFile::range(AST *ast) const
@@ -208,7 +208,7 @@ Utils::ChangeSet::Range CppRefactoringFile::range(AST *ast) const
int CppRefactoringFile::startOf(unsigned index) const
{
- unsigned line, column;
+ int line, column;
cppDocument()->translationUnit()->getPosition(tokenAt(index).utf16charsBegin(), &line, &column);
return document()->findBlockByNumber(line - 1).position() + column - 1;
}
@@ -220,21 +220,21 @@ int CppRefactoringFile::startOf(const AST *ast) const
int CppRefactoringFile::endOf(unsigned index) const
{
- unsigned line, column;
+ int line, column;
cppDocument()->translationUnit()->getPosition(tokenAt(index).utf16charsEnd(), &line, &column);
return document()->findBlockByNumber(line - 1).position() + column - 1;
}
int CppRefactoringFile::endOf(const AST *ast) const
{
- unsigned end = ast->lastToken();
+ int end = ast->lastToken();
QTC_ASSERT(end > 0, return -1);
return endOf(end - 1);
}
void CppRefactoringFile::startAndEndOf(unsigned index, int *start, int *end) const
{
- unsigned line, column;
+ int line, column;
Token token(tokenAt(index));
cppDocument()->translationUnit()->getPosition(token.utf16charsBegin(), &line, &column);
*start = document()->findBlockByNumber(line - 1).position() + column - 1;
diff --git a/src/plugins/cpptools/cppselectionchanger.cpp b/src/plugins/cpptools/cppselectionchanger.cpp
index 98437c1ced..3159f16eb3 100644
--- a/src/plugins/cpptools/cppselectionchanger.cpp
+++ b/src/plugins/cpptools/cppselectionchanger.cpp
@@ -136,13 +136,12 @@ int CppSelectionChanger::getTokenStartCursorPosition(
unsigned tokenIndex,
const QTextCursor &cursor) const
{
- unsigned startLine, startColumn;
+ int startLine, startColumn;
m_unit->getTokenStartPosition(tokenIndex, &startLine, &startColumn);
const QTextDocument *document = cursor.document();
- const int startPosition =
- document->findBlockByNumber(static_cast<int>(startLine) - 1).position()
- + static_cast<int>(startColumn) - 1;
+ const int startPosition = document->findBlockByNumber(startLine - 1).position()
+ + startColumn - 1;
return startPosition;
}
@@ -151,13 +150,12 @@ int CppSelectionChanger::getTokenEndCursorPosition(
unsigned tokenIndex,
const QTextCursor &cursor) const
{
- unsigned endLine, endColumn;
+ int endLine, endColumn;
m_unit->getTokenEndPosition(tokenIndex, &endLine, &endColumn);
const QTextDocument *document = cursor.document();
- const int endPosition =
- document->findBlockByNumber(static_cast<int>(endLine) - 1).position()
- + static_cast<int>(endColumn) - 1;
+ const int endPosition = document->findBlockByNumber(endLine - 1).position()
+ + endColumn - 1;
return endPosition;
}
@@ -167,7 +165,7 @@ void CppSelectionChanger::printTokenDebugInfo(
const QTextCursor &cursor,
QString prefix) const
{
- unsigned line, column;
+ int line, column;
const Token token = m_unit->tokenAt(tokenIndex);
m_unit->getTokenStartPosition(tokenIndex, &line, &column);
const int startPos = getTokenStartCursorPosition(tokenIndex, cursor);
@@ -571,7 +569,7 @@ void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions)
// Start position will be the end position minus the size of the actual contents of the
// literal.
- int newPosStart = newPosEnd - static_cast<int>(firstToken.string->size());
+ int newPosStart = newPosEnd - firstToken.string->size();
// Skip raw literal parentheses.
if (isRawLiteral)
@@ -591,7 +589,7 @@ void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions)
qDebug() << "Selecting inner contents of char literal.";
positions.astPosEnd = positions.astPosEnd - 1;
- positions.astPosStart = positions.astPosEnd - int(firstToken.literal->size());
+ positions.astPosStart = positions.astPosEnd - firstToken.literal->size();
}
}
} else if (ForStatementAST *forStatementAST = ast->asForStatement()) {
diff --git a/src/plugins/cpptools/cppsemanticinfo.h b/src/plugins/cpptools/cppsemanticinfo.h
index 57e67eaf72..1c61592655 100644
--- a/src/plugins/cpptools/cppsemanticinfo.h
+++ b/src/plugins/cpptools/cppsemanticinfo.h
@@ -62,7 +62,6 @@ public:
public:
using Use = TextEditor::HighlightingResult;
using LocalUseMap = QHash<CPlusPlus::Symbol *, QList<Use>>;
- using LocalUseIterator = QHashIterator<CPlusPlus::Symbol *, QList<Use>>;
// Document specific
unsigned revision = 0;
diff --git a/src/plugins/cpptools/cppsourceprocessor.cpp b/src/plugins/cpptools/cppsourceprocessor.cpp
index 35a0ccf529..7f232c1ad7 100644
--- a/src/plugins/cpptools/cppsourceprocessor.cpp
+++ b/src/plugins/cpptools/cppsourceprocessor.cpp
@@ -324,8 +324,8 @@ void CppSourceProcessor::macroAdded(const CPlusPlus::Macro &macro)
m_currentDoc->appendMacro(macro);
}
-void CppSourceProcessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const CPlusPlus::Macro &macro)
+void CppSourceProcessor::passedMacroDefinitionCheck(int bytesOffset, int utf16charsOffset,
+ int line, const CPlusPlus::Macro &macro)
{
if (!m_currentDoc)
return;
@@ -336,7 +336,7 @@ void CppSourceProcessor::passedMacroDefinitionCheck(unsigned bytesOffset, unsign
line, QVector<MacroArgumentReference>());
}
-void CppSourceProcessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charOffset,
+void CppSourceProcessor::failedMacroDefinitionCheck(int bytesOffset, int utf16charOffset,
const ByteArrayRef &name)
{
if (!m_currentDoc)
@@ -346,8 +346,8 @@ void CppSourceProcessor::failedMacroDefinitionCheck(unsigned bytesOffset, unsign
bytesOffset, utf16charOffset);
}
-void CppSourceProcessor::notifyMacroReference(unsigned bytesOffset, unsigned utf16charOffset,
- unsigned line, const CPlusPlus::Macro &macro)
+void CppSourceProcessor::notifyMacroReference(int bytesOffset, int utf16charOffset,
+ int line, const CPlusPlus::Macro &macro)
{
if (!m_currentDoc)
return;
@@ -358,8 +358,8 @@ void CppSourceProcessor::notifyMacroReference(unsigned bytesOffset, unsigned utf
line, QVector<MacroArgumentReference>());
}
-void CppSourceProcessor::startExpandingMacro(unsigned bytesOffset, unsigned utf16charOffset,
- unsigned line, const CPlusPlus::Macro &macro,
+void CppSourceProcessor::startExpandingMacro(int bytesOffset, int utf16charOffset,
+ int line, const CPlusPlus::Macro &macro,
const QVector<MacroArgumentReference> &actuals)
{
if (!m_currentDoc)
@@ -371,7 +371,7 @@ void CppSourceProcessor::startExpandingMacro(unsigned bytesOffset, unsigned utf1
line, actuals);
}
-void CppSourceProcessor::stopExpandingMacro(unsigned, const CPlusPlus::Macro &)
+void CppSourceProcessor::stopExpandingMacro(int, const CPlusPlus::Macro &)
{
if (!m_currentDoc)
return;
@@ -409,19 +409,19 @@ void CppSourceProcessor::mergeEnvironment(Document::Ptr doc)
m_env.addMacros(doc->definedMacros());
}
-void CppSourceProcessor::startSkippingBlocks(unsigned utf16charsOffset)
+void CppSourceProcessor::startSkippingBlocks(int utf16charsOffset)
{
if (m_currentDoc)
m_currentDoc->startSkippingBlocks(utf16charsOffset);
}
-void CppSourceProcessor::stopSkippingBlocks(unsigned utf16charsOffset)
+void CppSourceProcessor::stopSkippingBlocks(int utf16charsOffset)
{
if (m_currentDoc)
m_currentDoc->stopSkippingBlocks(utf16charsOffset);
}
-void CppSourceProcessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type,
+void CppSourceProcessor::sourceNeeded(int line, const QString &fileName, IncludeType type,
const QStringList &initialIncludes)
{
if (fileName.isEmpty())
diff --git a/src/plugins/cpptools/cppsourceprocessor.h b/src/plugins/cpptools/cppsourceprocessor.h
index de6ea7928a..faa5a266c8 100644
--- a/src/plugins/cpptools/cppsourceprocessor.h
+++ b/src/plugins/cpptools/cppsourceprocessor.h
@@ -93,20 +93,20 @@ private:
// Client interface
void macroAdded(const CPlusPlus::Macro &macro) override;
- void passedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charsOffset,
- unsigned line, const CPlusPlus::Macro &macro) override;
- void failedMacroDefinitionCheck(unsigned bytesOffset, unsigned utf16charOffset,
+ void passedMacroDefinitionCheck(int bytesOffset, int utf16charsOffset,
+ int line, const CPlusPlus::Macro &macro) override;
+ void failedMacroDefinitionCheck(int bytesOffset, int utf16charOffset,
const CPlusPlus::ByteArrayRef &name) override;
- void notifyMacroReference(unsigned bytesOffset, unsigned utf16charOffset,
- unsigned line, const CPlusPlus::Macro &macro) override;
- void startExpandingMacro(unsigned bytesOffset, unsigned utf16charOffset,
- unsigned line, const CPlusPlus::Macro &macro,
+ void notifyMacroReference(int bytesOffset, int utf16charOffset,
+ int line, const CPlusPlus::Macro &macro) override;
+ void startExpandingMacro(int bytesOffset, int utf16charOffset,
+ int line, const CPlusPlus::Macro &macro,
const QVector<CPlusPlus::MacroArgumentReference> &actuals) override;
- void stopExpandingMacro(unsigned bytesOffset, const CPlusPlus::Macro &macro) override;
+ void stopExpandingMacro(int bytesOffset, const CPlusPlus::Macro &macro) override;
void markAsIncludeGuard(const QByteArray &macroName) override;
- void startSkippingBlocks(unsigned utf16charsOffset) override;
- void stopSkippingBlocks(unsigned utf16charsOffset) override;
- void sourceNeeded(unsigned line, const QString &fileName, IncludeType type,
+ void startSkippingBlocks(int utf16charsOffset) override;
+ void stopSkippingBlocks(int utf16charsOffset) override;
+ void sourceNeeded(int line, const QString &fileName, IncludeType type,
const QStringList &initialIncludes) override;
private:
diff --git a/src/plugins/cpptools/cppsourceprocessor_test.cpp b/src/plugins/cpptools/cppsourceprocessor_test.cpp
index 009264cc3c..67a1b9f702 100644
--- a/src/plugins/cpptools/cppsourceprocessor_test.cpp
+++ b/src/plugins/cpptools/cppsourceprocessor_test.cpp
@@ -179,11 +179,11 @@ void CppToolsPlugin::test_cppsourceprocessor_macroUses()
const QList<Document::MacroUse> macroUses = document->macroUses();
QCOMPARE(macroUses.size(), 1);
const Document::MacroUse macroUse = macroUses.at(0);
- QCOMPARE(macroUse.bytesBegin(), 25U);
- QCOMPARE(macroUse.bytesEnd(), 35U);
- QCOMPARE(macroUse.utf16charsBegin(), 25U);
- QCOMPARE(macroUse.utf16charsEnd(), 35U);
- QCOMPARE(macroUse.beginLine(), 2U);
+ QCOMPARE(macroUse.bytesBegin(), 25);
+ QCOMPARE(macroUse.bytesEnd(), 35);
+ QCOMPARE(macroUse.utf16charsBegin(), 25);
+ QCOMPARE(macroUse.utf16charsEnd(), 35);
+ QCOMPARE(macroUse.beginLine(), 2);
}
static bool isMacroDefinedInDocument(const QByteArray &macroName, const Document::Ptr &document)
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 04b7ce1adc..970c8fdbd7 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -53,8 +53,8 @@ HEADERS += \
cpppointerdeclarationformatter.h \
cppprojectfile.h \
cppprojectupdater.h \
+ cppprojectupdaterinterface.h \
cppqtstyleindenter.h \
- cpprawprojectpart.h \
cpprefactoringchanges.h \
cpprefactoringengine.h \
cppselectionchanger.h \
@@ -104,7 +104,6 @@ HEADERS += \
cppmodelmanagerinterface.h \
cppbuiltinmodelmanagersupport.h \
headerpathfilter.h \
- cppkitinfo.h \
cpptools_clazychecks.h
SOURCES += \
@@ -155,7 +154,6 @@ SOURCES += \
cppprojectfile.cpp \
cppprojectupdater.cpp \
cppqtstyleindenter.cpp \
- cpprawprojectpart.cpp \
cpprefactoringchanges.cpp \
cpprefactoringengine.cpp \
cppselectionchanger.cpp \
@@ -192,8 +190,7 @@ SOURCES += \
cppprojectpartchooser.cpp \
wrappablelineedit.cpp \
cppbuiltinmodelmanagersupport.cpp \
- headerpathfilter.cpp \
- cppkitinfo.cpp
+ headerpathfilter.cpp
FORMS += \
clangdiagnosticconfigswidget.ui \
@@ -227,6 +224,3 @@ equals(TEST, 1) {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-
-RESOURCES += \
- cpptools.qrc
diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs
index 85e086ddf9..8446281281 100644
--- a/src/plugins/cpptools/cpptools.qbs
+++ b/src/plugins/cpptools/cpptools.qbs
@@ -116,8 +116,6 @@ Project {
"cppincludesfilter.h",
"cppindexingsupport.cpp",
"cppindexingsupport.h",
- "cppkitinfo.cpp",
- "cppkitinfo.h",
"cpplocalsymbols.cpp",
"cpplocalsymbols.h",
"cpplocatordata.cpp",
@@ -142,10 +140,9 @@ Project {
"cppprojectpartchooser.h",
"cppprojectupdater.cpp",
"cppprojectupdater.h",
+ "cppprojectupdaterinterface.h",
"cppqtstyleindenter.cpp",
"cppqtstyleindenter.h",
- "cpprawprojectpart.cpp",
- "cpprawprojectpart.h",
"cpprefactoringchanges.cpp",
"cpprefactoringchanges.h",
"cpprefactoringengine.cpp",
@@ -157,7 +154,6 @@ Project {
"cppsemanticinfoupdater.h",
"cppsourceprocessor.cpp",
"cppsourceprocessor.h",
- "cpptools.qrc",
"cpptools_clangtidychecks.h",
"cpptools_clazychecks.h",
"cpptools_global.h",
diff --git a/src/plugins/cpptools/cpptools.qrc b/src/plugins/cpptools/cpptools.qrc
deleted file mode 100644
index 7ba7243975..0000000000
--- a/src/plugins/cpptools/cpptools.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-<RCC>
- <qresource prefix="/cpptools">
- <file>images/settingscategory_cpp.png</file>
- <file>images/settingscategory_cpp@2x.png</file>
- </qresource>
-</RCC>
diff --git a/src/plugins/cpptools/cpptoolsconstants.h b/src/plugins/cpptools/cpptoolsconstants.h
index 8490f2ccf5..f62a06dee2 100644
--- a/src/plugins/cpptools/cpptoolsconstants.h
+++ b/src/plugins/cpptools/cpptoolsconstants.h
@@ -43,6 +43,7 @@ const char OBJECTIVE_CPP_SOURCE_MIMETYPE[] = "text/x-objc++src";
const char CPP_HEADER_MIMETYPE[] = "text/x-c++hdr";
const char QDOC_MIMETYPE[] = "text/x-qdoc";
const char MOC_MIMETYPE[] = "text/x-moc";
+const char AMBIGUOUS_HEADER_MIMETYPE[] = "application/vnd.qtc.ambiguousheader"; // not a real MIME type
// QSettings keys for use by the "New Class" wizards.
const char CPPTOOLS_SETTINGSGROUP[] = "CppTools";
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index be52ced3f1..d0d486e201 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -23,31 +23,33 @@
**
****************************************************************************/
-#include "cpptoolsconstants.h"
#include "cpptoolsplugin.h"
-#include "cppfilesettingspage.h"
#include "cppcodemodelsettingspage.h"
#include "cppcodestylesettingspage.h"
+#include "cppfilesettingspage.h"
#include "cppmodelmanager.h"
-#include "cpptoolsjsextension.h"
-#include "cpptoolssettings.h"
-#include "cpptoolsreuse.h"
#include "cppprojectfile.h"
+#include "cppprojectupdater.h"
#include "cpptoolsbridge.h"
+#include "cpptoolsbridgeqtcreatorimplementation.h"
+#include "cpptoolsconstants.h"
+#include "cpptoolsjsextension.h"
+#include "cpptoolsreuse.h"
+#include "cpptoolssettings.h"
#include "projectinfo.h"
#include "stringtable.h"
-#include "cpptoolsbridgeqtcreatorimplementation.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
-#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/documentmanager.h>
+#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
#include <coreplugin/jsexpander.h>
#include <coreplugin/vcsmanager.h>
#include <cppeditor/cppeditorconstants.h>
+#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
@@ -97,6 +99,7 @@ public:
delete m_cppCodeModelSettingsPage;
if (m_cppCodeStyleSettingsPage)
delete m_cppCodeStyleSettingsPage;
+ ExtensionSystem::PluginManager::removeObject(&m_cppProjectUpdaterFactory);
}
QSharedPointer<CppCodeModelSettings> m_codeModelSettings;
@@ -104,6 +107,7 @@ public:
CppFileSettingsPage *m_cppFileSettingsPage = nullptr;
CppCodeModelSettingsPage *m_cppCodeModelSettingsPage = nullptr;
QPointer<CppCodeStyleSettingsPage> m_cppCodeStyleSettingsPage = nullptr;
+ CppProjectUpdaterFactory m_cppProjectUpdaterFactory;
};
CppToolsPlugin::CppToolsPlugin()
@@ -173,6 +177,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
d = new CppToolsPluginPrivate;
JsExpander::registerGlobalObject<CppToolsJsExtension>("Cpp");
+ ExtensionSystem::PluginManager::addObject(&d->m_cppProjectUpdaterFactory);
// Menus
ActionContainer *mtools = ActionManager::actionContainer(Core::Constants::M_TOOLS);
diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h
index d319c9eb1e..8035c08785 100644
--- a/src/plugins/cpptools/cpptoolsplugin.h
+++ b/src/plugins/cpptools/cpptoolsplugin.h
@@ -159,6 +159,8 @@ private slots:
void test_cpplocatorfilters_CppLocatorFilter();
void test_cpplocatorfilters_CppLocatorFilter_data();
void test_cpplocatorfilters_CppCurrentDocumentFilter();
+ void test_cpplocatorfilters_CppCurrentDocumentHighlighting();
+ void test_cpplocatorfilters_CppFunctionsFilterHighlighting();
void test_builtinsymbolsearcher();
void test_builtinsymbolsearcher_data();
diff --git a/src/plugins/cpptools/cpptoolstestcase.cpp b/src/plugins/cpptools/cpptoolstestcase.cpp
index 22e2567b44..b9ba701aeb 100644
--- a/src/plugins/cpptools/cpptoolstestcase.cpp
+++ b/src/plugins/cpptools/cpptoolstestcase.cpp
@@ -291,7 +291,7 @@ ProjectInfo ProjectOpenerAndCloser::open(const QString &projectFile, bool config
Project *project = result.project();
if (configureAsExampleProject)
- project->configureAsExampleProject({ });
+ project->configureAsExampleProject();
if (TestCase::waitUntilCppModelManagerIsAwareOf(project)) {
m_openProjects.append(project);
diff --git a/src/plugins/cpptools/cppworkingcopy.h b/src/plugins/cpptools/cppworkingcopy.h
index 1477720553..1dd1c719d2 100644
--- a/src/plugins/cpptools/cppworkingcopy.h
+++ b/src/plugins/cpptools/cppworkingcopy.h
@@ -70,14 +70,14 @@ public:
QPair<QByteArray, unsigned> get(const Utils::FilePath &fileName) const
{ return _elements.value(fileName); }
- QHashIterator<Utils::FilePath, QPair<QByteArray, unsigned> > iterator() const
- { return QHashIterator<Utils::FilePath, QPair<QByteArray, unsigned> >(_elements); }
+ using Table = QHash<Utils::FilePath, QPair<QByteArray, unsigned> >;
+ const Table &elements() const
+ { return _elements; }
int size() const
{ return _elements.size(); }
private:
- using Table = QHash<Utils::FilePath, QPair<QByteArray, unsigned> >;
Table _elements;
};
diff --git a/src/plugins/cpptools/doxygengenerator.cpp b/src/plugins/cpptools/doxygengenerator.cpp
index c11cb4d7cb..702f92e524 100644
--- a/src/plugins/cpptools/doxygengenerator.cpp
+++ b/src/plugins/cpptools/doxygengenerator.cpp
@@ -108,6 +108,10 @@ QString DoxygenGenerator::generate(QTextCursor cursor,
return QString();
QString declCandidate = cursor.selectedText();
+
+ if (declCandidate.startsWith(QLatin1String("Q_INVOKABLE")))
+ declCandidate = declCandidate.mid(11);
+
declCandidate.replace(QChar::ParagraphSeparator, QLatin1Char('\n'));
// Let's append a closing brace in the case we got content like 'class MyType {'
diff --git a/src/plugins/cpptools/headerpathfilter.cpp b/src/plugins/cpptools/headerpathfilter.cpp
index e2d1e6a4ca..d401f547f5 100644
--- a/src/plugins/cpptools/headerpathfilter.cpp
+++ b/src/plugins/cpptools/headerpathfilter.cpp
@@ -86,8 +86,8 @@ QString clangIncludeDirectory(const QString &clangVersion, const QString &clangR
#ifndef UNIT_TESTS
return Core::ICore::clangIncludeDirectory(clangVersion, clangResourceDirectory);
#else
- Q_UNUSED(clangVersion);
- Q_UNUSED(clangResourceDirectory);
+ Q_UNUSED(clangVersion)
+ Q_UNUSED(clangResourceDirectory)
return CLANG_RESOURCE_DIR;
#endif
}
diff --git a/src/plugins/cpptools/includeutils.cpp b/src/plugins/cpptools/includeutils.cpp
index c57366332c..c42b104acf 100644
--- a/src/plugins/cpptools/includeutils.cpp
+++ b/src/plugins/cpptools/includeutils.cpp
@@ -319,7 +319,7 @@ QList<IncludeGroup> IncludeGroup::detectIncludeGroupsByNewLines(QList<Document::
{
// Create groups
QList<IncludeGroup> result;
- unsigned lastLine = 0;
+ int lastLine = 0;
QList<Include> currentIncludes;
bool isFirst = true;
foreach (const Include &include, includes) {
diff --git a/src/plugins/cpptools/insertionpointlocator.cpp b/src/plugins/cpptools/insertionpointlocator.cpp
index e6db241d79..c92d8bbca8 100644
--- a/src/plugins/cpptools/insertionpointlocator.cpp
+++ b/src/plugins/cpptools/insertionpointlocator.cpp
@@ -58,7 +58,7 @@ static int ordering(InsertionPointLocator::AccessSpec xsSpec)
struct AccessRange
{
- unsigned start = 0;
+ int start = 0;
unsigned end = 0;
InsertionPointLocator::AccessSpec xsSpec = InsertionPointLocator::Invalid;
unsigned colonToken = 0;
@@ -119,7 +119,7 @@ protected:
bool needsSuffix = false;
findMatch(ranges, _xsSpec, beforeToken, needsLeadingEmptyLine, needsPrefix, needsSuffix);
- unsigned line = 0, column = 0;
+ int line = 0, column = 0;
getTokenStartPosition(beforeToken, &line, &column);
QString prefix;
@@ -253,7 +253,7 @@ InsertionLocation::InsertionLocation() = default;
InsertionLocation::InsertionLocation(const QString &fileName,
const QString &prefix,
const QString &suffix,
- unsigned line, unsigned column)
+ int line, int column)
: m_fileName(fileName)
, m_prefix(prefix)
, m_suffix(suffix)
@@ -350,7 +350,7 @@ public:
: ASTVisitor(translationUnit)
{}
- void operator()(Symbol *decl, unsigned *line, unsigned *column)
+ void operator()(Symbol *decl, int *line, int *column)
{
// default to end of file
const unsigned lastToken = translationUnit()->ast()->lastToken();
@@ -408,15 +408,15 @@ protected:
class FindFunctionDefinition : protected ASTVisitor
{
FunctionDefinitionAST *_result = nullptr;
- unsigned _line = 0;
- unsigned _column = 0;
+ int _line = 0;
+ int _column = 0;
public:
explicit FindFunctionDefinition(TranslationUnit *translationUnit)
: ASTVisitor(translationUnit)
{
}
- FunctionDefinitionAST *operator()(unsigned line, unsigned column)
+ FunctionDefinitionAST *operator()(int line, int column)
{
_result = nullptr;
_line = line;
@@ -430,7 +430,7 @@ protected:
{
if (_result)
return false;
- unsigned line, column;
+ int line, column;
translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
if (line > _line || (line == _line && column > _column))
return false;
@@ -473,7 +473,7 @@ static InsertionLocation nextToSurroundingDefinitions(Symbol *declaration,
// find the index of declaration
int declIndex = -1;
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *s = klass->memberAt(i);
if (s == declaration) {
declIndex = i;
@@ -505,7 +505,7 @@ static InsertionLocation nextToSurroundingDefinitions(Symbol *declaration,
}
if (!definitionFunction) {
// try to find one below
- for (unsigned i = declIndex + 1; i < klass->memberCount(); ++i) {
+ for (int i = declIndex + 1; i < klass->memberCount(); ++i) {
Symbol *s = klass->memberAt(i);
surroundingFunctionDecl = isNonVirtualFunctionDeclaration(s);
if (!surroundingFunctionDecl)
@@ -526,7 +526,7 @@ static InsertionLocation nextToSurroundingDefinitions(Symbol *declaration,
if (!definitionFunction)
return noResult;
- unsigned line, column;
+ int line, column;
if (suffix.isEmpty()) {
Document::Ptr targetDoc = changes.snapshot().document(QString::fromUtf8(definitionFunction->fileName()));
if (!targetDoc)
@@ -586,7 +586,7 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition(Symbol *declara
if (doc.isNull())
return result;
- unsigned line = 0, column = 0;
+ int line = 0, column = 0;
FindMethodDefinitionInsertPoint finder(doc->translationUnit());
finder(declaration, &line, &column);
diff --git a/src/plugins/cpptools/insertionpointlocator.h b/src/plugins/cpptools/insertionpointlocator.h
index c05bc0f6ff..a54f988241 100644
--- a/src/plugins/cpptools/insertionpointlocator.h
+++ b/src/plugins/cpptools/insertionpointlocator.h
@@ -35,7 +35,7 @@ class CPPTOOLS_EXPORT InsertionLocation
public:
InsertionLocation();
InsertionLocation(const QString &fileName, const QString &prefix,
- const QString &suffix, unsigned line, unsigned column);
+ const QString &suffix, int line, int column);
QString fileName() const
{ return m_fileName; }
@@ -49,11 +49,11 @@ public:
{ return m_suffix; }
/// \returns The line where to insert. The line number is 1-based.
- unsigned line() const
+ int line() const
{ return m_line; }
/// \returns The column where to insert. The column number is 1-based.
- unsigned column() const
+ int column() const
{ return m_column; }
bool isValid() const
@@ -63,8 +63,8 @@ private:
QString m_fileName;
QString m_prefix;
QString m_suffix;
- unsigned m_line = 0;
- unsigned m_column = 0;
+ int m_line = 0;
+ int m_column = 0;
};
class CPPTOOLS_EXPORT InsertionPointLocator
diff --git a/src/plugins/cpptools/projectinfo.cpp b/src/plugins/cpptools/projectinfo.cpp
index 1cc5515eb9..a7047dc972 100644
--- a/src/plugins/cpptools/projectinfo.cpp
+++ b/src/plugins/cpptools/projectinfo.cpp
@@ -25,47 +25,14 @@
#include "projectinfo.h"
-#include "cppkitinfo.h"
-
#include <projectexplorer/abi.h>
-#include <projectexplorer/toolchain.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/rawprojectpart.h>
+#include <projectexplorer/toolchain.h>
namespace CppTools {
-ToolChainInfo::ToolChainInfo(const ProjectExplorer::ToolChain *toolChain,
- const QString &sysRootPath)
-{
- if (toolChain) {
- // Keep the following cheap/non-blocking for the ui thread...
- type = toolChain->typeId();
- isMsvc2015ToolChain
- = toolChain->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMsvc2015Flavor;
- wordWidth = toolChain->targetAbi().wordWidth();
- targetTriple = toolChain->originalTargetTriple();
- extraCodeModelFlags = toolChain->extraCodeModelFlags();
-
- // ...and save the potentially expensive operations for later so that
- // they can be run from a worker thread.
- this->sysRootPath = sysRootPath;
- headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner();
- macroInspectionRunner = toolChain->createMacroInspectionRunner();
- }
-}
-
-ProjectUpdateInfo::ProjectUpdateInfo(ProjectExplorer::Project *project,
- const KitInfo &kitInfo,
- const RawProjectParts &rawProjectParts)
- : project(project)
- , rawProjectParts(rawProjectParts)
- , cToolChain(kitInfo.cToolChain)
- , cxxToolChain(kitInfo.cxxToolChain)
- , cToolChainInfo(ToolChainInfo(cToolChain, kitInfo.sysRootPath))
- , cxxToolChainInfo(ToolChainInfo(cxxToolChain, kitInfo.sysRootPath))
-{
-}
-
ProjectInfo::ProjectInfo(QPointer<ProjectExplorer::Project> project)
: m_project(project)
{
diff --git a/src/plugins/cpptools/projectinfo.h b/src/plugins/cpptools/projectinfo.h
index c934bda2d5..347e72f477 100644
--- a/src/plugins/cpptools/projectinfo.h
+++ b/src/plugins/cpptools/projectinfo.h
@@ -27,10 +27,10 @@
#include "cpptools_global.h"
-#include "cpprawprojectpart.h"
#include "projectpart.h"
#include <projectexplorer/project.h>
+#include <projectexplorer/rawprojectpart.h>
#include <projectexplorer/toolchain.h>
#include <QHash>
@@ -40,49 +40,6 @@
namespace CppTools {
-class KitInfo;
-
-class ToolChainInfo
-{
-public:
- ToolChainInfo() = default;
- ToolChainInfo(const ProjectExplorer::ToolChain *toolChain,
- const QString &sysRootPath);
-
- bool isValid() const { return type.isValid(); }
-
-public:
- Core::Id type;
- bool isMsvc2015ToolChain = false;
- unsigned wordWidth = 0;
- QString targetTriple;
- QStringList extraCodeModelFlags;
-
- QString sysRootPath; // For headerPathsRunner.
- ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner;
- ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner;
-};
-
-class CPPTOOLS_EXPORT ProjectUpdateInfo
-{
-public:
- ProjectUpdateInfo() = default;
- ProjectUpdateInfo(ProjectExplorer::Project *project,
- const KitInfo &kitInfo,
- const RawProjectParts &rawProjectParts);
- bool isValid() const { return project && !rawProjectParts.isEmpty(); }
-
-public:
- QPointer<ProjectExplorer::Project> project;
- QVector<RawProjectPart> rawProjectParts;
-
- const ProjectExplorer::ToolChain *cToolChain = nullptr;
- const ProjectExplorer::ToolChain *cxxToolChain = nullptr;
-
- ToolChainInfo cToolChainInfo;
- ToolChainInfo cxxToolChainInfo;
-};
-
class CPPTOOLS_EXPORT ProjectInfo
{
public:
diff --git a/src/plugins/cpptools/projectpart.cpp b/src/plugins/cpptools/projectpart.cpp
index 4569f231d1..f88fefac82 100644
--- a/src/plugins/cpptools/projectpart.cpp
+++ b/src/plugins/cpptools/projectpart.cpp
@@ -36,8 +36,9 @@ namespace CppTools {
void ProjectPart::updateLanguageFeatures()
{
const bool hasCxx = languageVersion >= Utils::LanguageVersion::CXX98;
- const bool hasQt = hasCxx && qtVersion != NoQt;
+ const bool hasQt = hasCxx && qtVersion != Utils::QtVersion::None;
languageFeatures.cxx11Enabled = languageVersion >= Utils::LanguageVersion::CXX11;
+ languageFeatures.cxx14Enabled = languageVersion >= Utils::LanguageVersion::CXX14;
languageFeatures.cxxEnabled = hasCxx;
languageFeatures.c99Enabled = languageVersion >= Utils::LanguageVersion::C99;
languageFeatures.objCEnabled = languageExtensions.testFlag(Utils::LanguageExtension::ObjectiveC);
diff --git a/src/plugins/cpptools/projectpart.h b/src/plugins/cpptools/projectpart.h
index 71df5e1ee5..f7a872e2a1 100644
--- a/src/plugins/cpptools/projectpart.h
+++ b/src/plugins/cpptools/projectpart.h
@@ -29,9 +29,11 @@
#include "cppprojectfile.h"
+#include <projectexplorer/buildtargettype.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/projectexplorer_global.h>
#include <projectexplorer/projectmacro.h>
+#include <projectexplorer/rawprojectpart.h>
#include <coreplugin/id.h>
@@ -53,24 +55,11 @@ namespace CppTools {
class CPPTOOLS_EXPORT ProjectPart
{
public:
- enum QtVersion {
- UnknownQt = -1,
- NoQt,
- Qt4,
- Qt5
- };
-
enum ToolChainWordWidth {
WordWidth32Bit,
WordWidth64Bit,
};
- enum BuildTargetType {
- Unknown,
- Executable,
- Library
- };
-
using Ptr = QSharedPointer<ProjectPart>;
public:
@@ -97,7 +86,7 @@ public:
::Utils::LanguageVersion languageVersion = ::Utils::LanguageVersion::LatestCxx;
::Utils::LanguageExtensions languageExtensions = ::Utils::LanguageExtension::None;
CPlusPlus::LanguageFeatures languageFeatures;
- QtVersion qtVersion = UnknownQt;
+ ::Utils::QtVersion qtVersion = ::Utils::QtVersion::Unknown;
// Files
ProjectFiles files;
@@ -111,7 +100,7 @@ public:
// Build system
QString buildSystemTarget;
- BuildTargetType buildTargetType = Unknown;
+ ProjectExplorer::BuildTargetType buildTargetType = ProjectExplorer::BuildTargetType::Unknown;
bool selectedForBuilding = true;
// ToolChain
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
index 6adb437bf8..05080fdb87 100644
--- a/src/plugins/cpptools/searchsymbols.cpp
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -70,7 +70,7 @@ IndexItem::Ptr SearchSymbols::operator()(Document::Ptr doc, const QString &scope
QTC_ASSERT(_parent->fileName() == Internal::StringTable::insert(doc->fileName()),
return IndexItem::Ptr());
- for (unsigned i = 0, ei = doc->globalSymbolCount(); i != ei; ++i)
+ for (int i = 0, ei = doc->globalSymbolCount(); i != ei; ++i)
accept(doc->globalSymbolAt(i));
Internal::StringTable::scheduleGC();
@@ -95,7 +95,7 @@ bool SearchSymbols::visit(Enum *symbol)
QString newScope = scopedSymbolName(name, symbol);
ScopedScope scopeRaii(_scope, newScope);
- for (unsigned i = 0, ei = symbol->memberCount(); i != ei; ++i)
+ for (int i = 0, ei = symbol->memberCount(); i != ei; ++i)
accept(symbol->memberAt(i));
return false;
@@ -112,7 +112,7 @@ bool SearchSymbols::visit(Namespace *symbol)
QString name = scopedSymbolName(symbol);
QString newScope = name;
ScopedScope raii(_scope, newScope);
- for (unsigned i = 0; i < symbol->memberCount(); ++i) {
+ for (int i = 0; i < symbol->memberCount(); ++i) {
accept(symbol->memberAt(i));
}
return false;
@@ -321,7 +321,7 @@ void SearchSymbols::processClass(T *clazz)
QString newScope = scopedSymbolName(name, clazz);
ScopedScope scopeRaii(_scope, newScope);
- for (unsigned i = 0, ei = clazz->memberCount(); i != ei; ++i)
+ for (int i = 0, ei = clazz->memberCount(); i != ei; ++i)
accept(clazz->memberAt(i));
}
diff --git a/src/plugins/cpptools/symbolsfindfilter.cpp b/src/plugins/cpptools/symbolsfindfilter.cpp
index 404a4209a6..3cba030352 100644
--- a/src/plugins/cpptools/symbolsfindfilter.cpp
+++ b/src/plugins/cpptools/symbolsfindfilter.cpp
@@ -263,7 +263,7 @@ SymbolsFindFilterConfigWidget::SymbolsFindFilterConfigWidget(SymbolsFindFilter *
auto layout = new QGridLayout(this);
setLayout(layout);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
auto typeLabel = new QLabel(tr("Types:"));
layout->addWidget(typeLabel, 0, 0);
diff --git a/src/plugins/cpptools/typehierarchybuilder.cpp b/src/plugins/cpptools/typehierarchybuilder.cpp
index aee41076d7..b0a31ad62a 100644
--- a/src/plugins/cpptools/typehierarchybuilder.cpp
+++ b/src/plugins/cpptools/typehierarchybuilder.cpp
@@ -71,13 +71,13 @@ void DerivedHierarchyVisitor::execute(const CPlusPlus::Document::Ptr &doc,
_otherBases.clear();
_context = CPlusPlus::LookupContext(doc, snapshot);
- for (unsigned i = 0; i < doc->globalSymbolCount(); ++i)
+ for (int i = 0; i < doc->globalSymbolCount(); ++i)
accept(doc->globalSymbolAt(i));
}
bool DerivedHierarchyVisitor::visit(CPlusPlus::Class *symbol)
{
- for (unsigned i = 0; i < symbol->baseClassCount(); ++i) {
+ for (int i = 0; i < symbol->baseClassCount(); ++i) {
CPlusPlus::BaseClass *baseSymbol = symbol->baseClassAt(i);
QString baseName = _actualBases.value(baseSymbol);
diff --git a/src/plugins/cpptools/usages.h b/src/plugins/cpptools/usages.h
index 1e0f502c5e..3248fc4e90 100644
--- a/src/plugins/cpptools/usages.h
+++ b/src/plugins/cpptools/usages.h
@@ -51,6 +51,12 @@ public:
&& first.path == second.path;
}
+ friend bool operator<(const Usage &first, const Usage &second)
+ {
+ return std::tie(first.path, first.line, first.column)
+ < std::tie(second.path, second.line, second.column);
+ }
+
public:
QString path;
int line = 0;
diff --git a/src/plugins/ctfvisualizer/CMakeLists.txt b/src/plugins/ctfvisualizer/CMakeLists.txt
new file mode 100644
index 0000000000..342393bcd1
--- /dev/null
+++ b/src/plugins/ctfvisualizer/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_qtc_plugin(CtfVisualizer
+ DEPENDS Tracing Qt5::QuickWidgets
+ INCLUDES ${PROJECT_SOURCE_DIR}/src
+ PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
+ SOURCES
+ ctfstatisticsmodel.cpp
+ ctfstatisticsview.cpp
+ ctfvisualizerplugin.cpp
+ ctfvisualizertool.cpp
+ ctftimelinemodel.cpp
+ ctftracemanager.cpp
+ ctfvisualizertraceview.cpp
+ ctfstatisticsmodel.h
+ ctfstatisticsview.h
+ ctfvisualizerplugin.h
+ ctfvisualizertool.h
+ ctftimelinemodel.h
+ ctftracemanager.h
+ ctfvisualizerconstants.h
+ ctfvisualizertraceview.h
+ ../../libs/3rdparty/json/json.hpp
+)
diff --git a/src/plugins/ctfvisualizer/CtfVisualizer.json.in b/src/plugins/ctfvisualizer/CtfVisualizer.json.in
new file mode 100644
index 0000000000..78b6e093f0
--- /dev/null
+++ b/src/plugins/ctfvisualizer/CtfVisualizer.json.in
@@ -0,0 +1,20 @@
+{
+ \"Name\" : \"CtfVisualizer\",
+ \"Version\" : \"$$QTCREATOR_VERSION\",
+ \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
+ \"Revision\" : \"$$QTC_PLUGIN_REVISION\",
+ \"Vendor\" : \"KDAB Group, www.kdab.com\",
+ \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com\",
+ \"License\" : [ \"Commercial Usage\",
+ \"\",
+ \"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt 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.\",
+ \"\",
+ \"GNU General Public License Usage\",
+ \"\",
+ \"Alternatively, this plugin 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 plugin. 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.\"
+ ],
+ \"Category\" : \"Code Analyzer\",
+ \"Description\" : \"Chrome Trace Format Visualizer Plugin.\",
+ \"Url\" : \"https://www.kdab.com\",
+ $$dependencyList
+}
diff --git a/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp b/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp
new file mode 100644
index 0000000000..bdf88eaf5c
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfstatisticsmodel.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfstatisticsmodel.h"
+
+#include "ctfvisualizerconstants.h"
+
+#include <tracing/timelineformattime.h>
+
+namespace CtfVisualizer {
+namespace Internal {
+
+using json = nlohmann::json;
+using namespace Constants;
+
+CtfStatisticsModel::CtfStatisticsModel(QObject *parent)
+ : QAbstractTableModel(parent)
+{
+
+}
+
+void CtfStatisticsModel::beginLoading()
+{
+ beginResetModel();
+ m_data.clear();
+}
+
+void CtfStatisticsModel::addEvent(const json &event, qint64 durationInNs)
+{
+ const std::string name = event.value(CtfEventNameKey, "");
+
+ EventData &data = m_data[QString::fromStdString(name)];
+ ++data.count;
+ if (durationInNs >= 0) {
+ data.totalDuration += durationInNs;
+ data.minDuration = std::min(data.minDuration, durationInNs);
+ data.maxDuration = std::max(data.maxDuration, durationInNs);
+ }
+}
+
+void CtfStatisticsModel::endLoading()
+{
+ endResetModel();
+}
+
+int CtfStatisticsModel::rowCount(const QModelIndex &parent) const
+{
+ return parent.isValid() ? 0 : m_data.size();
+}
+
+int CtfStatisticsModel::columnCount(const QModelIndex &parent) const
+{
+ return parent.isValid() ? 0 : Column::COUNT;
+}
+
+QVariant CtfStatisticsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ QString title = m_data.keys().at(index.row());
+
+ switch (role) {
+ case Qt::TextAlignmentRole:
+ switch (index.column()) {
+ case Column::Title:
+ return Qt::AlignLeft;
+ case Column::Count:
+ case Column::TotalDuration:
+ case Column::MinDuration:
+ case Column::AvgDuration:
+ case Column::MaxDuration:
+ return Qt::AlignRight;
+ }
+ case SortRole:
+ switch (index.column()) {
+ case Column::Title:
+ return title;
+ case Column::Count:
+ return m_data.value(title).count;
+ case Column::TotalDuration:
+ return m_data.value(title).totalDuration;
+ case Column::MinDuration:
+ {
+ auto minDuration = m_data.value(title).minDuration;
+ return minDuration != std::numeric_limits<qint64>::max() ? minDuration : 0;
+ }
+ case Column::AvgDuration:
+ {
+ auto data = m_data.value(title);
+ if (data.totalDuration > 0 && data.count > 0)
+ return double(data.totalDuration) / data.count;
+ return 0;
+ }
+ case Column::MaxDuration:
+ return m_data.value(title).maxDuration;
+ default:
+ return QVariant();
+ }
+ case Qt::DisplayRole:
+ switch (index.column()) {
+ case Column::Title:
+ return title;
+ case Column::Count:
+ return m_data.value(title).count;
+ case Column::TotalDuration:
+ {
+ auto totalDuration = m_data.value(title).totalDuration;
+ if (totalDuration > 0)
+ return Timeline::formatTime(totalDuration);
+ else
+ return "-";
+ }
+ case Column::MinDuration:
+ {
+ auto minDuration = m_data.value(title).minDuration;
+ if (minDuration != std::numeric_limits<qint64>::max())
+ return Timeline::formatTime(minDuration);
+ else
+ return "-";
+ }
+ case Column::AvgDuration:
+ {
+ auto data = m_data.value(title);
+ if (data.totalDuration > 0 && data.count > 0)
+ return Timeline::formatTime(data.totalDuration / data.count);
+ return "-";
+ }
+ case Column::MaxDuration:
+ {
+ auto maxDuration = m_data.value(title).maxDuration;
+ if (maxDuration > 0)
+ return Timeline::formatTime(maxDuration);
+ else
+ return "-";
+ }
+ }
+ }
+
+ return QVariant();
+}
+
+QVariant CtfStatisticsModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
+ return QAbstractTableModel::headerData(section, orientation, role);
+
+ switch (section) {
+ case Column::Title:
+ return tr("Title");
+ case Column::Count:
+ return tr("Count");
+ case Column::TotalDuration:
+ return tr("Total Time");
+ case Column::MinDuration:
+ return tr("Minimum Time");
+ case Column::AvgDuration:
+ return tr("Average Time");
+ case Column::MaxDuration:
+ return tr("Maximum Time");
+ default:
+ return "";
+ }
+}
+
+} // Internal
+} // CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfstatisticsmodel.h b/src/plugins/ctfvisualizer/ctfstatisticsmodel.h
new file mode 100644
index 0000000000..10af0b8b3a
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfstatisticsmodel.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "json/json.hpp"
+
+#include <QHash>
+#include <QStack>
+#include <QVector>
+#include <QPointer>
+#include <QAbstractTableModel>
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfStatisticsModel : public QAbstractTableModel
+{
+
+public:
+ enum Role {
+ SortRole = Qt::UserRole + 1,
+ };
+
+ enum Column {
+ Title = 0,
+ Count,
+ TotalDuration,
+ MinDuration,
+ AvgDuration,
+ MaxDuration,
+ COUNT
+ };
+
+ struct EventData {
+ int count = 0;
+ qint64 totalDuration = 0.0;
+ qint64 minDuration = std::numeric_limits<qint64>::max();
+ qint64 maxDuration = 0.0;
+ };
+
+ explicit CtfStatisticsModel(QObject *parent);
+ ~CtfStatisticsModel() override = default;
+
+ void beginLoading();
+ void addEvent(const nlohmann::json &event, qint64 duration);
+ void endLoading();
+
+private:
+
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+ QHash<QString, EventData> m_data;
+
+};
+
+} // Internal
+} // CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfstatisticsview.cpp b/src/plugins/ctfvisualizer/ctfstatisticsview.cpp
new file mode 100644
index 0000000000..16c886249a
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfstatisticsview.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfstatisticsview.h"
+
+#include "ctfstatisticsmodel.h"
+
+#include <QHeaderView>
+#include <QSortFilterProxyModel>
+
+namespace CtfVisualizer {
+namespace Internal {
+
+CtfStatisticsView::CtfStatisticsView(CtfStatisticsModel *model, QWidget *parent)
+ : Utils::TreeView(parent)
+{
+ setObjectName(QLatin1String("CtfVisualizerStatisticsView"));
+
+ auto sortModel = new QSortFilterProxyModel(this);
+ sortModel->setSourceModel(model);
+ sortModel->setSortRole(CtfStatisticsModel::SortRole);
+ sortModel->setSortCaseSensitivity(Qt::CaseInsensitive);
+
+ setModel(sortModel);
+
+ header()->setSectionResizeMode(QHeaderView::Interactive);
+ header()->setDefaultSectionSize(100);
+ header()->setMinimumSectionSize(50);
+ header()->setStretchLastSection(false);
+ header()->setSectionResizeMode(CtfStatisticsModel::Column::Title, QHeaderView::Stretch);
+ setRootIsDecorated(false);
+ setUniformRowHeights(true);
+ setSortingEnabled(true);
+
+ connect(selectionModel(), &QItemSelectionModel::currentChanged,
+ [this] (const QModelIndex &current, const QModelIndex &previous)
+ {
+ Q_UNUSED(previous);
+ QModelIndex index = this->model()->index(current.row(), CtfStatisticsModel::Title);
+ QString title = this->model()->data(index).toString();
+ emit this->eventTypeSelected(title);
+ });
+}
+
+void CtfStatisticsView::selectByTitle(const QString &title)
+{
+ auto model = this->model();
+ for (int row = 0; row < model->rowCount(); ++row)
+ {
+ auto index = model->index(row, CtfStatisticsModel::Column::Title);
+ if (model->data(index).toString() == title)
+ {
+ QItemSelection selection(index, model->index(row, CtfStatisticsModel::Column::COUNT - 1));
+ selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
+ scrollTo(index);
+ break;
+ }
+ }
+}
+
+} // Internal
+} // CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfstatisticsview.h b/src/plugins/ctfvisualizer/ctfstatisticsview.h
new file mode 100644
index 0000000000..3e94e0115f
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfstatisticsview.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfvisualizerconstants.h"
+
+#include <utils/itemviews.h>
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfStatisticsModel;
+
+class CtfStatisticsView : public Utils::TreeView
+{
+ Q_OBJECT
+public:
+ explicit CtfStatisticsView(CtfStatisticsModel *model, QWidget *parent = nullptr);
+ ~CtfStatisticsView() override = default;
+
+ void selectByTitle(const QString &title);
+
+signals:
+ void eventTypeSelected(const QString &title);
+};
+
+} // Internal
+} // CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.cpp b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp
new file mode 100644
index 0000000000..4b0d6b1a61
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp
@@ -0,0 +1,383 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctftimelinemodel.h"
+
+#include "ctftracemanager.h"
+#include "ctfvisualizerconstants.h"
+
+#include <tracing/timelineformattime.h>
+#include <tracing/timelinemodelaggregator.h>
+#include <utils/qtcassert.h>
+
+#include <QDebug>
+
+#include <string>
+
+
+namespace CtfVisualizer {
+namespace Internal {
+
+using json = nlohmann::json;
+using namespace Constants;
+
+CtfTimelineModel::CtfTimelineModel(Timeline::TimelineModelAggregator *parent,
+ CtfTraceManager *traceManager, int tid, int pid)
+ : Timeline::TimelineModel (parent)
+ , m_traceManager(traceManager)
+ , m_threadId(tid)
+ , m_processId(pid)
+{
+ updateName();
+ setCollapsedRowCount(1);
+ setCategoryColor(colorByHue(pid * 25));
+ setHasMixedTypesInExpandedState(true);
+}
+
+QRgb CtfTimelineModel::color(int index) const
+{
+ return colorBySelectionId(index);
+}
+
+QVariantList CtfTimelineModel::labels() const
+{
+ QVariantList result;
+
+ QVector<std::string> sortedCounterNames = m_counterNames;
+ std::sort(sortedCounterNames.begin(), sortedCounterNames.end());
+ for (int i = 0; i < sortedCounterNames.size(); ++i) {
+ QVariantMap element;
+ element.insert(QLatin1String("description"), QString("~ %1").arg(QString::fromStdString(sortedCounterNames[i])));
+ element.insert(QLatin1String("id"), i);
+ result << element;
+ }
+
+ for (int i = 0; i < m_maxStackSize; ++i) {
+ QVariantMap element;
+ element.insert(QLatin1String("description"), QStringLiteral("- ").append(tr("Stack Level %1").arg(i)));
+ element.insert(QLatin1String("id"), m_counterNames.size() + i);
+ result << element;
+ }
+ return result;
+}
+
+QVariantMap CtfTimelineModel::orderedDetails(int index) const
+{
+ QMap<int, QPair<QString, QString>> info = m_details.value(index);
+ info.insert(2, {tr("Start"), Timeline::formatTime(startTime(index))});
+ info.insert(3, {tr("Wall Duration"), Timeline::formatTime(duration(index))});
+ QVariantMap data;
+ QString title = info.value(0).second;
+ data.insert("title", title);
+ QVariantList content;
+ auto it = info.constBegin();
+ auto end = info.constEnd();
+ ++it; // skip title
+ while (it != end) {
+ content.append(it.value().first);
+ content.append(it.value().second);
+ ++it;
+ }
+ data.insert("content", content);
+ emit detailsRequested(title);
+ return data;
+}
+
+int CtfTimelineModel::expandedRow(int index) const
+{
+ // m_itemToCounterIdx[index] is 0 for non-counter indexes
+ const int counterIdx = m_itemToCounterIdx.value(index, 0);
+ if (counterIdx > 0) {
+ return m_counterIndexToRow[counterIdx - 1] + 1;
+ }
+ return m_nestingLevels.value(index) + m_counterData.size() + 1;
+}
+
+int CtfTimelineModel::collapsedRow(int index) const
+{
+ Q_UNUSED(index);
+ return 0;
+}
+
+int CtfTimelineModel::typeId(int index) const
+{
+ QTC_ASSERT(index >= 0 && index < count(), return -1);
+ return selectionId(index);
+}
+
+bool CtfTimelineModel::handlesTypeId(int typeId) const
+{
+ return m_handledTypeIds.contains(typeId);
+}
+
+float CtfTimelineModel::relativeHeight(int index) const
+{
+ // m_itemToCounterIdx[index] is 0 for non-counter indexes
+ const int counterIdx = m_itemToCounterIdx.value(index, 0);
+ if (counterIdx > 0) {
+ const CounterData &data = m_counterData[counterIdx - 1];
+ const float value = m_counterValues[index] / std::max(data.max, 1.0f);
+ return value;
+ }
+ return 1.0f;
+}
+
+QPair<bool, qint64> CtfTimelineModel::addEvent(const json &event, double timeOffset)
+{
+ const double timestamp = event.value(CtfTracingClockTimestampKey, 0.0);
+ const qint64 normalizedTime = qint64((timestamp - timeOffset) * 1000);
+ const std::string eventPhase = event.value(CtfEventPhaseKey, "");
+ const std::string name = event.value(CtfEventNameKey, "");
+ qint64 duration = -1;
+
+ const int selectionId = m_traceManager->getSelectionId(name);
+ m_handledTypeIds.insert(selectionId);
+
+ bool visibleOnTimeline = false;
+ if (eventPhase == CtfEventTypeBegin || eventPhase == CtfEventTypeComplete
+ || eventPhase == CtfEventTypeInstant || eventPhase == CtfEventTypeInstantDeprecated) {
+ duration = newStackEvent(event, normalizedTime, eventPhase, name, selectionId);
+ visibleOnTimeline = true;
+ } else if (eventPhase == CtfEventTypeEnd) {
+ duration = closeStackEvent(event, timestamp, normalizedTime);
+ visibleOnTimeline = true;
+ } else if (eventPhase == CtfEventTypeCounter) {
+ addCounterValue(event, normalizedTime, name, selectionId);
+ visibleOnTimeline = true;
+ } else if (eventPhase == CtfEventTypeMetadata) {
+ const std::string name = event[CtfEventNameKey];
+ if (name == "thread_name") {
+ m_threadName = QString::fromStdString(event["args"]["name"]);
+ updateName();
+ } else if (name == "process_name") {
+ m_processName = QString::fromStdString(event["args"]["name"]);
+ updateName();
+ }
+ }
+ return {visibleOnTimeline, duration};
+}
+
+void CtfTimelineModel::finalize(double traceBegin, double traceEnd, const QString &processName, const QString &threadName)
+{
+ m_processName = processName;
+ m_threadName = threadName;
+ updateName();
+
+ qint64 normalizedEnd = qint64((traceEnd - traceBegin) * 1000);
+ while (!m_openEventIds.isEmpty()) {
+ int index = m_openEventIds.pop();
+ qint64 duration = normalizedEnd - startTime(index);
+ insertEnd(index, duration);
+ m_details[index].insert(3, {reuse(tr("Wall Duration")), Timeline::formatTime(duration)});
+ m_details[index].insert(6, {reuse(tr("Unfinished")), reuse(tr("true"))});
+ }
+ computeNesting();
+
+ QVector<std::string> sortedCounterNames = m_counterNames;
+ std::sort(sortedCounterNames.begin(), sortedCounterNames.end());
+ m_counterIndexToRow.resize(m_counterNames.size());
+ for (int i = 0; i < m_counterIndexToRow.size(); ++i) {
+ m_counterIndexToRow[i] = sortedCounterNames.indexOf(m_counterNames[i]);
+ }
+
+ // we insert an empty row in expanded state because otherwise
+ // the row label would be where the thread label is
+ setExpandedRowCount(1 + m_counterData.size() + m_maxStackSize);
+ emit contentChanged();
+}
+
+void CtfTimelineModel::updateName()
+{
+ if (m_threadName.isEmpty()) {
+ setDisplayName(tr("> Thread %1").arg(m_threadId));
+ } else {
+ setDisplayName(QString("> %1 (%2)").arg(m_threadName).arg(m_threadId));
+ }
+ QString process = m_processName.isEmpty() ? QString::number(m_processId) :
+ QString("%1 (%2)").arg(m_processName).arg(m_processId);
+ QString thread = m_threadName.isEmpty() ? QString::number(m_threadId) :
+ QString("%1 (%2)").arg(m_threadName).arg(m_threadId);
+ setTooltip(QString("Process: %1\nThread: %2").arg(process).arg(thread));
+}
+
+qint64 CtfTimelineModel::newStackEvent(const json &event, qint64 normalizedTime,
+ const std::string &eventPhase, const std::string &name,
+ int selectionId)
+{
+ int nestingLevel = m_openEventIds.size();
+ m_maxStackSize = std::max(m_maxStackSize, m_openEventIds.size() + 1);
+ int index = 0;
+ qint64 duration = -1;
+ if (eventPhase == CtfEventTypeBegin) {
+ index = insertStart(normalizedTime, selectionId);
+ m_openEventIds.push(index);
+ // if this event was inserted before existing events, we need to
+ // check whether indexes stored in m_openEventIds need to be updated (increased):
+ // (the top element is the current event and is skipped)
+ for (int i = m_openEventIds.size() - 2; i >= 0; --i) {
+ if (m_openEventIds[i] >= index) ++m_openEventIds[i];
+ }
+ } else if (eventPhase == CtfEventTypeComplete) {
+ duration = qint64(event[CtfDurationKey]) * 1000;
+ index = insert(normalizedTime, duration, selectionId);
+ for (int i = m_openEventIds.size() - 1; i >= 0; --i) {
+ if (m_openEventIds[i] >= index) {
+ ++m_openEventIds[i];
+ // if the event is before an open event, the nesting level decreases:
+ --nestingLevel;
+ }
+ }
+ } else {
+ index = insert(normalizedTime, 0, selectionId);
+ for (int i = m_openEventIds.size() - 1; i >= 0; --i) {
+ if (m_openEventIds[i] >= index) {
+ ++m_openEventIds[i];
+ --nestingLevel;
+ }
+ }
+ }
+ if (index >= m_details.size()) {
+ m_details.resize(index + 1);
+ m_details[index] = QMap<int, QPair<QString, QString>>();
+ m_nestingLevels.resize(index + 1);
+ m_nestingLevels[index] = nestingLevel;
+ } else {
+ m_details.insert(index, QMap<int, QPair<QString, QString>>());
+ m_nestingLevels.insert(index, nestingLevel);
+ }
+ if (m_counterValues.size() > index) {
+ // if the event was inserted before any counter, we need
+ // to shift the values after it and update the last index:
+ m_counterValues.insert(index, 0);
+ m_itemToCounterIdx.insert(index, 0);
+ for (CounterData &counterData: m_counterData) {
+ if (counterData.startEventIndex >= index) ++counterData.startEventIndex;
+ }
+ }
+
+ if (!name.empty()) {
+ m_details[index].insert(0, {{}, reuse(QString::fromStdString(name))});
+ }
+ if (event.contains(CtfEventCategoryKey)) {
+ m_details[index].insert(1, {reuse(tr("Categories")), reuse(QString::fromStdString(event[CtfEventCategoryKey]))});
+ }
+ if (event.contains("args") && !event["args"].empty()) {
+ QString argsJson = QString::fromStdString(event["args"].dump(1));
+ // strip leading and trailing curled brackets:
+ argsJson = argsJson.size() > 4 ? argsJson.mid(2, argsJson.size() - 4) : argsJson;
+ m_details[index].insert(4, {reuse(tr("Arguments")), reuse(argsJson)});
+ }
+ if (eventPhase == CtfEventTypeInstant) {
+ m_details[index].insert(6, {reuse(tr("Instant")), reuse(tr("true"))});
+ if (event.contains("s")) {
+ std::string scope = event["s"];
+ if (scope == "g") {
+ m_details[index].insert(7, {reuse(tr("Scope")), reuse(tr("global"))});
+ } else if (scope == "p") {
+ m_details[index].insert(7, {reuse(tr("Scope")), reuse(tr("process"))});
+ } else {
+ m_details[index].insert(7, {reuse(tr("Scope")), reuse(tr("thread"))});
+ }
+ }
+ }
+ return duration;
+}
+
+qint64 CtfTimelineModel::closeStackEvent(const json &event, double timestamp, qint64 normalizedTime)
+{
+ if (m_openEventIds.isEmpty()) {
+ qWarning() << QString("End event without open 'begin' event at timestamp %1").arg(timestamp, 0, 'f');
+ return -1;
+ } else {
+ const int index = m_openEventIds.pop();
+ const qint64 duration = normalizedTime - startTime(index);
+ insertEnd(index, duration);
+ if (event.contains("args") && !event["args"].empty()) {
+ QString argsJson = QString::fromStdString(event["args"].dump(1));
+ // strip leading and trailing curled brackets:
+ argsJson = argsJson.size() > 4 ? argsJson.mid(2, argsJson.size() - 4) : argsJson;
+ m_details[index].insert(5, {reuse(tr("Return Arguments")), reuse(argsJson)});
+ }
+ return duration;
+ }
+}
+
+void CtfTimelineModel::addCounterValue(const json &event, qint64 normalizedTime,
+ const std::string &name, int selectionId)
+{
+ if (!event.contains("args")) return;
+ // CTF documentation says all keys of 'args' should be displayed in
+ // one stacked graph, but we will display them separately:
+ for (auto it: event["args"].items()) {
+ std::string counterName = event.contains("id") ?
+ name + event.value("id", "") : name;
+ const std::string &key = it.key();
+ if (key != "value") {
+ counterName += " " + key;
+ }
+ const float value = it.value();
+ int counterIndex = m_counterNames.indexOf(counterName);
+ if (counterIndex < 0) {
+ counterIndex = m_counterData.size();
+ m_counterNames.append(counterName);
+ m_counterData.append(CounterData());
+ }
+ CounterData &data = m_counterData[counterIndex];
+ if (data.startEventIndex >= 0) {
+ insertEnd(data.startEventIndex, normalizedTime - data.end);
+ }
+ const int index = insertStart(normalizedTime, selectionId);
+ data.startEventIndex = index;
+ data.end = normalizedTime;
+ data.min = std::min(data.min, value);
+ data.max = std::max(data.max, value);
+ if (index >= m_counterValues.size()) {
+ m_counterValues.resize(index + 1);
+ m_counterValues[index] = value;
+ m_itemToCounterIdx.resize(index + 1);
+ // m_itemToCounterIdx[index] == 0 is used to indicate a non-counter value
+ m_itemToCounterIdx[index] = counterIndex + 1;
+ } else {
+ m_counterValues.insert(index, value);
+ m_itemToCounterIdx.insert(index, counterIndex + 1);
+ }
+ }
+}
+
+const QString &CtfTimelineModel::reuse(const QString &value)
+{
+ auto it = m_reusableStrings.find(value);
+ if (it == m_reusableStrings.end()) {
+ m_reusableStrings.insert(value);
+ return value;
+ }
+ return *it;
+}
+
+
+} // namespace Internal
+} // namespace CtfVisualizer
+
diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.h b/src/plugins/ctfvisualizer/ctftimelinemodel.h
new file mode 100644
index 0000000000..4be3012ba4
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctftimelinemodel.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "json/json.hpp"
+
+#include <tracing/timelinemodel.h>
+
+#include <QMap>
+#include <QSet>
+#include <QStack>
+#include <QVector>
+
+namespace Timeline {
+class TimelineModelAggregator;
+}
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfTraceManager;
+
+class CtfTimelineModel : public Timeline::TimelineModel
+{
+ Q_OBJECT
+
+ friend class CtfTraceManager;
+
+public:
+ explicit CtfTimelineModel(Timeline::TimelineModelAggregator *parent,
+ CtfTraceManager *traceManager, int tid, int pid);
+
+ QRgb color(int index) const override;
+ QVariantList labels() const override;
+ QVariantMap orderedDetails(int index) const override;
+ int expandedRow(int index) const override;
+ int collapsedRow(int index) const override;
+
+ int typeId(int index) const override;
+ bool handlesTypeId(int typeId) const override;
+ float relativeHeight(int index) const override;
+
+ QPair<bool, qint64> addEvent(const nlohmann::json &event, double traceBegin);
+
+ void finalize(double traceBegin, double traceEnd, const QString &processName, const QString &threadName);
+
+signals:
+ void detailsRequested(const QString &eventName) const;
+
+private:
+ void updateName();
+
+ qint64 newStackEvent(const nlohmann::json &event, qint64 normalizedTime,
+ const std::string &eventPhase, const std::string &name, int selectionId);
+
+ qint64 closeStackEvent(const nlohmann::json &event, double timestamp, qint64 normalizedTime);
+
+ void addCounterValue(const nlohmann::json &event, qint64 normalizedTime, const std::string &name, int selectionId);
+
+ const QString &reuse(const QString &value);
+
+protected:
+ CtfTraceManager *const m_traceManager;
+
+ int m_threadId;
+ QString m_threadName;
+ int m_processId;
+ QString m_processName;
+
+ int m_maxStackSize = 0;
+ QVector<int> m_nestingLevels;
+ QVector<QMap<int, QPair<QString, QString>>> m_details;
+ QSet<int> m_handledTypeIds;
+ QStack<int> m_openEventIds;
+ QSet<QString> m_reusableStrings;
+
+ struct CounterData {
+ qint64 end = 0;
+ int startEventIndex = -1;
+ float min = std::numeric_limits<float>::max();
+ float max = std::numeric_limits<float>::min();
+ };
+
+ QVector<std::string> m_counterNames;
+ QVector<CounterData> m_counterData;
+ QVector<float> m_counterValues;
+ QVector<int> m_itemToCounterIdx;
+ QVector<int> m_counterIndexToRow;
+};
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctftracemanager.cpp b/src/plugins/ctfvisualizer/ctftracemanager.cpp
new file mode 100644
index 0000000000..855f834128
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctftracemanager.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctftracemanager.h"
+
+#include "ctftimelinemodel.h"
+#include "ctfstatisticsmodel.h"
+#include "ctfvisualizerconstants.h"
+
+#include <coreplugin/icore.h>
+#include <tracing/timelinemodelaggregator.h>
+
+#include <QByteArray>
+#include <QDebug>
+#include <QFile>
+#include <QList>
+#include <QMessageBox>
+
+#include <fstream>
+
+
+namespace CtfVisualizer {
+namespace Internal {
+
+using json = nlohmann::json;
+
+using namespace Constants;
+
+
+class CtfJsonParserCallback
+{
+
+public:
+
+ explicit CtfJsonParserCallback(CtfTraceManager *traceManager)
+ : m_traceManager(traceManager)
+ {}
+
+ bool callback(int depth, nlohmann::json::parse_event_t event, nlohmann::json &parsed)
+ {
+ if ((event == json::parse_event_t::array_start && depth == 0)
+ || (event == json::parse_event_t::key && depth == 1 && parsed == json(CtfTraceEventsKey))) {
+ m_isInTraceArray = true;
+ m_traceArrayDepth = depth;
+ return true;
+ }
+ if (m_isInTraceArray && event == json::parse_event_t::array_end && depth == m_traceArrayDepth) {
+ m_isInTraceArray = false;
+ return false;
+ }
+ if (m_isInTraceArray && event == json::parse_event_t::object_end && depth == m_traceArrayDepth + 1) {
+ m_traceManager->addEvent(parsed);
+ return false;
+ }
+ if (m_isInTraceArray || (event == json::parse_event_t::object_start && depth == 0)) {
+ // keep outer object and values in trace objects:
+ return true;
+ }
+ // discard any objects outside of trace array:
+ // TODO: parse other data, e.g. stack frames
+ return false;
+ }
+
+protected:
+ CtfTraceManager *m_traceManager;
+
+ bool m_isInTraceArray = false;
+ int m_traceArrayDepth = 0;
+};
+
+CtfTraceManager::CtfTraceManager(QObject *parent,
+ Timeline::TimelineModelAggregator *modelAggregator,
+ CtfStatisticsModel *statisticsModel)
+ : QObject(parent)
+ , m_modelAggregator(modelAggregator)
+ , m_statisticsModel(statisticsModel)
+{
+
+}
+
+qint64 CtfTraceManager::traceDuration() const
+{
+ return qint64((m_traceEnd - m_traceBegin) * 1000);
+}
+
+qint64 CtfTraceManager::traceBegin() const
+{
+ return qint64((m_traceBegin - m_timeOffset) * 1000);
+}
+
+qint64 CtfTraceManager::traceEnd() const
+{
+ return qint64((m_traceEnd - m_timeOffset) * 1000);
+}
+
+void CtfTraceManager::addEvent(const json &event)
+{
+ const double timestamp = event.value(CtfTracingClockTimestampKey, -1.0);
+ if (timestamp < 0) {
+ // events without or with negative timestamp will be ignored
+ return;
+ }
+ if (m_timeOffset < 0) {
+ // the timestamp of the first event is used as the global offset
+ m_timeOffset = timestamp;
+ }
+
+ const int processId = event.value(CtfProcessIdKey, 0);
+ const int threadId = event.contains(CtfThreadIdKey) ? int(event[CtfThreadIdKey]) : processId;
+ if (!m_threadModels.contains(threadId)) {
+ addModelForThread(threadId, processId);
+ }
+ if (event.value(CtfEventPhaseKey, "") == CtfEventTypeMetadata) {
+ const std::string name = event[CtfEventNameKey];
+ if (name == "thread_name") {
+ m_threadNames[threadId] = QString::fromStdString(event["args"]["name"]);
+ } else if (name == "process_name") {
+ m_processNames[processId] = QString::fromStdString(event["args"]["name"]);
+ }
+ }
+
+ const QPair<bool, qint64> result = m_threadModels[threadId]->addEvent(event, m_timeOffset);
+ const bool visibleOnTimeline = result.first;
+ if (visibleOnTimeline) {
+ m_traceBegin = std::min(m_traceBegin, timestamp);
+ m_traceEnd = std::max(m_traceEnd, timestamp);
+ m_statisticsModel->addEvent(event, result.second);
+ } else if (m_timeOffset == timestamp) {
+ // this timestamp was used as the time offset but it is not a visible element
+ // -> reset the time offset again:
+ m_timeOffset = -1.0;
+ }
+}
+
+void CtfVisualizer::Internal::CtfTraceManager::load(const QString &filename)
+{
+ clearAll();
+
+ std::ifstream file(filename.toStdString());
+ if (!file.is_open()) {
+ QMessageBox::warning(Core::ICore::mainWindow(),
+ tr("CTF Visualizer"),
+ tr("Cannot read the CTF file."));
+ return;
+ }
+ CtfJsonParserCallback ctfParser(this);
+ json::parser_callback_t callback = [&ctfParser](int depth, json::parse_event_t event, json &parsed) {
+ return ctfParser.callback(depth, event, parsed);
+ };
+ m_statisticsModel->beginLoading();
+ json unusedValues = json::parse(file, callback, /*allow_exceptions*/ false);
+ m_statisticsModel->endLoading();
+ file.close();
+}
+
+void CtfTraceManager::finalize()
+{
+ bool userConsentToIgnoreDeepTraces = false;
+ for (qint64 tid: m_threadModels.keys()) {
+ if (m_threadModels[tid]->m_maxStackSize > 512) {
+ if (!userConsentToIgnoreDeepTraces) {
+ QMessageBox::StandardButton answer = QMessageBox::question(Core::ICore::mainWindow(),
+ tr("CTF Visualizer"),
+ tr("The trace contains threads with stack depth > 512.\nDo you want to display them anyway?"),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ if (answer == QMessageBox::No) {
+ userConsentToIgnoreDeepTraces = true;
+ } else {
+ break;
+ }
+ }
+ m_threadModels.remove(tid);
+ }
+ }
+ for (CtfTimelineModel *model: m_threadModels) {
+ model->finalize(m_traceBegin, m_traceEnd,
+ m_processNames[model->m_processId], m_threadNames[model->m_threadId]);
+ }
+ // TimelineModelAggregator::addModel() is called here because it
+ // needs to be run in the main thread
+ addModelsToAggregator();
+}
+
+bool CtfTraceManager::isEmpty() const
+{
+ return m_threadModels.isEmpty();
+}
+
+int CtfTraceManager::getSelectionId(const std::string &name)
+{
+ auto it = m_name2selectionId.find(name);
+ if (it == m_name2selectionId.end())
+ it = m_name2selectionId.insert(name, m_name2selectionId.size());
+ return *it;
+}
+
+void CtfTraceManager::addModelForThread(int threadId, int processId)
+{
+ CtfTimelineModel *model = new CtfTimelineModel(m_modelAggregator, this, threadId, processId);
+ m_threadModels.insert(threadId, model);
+ connect(model, &CtfTimelineModel::detailsRequested, this,
+ &CtfTraceManager::detailsRequested);
+}
+
+void CtfTraceManager::addModelsToAggregator()
+{
+ QList<CtfTimelineModel *> models = m_threadModels.values();
+ std::sort(models.begin(), models.end(), [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool {
+ return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId)
+ : (std::abs(a->m_threadId) < std::abs(b->m_threadId));
+ });
+
+ QVariantList modelsToAdd;
+ for (CtfTimelineModel *model: models) {
+ modelsToAdd.append(QVariant::fromValue(model));
+ }
+ m_modelAggregator->setModels(modelsToAdd);
+}
+
+void CtfTraceManager::clearAll()
+{
+ m_modelAggregator->clear();
+ for (CtfTimelineModel *model: m_threadModels) {
+ model->deleteLater();
+ }
+ m_threadModels.clear();
+ m_traceBegin = std::numeric_limits<double>::max();
+ m_traceEnd = std::numeric_limits<double>::min();
+ m_timeOffset = -1;
+}
+
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctftracemanager.h b/src/plugins/ctfvisualizer/ctftracemanager.h
new file mode 100644
index 0000000000..5de87eafad
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctftracemanager.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "json/json.hpp"
+
+#include <QHash>
+#include <QMap>
+#include <QObject>
+#include <QVector>
+
+namespace Timeline {
+class TimelineModelAggregator;
+}
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfStatisticsModel;
+class CtfTimelineModel;
+
+class CtfTraceManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit CtfTraceManager(QObject *parent,
+ Timeline::TimelineModelAggregator *modelAggregator,
+ CtfStatisticsModel *statisticsModel);
+
+ qint64 traceDuration() const;
+ qint64 traceBegin() const;
+ qint64 traceEnd() const;
+
+ void addEvent(const nlohmann::json &event);
+
+ void load(const QString &filename);
+ void finalize();
+
+ bool isEmpty() const;
+
+ int getSelectionId(const std::string &name);
+
+signals:
+ void detailsRequested(const QString &title);
+
+protected:
+
+ void addModelForThread(int threadId, int processId);
+ void addModelsToAggregator();
+
+ void clearAll();
+
+ Timeline::TimelineModelAggregator *const m_modelAggregator;
+ CtfStatisticsModel *const m_statisticsModel;
+
+ QHash<qint64, CtfTimelineModel *> m_threadModels;
+ QHash<qint64, QString> m_processNames;
+ QHash<qint64, QString> m_threadNames;
+ QMap<std::string, int> m_name2selectionId;
+
+ double m_traceBegin = std::numeric_limits<double>::max();
+ double m_traceEnd = std::numeric_limits<double>::min();
+ double m_timeOffset = -1.0;
+
+};
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfvisualizer.pro b/src/plugins/ctfvisualizer/ctfvisualizer.pro
new file mode 100644
index 0000000000..bfea14962c
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizer.pro
@@ -0,0 +1,34 @@
+TARGET = CtfVisualizer
+TEMPLATE = lib
+
+QT += quick quickwidgets
+
+include(../../qtcreatorplugin.pri)
+include(ctfvisualizer_dependencies.pri)
+
+DEFINES += CTFVISUALIZER_LIBRARY
+
+# CtfVisualizer files
+
+SOURCES += \
+ ctfstatisticsmodel.cpp \
+ ctfstatisticsview.cpp \
+ ctfvisualizerplugin.cpp \
+ ctfvisualizertool.cpp \
+ ctftimelinemodel.cpp \
+ ctftracemanager.cpp \
+ ctfvisualizertraceview.cpp
+
+HEADERS += \
+ ctfstatisticsmodel.h \
+ ctfstatisticsview.h \
+ ctfvisualizerplugin.h \
+ ctfvisualizertool.h\
+ ctftimelinemodel.h \
+ ctftracemanager.h \
+ ctfvisualizerconstants.h \
+ ctfvisualizertraceview.h \
+ ../../libs/3rdparty/json/json.hpp
+
+OTHER_FILES += \
+ CtfVisualizer.json.in
diff --git a/src/plugins/ctfvisualizer/ctfvisualizer.qbs b/src/plugins/ctfvisualizer/ctfvisualizer.qbs
new file mode 100644
index 0000000000..aee007518c
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizer.qbs
@@ -0,0 +1,28 @@
+import qbs
+
+QtcPlugin {
+ name: "CtfVisualizer"
+
+ Depends { name: "Core" }
+ Depends { name: "Debugger" }
+ Depends { name: "QtSupport" }
+ Depends { name: "Tracing" }
+ Depends { name: "Utils" }
+
+ Depends {
+ name: "Qt"
+ submodules: [ "quick", "quickwidgets" ]
+ }
+
+ files: [
+ "ctfstatisticsmodel.cpp", "ctfstatisticsmodel.h",
+ "ctfstatisticsview.cpp", "ctfstatisticsview.h",
+ "ctftimelinemodel.cpp", "ctftimelinemodel.h",
+ "ctftracemanager.cpp", "ctftracemanager.h",
+ "ctfvisualizerplugin.cpp", "ctfvisualizerplugin.h",
+ "ctfvisualizertool.cpp", "ctfvisualizertool.h",
+ "ctfvisualizertraceview.cpp", "ctfvisualizertraceview.h",
+ "ctfvisualizerconstants.h",
+ "../../libs/3rdparty/json/json.hpp",
+ ]
+}
diff --git a/src/plugins/ctfvisualizer/ctfvisualizer_dependencies.pri b/src/plugins/ctfvisualizer/ctfvisualizer_dependencies.pri
new file mode 100644
index 0000000000..56a2101bdf
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizer_dependencies.pri
@@ -0,0 +1,9 @@
+QTC_PLUGIN_NAME = CtfVisualizer
+
+QTC_LIB_DEPENDS += \
+ utils \
+ tracing
+
+QTC_PLUGIN_DEPENDS += \
+ debugger \
+ qtsupport
diff --git a/src/plugins/ctfvisualizer/ctfvisualizerconstants.h b/src/plugins/ctfvisualizer/ctfvisualizerconstants.h
new file mode 100644
index 0000000000..93ef360a34
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizerconstants.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 <string>
+
+namespace CtfVisualizer {
+namespace Constants {
+
+const char CtfVisualizerMenuId[] = "Analyzer.Menu.CtfVisualizer";
+const char CtfVisualizerTaskLoadJson[] =
+ "Analyzer.Menu.StartAnalyzer.CtfVisualizer.LoadTrace";
+
+const char CtfVisualizerPerspectiveId[] = "CtfVisualizer.Perspective";
+
+const char CtfTraceEventsKey[] = "traceEvents";
+
+const char CtfEventNameKey[] = "name";
+const char CtfEventCategoryKey[] = "cat";
+const char CtfEventPhaseKey[] = "ph";
+const char CtfTracingClockTimestampKey[] = "ts";
+const char CtfProcessIdKey[] = "pid";
+const char CtfThreadIdKey[] = "tid";
+const char CtfDurationKey[] = "dur";
+
+const char CtfEventTypeBegin[] = "B";
+const char CtfEventTypeEnd[] = "E";
+const char CtfEventTypeComplete[] = "X";
+const char CtfEventTypeMetadata[] = "M";
+const char CtfEventTypeInstant[] = "i";
+const char CtfEventTypeInstantDeprecated[] = "I";
+const char CtfEventTypeCounter[] = "C";
+
+} // namespace Constants
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfvisualizerplugin.cpp b/src/plugins/ctfvisualizer/ctfvisualizerplugin.cpp
new file mode 100644
index 0000000000..c44b9eb20b
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizerplugin.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfvisualizerplugin.h"
+
+#include "ctfvisualizertool.h"
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfVisualizerPluginPrivate
+{
+public:
+ CtfVisualizerTool profilerTool;
+};
+
+CtfVisualizerPlugin::~CtfVisualizerPlugin()
+{
+ delete d;
+}
+
+bool CtfVisualizerPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ d = new CtfVisualizerPluginPrivate;
+ return true;
+}
+
+void CtfVisualizerPlugin::extensionsInitialized()
+{
+}
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfvisualizerplugin.h b/src/plugins/ctfvisualizer/ctfvisualizerplugin.h
new file mode 100644
index 0000000000..cd1844452c
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizerplugin.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 <extensionsystem/iplugin.h>
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfVisualizerPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "CtfVisualizer.json")
+
+public:
+ ~CtfVisualizerPlugin();
+
+ bool initialize(const QStringList &arguments, QString *errorString) final;
+ void extensionsInitialized() final;
+
+ class CtfVisualizerPluginPrivate *d = nullptr;
+};
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
new file mode 100644
index 0000000000..96b1489978
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfvisualizertool.h"
+
+#include "ctftracemanager.h"
+
+#include "ctfstatisticsmodel.h"
+#include "ctfstatisticsview.h"
+#include "ctfvisualizertraceview.h"
+
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <debugger/analyzer/analyzerconstants.h>
+
+#include <QAction>
+#include <QApplication>
+#include <QFileDialog>
+#include <QFutureInterface>
+#include <QMenu>
+#include <QMessageBox>
+#include <QThread>
+
+using namespace Core;
+using namespace CtfVisualizer::Constants;
+
+
+namespace CtfVisualizer {
+namespace Internal {
+
+CtfVisualizerTool::CtfVisualizerTool()
+ : QObject (nullptr)
+ , m_isLoading(false)
+ , m_loadJson(nullptr)
+ , m_traceView(nullptr)
+ , m_modelAggregator(new Timeline::TimelineModelAggregator(this))
+ , m_zoomControl(new Timeline::TimelineZoomControl(this))
+ , m_statisticsModel(new CtfStatisticsModel(this))
+ , m_statisticsView(nullptr)
+ , m_traceManager(new CtfTraceManager(this, m_modelAggregator.get(), m_statisticsModel.get()))
+{
+ ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
+ ActionContainer *options = ActionManager::createMenu(Constants::CtfVisualizerMenuId);
+ options->menu()->setTitle(tr("Chrome Trace Format Viewer"));
+ menu->addMenu(options, Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
+ options->menu()->setEnabled(true);
+
+ const Core::Context globalContext(Core::Constants::C_GLOBAL);
+
+ m_loadJson.reset(new QAction(tr("Load JSON File"), options));
+ Core::Command *command = Core::ActionManager::registerAction(m_loadJson.get(), Constants::CtfVisualizerTaskLoadJson,
+ globalContext);
+ connect(m_loadJson.get(), &QAction::triggered, this, &CtfVisualizerTool::loadJson);
+ options->addAction(command);
+
+ m_perspective.setAboutToActivateCallback([this]() { createViews(); });
+}
+
+CtfVisualizerTool::~CtfVisualizerTool() = default;
+
+void CtfVisualizerTool::createViews()
+{
+ m_traceView = new CtfVisualizerTraceView(nullptr, this);
+ m_traceView->setWindowTitle(tr("Timeline"));
+
+ QMenu *contextMenu = new QMenu(m_traceView);
+ contextMenu->addAction(m_loadJson.get());
+ connect(contextMenu->addAction(tr("Reset Zoom")), &QAction::triggered, this, [this](){
+ m_zoomControl->setRange(m_zoomControl->traceStart(), m_zoomControl->traceEnd());
+ });
+
+ m_traceView->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_traceView, &QWidget::customContextMenuRequested,
+ contextMenu, [contextMenu, this](const QPoint &pos) {
+ contextMenu->exec(m_traceView->mapToGlobal(pos));
+ });
+
+ m_perspective.addWindow(m_traceView, Utils::Perspective::OperationType::SplitVertical, nullptr);
+
+ m_statisticsView = new CtfStatisticsView(m_statisticsModel.get());
+ m_statisticsView->setWindowTitle(tr("Statistics"));
+ connect(m_statisticsView, &CtfStatisticsView::eventTypeSelected, [this] (QString title)
+ {
+ int typeId = m_traceManager->getSelectionId(title.toStdString());
+ m_traceView->selectByTypeId(typeId);
+ });
+ connect(m_traceManager.get(), &CtfTraceManager::detailsRequested, m_statisticsView,
+ &CtfStatisticsView::selectByTitle);
+
+ m_perspective.addWindow(m_statisticsView, Utils::Perspective::AddToTab, m_traceView);
+
+ m_perspective.setAboutToActivateCallback(Utils::Perspective::Callback());
+}
+
+Timeline::TimelineModelAggregator *CtfVisualizerTool::modelAggregator() const
+{
+ return m_modelAggregator.get();
+}
+
+CtfTraceManager *CtfVisualizerTool::traceManager() const
+{
+ return m_traceManager.get();
+}
+
+Timeline::TimelineZoomControl *CtfVisualizerTool::zoomControl() const
+{
+ return m_zoomControl.get();
+}
+
+void CtfVisualizerTool::loadJson()
+{
+ if (m_isLoading)
+ return;
+
+ m_isLoading = true;
+
+ QString filename = QFileDialog::getOpenFileName(
+ ICore::mainWindow(), tr("Load Chrome Trace Format File"),
+ "", tr("JSON File (*.json)"));
+ if (filename.isEmpty()) {
+ m_isLoading = false;
+ return;
+ }
+
+ auto *futureInterface = new QFutureInterface<void>();
+ auto *task = new QFuture<void>(futureInterface);
+
+ QThread *thread = QThread::create([this, filename, futureInterface]() {
+ m_traceManager->load(filename);
+
+ m_modelAggregator->moveToThread(QApplication::instance()->thread());
+ m_modelAggregator->setParent(this);
+ futureInterface->reportFinished();
+ });
+
+ connect(thread, &QThread::finished, this, [this, thread, task, futureInterface]() {
+ // in main thread:
+ if (m_traceManager->isEmpty()) {
+ QMessageBox::warning(Core::ICore::mainWindow(),
+ tr("CTF Visualizer"),
+ tr("The file does not contain any trace data."));
+ } else {
+ m_traceManager->finalize();
+ m_perspective.select();
+ zoomControl()->setTrace(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20);
+ zoomControl()->setRange(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20);
+ }
+ thread->deleteLater();
+ delete task;
+ delete futureInterface;
+ m_isLoading = false;
+ }, Qt::QueuedConnection);
+
+ m_modelAggregator->setParent(nullptr);
+ m_modelAggregator->moveToThread(thread);
+
+ thread->start();
+ Core::ProgressManager::addTask(*task, tr("Loading CTF File"), CtfVisualizerTaskLoadJson);
+}
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.h b/src/plugins/ctfvisualizer/ctfvisualizertool.h
new file mode 100644
index 0000000000..c5085d0f04
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizertool.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfvisualizerconstants.h"
+
+#include <debugger/debuggermainwindow.h>
+#include <tracing/timelinemodelaggregator.h>
+#include <tracing/timelinezoomcontrol.h>
+
+#include <QScopedPointer>
+
+namespace CtfVisualizer {
+namespace Internal {
+
+class CtfTraceManager;
+class CtfStatisticsModel;
+class CtfStatisticsView;
+class CtfVisualizerTraceView;
+
+
+class CtfVisualizerTool : public QObject
+{
+ Q_OBJECT
+
+public:
+ CtfVisualizerTool();
+ ~CtfVisualizerTool();
+
+ Timeline::TimelineModelAggregator *modelAggregator() const;
+ CtfTraceManager *traceManager() const;
+ Timeline::TimelineZoomControl *zoomControl() const;
+
+ void loadJson();
+
+private:
+ void createViews();
+
+ void initialize();
+ void finalize();
+
+ Utils::Perspective m_perspective{Constants::CtfVisualizerPerspectiveId,
+ tr("Chrome Trace Format Visualizer")};
+
+ bool m_isLoading;
+ QScopedPointer<QAction> m_loadJson;
+
+ CtfVisualizerTraceView *m_traceView;
+ const QScopedPointer<Timeline::TimelineModelAggregator> m_modelAggregator;
+ const QScopedPointer<Timeline::TimelineZoomControl> m_zoomControl;
+
+ const QScopedPointer<CtfStatisticsModel> m_statisticsModel;
+ CtfStatisticsView *m_statisticsView;
+
+ const QScopedPointer<CtfTraceManager> m_traceManager;
+};
+
+} // namespace Internal
+} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctfvisualizertraceview.cpp b/src/plugins/ctfvisualizer/ctfvisualizertraceview.cpp
new file mode 100644
index 0000000000..a89afe0df3
--- /dev/null
+++ b/src/plugins/ctfvisualizer/ctfvisualizertraceview.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
+** 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 "ctfvisualizertraceview.h"
+
+#include "ctfvisualizertool.h"
+
+#include <tracing/timelineformattime.h>
+#include <tracing/timelineoverviewrenderer.h>
+#include <tracing/timelinerenderer.h>
+#include <tracing/timelinetheme.h>
+
+#include <QQmlContext>
+
+
+namespace CtfVisualizer {
+namespace Internal {
+
+CtfVisualizerTraceView::CtfVisualizerTraceView(QWidget *parent, CtfVisualizerTool *tool)
+ : QQuickWidget(parent)
+{
+ setObjectName(QLatin1String("CtfVisualizerTraceView"));
+
+ qmlRegisterType<Timeline::TimelineRenderer>("TimelineRenderer", 1, 0, "TimelineRenderer");
+ qmlRegisterType<Timeline::TimelineOverviewRenderer>("TimelineOverviewRenderer", 1, 0,
+ "TimelineOverviewRenderer");
+ qmlRegisterType<Timeline::TimelineZoomControl>();
+ qmlRegisterType<Timeline::TimelineModel>();
+ qmlRegisterType<Timeline::TimelineNotesModel>();
+
+ setResizeMode(QQuickWidget::SizeRootObjectToView);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ // Minimum height: 5 rows of 20 pixels + scrollbar of 50 pixels + 20 pixels margin
+ setMinimumHeight(170);
+
+ Timeline::TimelineTheme::setupTheme(engine());
+ Timeline::TimeFormatter::setupTimeFormatter();
+
+ rootContext()->setContextProperty(QLatin1String("timelineModelAggregator"),
+ tool->modelAggregator());
+ rootContext()->setContextProperty(QLatin1String("zoomControl"),
+ tool->zoomControl());
+ setSource(QUrl(QLatin1String("qrc:/tracing/MainView.qml")));
+
+ // Avoid ugly warnings when reading from null properties in QML.
+ connect(tool->modelAggregator(), &QObject::destroyed, this, [this]{ setSource(QUrl()); });
+ connect(tool->zoomControl(), &QObject::destroyed, this, [this]{ setSource(QUrl()); });
+}
+
+CtfVisualizerTraceView::~CtfVisualizerTraceView() = default;
+
+void CtfVisualizerTraceView::selectByTypeId(int typeId)
+{
+ QMetaObject::invokeMethod(rootObject(), "selectByTypeId",
+ Q_ARG(QVariant,QVariant::fromValue<int>(typeId)));
+}
+
+
+} // namespace Internal
+} // namespace CtfVisualizer
+
diff --git a/src/plugins/clangtools/clangtoolsbasicsettings.h b/src/plugins/ctfvisualizer/ctfvisualizertraceview.h
index b9ecb0285e..ce3aafaee0 100644
--- a/src/plugins/clangtools/clangtoolsbasicsettings.h
+++ b/src/plugins/ctfvisualizer/ctfvisualizertraceview.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company,
+** info@kdab.com, author Tim Henning <tim.henning@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -22,30 +23,29 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
-
#pragma once
+#include <QQuickWidget>
#include <QWidget>
-namespace ClangTools {
+namespace CtfVisualizer {
namespace Internal {
-namespace Ui { class ClangToolsBasicSettings; }
-
-class ClangExecutableVersion;
+class CtfVisualizerTool;
-class ClangToolsBasicSettings : public QWidget
+class CtfVisualizerTraceView : public QQuickWidget
{
Q_OBJECT
public:
- explicit ClangToolsBasicSettings(QWidget *parent = nullptr);
- ~ClangToolsBasicSettings() override;
+ CtfVisualizerTraceView(QWidget *parent, CtfVisualizerTool *tool);
+
+ ~CtfVisualizerTraceView();
- Ui::ClangToolsBasicSettings *ui();
-private:
- Ui::ClangToolsBasicSettings *m_ui;
+ void selectByTypeId(int typeId);
};
+
} // namespace Internal
-} // namespace ClangTools
+} // namespace CtfVisualizer
+
diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp
index 454e95df63..7c499a20f6 100644
--- a/src/plugins/cvs/cvscontrol.cpp
+++ b/src/plugins/cvs/cvscontrol.cpp
@@ -57,7 +57,7 @@ Core::Id CvsControl::id() const
bool CvsControl::isVcsFileOrDirectory(const Utils::FilePath &fileName) const
{
- return fileName.toFileInfo().isDir()
+ return fileName.isDir()
&& !fileName.fileName().compare("CVS", Utils::HostOsInfo::fileNameCaseSensitivity());
}
@@ -90,7 +90,7 @@ bool CvsControl::supportsOperation(Operation operation) const
Core::IVersionControl::OpenSupportMode CvsControl::openSupportMode(const QString &fileName) const
{
- Q_UNUSED(fileName);
+ Q_UNUSED(fileName)
return OpenOptional;
}
@@ -114,8 +114,8 @@ bool CvsControl::vcsDelete(const QString &fileName)
bool CvsControl::vcsMove(const QString &from, const QString &to)
{
- Q_UNUSED(from);
- Q_UNUSED(to);
+ Q_UNUSED(from)
+ Q_UNUSED(to)
return false;
}
@@ -151,7 +151,7 @@ Core::ShellCommand *CvsControl::createInitialCheckoutCommand(const QString &url,
auto command = new VcsBase::VcsCommand(baseDirectory.toString(),
QProcessEnvironment::systemEnvironment());
command->setDisplayName(tr("CVS Checkout"));
- command->addJob(m_plugin->client()->vcsBinary(), settings.addOptions(args), -1);
+ command->addJob({m_plugin->client()->vcsBinary(), settings.addOptions(args)}, -1);
return command;
}
diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp
index 1d771ca31f..f46b5ffe8a 100644
--- a/src/plugins/cvs/cvsplugin.cpp
+++ b/src/plugins/cvs/cvsplugin.cpp
@@ -1109,7 +1109,7 @@ CvsResponse CvsPlugin::runCvs(const QString &workingDirectory,
}
// Run, connect stderr to the output window
const SynchronousProcessResponse sp_resp =
- runVcs(workingDirectory, executable, client()->settings().addOptions(arguments),
+ runVcs(workingDirectory, {executable, client()->settings().addOptions(arguments)},
timeOutS, flags, outputCodec);
response.result = CvsResponse::OtherError;
diff --git a/src/plugins/debugger/CMakeLists.txt b/src/plugins/debugger/CMakeLists.txt
index f88c5ffd60..7c2ca7d6d7 100644
--- a/src/plugins/debugger/CMakeLists.txt
+++ b/src/plugins/debugger/CMakeLists.txt
@@ -64,6 +64,7 @@ add_qtc_plugin(Debugger
namedemangler/parsetreenodes.cpp namedemangler/parsetreenodes.h
outputcollector.cpp outputcollector.h
pdb/pdbengine.cpp pdb/pdbengine.h
+ peripheralregisterhandler.cpp peripheralregisterhandler.h
procinterrupt.cpp procinterrupt.h
qml/interactiveinterpreter.cpp qml/interactiveinterpreter.h
#qml/qmlcppengine.cpp qml/qmlcppengine.h
diff --git a/src/plugins/debugger/analyzer/analyzermanager.h b/src/plugins/debugger/analyzer/analyzermanager.h
index e7c7f4d9d5..d8c5d1112a 100644
--- a/src/plugins/debugger/analyzer/analyzermanager.h
+++ b/src/plugins/debugger/analyzer/analyzermanager.h
@@ -63,7 +63,6 @@ DEBUGGER_EXPORT void showCannotStartDialog(const QString &toolName);
DEBUGGER_EXPORT void enableMainWindow(bool on);
// Convenience functions.
-DEBUGGER_EXPORT void showStatusMessage(const QString &message, int timeoutMS = 10000);
DEBUGGER_EXPORT void showPermanentStatusMessage(const QString &message);
DEBUGGER_EXPORT QAction *createStartAction();
diff --git a/src/plugins/debugger/analyzer/startremotedialog.cpp b/src/plugins/debugger/analyzer/startremotedialog.cpp
index 30ce83eca2..084ab82bee 100644
--- a/src/plugins/debugger/analyzer/startremotedialog.cpp
+++ b/src/plugins/debugger/analyzer/startremotedialog.cpp
@@ -133,7 +133,7 @@ Runnable StartRemoteDialog::runnable() const
Kit *kit = d->kitChooser->currentKit();
Runnable r;
r.device = DeviceKitAspect::device(kit);
- r.executable = d->executable->text();
+ r.executable = Utils::FilePath::fromString(d->executable->text());
r.commandLineArguments = d->arguments->text();
r.workingDirectory = d->workingDirectory->text();
return r;
diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp
index 5766a77406..d6a05fafc0 100644
--- a/src/plugins/debugger/breakpoint.cpp
+++ b/src/plugins/debugger/breakpoint.cpp
@@ -345,7 +345,7 @@ void BreakpointParameters::updateFromGdbOutput(const GdbMi &bkpt)
QString what = bkpt["what"].data();
if (what.startsWith("*0x")) {
type = WatchpointAtAddress;
- address = what.midRef(1).toULongLong(0, 0);
+ address = what.midRef(1).toULongLong(nullptr, 0);
} else {
type = WatchpointAtExpression;
expression = what;
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 4a3839159e..a5554a3aa8 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -277,7 +277,7 @@ void CdbEngine::adjustOperateByInstruction(bool operateByInstruction)
bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
{
- Q_UNUSED(context);
+ Q_UNUSED(context)
// Tooltips matching local variables are already handled in the
// base class. We don't handle anything else here in CDB
// as it can slow debugging down.
@@ -295,35 +295,6 @@ QString CdbEngine::extensionLibraryName(bool is64Bit)
return rc;
}
-// Determine environment for CDB.exe, start out with run config and
-// add CDB extension path merged with system value should there be one.
-static QStringList mergeEnvironment(QStringList runConfigEnvironment,
- QString cdbExtensionPath)
-{
- // Determine CDB extension path from Qt Creator
- static const char cdbExtensionPathVariableC[] = "_NT_DEBUGGER_EXTENSION_PATH";
- const QByteArray oldCdbExtensionPath = qgetenv(cdbExtensionPathVariableC);
- if (!oldCdbExtensionPath.isEmpty()) {
- cdbExtensionPath.append(';');
- cdbExtensionPath.append(QString::fromLocal8Bit(oldCdbExtensionPath));
- }
- // We do not assume someone sets _NT_DEBUGGER_EXTENSION_PATH in the run
- // config, just to make sure, delete any existing entries
- const QString cdbExtensionPathVariableAssign =
- QLatin1String(cdbExtensionPathVariableC) + '=';
- for (QStringList::iterator it = runConfigEnvironment.begin(); it != runConfigEnvironment.end() ; ) {
- if (it->startsWith(cdbExtensionPathVariableAssign)) {
- it = runConfigEnvironment.erase(it);
- break;
- } else {
- ++it;
- }
- }
- runConfigEnvironment.append(cdbExtensionPathVariableAssign +
- QDir::toNativeSeparators(cdbExtensionPath));
- return runConfigEnvironment;
-}
-
int CdbEngine::elapsedLogTime()
{
return m_logTimer.restart();
@@ -369,18 +340,16 @@ void CdbEngine::setupEngine()
m_effectiveStartMode = sp.startMode;
}
- const QChar blank(' ');
// Start engine which will run until initial breakpoint:
// Determine binary (force MSVC), extension lib name and path to use
// The extension is passed as relative name with the path variable set
//(does not work with absolute path names)
- const QString executable = sp.debugger.executable;
- if (executable.isEmpty()) {
+ if (sp.debugger.executable.isEmpty()) {
handleSetupFailure(tr("There is no CDB executable specified."));
return;
}
- bool cdbIs64Bit = Utils::is64BitWindowsBinary(executable);
+ bool cdbIs64Bit = Utils::is64BitWindowsBinary(sp.debugger.executable.toString());
if (!cdbIs64Bit)
m_wow64State = noWow64Stack;
const QFileInfo extensionFi(CdbEngine::extensionLibraryName(cdbIs64Bit));
@@ -398,78 +367,73 @@ void CdbEngine::setupEngine()
Core::Constants::IDE_DISPLAY_NAME));
return;
}
+
+ // Prepare command line.
+ CommandLine debugger{sp.debugger.executable};
+
const QString extensionFileName = extensionFi.fileName();
- // Prepare arguments
- QStringList arguments;
const bool isRemote = sp.startMode == AttachToRemoteServer;
if (isRemote) { // Must be first
- arguments << "-remote" << sp.remoteChannel;
+ debugger.addArgs({"-remote", sp.remoteChannel});
} else {
- arguments << ("-a" + extensionFileName);
+ debugger.addArg("-a" + extensionFileName);
}
+
// Source line info/No terminal breakpoint / Pull extension
- arguments << "-lines" << "-G"
- // register idle (debuggee stop) notification
- << "-c"
- << ".idle_cmd " + m_extensionCommandPrefix + "idle";
+ debugger.addArgs({"-lines", "-G",
+ // register idle (debuggee stop) notification
+ "-c", ".idle_cmd " + m_extensionCommandPrefix + "idle"});
+
if (sp.useTerminal) // Separate console
- arguments << "-2";
+ debugger.addArg("-2");
+
if (boolSetting(IgnoreFirstChanceAccessViolation))
- arguments << "-x";
+ debugger.addArg("-x");
const QStringList &sourcePaths = stringListSetting(CdbSourcePaths);
if (!sourcePaths.isEmpty())
- arguments << "-srcpath" << sourcePaths.join(';');
+ debugger.addArgs({"-srcpath", sourcePaths.join(';')});
QStringList symbolPaths = stringListSetting(CdbSymbolPaths);
- QString symbolPath = sp.inferior.environment.value("_NT_ALT_SYMBOL_PATH");
+ QString symbolPath = sp.inferior.environment.expandedValueForKey("_NT_ALT_SYMBOL_PATH");
if (!symbolPath.isEmpty())
symbolPaths += symbolPath;
- symbolPath = sp.inferior.environment.value("_NT_SYMBOL_PATH");
+ symbolPath = sp.inferior.environment.expandedValueForKey("_NT_SYMBOL_PATH");
if (!symbolPath.isEmpty())
symbolPaths += symbolPath;
- arguments << "-y" << (symbolPaths.isEmpty() ? "\"\"" : symbolPaths.join(';'));
+ debugger.addArgs({"-y", symbolPaths.join(';')});
- // Compile argument string preserving quotes
- QString nativeArguments = expand(stringSetting(CdbAdditionalArguments));
switch (sp.startMode) {
case StartInternal:
case StartExternal:
- if (!nativeArguments.isEmpty())
- nativeArguments.push_back(blank);
- QtcProcess::addArgs(&nativeArguments,
- QStringList(QDir::toNativeSeparators(sp.inferior.executable)));
- if (!sp.inferior.commandLineArguments.isEmpty()) { // Complete native argument string.
- if (!nativeArguments.isEmpty())
- nativeArguments.push_back(blank);
- nativeArguments += sp.inferior.commandLineArguments;
- }
+ debugger.addArg(sp.inferior.executable.toUserOutput());
+ // Complete native argument string.
+ debugger.addArgs(sp.inferior.commandLineArguments, CommandLine::Raw);
break;
case AttachToRemoteServer:
break;
case AttachExternal:
case AttachCrashedExternal:
- arguments << "-p" << QString::number(sp.attachPID.pid());
+ debugger.addArgs({"-p", QString::number(sp.attachPID.pid())});
if (sp.startMode == AttachCrashedExternal) {
- arguments << "-e" << sp.crashParameter << "-g";
+ debugger.addArgs({"-e", sp.crashParameter, "-g"});
} else {
if (terminal())
- arguments << "-pr" << "-pb";
+ debugger.addArgs({"-pr", "-pb"});
}
break;
case AttachCore:
- arguments << "-z" << sp.coreFile;
+ debugger.addArgs({"-z", sp.coreFile});
break;
default:
handleSetupFailure(QString("Internal error: Unsupported start mode %1.").arg(sp.startMode));
return;
}
- const QString msg = QString("Launching %1 %2\nusing %3 of %4.").
- arg(QDir::toNativeSeparators(executable),
- arguments.join(blank) + blank + nativeArguments,
- QDir::toNativeSeparators(extensionFi.absoluteFilePath()),
- extensionFi.lastModified().toString(Qt::SystemLocaleShortDate));
+ const QString msg = QString("Launching %1\nusing %2 of %3.")
+ .arg(debugger.toUserOutput(),
+ QDir::toNativeSeparators(extensionFi.absoluteFilePath()),
+ extensionFi.lastModified().toString(Qt::SystemLocaleShortDate));
showMessage(msg, LogMisc);
m_outputBuffer.clear();
@@ -483,25 +447,29 @@ void CdbEngine::setupEngine()
if (!sp.useTerminal && !inferiorEnvironment.hasKey(qtLoggingToConsoleKey))
inferiorEnvironment.set(qtLoggingToConsoleKey, "0");
- m_process.setEnvironment(mergeEnvironment(inferiorEnvironment.toStringList(),
- extensionFi.absolutePath()));
+ static const char cdbExtensionPathVariableC[] = "_NT_DEBUGGER_EXTENSION_PATH";
+ inferiorEnvironment.prependOrSet(cdbExtensionPathVariableC, extensionFi.absolutePath());
+ const QByteArray oldCdbExtensionPath = qgetenv(cdbExtensionPathVariableC);
+ if (!oldCdbExtensionPath.isEmpty()) {
+ inferiorEnvironment.appendOrSet(cdbExtensionPathVariableC,
+ QString::fromLocal8Bit(oldCdbExtensionPath));
+ }
+
+ m_process.setEnvironment(inferiorEnvironment);
if (!sp.inferior.workingDirectory.isEmpty())
m_process.setWorkingDirectory(sp.inferior.workingDirectory);
-#ifdef Q_OS_WIN
- if (!nativeArguments.isEmpty()) // Appends
- m_process.setNativeArguments(nativeArguments);
-#endif
- m_process.start(executable, arguments);
+ m_process.setCommand(debugger);
+ m_process.start();
if (!m_process.waitForStarted()) {
handleSetupFailure(QString("Internal error: Cannot start process %1: %2").
- arg(QDir::toNativeSeparators(executable), m_process.errorString()));
+ arg(debugger.toUserOutput(), m_process.errorString()));
return;
}
const qint64 pid = m_process.processId();
- showMessage(QString("%1 running as %2").
- arg(QDir::toNativeSeparators(executable)).arg(pid), LogMisc);
+ showMessage(QString("%1 running as %2").arg(debugger.executable().toUserOutput()).arg(pid),
+ LogMisc);
m_hasDebuggee = true;
m_initialSessionIdleHandled = false;
if (isRemote) { // We do not get an 'idle' in a remote session, but are accessible
@@ -523,8 +491,7 @@ void CdbEngine::handleInitialSessionIdle()
if (rp.breakOnMain) {
BreakpointParameters bp(BreakpointAtMain);
if (rp.startMode == StartInternal || rp.startMode == StartExternal) {
- const QString &moduleFileName = Utils::FilePath::fromString(rp.inferior.executable)
- .fileName();
+ const QString &moduleFileName = rp.inferior.executable.fileName();
bp.module = moduleFileName.left(moduleFileName.indexOf('.'));
}
QString function = cdbAddBreakpointCommand(bp, m_sourcePathMappings);
@@ -858,7 +825,7 @@ void CdbEngine::doInterruptInferior(const InterruptCallback &callback)
connect(m_signalOperation.data(), &DeviceProcessSignalOperation::finished,
this, &CdbEngine::handleDoInterruptInferior);
- m_signalOperation->setDebuggerCommand(runParameters().debugger.executable);
+ m_signalOperation->setDebuggerCommand(runParameters().debugger.executable.toString());
m_signalOperation->interruptProcess(inferiorPid());
}
@@ -1078,13 +1045,13 @@ void CdbEngine::activateFrame(int index)
// TODO: assembler,etc
if (index < 0)
return;
- const StackFrames &frames = stackHandler()->frames();
- if (index >= frames.size()) {
+
+ if (stackHandler()->isSpecialFrame(index)) {
reloadFullStack(); // Clicked on "More...".
return;
}
- const StackFrame frame = frames.at(index);
+ const StackFrame frame = stackHandler()->frameAt(index);
if (frame.language != CppLanguage) {
gotoLocation(frame);
return;
@@ -1352,7 +1319,8 @@ void CdbEngine::handleResolveSymbol(const DebuggerResponse &response, const QStr
{
// Insert all matches of (potentially) ambiguous symbols
if (!response.data.data().isEmpty()) {
- foreach (const QString &line, response.data.data().split('\n')) {
+ const QStringList lines = response.data.data().split('\n');
+ for (const QString &line : lines) {
if (const quint64 address = resolvedAddress(line)) {
m_symbolAddressCache.insert(symbol, address);
showMessage(QString("Obtained 0x%1 for %2").
@@ -1972,7 +1940,8 @@ void CdbEngine::ensureUsing32BitStackInWow64(const DebuggerResponse &response, c
{
// Parsing the header of the stack output to check which bitness
// the cdb is currently using.
- foreach (const QStringRef &line, response.data.data().splitRef('\n')) {
+ const QVector<QStringRef> lines = response.data.data().splitRef('\n');
+ for (const QStringRef &line : lines) {
if (!line.startsWith("Child"))
continue;
if (line.startsWith("ChildEBP")) {
diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h
index fd0e35ba8a..1c454d6d51 100644
--- a/src/plugins/debugger/cdb/cdbengine.h
+++ b/src/plugins/debugger/cdb/cdbengine.h
@@ -200,7 +200,7 @@ private:
const QString m_tokenPrefix;
void handleSetupFailure(const QString &errorMessage);
- QProcess m_process;
+ Utils::QtcProcess m_process;
DebuggerStartMode m_effectiveStartMode = NoStartMode;
QByteArray m_outputBuffer;
//! Debugger accessible (expecting commands)
diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp
index b6c6a29f0a..1bf4fb4da4 100644
--- a/src/plugins/debugger/cdb/cdboptionspage.cpp
+++ b/src/plugins/debugger/cdb/cdboptionspage.cpp
@@ -78,7 +78,7 @@ CdbBreakEventWidget::CdbBreakEventWidget(QWidget *parent) : QWidget(parent)
// 1 column with checkboxes only,
// further columns with checkbox + parameter
auto mainLayout = new QHBoxLayout;
- mainLayout->setMargin(0);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
auto leftLayout = new QVBoxLayout;
QFormLayout *parameterLayout = nullptr;
mainLayout->addLayout(leftLayout);
@@ -107,11 +107,11 @@ CdbBreakEventWidget::CdbBreakEventWidget(QWidget *parent) : QWidget(parent)
void CdbBreakEventWidget::clear()
{
- foreach (QLineEdit *l, m_lineEdits) {
+ for (QLineEdit *l : qAsConst(m_lineEdits)) {
if (l)
l->clear();
}
- foreach (QCheckBox *c, m_checkBoxes)
+ for (QCheckBox *c : qAsConst(m_checkBoxes))
c->setChecked(false);
}
@@ -154,17 +154,17 @@ QStringList CdbBreakEventWidget::breakEvents() const
return rc;
}
-CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent)
- : QWidget(parent)
- , m_breakEventWidget(new CdbBreakEventWidget)
+CdbOptionsPageWidget::CdbOptionsPageWidget()
+ : m_breakEventWidget(new CdbBreakEventWidget)
{
m_ui.setupUi(this);
// Squeeze the groupbox layouts vertically to
// accommodate all options. This page only shows on
// Windows, which has large margins by default.
- const int margin = layout()->margin();
- const QMargins margins(margin, margin / 3, margin, margin / 3);
+ int left, top, right, bottom;
+ layout()->getContentsMargins(&left, &top, &right, &bottom);
+ const QMargins margins(left, top / 3, right, bottom / 3);
m_ui.startupFormLayout->setContentsMargins(margins);
diff --git a/src/plugins/debugger/cdb/cdboptionspage.h b/src/plugins/debugger/cdb/cdboptionspage.h
index 9411672175..03c1bec13e 100644
--- a/src/plugins/debugger/cdb/cdboptionspage.h
+++ b/src/plugins/debugger/cdb/cdboptionspage.h
@@ -71,7 +71,8 @@ class CdbOptionsPageWidget : public QWidget
Q_OBJECT
public:
- explicit CdbOptionsPageWidget(QWidget *parent = nullptr);
+ CdbOptionsPageWidget();
+
QStringList breakEvents() const;
Utils::SavedActionSet group;
@@ -91,7 +92,7 @@ class CdbOptionsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit CdbOptionsPage();
+ CdbOptionsPage();
~CdbOptionsPage() override;
// IOptionsPage
@@ -111,7 +112,7 @@ class CdbPathsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit CdbPathsPage();
+ CdbPathsPage();
~CdbPathsPage() override;
static CdbPathsPage *instance();
diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp
index 2590a47a09..158edd9911 100644
--- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp
+++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp
@@ -497,7 +497,8 @@ DisassemblerLines parseCdbDisassembler(const QString &a)
quint64 functionOffset = 0;
QString sourceFile;
- foreach (const QString &line, a.split('\n')) {
+ const QStringList lines = a.split('\n');
+ for (const QString &line : lines) {
// New function. Append as comment line.
if (parseCdbDisassemblerFunctionLine(line, &currentFunction, &functionOffset, &sourceFile)) {
functionAddress = 0;
diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp
index 0aeee7f2d7..de39258df1 100644
--- a/src/plugins/debugger/commonoptionspage.cpp
+++ b/src/plugins/debugger/commonoptionspage.cpp
@@ -248,7 +248,7 @@ QWidget *CommonOptionsPage::widget()
}
SourcePathMap allPathMap = m_options->sourcePathMap;
- foreach (auto regExpMap, m_options->sourcePathRegExpMap)
+ for (auto regExpMap : qAsConst(m_options->sourcePathRegExpMap))
allPathMap.insert(regExpMap.first.pattern(), regExpMap.second);
m_sourceMappingWidget->setSourcePathMap(allPathMap);
}
diff --git a/src/plugins/debugger/console/console.cpp b/src/plugins/debugger/console/console.cpp
index c7fe001c74..bc538c03d0 100644
--- a/src/plugins/debugger/console/console.cpp
+++ b/src/plugins/debugger/console/console.cpp
@@ -64,7 +64,7 @@ Console::Console()
m_consoleWidget->setEnabled(true);
auto vbox = new QVBoxLayout(m_consoleWidget);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
vbox->setSpacing(0);
m_consoleView = new ConsoleView(m_consoleItemModel, m_consoleWidget);
@@ -285,20 +285,5 @@ void Console::evaluate(const QString &expression)
}
}
-static Console *theConsole = nullptr;
-
-Console *debuggerConsole()
-{
- if (!theConsole)
- theConsole = new Console;
- return theConsole;
-}
-
-void destroyDebuggerConsole()
-{
- delete theConsole;
- theConsole = nullptr;
-}
-
} // Internal
} // Debugger
diff --git a/src/plugins/debugger/console/console.h b/src/plugins/debugger/console/console.h
index 4690283a34..8ad12eac69 100644
--- a/src/plugins/debugger/console/console.h
+++ b/src/plugins/debugger/console/console.h
@@ -100,7 +100,6 @@ private:
};
Console *debuggerConsole();
-void destroyDebuggerConsole();
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/console/consoleview.cpp b/src/plugins/debugger/console/consoleview.cpp
index c6387cc9e0..823e37ae6b 100644
--- a/src/plugins/debugger/console/consoleview.cpp
+++ b/src/plugins/debugger/console/consoleview.cpp
@@ -208,7 +208,7 @@ void ConsoleView::contextMenuEvent(QContextMenuEvent *event)
void ConsoleView::focusInEvent(QFocusEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
selectionModel()->setCurrentIndex(model()->index(model()->rowCount() - 1, 0),
QItemSelectionModel::ClearAndSelect);
}
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 0f91ac1a92..52bfd05ead 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -17,29 +17,36 @@ HEADERS += \
commonoptionspage.h \
debugger_global.h \
debuggeractions.h \
- debuggercore.h \
debuggerconstants.h \
+ debuggercore.h \
+ debuggerdialogs.h \
+ debuggerengine.h \
+ debuggericons.h \
debuggerinternalconstants.h \
debuggeritem.h \
debuggeritemmanager.h \
- debuggerdialogs.h \
- debuggerengine.h \
+ debuggerkitinformation.h \
debuggermainwindow.h \
debuggerplugin.h \
debuggerprotocol.h \
debuggerrunconfigurationaspect.h \
debuggerruncontrol.h \
- debuggerkitinformation.h \
+ debuggersourcepathmappingwidget.h \
+ debuggertooltipmanager.h \
disassembleragent.h \
disassemblerlines.h \
+ enginemanager.h \
+ imageviewer.h \
loadcoredialog.h \
+ localsandexpressionswindow.h \
logwindow.h \
memoryagent.h \
moduleshandler.h \
outputcollector.h \
+ peripheralregisterhandler.h \
procinterrupt.h \
registerhandler.h \
- enginemanager.h \
+ simplifytype.h \
sourceagent.h \
sourcefileshandler.h \
sourceutils.h \
@@ -47,19 +54,13 @@ HEADERS += \
stackhandler.h \
stackwindow.h \
terminal.h \
- watchhandler.h \
- watchutils.h \
- watchwindow.h \
threaddata.h \
threadshandler.h \
- watchdelegatewidgets.h \
- debuggertooltipmanager.h \
- debuggersourcepathmappingwidget.h \
- localsandexpressionswindow.h \
- imageviewer.h \
- simplifytype.h \
unstartedappwatcherdialog.h \
- debuggericons.h
+ watchdelegatewidgets.h \
+ watchhandler.h \
+ watchutils.h \
+ watchwindow.h
SOURCES += \
breakhandler.cpp \
@@ -68,44 +69,45 @@ SOURCES += \
debuggeractions.cpp \
debuggerdialogs.cpp \
debuggerengine.cpp \
+ debuggericons.cpp \
debuggeritem.cpp \
debuggeritemmanager.cpp \
+ debuggerkitinformation.cpp \
debuggermainwindow.cpp \
debuggerplugin.cpp \
debuggerprotocol.cpp \
debuggerrunconfigurationaspect.cpp \
debuggerruncontrol.cpp \
- debuggerkitinformation.cpp \
+ debuggersourcepathmappingwidget.cpp \
+ debuggertooltipmanager.cpp \
disassembleragent.cpp \
disassemblerlines.cpp \
+ enginemanager.cpp \
+ imageviewer.cpp \
loadcoredialog.cpp \
+ localsandexpressionswindow.cpp \
logwindow.cpp \
memoryagent.cpp \
moduleshandler.cpp \
outputcollector.cpp \
+ peripheralregisterhandler.cpp \
procinterrupt.cpp \
registerhandler.cpp \
- enginemanager.cpp \
+ simplifytype.cpp \
sourceagent.cpp \
sourcefileshandler.cpp \
sourceutils.cpp \
+ stackframe.cpp \
stackhandler.cpp \
stackwindow.cpp \
- threadshandler.cpp \
terminal.cpp \
+ threadshandler.cpp \
+ unstartedappwatcherdialog.cpp \
watchdata.cpp \
+ watchdelegatewidgets.cpp \
watchhandler.cpp \
watchutils.cpp \
- watchwindow.cpp \
- stackframe.cpp \
- watchdelegatewidgets.cpp \
- debuggertooltipmanager.cpp \
- debuggersourcepathmappingwidget.cpp \
- localsandexpressionswindow.cpp \
- imageviewer.cpp \
- simplifytype.cpp \
- unstartedappwatcherdialog.cpp \
- debuggericons.cpp
+ watchwindow.cpp
RESOURCES += debugger.qrc
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs
index 6add8dd906..8199a90f48 100644
--- a/src/plugins/debugger/debugger.qbs
+++ b/src/plugins/debugger/debugger.qbs
@@ -69,6 +69,7 @@ Project {
"memoryagent.cpp", "memoryagent.h",
"moduleshandler.cpp", "moduleshandler.h",
"outputcollector.cpp", "outputcollector.h",
+ "peripheralregisterhandler.cpp", "peripheralregisterhandler.h",
"procinterrupt.cpp", "procinterrupt.h",
"registerhandler.cpp", "registerhandler.h",
"sourceagent.cpp", "sourceagent.h",
diff --git a/src/plugins/debugger/debugger_global.h b/src/plugins/debugger/debugger_global.h
index fc1597cc82..7ec10b5508 100644
--- a/src/plugins/debugger/debugger_global.h
+++ b/src/plugins/debugger/debugger_global.h
@@ -29,6 +29,8 @@
#if defined(DEBUGGER_LIBRARY)
# define DEBUGGER_EXPORT Q_DECL_EXPORT
+#elif defined(DEBUGGER_STATIC_LIBRARY) // Abuse single files for tests
+# define DEBUGGER_EXPORT
#else
# define DEBUGGER_EXPORT Q_DECL_IMPORT
#endif
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index aeb3cf992e..3605115b09 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -668,27 +668,27 @@ void DebuggerSettings::insertItem(int code, SavedAction *item)
void DebuggerSettings::readSettings()
{
QSettings *settings = Core::ICore::settings();
- foreach (SavedAction *item, m_items)
+ for (SavedAction *item : qAsConst(m_items))
item->readSettings(settings);
}
void DebuggerSettings::writeSettings() const
{
QSettings *settings = Core::ICore::settings();
- foreach (SavedAction *item, m_items)
+ for (SavedAction *item : qAsConst(m_items))
item->writeSettings(settings);
}
SavedAction *DebuggerSettings::item(int code) const
{
- QTC_ASSERT(m_items.value(code, 0), qDebug() << "CODE: " << code; return nullptr);
- return m_items.value(code, 0);
+ QTC_ASSERT(m_items.value(code, nullptr), qDebug() << "CODE: " << code; return nullptr);
+ return m_items.value(code, nullptr);
}
QString DebuggerSettings::dump()
{
QStringList settings;
- foreach (SavedAction *item, theDebuggerSettings->m_items) {
+ for (SavedAction *item : qAsConst(theDebuggerSettings->m_items)) {
QString key = item->settingsKey();
if (!key.isEmpty()) {
const QString current = item->value().toString();
diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h
index d7aee4b7db..60bd22f373 100644
--- a/src/plugins/debugger/debuggercore.h
+++ b/src/plugins/debugger/debuggercore.h
@@ -42,19 +42,15 @@ class QMenu;
class QAction;
QT_END_NAMESPACE
-namespace CPlusPlus { class Snapshot; }
-
namespace Utils {
class BaseTreeView;
class SavedAction;
}
namespace Debugger {
-
-class DebuggerRunTool;
-
namespace Internal {
+class Console;
class Symbol;
class Section;
class GlobalDebuggerOptions;
@@ -73,12 +69,11 @@ void showModuleSections(const QString &moduleName, const QVector<Internal::Secti
QSharedPointer<Internal::GlobalDebuggerOptions> globalDebuggerOptions();
-QVariant configValue(const QString &name);
-void setConfigValue(const QString &name, const QVariant &value);
-
bool isTestRun();
Utils::SavedAction *action(int code);
+Console *console();
+
bool boolSetting(int code);
QString stringSetting(int code);
QStringList stringListSetting(int code);
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 5fc852cf2c..ea442c1891 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -99,36 +99,6 @@ namespace Internal {
///////////////////////////////////////////////////////////////////////
//
-// DebuggerKitChooser
-//
-///////////////////////////////////////////////////////////////////////
-
-DebuggerKitChooser::DebuggerKitChooser(Mode mode, QWidget *parent)
- : KitChooser(parent)
- , m_hostAbi(Abi::hostAbi())
- , m_mode(mode)
-{
- setKitPredicate([this](const Kit *k) {
- // Match valid debuggers and restrict local debugging to compatible toolchains.
- auto errors = DebuggerKitAspect::configurationErrors(k);
- // we do not care for mismatched ABI if we want *any* debugging
- if (m_mode == AnyDebugging && errors == DebuggerKitAspect::DebuggerDoesNotMatch)
- errors = DebuggerKitAspect::NoConfigurationError;
- if (errors)
- return false;
- if (m_mode == LocalDebugging)
- return ToolChainKitAspect::targetAbi(k).os() == m_hostAbi.os();
- return true;
- });
-}
-
-QString DebuggerKitChooser::kitToolTip(Kit *k) const
-{
- return DebuggerKitAspect::displayString(k);
-}
-
-///////////////////////////////////////////////////////////////////////
-//
// StartApplicationParameters
//
///////////////////////////////////////////////////////////////////////
@@ -172,7 +142,7 @@ QString StartApplicationParameters::displayName() const
{
const int maxLength = 60;
- QString name = FilePath::fromString(runnable.executable).fileName()
+ QString name = runnable.executable.fileName()
+ ' ' + runnable.commandLineArguments;
if (name.size() > 60) {
int index = name.lastIndexOf(' ', maxLength);
@@ -193,7 +163,7 @@ void StartApplicationParameters::toSettings(QSettings *settings) const
settings->setValue("LastKitId", kitId.toSetting());
settings->setValue("LastServerPort", serverPort);
settings->setValue("LastServerAddress", serverAddress);
- settings->setValue("LastExternalExecutable", runnable.executable);
+ settings->setValue("LastExternalExecutable", runnable.executable.toVariant());
settings->setValue("LastExternalExecutableArguments", runnable.commandLineArguments);
settings->setValue("LastExternalWorkingDirectory", runnable.workingDirectory);
settings->setValue("LastExternalBreakAtMain", breakAtMain);
@@ -207,7 +177,7 @@ void StartApplicationParameters::fromSettings(const QSettings *settings)
kitId = Id::fromSetting(settings->value("LastKitId"));
serverPort = settings->value("LastServerPort").toUInt();
serverAddress = settings->value("LastServerAddress").toString();
- runnable.executable = settings->value("LastExternalExecutable").toString();
+ runnable.executable = FilePath::fromVariant(settings->value("LastExternalExecutable"));
runnable.commandLineArguments = settings->value("LastExternalExecutableArguments").toString();
runnable.workingDirectory = settings->value("LastExternalWorkingDirectory").toString();
breakAtMain = settings->value("LastExternalBreakAtMain").toBool();
@@ -472,7 +442,7 @@ StartApplicationParameters StartApplicationDialog::parameters() const
StartApplicationParameters result;
result.serverPort = d->serverPortSpinBox->value();
result.serverAddress = d->channelOverrideEdit->text();
- result.runnable.executable = d->localExecutablePathChooser->path();
+ result.runnable.executable = d->localExecutablePathChooser->fileName();
result.serverStartScript = d->serverStartScriptPathChooser->fileName();
result.kitId = d->kitChooser->currentKitId();
result.debugInfoLocation = d->debuginfoPathChooser->path();
@@ -488,7 +458,7 @@ void StartApplicationDialog::setParameters(const StartApplicationParameters &p)
d->kitChooser->setCurrentKitId(p.kitId);
d->serverPortSpinBox->setValue(p.serverPort);
d->channelOverrideEdit->setText(p.serverAddress);
- d->localExecutablePathChooser->setPath(p.runnable.executable);
+ d->localExecutablePathChooser->setFileName(p.runnable.executable);
d->serverStartScriptPathChooser->setFileName(p.serverStartScript);
d->debuginfoPathChooser->setPath(p.debugInfoLocation);
d->arguments->setText(p.runnable.commandLineArguments);
@@ -518,7 +488,8 @@ AttachToQmlPortDialog::AttachToQmlPortDialog(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Start Debugger"));
- d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging, this);
+ d->kitChooser = new KitChooser(this);
+ d->kitChooser->setShowIcons(true);
d->kitChooser->populate();
d->portSpinBox = new QSpinBox(this);
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index 4cec4143a6..20d38307e7 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -47,23 +47,6 @@ class StartApplicationParameters;
class StartApplicationDialogPrivate;
class StartRemoteEngineDialogPrivate;
-class DebuggerKitChooser : public ProjectExplorer::KitChooser
-{
- Q_OBJECT
-
-public:
- enum Mode { AnyDebugging, LocalDebugging };
-
- explicit DebuggerKitChooser(Mode mode = AnyDebugging, QWidget *parent = nullptr);
-
-protected:
- QString kitToolTip(ProjectExplorer::Kit *k) const final;
-
-private:
- const ProjectExplorer::Abi m_hostAbi;
- const Mode m_mode;
-};
-
class StartApplicationDialog : public QDialog
{
Q_OBJECT
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index 6b94e5025d..0dd02e1b63 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -43,6 +43,7 @@
#include "memoryagent.h"
#include "moduleshandler.h"
#include "registerhandler.h"
+#include "peripheralregisterhandler.h"
#include "sourcefileshandler.h"
#include "sourceutils.h"
#include "stackhandler.h"
@@ -73,7 +74,6 @@
#include <texteditor/fontsettings.h>
#include <utils/basetreeview.h>
-#include <utils/fileinprojectfinder.h>
#include <utils/macroexpander.h>
#include <utils/processhandle.h>
#include <utils/qtcassert.h>
@@ -225,7 +225,7 @@ public:
{
auto agent = new MemoryAgent(data, engine);
if (agent->isUsable()) {
- m_agents.append(agent);
+ m_agents.push_back(agent);
} else {
delete agent;
AsynchronousMessageBox::warning(
@@ -238,7 +238,7 @@ public:
// On stack frame completed and on request.
void updateContents()
{
- foreach (MemoryAgent *agent, m_agents) {
+ for (MemoryAgent *agent : m_agents) {
if (agent)
agent->updateContents();
}
@@ -246,14 +246,14 @@ public:
void handleDebuggerFinished()
{
- foreach (MemoryAgent *agent, m_agents) {
+ for (MemoryAgent *agent : m_agents) {
if (agent)
agent->setFinished(); // Prevent triggering updates, etc.
}
}
private:
- QList<MemoryAgent *> m_agents;
+ std::vector<MemoryAgent *> m_agents;
};
@@ -274,6 +274,7 @@ public:
m_breakHandler(engine),
m_modulesHandler(engine),
m_registerHandler(engine),
+ m_peripheralRegisterHandler(engine),
m_sourceFilesHandler(engine),
m_stackHandler(engine),
m_threadsHandler(engine),
@@ -343,6 +344,7 @@ public:
delete m_watchersWindow;
delete m_inspectorWindow;
delete m_registerWindow;
+ delete m_peripheralRegisterWindow;
delete m_modulesWindow;
delete m_sourceFilesWindow;
delete m_stackWindow;
@@ -354,6 +356,7 @@ public:
delete m_watchersView;
delete m_inspectorView;
delete m_registerView;
+ delete m_peripheralRegisterView;
delete m_modulesView;
delete m_sourceFilesView;
delete m_stackView;
@@ -439,8 +442,6 @@ public:
m_lookupRequests.clear();
m_locationTimer.stop();
m_locationMark.reset();
- m_stackHandler.resetLocation();
- m_watchHandler.resetLocation();
m_disassemblerAgent.resetLocation();
m_toolTipManager.resetLocation();
}
@@ -471,6 +472,7 @@ public:
BreakHandler m_breakHandler;
ModulesHandler m_modulesHandler;
RegisterHandler m_registerHandler;
+ PeripheralRegisterHandler m_peripheralRegisterHandler;
SourceFilesHandler m_sourceFilesHandler;
StackHandler m_stackHandler;
ThreadsHandler m_threadsHandler;
@@ -482,7 +484,6 @@ public:
QScopedPointer<LocationMark> m_locationMark;
QTimer m_locationTimer;
- Utils::FileInProjectFinder m_fileFinder;
QString m_qtNamespace;
// Safety net to avoid infinite lookups.
@@ -495,6 +496,7 @@ public:
QPointer<BaseTreeView> m_watchersView;
QPointer<WatchTreeView> m_inspectorView;
QPointer<BaseTreeView> m_registerView;
+ QPointer<BaseTreeView> m_peripheralRegisterView;
QPointer<BaseTreeView> m_modulesView;
QPointer<BaseTreeView> m_sourceFilesView;
QPointer<BaseTreeView> m_stackView;
@@ -505,6 +507,7 @@ public:
QPointer<QWidget> m_watchersWindow;
QPointer<QWidget> m_inspectorWindow;
QPointer<QWidget> m_registerWindow;
+ QPointer<QWidget> m_peripheralRegisterWindow;
QPointer<QWidget> m_modulesWindow;
QPointer<QWidget> m_sourceFilesWindow;
QPointer<QWidget> m_stackWindow;
@@ -645,6 +648,17 @@ void DebuggerEnginePrivate::setupViews()
m_registerWindow->setObjectName("Debugger.Dock.Register." + engineId);
m_registerWindow->setWindowTitle(tr("Reg&isters"));
+ m_peripheralRegisterView = new BaseTreeView;
+ m_peripheralRegisterView->setModel(m_peripheralRegisterHandler.model());
+ m_peripheralRegisterView->setRootIsDecorated(true);
+ m_peripheralRegisterView->setSettings(settings, "Debugger.PeripheralRegisterView");
+ connect(m_peripheralRegisterView, &BaseTreeView::aboutToShow,
+ m_engine, &DebuggerEngine::reloadPeripheralRegisters,
+ Qt::QueuedConnection);
+ m_peripheralRegisterWindow = addSearch(m_peripheralRegisterView);
+ m_peripheralRegisterWindow->setObjectName("Debugger.Dock.PeripheralRegister." + engineId);
+ m_peripheralRegisterWindow->setWindowTitle(tr("Peripheral Reg&isters"));
+
m_stackView = new StackTreeView;
m_stackView->setModel(m_stackHandler.model());
m_stackView->setSettings(settings, "Debugger.StackView");
@@ -818,6 +832,7 @@ void DebuggerEnginePrivate::setupViews()
m_modulesWindow->setFont(font);
//m_consoleWindow->setFont(font);
m_registerWindow->setFont(font);
+ m_peripheralRegisterWindow->setFont(font);
m_returnWindow->setFont(font);
m_sourceFilesWindow->setFont(font);
m_stackWindow->setFont(font);
@@ -834,6 +849,7 @@ void DebuggerEnginePrivate::setupViews()
m_perspective->addWindow(m_localsAndInspectorWindow, Perspective::AddToTab, nullptr, true, Qt::RightDockWidgetArea);
m_perspective->addWindow(m_watchersWindow, Perspective::SplitVertical, m_localsAndInspectorWindow, true, Qt::RightDockWidgetArea);
m_perspective->addWindow(m_registerWindow, Perspective::AddToTab, m_localsAndInspectorWindow, false, Qt::RightDockWidgetArea);
+ m_perspective->addWindow(m_peripheralRegisterWindow, Perspective::AddToTab, m_localsAndInspectorWindow, false, Qt::RightDockWidgetArea);
m_perspective->addWindow(m_logWindow, Perspective::AddToTab, nullptr, false, Qt::TopDockWidgetArea);
m_perspective->select();
@@ -911,6 +927,11 @@ bool DebuggerEngine::isRegistersWindowVisible() const
return d->m_registerWindow->isVisible();
}
+bool DebuggerEngine::isPeripheralRegistersWindowVisible() const
+{
+ return d->m_peripheralRegisterWindow->isVisible();
+}
+
bool DebuggerEngine::isModulesWindowVisible() const
{
return d->m_modulesWindow->isVisible();
@@ -942,6 +963,11 @@ RegisterHandler *DebuggerEngine::registerHandler() const
return &d->m_registerHandler;
}
+PeripheralRegisterHandler *DebuggerEngine::peripheralRegisterHandler() const
+{
+ return &d->m_peripheralRegisterHandler;
+}
+
StackHandler *DebuggerEngine::stackHandler() const
{
return &d->m_stackHandler;
@@ -979,20 +1005,26 @@ DisassemblerAgent *DebuggerEngine::disassemblerAgent() const
void DebuggerEngine::fetchMemory(MemoryAgent *, quint64 addr, quint64 length)
{
- Q_UNUSED(addr);
- Q_UNUSED(length);
+ Q_UNUSED(addr)
+ Q_UNUSED(length)
}
void DebuggerEngine::changeMemory(MemoryAgent *, quint64 addr, const QByteArray &data)
{
- Q_UNUSED(addr);
- Q_UNUSED(data);
+ Q_UNUSED(addr)
+ Q_UNUSED(data)
}
void DebuggerEngine::setRegisterValue(const QString &name, const QString &value)
{
- Q_UNUSED(name);
- Q_UNUSED(value);
+ Q_UNUSED(name)
+ Q_UNUSED(value)
+}
+
+void DebuggerEngine::setPeripheralRegisterValue(quint64 address, quint64 value)
+{
+ Q_UNUSED(address)
+ Q_UNUSED(value)
}
void DebuggerEngine::setRunParameters(const DebuggerRunParameters &runParameters)
@@ -1595,6 +1627,7 @@ void DebuggerEnginePrivate::setBusyCursor(bool busy)
m_modulesWindow->setCursor(cursor);
m_logWindow->setCursor(cursor);
m_registerWindow->setCursor(cursor);
+ m_peripheralRegisterWindow->setCursor(cursor);
m_returnWindow->setCursor(cursor);
m_sourceFilesWindow->setCursor(cursor);
m_stackWindow->setCursor(cursor);
@@ -1707,7 +1740,7 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c
case StatusBar:
d->m_logWindow->showInput(LogMisc, msg);
d->m_logWindow->showOutput(LogMisc, msg);
- Debugger::showStatusMessage(msg, timeout);
+ DebuggerMainWindow::showStatusMessage(msg, timeout);
break;
case LogMiscInput:
d->m_logWindow->showInput(LogMisc, msg);
@@ -1829,18 +1862,6 @@ bool DebuggerEngine::canDisplayTooltip() const
return state() == InferiorStopOk;
}
-QString DebuggerEngine::toFileInProject(const QUrl &fileUrl)
-{
- // make sure file finder is properly initialized
- const DebuggerRunParameters &rp = runParameters();
- d->m_fileFinder.setProjectDirectory(rp.projectSourceDirectory);
- d->m_fileFinder.setProjectFiles(rp.projectSourceFiles);
- d->m_fileFinder.setAdditionalSearchDirectories(rp.additionalSearchDirectories);
- d->m_fileFinder.setSysroot(rp.sysRoot);
-
- return d->m_fileFinder.findFile(fileUrl).first().toString();
-}
-
QString DebuggerEngine::expand(const QString &string) const
{
return runParameters().macroExpander->expand(string);
@@ -1889,7 +1910,7 @@ void DebuggerEngine::operateByInstructionTriggered(bool on)
{
// Go to source only if we have the file.
// if (DebuggerEngine *cppEngine = m_engine->cppEngine()) {
- d->m_stackHandler.resetModel();
+ d->m_stackHandler.rootItem()->updateAll();
if (d->m_stackHandler.currentIndex() >= 0) {
const StackFrame frame = d->m_stackHandler.currentFrame();
if (on || frame.isUsable())
@@ -2077,6 +2098,10 @@ void DebuggerEngine::reloadRegisters()
{
}
+void DebuggerEngine::reloadPeripheralRegisters()
+{
+}
+
void DebuggerEngine::reloadSourceFiles()
{
}
@@ -2522,7 +2547,7 @@ bool DebuggerEngine::isNativeMixedActiveFrame() const
{
if (!isNativeMixedActive())
return false;
- if (stackHandler()->frames().isEmpty())
+ if (stackHandler()->rowCount() == 0)
return false;
StackFrame frame = stackHandler()->frameAt(0);
return frame.language == QmlLanguage;
@@ -2564,8 +2589,7 @@ QString DebuggerEngine::formatStartParameters() const
str << "qml";
str << '\n';
if (!sp.inferior.executable.isEmpty()) {
- str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable)
- << ' ' << sp.inferior.commandLineArguments;
+ str << "Executable: " << sp.inferior.commandLine().toUserOutput();
if (d->m_terminalRunner)
str << " [terminal]";
str << '\n';
@@ -2573,9 +2597,8 @@ QString DebuggerEngine::formatStartParameters() const
str << "Directory: " << QDir::toNativeSeparators(sp.inferior.workingDirectory)
<< '\n';
}
- QString cmd = sp.debugger.executable;
- if (!cmd.isEmpty())
- str << "Debugger: " << QDir::toNativeSeparators(cmd) << '\n';
+ if (!sp.debugger.executable.isEmpty())
+ str << "Debugger: " << sp.debugger.executable.toUserOutput() << '\n';
if (!sp.coreFile.isEmpty())
str << "Core: " << QDir::toNativeSeparators(sp.coreFile) << '\n';
if (sp.attachPID.isValid())
@@ -2630,11 +2653,11 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
&& rp.cppEngineType == CdbEngineType
&& rp.startMode != AttachToRemoteServer) {
QTC_ASSERT(!rp.symbolFile.isEmpty(), return);
- if (!rp.symbolFile.endsWith(".exe", Qt::CaseInsensitive))
- rp.symbolFile.append(".exe");
+ if (!rp.symbolFile.exists() && !rp.symbolFile.endsWith(".exe"))
+ rp.symbolFile = rp.symbolFile.stringAppended(".exe");
QString errorMessage;
QStringList rc;
- if (getPDBFiles(rp.symbolFile, &rc, &errorMessage) && !rc.isEmpty())
+ if (getPDBFiles(rp.symbolFile.toString(), &rc, &errorMessage) && !rc.isEmpty())
return;
if (!errorMessage.isEmpty()) {
detailedWarning.append('\n');
@@ -2655,11 +2678,11 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
break;
}
- Utils::ElfReader reader(rp.symbolFile);
+ Utils::ElfReader reader(rp.symbolFile.toString());
const ElfData elfData = reader.readHeaders();
const QString error = reader.errorString();
- showMessage("EXAMINING " + rp.symbolFile, LogDebug);
+ showMessage("EXAMINING " + rp.symbolFile.toString(), LogDebug);
QByteArray msg = "ELF SECTIONS: ";
static const QList<QByteArray> interesting = {
@@ -2702,7 +2725,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
QSharedPointer<GlobalDebuggerOptions> options = Internal::globalDebuggerOptions();
SourcePathRegExpMap globalRegExpSourceMap;
globalRegExpSourceMap.reserve(options->sourcePathRegExpMap.size());
- foreach (auto entry, options->sourcePathRegExpMap) {
+ for (auto entry : qAsConst(options->sourcePathRegExpMap)) {
const QString expanded = Utils::globalMacroExpander()->expand(entry.second);
if (!expanded.isEmpty())
globalRegExpSourceMap.push_back(qMakePair(entry.first, expanded));
@@ -2739,7 +2762,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
if (hasEmbeddedInfo || hasLink)
return;
- foreach (const QByteArray &name, interesting) {
+ for (const QByteArray &name : qAsConst(interesting)) {
const QString found = seen.contains(name) ? DebuggerEngine::tr("Found.")
: DebuggerEngine::tr("Not found.");
detailedWarning.append('\n' + DebuggerEngine::tr("Section %1: %2").arg(QString::fromUtf8(name)).arg(found));
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 78826dd518..f4ba9e47cb 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -101,6 +101,7 @@ class LocationMark;
class LogWindow;
class ModulesHandler;
class RegisterHandler;
+class PeripheralRegisterHandler;
class StackHandler;
class StackFrame;
class SourceFilesHandler;
@@ -128,7 +129,7 @@ public:
// Used by general remote debugging.
QString remoteChannel;
bool useExtendedRemote = false; // Whether to use GDB's target extended-remote or not.
- QString symbolFile;
+ Utils::FilePath symbolFile;
// Used by Mer plugin (3rd party)
QMap<QString, QString> sourcePathMap;
@@ -316,12 +317,14 @@ public:
virtual void requestModuleSections(const QString &moduleName);
virtual void reloadRegisters();
+ virtual void reloadPeripheralRegisters();
virtual void reloadSourceFiles();
virtual void reloadFullStack();
virtual void loadAdditionalQmlStack();
virtual void reloadDebuggingHelpers();
virtual void setRegisterValue(const QString &name, const QString &value);
+ virtual void setPeripheralRegisterValue(quint64 address, quint64 value);
virtual void addOptionPages(QList<Core::IOptionsPage*> *) const;
virtual bool hasCapability(unsigned cap) const = 0;
virtual void debugLastCommand() {}
@@ -356,6 +359,7 @@ public:
ModulesHandler *modulesHandler() const;
RegisterHandler *registerHandler() const;
+ PeripheralRegisterHandler *peripheralRegisterHandler() const;
StackHandler *stackHandler() const;
ThreadsHandler *threadsHandler() const;
WatchHandler *watchHandler() const;
@@ -401,8 +405,6 @@ public:
virtual bool canDisplayTooltip() const;
- QString toFileInProject(const QUrl &fileUrl);
-
QString expand(const QString &string) const;
QString nativeStartupCommands() const;
Utils::Perspective *perspective() const;
@@ -453,6 +455,7 @@ public:
QString debuggerName() const;
bool isRegistersWindowVisible() const;
+ bool isPeripheralRegistersWindowVisible() const;
bool isModulesWindowVisible() const;
void openMemoryEditor();
@@ -551,6 +554,7 @@ private:
friend class DebuggerPluginPrivate;
friend class DebuggerEnginePrivate;
friend class LocationMark;
+ friend class PeripheralRegisterHandler;
DebuggerEnginePrivate *d;
};
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index c17766361c..0fcd7a165a 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -64,12 +64,12 @@ const char DEBUGGER_INFORMATION_WORKINGDIRECTORY[] = "WorkingDirectory";
//! Return the configuration of gdb as a list of --key=value
//! \note That the list will also contain some output not in this format.
-static QString getConfigurationOfGdbCommand(const QString &command)
+static QString getConfigurationOfGdbCommand(const FilePath &command)
{
// run gdb with the --configuration opion
Utils::SynchronousProcess gdbConfigurationCall;
Utils::SynchronousProcessResponse output =
- gdbConfigurationCall.runBlocking(command, {QString("--configuration")});
+ gdbConfigurationCall.runBlocking({command, {"--configuration"}});
return output.allOutput();
}
@@ -115,7 +115,8 @@ DebuggerItem::DebuggerItem(const QVariantMap &data)
static_cast<int>(NoEngineType)).toInt());
m_lastModified = data.value(DEBUGGER_INFORMATION_LASTMODIFIED).toDateTime();
- foreach (const QString &a, data.value(DEBUGGER_INFORMATION_ABIS).toStringList()) {
+ const QStringList abis = data.value(DEBUGGER_INFORMATION_ABIS).toStringList();
+ for (const QString &a : abis) {
Abi abi = Abi::fromString(a);
if (!abi.isNull())
m_abis.append(abi);
@@ -142,15 +143,14 @@ void DebuggerItem::reinitializeFromFile()
// CDB only understands the single-dash -version, whereas GDB and LLDB are
// happy with both -version and --version. So use the "working" -version
// except for the experimental LLDB-MI which insists on --version.
- const char *version = "-version";
+ QString version = "-version";
const QFileInfo fileInfo = m_command.toFileInfo();
m_lastModified = fileInfo.lastModified();
if (fileInfo.baseName().toLower().contains("lldb-mi"))
version = "--version";
SynchronousProcess proc;
- SynchronousProcessResponse response
- = proc.runBlocking(m_command.toString(), {QLatin1String(version)});
+ SynchronousProcessResponse response = proc.runBlocking({m_command, {version}});
if (response.result != SynchronousProcessResponse::Finished) {
m_engineType = NoEngineType;
return;
@@ -173,7 +173,7 @@ void DebuggerItem::reinitializeFromFile()
const bool unableToFindAVersion = (0 == version);
const bool gdbSupportsConfigurationFlag = (version >= 70700);
if (gdbSupportsConfigurationFlag || unableToFindAVersion) {
- const auto gdbConfiguration = getConfigurationOfGdbCommand(m_command.toString());
+ const auto gdbConfiguration = getConfigurationOfGdbCommand(m_command);
const auto gdbTargetAbiString =
extractGdbTargetAbiStringFromGdbOutput(gdbConfiguration);
if (!gdbTargetAbiString.isEmpty()) {
@@ -260,7 +260,7 @@ QIcon DebuggerItem::decoration() const
return Utils::Icons::CRITICAL.icon();
if (!m_command.toFileInfo().isExecutable())
return Utils::Icons::WARNING.icon();
- if (!m_workingDirectory.isEmpty() && !m_workingDirectory.toFileInfo().isDir())
+ if (!m_workingDirectory.isEmpty() && !m_workingDirectory.isDir())
return Utils::Icons::WARNING.icon();
return QIcon();
}
diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp
index 6d1e14cff8..270c3851c9 100644
--- a/src/plugins/debugger/debuggeritemmanager.cpp
+++ b/src/plugins/debugger/debuggeritemmanager.cpp
@@ -350,8 +350,9 @@ DebuggerItem DebuggerItemConfigWidget::item() const
item.setCommand(m_binaryChooser->fileName());
item.setWorkingDirectory(m_workingDirectoryChooser->fileName());
item.setAutoDetected(m_autodetected);
- ProjectExplorer::Abis abiList;
- foreach (const QString &a, m_abis->text().split(QRegExp("[^A-Za-z0-9-_]+"))) {
+ Abis abiList;
+ const QStringList abis = m_abis->text().split(QRegExp("[^A-Za-z0-9-_]+"));
+ for (const QString &a : abis) {
if (a.isNull())
continue;
abiList << Abi::fromString(a);
@@ -696,10 +697,43 @@ void DebuggerItemManagerPrivate::autoDetectCdbDebuggers()
}
}
+static Utils::FilePathList searchGdbPathsFromRegistry()
+{
+ if (!HostOsInfo::isWindowsHost())
+ return {};
+
+ // Registry token for the "GNU Tools for ARM Embedded Processors".
+ static const char kRegistryToken[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \
+ "Windows\\CurrentVersion\\Uninstall\\";
+
+ Utils::FilePathList searchPaths;
+
+ QSettings registry(kRegistryToken, QSettings::NativeFormat);
+ const auto productGroups = registry.childGroups();
+ for (const QString &productKey : productGroups) {
+ if (!productKey.startsWith("GNU Tools for ARM Embedded Processors"))
+ continue;
+ registry.beginGroup(productKey);
+ QString uninstallFilePath = registry.value("UninstallString").toString();
+ if (uninstallFilePath.startsWith(QLatin1Char('"')))
+ uninstallFilePath.remove(0, 1);
+ if (uninstallFilePath.endsWith(QLatin1Char('"')))
+ uninstallFilePath.remove(uninstallFilePath.size() - 1, 1);
+ registry.endGroup();
+
+ const QString toolkitRootPath = QFileInfo(uninstallFilePath).path();
+ const QString toolchainPath = toolkitRootPath + QLatin1String("/bin");
+ searchPaths.push_back(FilePath::fromString(toolchainPath));
+ }
+
+ return searchPaths;
+}
+
void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers()
{
const QStringList filters = {"gdb-i686-pc-mingw32", "gdb-i686-pc-mingw32.exe", "gdb",
- "gdb.exe", "lldb", "lldb.exe", "lldb-[1-9]*"};
+ "gdb.exe", "lldb", "lldb.exe", "lldb-[1-9]*",
+ "arm-none-eabi-gdb-py.exe"};
// DebuggerItem result;
// result.setAutoDetected(true);
@@ -709,7 +743,7 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers()
Environment env = Environment::systemEnvironment();
if (tc) {
tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment.
- QString path = tc->suggestedDebugger().toString();
+ QString path = tc->suggestedDebugger().toString(); // Won't compile
if (!path.isEmpty()) {
const QFileInfo fi(path);
if (!fi.isAbsolute())
@@ -726,8 +760,7 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers()
if (HostOsInfo::isMacHost()) {
SynchronousProcess lldbInfo;
lldbInfo.setTimeoutS(2);
- SynchronousProcessResponse response
- = lldbInfo.runBlocking("xcrun", {"--find", "lldb"});
+ SynchronousProcessResponse response = lldbInfo.runBlocking({"xcrun", {"--find", "lldb"}});
if (response.result == Utils::SynchronousProcessResponse::Finished) {
QString lPath = response.allOutput().trimmed();
if (!lPath.isEmpty()) {
@@ -738,18 +771,20 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers()
}
}
- Utils::FilePathList path = Environment::systemEnvironment().path();
- path = Utils::filteredUnique(path);
+ FilePathList path = Utils::filteredUnique(
+ Environment::systemEnvironment().path() + searchGdbPathsFromRegistry());
+
QDir dir;
dir.setNameFilters(filters);
dir.setFilter(QDir::Files | QDir::Executable);
- foreach (const Utils::FilePath &base, path) {
+ for (const FilePath &base : path) {
dir.setPath(base.toFileInfo().absoluteFilePath());
- foreach (const QString &entry, dir.entryList())
+ const QStringList entries = dir.entryList();
+ for (const QString &entry : entries)
suspects.append(FilePath::fromString(dir.absoluteFilePath(entry)));
}
- foreach (const FilePath &command, suspects) {
+ for (const FilePath &command : qAsConst(suspects)) {
const auto commandMatches = [command](const DebuggerTreeItem *titem) {
return titem->m_item.command() == command;
};
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index 412d54b33c..356dd9ed95 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -115,7 +115,7 @@ private:
void currentDebuggerChanged(int idx)
{
- Q_UNUSED(idx);
+ Q_UNUSED(idx)
if (m_ignoreChanges)
return;
@@ -335,7 +335,7 @@ Runnable DebuggerKitAspect::runnable(const Kit *kit)
{
Runnable runnable;
if (const DebuggerItem *item = debugger(kit)) {
- runnable.executable = item->command().toString();
+ runnable.executable = item->command();
runnable.workingDirectory = item->workingDirectory().toString();
runnable.environment = Utils::Environment::systemEnvironment();
runnable.environment.set("LC_NUMERIC", "C");
diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp
index ee6ccae238..caa145b0f7 100644
--- a/src/plugins/debugger/debuggermainwindow.cpp
+++ b/src/plugins/debugger/debuggermainwindow.cpp
@@ -132,8 +132,6 @@ class DebuggerMainWindowPrivate : public QObject
public:
DebuggerMainWindowPrivate(DebuggerMainWindow *parent);
- void createToolBar();
-
void selectPerspective(Perspective *perspective);
void depopulateCurrentPerspective();
void populateCurrentPerspective();
@@ -207,18 +205,18 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
// "Engine switcher" style comboboxes
auto subPerspectiveSwitcher = new QWidget;
m_subPerspectiveSwitcherLayout = new QHBoxLayout(subPerspectiveSwitcher);
- m_subPerspectiveSwitcherLayout->setMargin(0);
+ m_subPerspectiveSwitcherLayout->setContentsMargins(0, 0, 0, 0);
m_subPerspectiveSwitcherLayout->setSpacing(0);
// All perspective toolbars will get inserted here, but only
// the current perspective's toolbar is set visible.
auto innerTools = new QWidget;
m_innerToolsLayout = new QHBoxLayout(innerTools);
- m_innerToolsLayout->setMargin(0);
+ m_innerToolsLayout->setContentsMargins(0, 0, 0, 0);
m_innerToolsLayout->setSpacing(0);
auto hbox = new QHBoxLayout(toolbar);
- hbox->setMargin(0);
+ hbox->setContentsMargins(0, 0, 0, 0);
hbox->setSpacing(0);
hbox->addWidget(m_perspectiveChooser);
hbox->addWidget(subPerspectiveSwitcher);
@@ -735,7 +733,7 @@ Perspective::Perspective(const QString &id, const QString &name,
theMainWindow->d->m_innerToolsLayout->addWidget(d->m_innerToolBar);
d->m_innerToolBarLayout = new QHBoxLayout(d->m_innerToolBar);
- d->m_innerToolBarLayout->setMargin(0);
+ d->m_innerToolBarLayout->setContentsMargins(0, 0, 0, 0);
d->m_innerToolBarLayout->setSpacing(0);
}
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 699ea751bd..0bf371835d 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -482,7 +482,7 @@ public:
DebuggerMainWindow *mainWindow = DebuggerMainWindow::instance();
auto editorHolderLayout = new QVBoxLayout;
- editorHolderLayout->setMargin(0);
+ editorHolderLayout->setContentsMargins(0, 0, 0, 0);
editorHolderLayout->setSpacing(0);
auto editorAndFindWidget = new QWidget;
@@ -499,7 +499,7 @@ public:
auto centralEditorWidget = new QWidget;
auto centralLayout = new QVBoxLayout(centralEditorWidget);
centralEditorWidget->setLayout(centralLayout);
- centralLayout->setMargin(0);
+ centralLayout->setContentsMargins(0, 0, 0, 0);
centralLayout->setSpacing(0);
centralLayout->addWidget(documentAndRightPane);
centralLayout->setStretch(0, 1);
@@ -540,16 +540,6 @@ public:
//
///////////////////////////////////////////////////////////////////////
-QWidget *addSearch(BaseTreeView *treeView)
-{
- QAction *act = action(UseAlternatingRowColors);
- treeView->setAlternatingRowColors(act->isChecked());
- QObject::connect(act, &QAction::toggled,
- treeView, &BaseTreeView::setAlternatingRowColors);
-
- return ItemViewFind::createSearchableWrapper(treeView);
-}
-
static Kit::Predicate cdbPredicate(char wordWidth = 0)
{
return [wordWidth](const Kit *k) -> bool {
@@ -610,12 +600,14 @@ private:
QHash<unsigned, QString> m_debugInfoTasks;
};
+
///////////////////////////////////////////////////////////////////////
//
// DebuggerPluginPrivate
//
///////////////////////////////////////////////////////////////////////
+static DebuggerPlugin *m_instance = nullptr;
static DebuggerPluginPrivate *dd = nullptr;
/*!
@@ -632,36 +624,22 @@ static DebuggerPluginPrivate *dd = nullptr;
Implementation of DebuggerCore.
*/
-struct Callback
-{
- Callback()
- : cb([]{})
- {}
- Callback(void (DebuggerEngine::*func)())
- : cb([func] { if (DebuggerEngine *engine = EngineManager::currentEngine()) (engine->*func)(); })
- {}
-
- std::function<void()> cb;
-};
-
class DebuggerPluginPrivate : public QObject
{
Q_OBJECT
public:
- explicit DebuggerPluginPrivate(DebuggerPlugin *plugin);
+ explicit DebuggerPluginPrivate(const QStringList &arguments);
~DebuggerPluginPrivate() override;
- bool initialize(const QStringList &arguments, QString *errorMessage);
void extensionsInitialized();
void aboutToShutdown();
- void doShutdown();
RunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process, bool contAfterAttach);
void writeSettings()
{
- m_debuggerSettings->writeSettings();
+ m_debuggerSettings.writeSettings();
// writeWindowSettings();
}
@@ -722,6 +700,8 @@ public:
void parseCommandLineArguments();
void updatePresetState();
+ SavedAction *action(int code);
+ QWidget *addSearch(BaseTreeView *treeView);
public:
QPointer<DebugMode> m_mode;
@@ -750,21 +730,14 @@ public:
QAction m_breakAction{tr("Toggle Breakpoint")};
BreakpointManager m_breakpointManager;
- QPointer<BaseTreeView> m_breakpointManagerView;
- QPointer<QWidget> m_breakpointManagerWindow;
-
- QPointer<BaseTreeView> m_engineManagerView;
- QPointer<QWidget> m_engineManagerWindow;
- QPointer<GlobalLogWindow> m_globalLogWindow;
-
QString m_lastPermanentStatusMessage;
- DebuggerPlugin *m_plugin = nullptr;
-
EngineManager m_engineManager;
QTimer m_shutdownTimer;
bool m_shuttingDown = false;
- DebuggerSettings *m_debuggerSettings = nullptr;
+
+ Console m_console; // ensure Debugger Console is created before settings are taken into account
+ DebuggerSettings m_debuggerSettings;
QStringList m_arguments;
const QSharedPointer<GlobalDebuggerOptions> m_globalDebuggerOptions;
@@ -776,208 +749,39 @@ public:
Perspective m_perspective{Constants::PRESET_PERSPECTIVE_ID, tr("Debugger")};
DebuggerKitAspect debuggerKitAspect;
+
+ RunWorkerFactory debuggerWorkerFactory{
+ RunWorkerFactory::make<DebuggerRunTool>(),
+ {ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ {}, // All local run configs?
+ {PE::DESKTOP_DEVICE_TYPE}
+ };
+
+ // FIXME: Needed?
+// QString mainScript = runConfig->property("mainScript").toString();
+// const bool isDebuggableScript = mainScript.endsWith(".py"); // Only Python for now.
+// return isDebuggableScript;
};
-DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
+DebuggerPluginPrivate::DebuggerPluginPrivate(const QStringList &arguments)
: m_globalDebuggerOptions(new GlobalDebuggerOptions)
{
qRegisterMetaType<ContextData>("ContextData");
qRegisterMetaType<DebuggerRunParameters>("DebuggerRunParameters");
- QTC_CHECK(!dd);
- dd = this;
-
- m_plugin = plugin;
- debuggerConsole(); // ensure Debugger Console is created before settings are taken into account
-}
-
-DebuggerPluginPrivate::~DebuggerPluginPrivate()
-{
- destroyDebuggerConsole();
-
- qDeleteAll(m_optionPages);
- m_optionPages.clear();
-
- delete m_debuggerSettings;
- m_debuggerSettings = nullptr;
-}
-
-static QString msgParameterMissing(const QString &a)
-{
- return DebuggerPlugin::tr("Option \"%1\" is missing the parameter.").arg(a);
-}
-
-static Kit *guessKitFromAbis(const Abis &abis)
-{
- Kit *kit = nullptr;
-
- // Try to find a kit via ABI.
- if (!abis.isEmpty()) {
- // Try exact abis.
- kit = KitManager::kit([abis](const Kit *k) {
- const Abi tcAbi = ToolChainKitAspect::targetAbi(k);
- return abis.contains(tcAbi) && !DebuggerKitAspect::configurationErrors(k);
- });
- if (!kit) {
- // Or something compatible.
- kit = KitManager::kit([abis](const Kit *k) {
- const Abi tcAbi = ToolChainKitAspect::targetAbi(k);
- return !DebuggerKitAspect::configurationErrors(k)
- && Utils::contains(abis, [tcAbi](const Abi &a) { return a.isCompatibleWith(tcAbi); });
- });
- }
- }
-
- if (!kit)
- kit = KitManager::defaultKit();
-
- return kit;
-}
-
-bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
- const QStringList::const_iterator &cend, QString *errorMessage)
-{
- const QString &option = *it;
- // '-debug <pid>'
- // '-debug <exe>[,server=<server:port>][,core=<core>][,kit=<kit>][,terminal={0,1}]'
- if (*it == "-debug") {
- ++it;
- if (it == cend) {
- *errorMessage = msgParameterMissing(*it);
- return false;
- }
- const qulonglong pid = it->toULongLong();
- const QStringList args = it->split(',');
-
- Kit *kit = nullptr;
- DebuggerStartMode startMode = StartExternal;
- QString executable;
- QString remoteChannel;
- QString coreFile;
- bool useTerminal = false;
-
- if (!pid) {
- for (const QString &arg : args) {
- const QString key = arg.section('=', 0, 0);
- const QString val = arg.section('=', 1, 1);
- if (val.isEmpty()) {
- if (key.isEmpty()) {
- continue;
- } else if (executable.isEmpty()) {
- executable = key;
- } else {
- *errorMessage = DebuggerPlugin::tr("Only one executable allowed.");
- return false;
- }
- } else if (key == "kit") {
- kit = KitManager::kit(Id::fromString(val));
- if (!kit)
- kit = KitManager::kit(Utils::equal(&Kit::displayName, val));
- } else if (key == "server") {
- startMode = AttachToRemoteServer;
- remoteChannel = val;
- } else if (key == "core") {
- startMode = AttachCore;
- coreFile = val;
- } else if (key == "terminal") {
- useTerminal = true;
- }
- }
- }
- if (!kit)
- kit = guessKitFromAbis(Abi::abisOfBinary(FilePath::fromString(executable)));
-
- auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
- runControl->setKit(kit);
- auto debugger = new DebuggerRunTool(runControl);
- debugger->setInferiorExecutable(executable);
- if (pid) {
- debugger->setStartMode(AttachExternal);
- debugger->setCloseMode(DetachAtClose);
- debugger->setAttachPid(pid);
- debugger->setRunControlName(tr("Process %1").arg(pid));
- debugger->setStartMessage(tr("Attaching to local process %1.").arg(pid));
- } else if (startMode == AttachToRemoteServer) {
- debugger->setStartMode(AttachToRemoteServer);
- debugger->setRemoteChannel(remoteChannel);
- debugger->setRunControlName(tr("Remote: \"%1\"").arg(remoteChannel));
- debugger->setStartMessage(tr("Attaching to remote server %1.").arg(remoteChannel));
- } else if (startMode == AttachCore) {
- debugger->setStartMode(AttachCore);
- debugger->setCloseMode(DetachAtClose);
- debugger->setCoreFileName(coreFile);
- debugger->setRunControlName(tr("Core file \"%1\"").arg(coreFile));
- debugger->setStartMessage(tr("Attaching to core file %1.").arg(coreFile));
- } else {
- debugger->setStartMode(StartExternal);
- debugger->setRunControlName(tr("Executable file \"%1\"").arg(executable));
- debugger->setStartMessage(tr("Debugging file %1.").arg(executable));
- }
- debugger->setUseTerminal(useTerminal);
-
- m_scheduledStarts.append(debugger);
- return true;
- }
- // -wincrashevent <event-handle>:<pid>. A handle used for
- // a handshake when attaching to a crashed Windows process.
- // This is created by $QTC/src/tools/qtcdebugger/main.cpp:
- // args << "-wincrashevent"
- // << QString::fromLatin1("%1:%2").arg(argWinCrashEvent).arg(argProcessId);
- if (*it == "-wincrashevent") {
- ++it;
- if (it == cend) {
- *errorMessage = msgParameterMissing(*it);
- return false;
- }
- qint64 pid = it->section(':', 1, 1).toULongLong();
- auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
- runControl->setKit(findUniversalCdbKit());
- auto debugger = new DebuggerRunTool(runControl);
- debugger->setStartMode(AttachCrashedExternal);
- debugger->setCrashParameter(it->section(':', 0, 0));
- debugger->setAttachPid(pid);
- debugger->setRunControlName(tr("Crashed process %1").arg(pid));
- debugger->setStartMessage(tr("Attaching to crashed process %1").arg(pid));
- if (pid < 1) {
- *errorMessage = DebuggerPlugin::tr("The parameter \"%1\" of option \"%2\" "
- "does not match the pattern <handle>:<pid>.").arg(*it, option);
- return false;
- }
- m_scheduledStarts.append(debugger);
- return true;
- }
-
- *errorMessage = DebuggerPlugin::tr("Invalid debugger option: %1").arg(option);
- return false;
-}
-
-bool DebuggerPluginPrivate::parseArguments(const QStringList &args,
- QString *errorMessage)
-{
- const QStringList::const_iterator cend = args.constEnd();
- for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it)
- if (!parseArgument(it, cend, errorMessage))
- return false;
- return true;
-}
+ // Menu groups
+ ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
+ mstart->appendGroup(MENU_GROUP_GENERAL);
+ mstart->appendGroup(MENU_GROUP_SPECIAL);
+ mstart->appendGroup(MENU_GROUP_START_QML);
-void DebuggerPluginPrivate::parseCommandLineArguments()
-{
- QString errorMessage;
- if (!parseArguments(m_arguments, &errorMessage)) {
- errorMessage = tr("Error evaluating command line arguments: %1")
- .arg(errorMessage);
- qWarning("%s\n", qPrintable(errorMessage));
- MessageManager::write(errorMessage);
- }
- if (!m_scheduledStarts.isEmpty())
- QTimer::singleShot(0, this, &DebuggerPluginPrivate::runScheduled);
-}
+ // Separators
+ mstart->addSeparator(MENU_GROUP_GENERAL);
+ mstart->addSeparator(MENU_GROUP_SPECIAL);
-bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
- QString *errorMessage)
-{
- Q_UNUSED(errorMessage);
+ // Task integration.
+ //: Category under which Analyzer tasks are listed in Issues view
+ TaskHub::addCategory(ANALYZERTASK_ID, tr("Debugger"));
const Context debuggerNotRunning(C_DEBUGGER_NOTRUNNING);
ICore::addAdditionalContext(debuggerNotRunning);
@@ -1018,15 +822,10 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
act->setEnabled(false);
Command *cmd = ActionManager::registerAction(act, Constants::OPEN_MEMORY_EDITOR);
- TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_DEBUGINFO,
- tr("Debug Information"));
- TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_RUNTIME,
- tr("Debugger Runtime"));
-
- QSettings *settings = ICore::settings();
+ TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_DEBUGINFO, tr("Debug Information"));
+ TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_RUNTIME, tr("Debugger Runtime"));
- m_debuggerSettings = new DebuggerSettings;
- m_debuggerSettings->readSettings();
+ m_debuggerSettings.readSettings();
const auto addLabel = [](QWidget *widget, const QString &text) {
auto vbox = qobject_cast<QVBoxLayout *>(widget->layout());
@@ -1037,34 +836,50 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
vbox->insertWidget(0, label);
};
- m_breakpointManagerView = new BaseTreeView;
- m_breakpointManagerView->setActivationMode(Utils::DoubleClickActivation);
- m_breakpointManagerView->setIconSize(QSize(10, 10));
- m_breakpointManagerView->setWindowIcon(Icons::BREAKPOINTS.icon());
- m_breakpointManagerView->setSelectionMode(QAbstractItemView::ExtendedSelection);
- m_breakpointManagerView->setSettings(settings, "Debugger.BreakWindow");
- m_breakpointManagerView->setRootIsDecorated(true);
- m_breakpointManagerView->setModel(BreakpointManager::model());
- m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
- m_breakpointManagerWindow = addSearch(m_breakpointManagerView);
- m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset"));
- m_breakpointManagerWindow->setObjectName("Debugger.Docks.BreakpointManager");
- addLabel(m_breakpointManagerWindow, m_breakpointManagerWindow->windowTitle());
+ const auto addFontSizeAdaptation = [](QWidget *widget) {
+ QObject::connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,
+ [widget](const FontSettings &settings) {
+ if (!boolSetting(FontSizeFollowsEditor))
+ return;
+ qreal size = settings.fontZoom() * settings.fontSize() / 100.;
+ QFont font = widget->font();
+ font.setPointSizeF(size);
+ widget->setFont(font);
+ });
+ };
+ auto breakpointManagerView = new BaseTreeView;
+ breakpointManagerView->setActivationMode(Utils::DoubleClickActivation);
+ breakpointManagerView->setIconSize(QSize(10, 10));
+ breakpointManagerView->setWindowIcon(Icons::BREAKPOINTS.icon());
+ breakpointManagerView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ breakpointManagerView->setSettings(ICore::settings(), "Debugger.BreakWindow");
+ breakpointManagerView->setRootIsDecorated(true);
+ breakpointManagerView->setModel(BreakpointManager::model());
+ breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
+
+ auto breakpointManagerWindow = addSearch(breakpointManagerView);
+ breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset"));
+ breakpointManagerWindow->setObjectName("Debugger.Docks.BreakpointManager");
+ addLabel(breakpointManagerWindow, breakpointManagerWindow->windowTitle());
+ addFontSizeAdaptation(breakpointManagerWindow);
// Snapshot
- m_engineManagerView = new BaseTreeView;
- m_engineManagerView->setWindowTitle(tr("Running Debuggers"));
- m_engineManagerView->setSettings(settings, "Debugger.SnapshotView");
- m_engineManagerView->setIconSize(QSize(10, 10));
- m_engineManagerView->setModel(m_engineManager.model());
- m_engineManagerWindow = addSearch(m_engineManagerView);
- m_engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));
- m_engineManagerWindow->setObjectName("Debugger.Docks.Snapshots");
- addLabel(m_engineManagerWindow, m_engineManagerWindow->windowTitle());
+ auto engineManagerView = new BaseTreeView;
+ engineManagerView->setWindowTitle(tr("Running Debuggers"));
+ engineManagerView->setSettings(ICore::settings(), "Debugger.SnapshotView");
+ engineManagerView->setIconSize(QSize(10, 10));
+ engineManagerView->setModel(m_engineManager.model());
+
+ auto engineManagerWindow = addSearch(engineManagerView);
+ engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));
+ engineManagerWindow->setObjectName("Debugger.Docks.Snapshots");
+ addLabel(engineManagerWindow, engineManagerWindow->windowTitle());
+ addFontSizeAdaptation(engineManagerWindow);
// Logging
- m_globalLogWindow = new GlobalLogWindow;
+ auto globalLogWindow = new GlobalLogWindow;
+ addFontSizeAdaptation(globalLogWindow);
ActionContainer *debugMenu = ActionManager::actionContainer(PE::M_DEBUG);
@@ -1107,10 +922,8 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
// MENU_GROUP_START_REMOTE
// MENU_GROUP_START_QML
- ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
const QKeySequence startShortcut(useMacShortcuts ? tr("Ctrl+Y") : tr("F5"));
-
cmd = ActionManager::registerAction(&m_visibleStartAction, "Debugger.Debug");
cmd->setDescription(tr("Start Debugging or Continue"));
@@ -1389,20 +1202,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
connect(ICore::instance(), &ICore::saveSettingsRequested,
this, &DebuggerPluginPrivate::writeSettings);
- // TextEditor
- connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,
- [this](const FontSettings &settings) {
- if (!boolSetting(FontSizeFollowsEditor))
- return;
- qreal size = settings.fontZoom() * settings.fontSize() / 100.;
- QFont font = m_breakpointManagerWindow->font();
- font.setPointSizeF(size);
- m_breakpointManagerWindow->setFont(font);
- m_globalLogWindow->setFont(font);
- m_engineManagerWindow->setFont(font);
- });
-
-
// ProjectExplorer
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
this, &DebuggerPluginPrivate::updatePresetState);
@@ -1420,9 +1219,9 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
m_perspective.useSubPerspectiveSwitcher(EngineManager::engineChooser());
m_perspective.addToolBarAction(&m_startAction);
- m_perspective.addWindow(m_engineManagerWindow, Perspective::SplitVertical, nullptr);
- m_perspective.addWindow(m_breakpointManagerWindow, Perspective::SplitHorizontal, m_engineManagerWindow);
- m_perspective.addWindow(m_globalLogWindow, Perspective::AddToTab, nullptr, false, Qt::TopDockWidgetArea);
+ m_perspective.addWindow(engineManagerWindow, Perspective::SplitVertical, nullptr);
+ m_perspective.addWindow(breakpointManagerWindow, Perspective::SplitHorizontal, engineManagerWindow);
+ m_perspective.addWindow(globalLogWindow, Perspective::AddToTab, nullptr, false, Qt::TopDockWidgetArea);
setInitialState();
@@ -1436,16 +1235,193 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
m_optionPages.append(new CommonOptionsPage(m_globalDebuggerOptions));
m_globalDebuggerOptions->fromSettings();
+}
+
+DebuggerPluginPrivate::~DebuggerPluginPrivate()
+{
+ qDeleteAll(m_optionPages);
+ m_optionPages.clear();
+}
+
+static QString msgParameterMissing(const QString &a)
+{
+ return DebuggerPlugin::tr("Option \"%1\" is missing the parameter.").arg(a);
+}
+
+static Kit *guessKitFromAbis(const Abis &abis)
+{
+ Kit *kit = nullptr;
+
+ // Try to find a kit via ABI.
+ if (!abis.isEmpty()) {
+ // Try exact abis.
+ kit = KitManager::kit([abis](const Kit *k) {
+ const Abi tcAbi = ToolChainKitAspect::targetAbi(k);
+ return abis.contains(tcAbi) && !DebuggerKitAspect::configurationErrors(k);
+ });
+ if (!kit) {
+ // Or something compatible.
+ kit = KitManager::kit([abis](const Kit *k) {
+ const Abi tcAbi = ToolChainKitAspect::targetAbi(k);
+ return !DebuggerKitAspect::configurationErrors(k)
+ && Utils::contains(abis, [tcAbi](const Abi &a) { return a.isCompatibleWith(tcAbi); });
+ });
+ }
+ }
+
+ if (!kit)
+ kit = KitManager::defaultKit();
+
+ return kit;
+}
+
+bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
+ const QStringList::const_iterator &cend, QString *errorMessage)
+{
+ const QString &option = *it;
+ // '-debug <pid>'
+ // '-debug <exe>[,server=<server:port>][,core=<core>][,kit=<kit>][,terminal={0,1}]'
+ if (*it == "-debug") {
+ ++it;
+ if (it == cend) {
+ *errorMessage = msgParameterMissing(*it);
+ return false;
+ }
+ const qulonglong pid = it->toULongLong();
+ const QStringList args = it->split(',');
+
+ Kit *kit = nullptr;
+ DebuggerStartMode startMode = StartExternal;
+ FilePath executable;
+ QString remoteChannel;
+ QString coreFile;
+ bool useTerminal = false;
+
+ if (!pid) {
+ for (const QString &arg : args) {
+ const QString key = arg.section('=', 0, 0);
+ const QString val = arg.section('=', 1, 1);
+ if (val.isEmpty()) {
+ if (key.isEmpty()) {
+ continue;
+ } else if (executable.isEmpty()) {
+ executable = FilePath::fromString(key);
+ } else {
+ *errorMessage = DebuggerPlugin::tr("Only one executable allowed.");
+ return false;
+ }
+ } else if (key == "kit") {
+ kit = KitManager::kit(Id::fromString(val));
+ if (!kit)
+ kit = KitManager::kit(Utils::equal(&Kit::displayName, val));
+ } else if (key == "server") {
+ startMode = AttachToRemoteServer;
+ remoteChannel = val;
+ } else if (key == "core") {
+ startMode = AttachCore;
+ coreFile = val;
+ } else if (key == "terminal") {
+ useTerminal = true;
+ }
+ }
+ }
+ if (!kit)
+ kit = guessKitFromAbis(Abi::abisOfBinary(executable));
+
+ auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
+ runControl->setKit(kit);
+ auto debugger = new DebuggerRunTool(runControl);
+ debugger->setInferiorExecutable(executable);
+ if (pid) {
+ debugger->setStartMode(AttachExternal);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setAttachPid(pid);
+ debugger->setRunControlName(tr("Process %1").arg(pid));
+ debugger->setStartMessage(tr("Attaching to local process %1.").arg(pid));
+ } else if (startMode == AttachToRemoteServer) {
+ debugger->setStartMode(AttachToRemoteServer);
+ debugger->setRemoteChannel(remoteChannel);
+ debugger->setRunControlName(tr("Remote: \"%1\"").arg(remoteChannel));
+ debugger->setStartMessage(tr("Attaching to remote server %1.").arg(remoteChannel));
+ } else if (startMode == AttachCore) {
+ debugger->setStartMode(AttachCore);
+ debugger->setCloseMode(DetachAtClose);
+ debugger->setCoreFileName(coreFile);
+ debugger->setRunControlName(tr("Core file \"%1\"").arg(coreFile));
+ debugger->setStartMessage(tr("Attaching to core file %1.").arg(coreFile));
+ } else {
+ debugger->setStartMode(StartExternal);
+ debugger->setRunControlName(tr("Executable file \"%1\"").arg(executable.toUserOutput()));
+ debugger->setStartMessage(tr("Debugging file %1.").arg(executable.toUserOutput()));
+ }
+ debugger->setUseTerminal(useTerminal);
+
+ m_scheduledStarts.append(debugger);
+ return true;
+ }
+ // -wincrashevent <event-handle>:<pid>. A handle used for
+ // a handshake when attaching to a crashed Windows process.
+ // This is created by $QTC/src/tools/qtcdebugger/main.cpp:
+ // args << "-wincrashevent"
+ // << QString::fromLatin1("%1:%2").arg(argWinCrashEvent).arg(argProcessId);
+ if (*it == "-wincrashevent") {
+ ++it;
+ if (it == cend) {
+ *errorMessage = msgParameterMissing(*it);
+ return false;
+ }
+ qint64 pid = it->section(':', 1, 1).toULongLong();
+ auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
+ runControl->setKit(findUniversalCdbKit());
+ auto debugger = new DebuggerRunTool(runControl);
+ debugger->setStartMode(AttachCrashedExternal);
+ debugger->setCrashParameter(it->section(':', 0, 0));
+ debugger->setAttachPid(pid);
+ debugger->setRunControlName(tr("Crashed process %1").arg(pid));
+ debugger->setStartMessage(tr("Attaching to crashed process %1").arg(pid));
+ if (pid < 1) {
+ *errorMessage = DebuggerPlugin::tr("The parameter \"%1\" of option \"%2\" "
+ "does not match the pattern <handle>:<pid>.").arg(*it, option);
+ return false;
+ }
+ m_scheduledStarts.append(debugger);
+ return true;
+ }
+
+ *errorMessage = DebuggerPlugin::tr("Invalid debugger option: %1").arg(option);
+ return false;
+}
+
+bool DebuggerPluginPrivate::parseArguments(const QStringList &args,
+ QString *errorMessage)
+{
+ const QStringList::const_iterator cend = args.constEnd();
+ for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it)
+ if (!parseArgument(it, cend, errorMessage))
+ return false;
return true;
}
-void setConfigValue(const QString &name, const QVariant &value)
+void DebuggerPluginPrivate::parseCommandLineArguments()
+{
+ QString errorMessage;
+ if (!parseArguments(m_arguments, &errorMessage)) {
+ errorMessage = tr("Error evaluating command line arguments: %1")
+ .arg(errorMessage);
+ qWarning("%s\n", qPrintable(errorMessage));
+ MessageManager::write(errorMessage);
+ }
+ if (!m_scheduledStarts.isEmpty())
+ QTimer::singleShot(0, this, &DebuggerPluginPrivate::runScheduled);
+}
+
+static void setConfigValue(const QString &name, const QVariant &value)
{
ICore::settings()->setValue("DebugMode/" + name, value);
}
-QVariant configValue(const QString &name)
+static QVariant configValue(const QString &name)
{
return ICore::settings()->value("DebugMode/" + name);
}
@@ -1588,7 +1564,7 @@ void DebuggerPluginPrivate::attachCore()
if (dlg.exec() != QDialog::Accepted)
return;
- setConfigValue("LastExternalExecutableFile", dlg.symbolFile());
+ setConfigValue("LastExternalExecutableFile", dlg.symbolFile().toVariant());
setConfigValue("LastLocalCoreFile", dlg.localCoreFile());
setConfigValue("LastRemoteCoreFile", dlg.remoteCoreFile());
setConfigValue("LastExternalKit", dlg.kit()->id().toSetting());
@@ -1640,11 +1616,9 @@ public:
{
setId("AttachToRunningProcess");
setUsePortsGatherer(true, false);
- portsGatherer()->setDevice(runControl->device());
auto gdbServer = new GdbServerRunner(runControl, portsGatherer());
gdbServer->setUseMulti(false);
- gdbServer->setDevice(runControl->device());
gdbServer->setAttachPid(ProcessHandle(pid));
addStartDependency(gdbServer);
@@ -1660,7 +1634,8 @@ public:
void DebuggerPluginPrivate::attachToRunningApplication()
{
- auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
+ auto kitChooser = new KitChooser;
+ kitChooser->setShowIcons(true);
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
@@ -1743,7 +1718,7 @@ RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
runControl->setDisplayName(tr("Process %1").arg(process.pid));
auto debugger = new DebuggerRunTool(runControl);
debugger->setAttachPid(ProcessHandle(process.pid));
- debugger->setInferiorExecutable(process.exe);
+ debugger->setInferiorExecutable(FilePath::fromString(process.exe));
debugger->setInferiorDevice(device);
debugger->setStartMode(AttachExternal);
debugger->setCloseMode(DetachAtClose);
@@ -2022,7 +1997,17 @@ void DebuggerPluginPrivate::aboutToShutdown()
m_shutdownTimer.setInterval(0);
m_shutdownTimer.setSingleShot(true);
- connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);
+
+ connect(&m_shutdownTimer, &QTimer::timeout, this, [this] {
+ DebuggerMainWindow::doShutdown();
+
+ m_shutdownTimer.stop();
+
+ delete m_mode;
+ m_mode = nullptr;
+ emit m_instance->asynchronousShutdownFinished();
+ });
+
if (EngineManager::shutDown()) {
// If any engine is aborting we give them extra three seconds.
m_shutdownTimer.setInterval(3000);
@@ -2053,8 +2038,7 @@ void DebuggerPluginPrivate::remoteCommand(const QStringList &options)
runScheduled();
}
-QMessageBox *showMessageBox(int icon, const QString &title,
- const QString &text, int buttons)
+QMessageBox *showMessageBox(int icon, const QString &title, const QString &text, int buttons)
{
QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
title, text, QMessageBox::StandardButtons(buttons),
@@ -2086,44 +2070,51 @@ void DebuggerPluginPrivate::extensionsInitialized()
}
}
- auto constraint = [](RunConfiguration *runConfig) {
- Runnable runnable = runConfig->runnable();
- if (runnable.device && runnable.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
- return true;
+ DebuggerMainWindow::ensureMainWindowExists();
+}
- if (DeviceTypeKitAspect::deviceTypeId(runConfig->target()->kit())
- == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
- return true;
+SavedAction *DebuggerPluginPrivate::action(int code)
+{
+ return m_debuggerSettings.item(code);
+}
- QString mainScript = runConfig->property("mainScript").toString();
- const bool isDebuggableScript = mainScript.endsWith(".py"); // Only Python for now.
- return isDebuggableScript;
- };
+QWidget *DebuggerPluginPrivate::addSearch(BaseTreeView *treeView)
+{
+ QAction *act = action(UseAlternatingRowColors);
+ treeView->setAlternatingRowColors(act->isChecked());
+ connect(act, &QAction::toggled, treeView, &BaseTreeView::setAlternatingRowColors);
- RunControl::registerWorker<DebuggerRunTool>
- (ProjectExplorer::Constants::DEBUG_RUN_MODE, constraint);
+ return ItemViewFind::createSearchableWrapper(treeView);
+}
- DebuggerMainWindow::ensureMainWindowExists();
+Console *debuggerConsole()
+{
+ return &dd->m_console;
}
SavedAction *action(int code)
{
- return dd->m_debuggerSettings->item(code);
+ return dd->action(code);
+}
+
+QWidget *addSearch(BaseTreeView *treeView)
+{
+ return dd->addSearch(treeView);
}
bool boolSetting(int code)
{
- return dd->m_debuggerSettings->item(code)->value().toBool();
+ return action(code)->value().toBool();
}
QString stringSetting(int code)
{
- return dd->m_debuggerSettings->item(code)->value().toString();
+ return action(code)->value().toString();
}
QStringList stringListSetting(int code)
{
- return dd->m_debuggerSettings->item(code)->value().toStringList();
+ return action(code)->value().toStringList();
}
void showModuleSymbols(const QString &moduleName, const Symbols &symbols)
@@ -2184,17 +2175,6 @@ void showModuleSections(const QString &moduleName, const Sections &sections)
createNewDock(w);
}
-void DebuggerPluginPrivate::doShutdown()
-{
- DebuggerMainWindow::doShutdown();
-
- m_shutdownTimer.stop();
-
- delete m_mode;
- m_mode = nullptr;
- emit m_plugin->asynchronousShutdownFinished();
-}
-
void openTextEditor(const QString &titlePattern0, const QString &contents)
{
if (dd->m_shuttingDown)
@@ -2232,8 +2212,6 @@ QSharedPointer<Internal::GlobalDebuggerOptions> globalDebuggerOptions()
is DebuggerCore, implemented in DebuggerPluginPrivate.
*/
-static DebuggerPlugin *m_instance = nullptr;
-
DebuggerPlugin::DebuggerPlugin()
{
setObjectName("DebuggerPlugin");
@@ -2247,33 +2225,15 @@ DebuggerPlugin::~DebuggerPlugin()
m_instance = nullptr;
}
-DebuggerPlugin *DebuggerPlugin::instance()
-{
- return m_instance;
-}
-
bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- dd = new DebuggerPluginPrivate(this);
+ Q_UNUSED(errorMessage)
// Needed for call from AppOutputPane::attachToRunControl() and GammarayIntegration.
ExtensionSystem::PluginManager::addObject(this);
- // Menu groups
- ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
- mstart->appendGroup(MENU_GROUP_GENERAL);
- mstart->appendGroup(MENU_GROUP_SPECIAL);
- mstart->appendGroup(MENU_GROUP_START_QML);
-
- // Separators
- mstart->addSeparator(MENU_GROUP_GENERAL);
- mstart->addSeparator(MENU_GROUP_SPECIAL);
-
- // Task integration.
- //: Category under which Analyzer tasks are listed in Issues view
- ProjectExplorer::TaskHub::addCategory(Debugger::Constants::ANALYZERTASK_ID, tr("Debugger"));
-
- return dd->initialize(arguments, errorMessage);
+ dd = new DebuggerPluginPrivate(arguments);
+ return true;
}
IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
@@ -2287,8 +2247,8 @@ QObject *DebuggerPlugin::remoteCommand(const QStringList &options,
const QString &workingDirectory,
const QStringList &list)
{
- Q_UNUSED(workingDirectory);
- Q_UNUSED(list);
+ Q_UNUSED(workingDirectory)
+ Q_UNUSED(list)
dd->remoteCommand(options);
return nullptr;
}
@@ -2401,7 +2361,7 @@ bool wantRunTool(ToolMode toolMode, const QString &toolName)
QAction *createStartAction()
{
- auto action = new QAction(DebuggerMainWindow::tr("Start"), DebuggerPlugin::instance());
+ auto action = new QAction(DebuggerMainWindow::tr("Start"), m_instance);
action->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR.icon());
action->setEnabled(true);
return action;
@@ -2409,7 +2369,7 @@ QAction *createStartAction()
QAction *createStopAction()
{
- auto action = new QAction(DebuggerMainWindow::tr("Stop"), DebuggerPlugin::instance());
+ auto action = new QAction(DebuggerMainWindow::tr("Stop"), m_instance);
action->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon());
action->setEnabled(true);
return action;
@@ -2420,11 +2380,6 @@ void enableMainWindow(bool on)
DebuggerMainWindow::instance()->setEnabled(on);
}
-void showStatusMessage(const QString &message, int timeoutMS)
-{
- DebuggerMainWindow::showStatusMessage(message, timeoutMS);
-}
-
void showPermanentStatusMessage(const QString &message)
{
DebuggerMainWindow::showStatusMessage(message, -1);
diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h
index 45050f7c4d..b45f538cde 100644
--- a/src/plugins/debugger/debuggerplugin.h
+++ b/src/plugins/debugger/debuggerplugin.h
@@ -42,8 +42,6 @@ public:
DebuggerPlugin();
~DebuggerPlugin() override;
- static DebuggerPlugin *instance();
-
private:
// IPlugin implementation.
bool initialize(const QStringList &arguments, QString *errorMessage) override;
diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp
index d01e82f649..cb9302211b 100644
--- a/src/plugins/debugger/debuggerprotocol.cpp
+++ b/src/plugins/debugger/debuggerprotocol.cpp
@@ -457,7 +457,13 @@ void extractGdbVersion(const QString &msg,
QString build;
bool inClean = true;
bool inParenthesis = false;
- for (QChar c : msg) {
+
+ int gdbMsgBegin = msg.indexOf("GNU gdb");
+ if (gdbMsgBegin == -1)
+ gdbMsgBegin = 0;
+
+ for (int i = gdbMsgBegin, gdbMsgSize = msg.size(); i < gdbMsgSize; ++i) {
+ QChar c = msg.at(i);
if (inClean && !cleaned.isEmpty() && c != dot && (c.isPunct() || c.isSpace()))
inClean = false;
if (ignoreParenthesisContent) {
diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
index 161c755d10..baae994a13 100644
--- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
+++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp
@@ -127,7 +127,7 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(DebuggerRunConfigurationAspect
this, &DebuggerRunConfigWidget::useMultiProcessToggled);
auto qmlLayout = new QHBoxLayout;
- qmlLayout->setMargin(0);
+ qmlLayout->setContentsMargins(0, 0, 0, 0);
qmlLayout->addWidget(m_useQmlDebugger);
qmlLayout->addWidget(m_debugServerPortLabel);
qmlLayout->addWidget(m_debugServerPort);
@@ -135,7 +135,7 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(DebuggerRunConfigurationAspect
qmlLayout->addStretch();
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_useCppDebugger);
layout->addLayout(qmlLayout);
layout->addWidget(m_useMultiProcess);
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index f68d637e1f..86c8119d9b 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -23,6 +23,7 @@
**
****************************************************************************/
+#include "debuggermainwindow.h"
#include "debuggerruncontrol.h"
#include "terminal.h"
@@ -316,7 +317,7 @@ void DebuggerRunTool::setSysRoot(const Utils::FilePath &sysRoot)
m_runParameters.sysRoot = sysRoot;
}
-void DebuggerRunTool::setSymbolFile(const QString &symbolFile)
+void DebuggerRunTool::setSymbolFile(const FilePath &symbolFile)
{
if (symbolFile.isEmpty())
reportFailure(tr("Cannot debug: Local executable is not set."));
@@ -404,8 +405,8 @@ void DebuggerRunTool::setServerStartScript(const FilePath &serverStartScript)
{
if (!serverStartScript.isEmpty()) {
// Provide script information about the environment
- CommandLine serverStarter(serverStartScript, {});
- serverStarter.addArgs({m_runParameters.inferior.executable, m_runParameters.remoteChannel});
+ const CommandLine serverStarter(serverStartScript,
+ {m_runParameters.inferior.executable.toString(), m_runParameters.remoteChannel});
addStartDependency(new LocalProcessRunner(this, serverStarter));
}
}
@@ -445,12 +446,17 @@ void DebuggerRunTool::setOverrideStartScript(const QString &script)
m_runParameters.overrideStartScript = script;
}
+void DebuggerRunTool::setAbi(const Abi &abi)
+{
+ m_runParameters.toolChainAbi = abi;
+}
+
void DebuggerRunTool::setInferior(const Runnable &runnable)
{
m_runParameters.inferior = runnable;
}
-void DebuggerRunTool::setInferiorExecutable(const QString &executable)
+void DebuggerRunTool::setInferiorExecutable(const FilePath &executable)
{
m_runParameters.inferior.executable = executable;
}
@@ -486,20 +492,6 @@ void DebuggerRunTool::setCoreFileName(const QString &coreFile, bool isSnapshot)
m_runParameters.isSnapshot = isSnapshot;
}
-void DebuggerRunTool::appendInferiorCommandLineArgument(const QString &arg)
-{
- QtcProcess::addArg(&m_runParameters.inferior.commandLineArguments, arg,
- device() ? device()->osType() : HostOsInfo::hostOs());
-}
-
-void DebuggerRunTool::prependInferiorCommandLineArgument(const QString &arg)
-{
- if (!m_runParameters.inferior.commandLineArguments.isEmpty())
- m_runParameters.inferior.commandLineArguments.prepend(' ');
- m_runParameters.inferior.commandLineArguments.prepend(
- QtcProcess::quoteArg(arg, device() ? device()->osType() : HostOsInfo::hostOs()));
-}
-
void DebuggerRunTool::addQmlServerInferiorCommandLineArgumentIfNeeded()
{
d->addQmlServerInferiorCommandLineArgumentIfNeeded = true;
@@ -531,12 +523,16 @@ void DebuggerRunTool::start()
if (d->addQmlServerInferiorCommandLineArgumentIfNeeded
&& m_runParameters.isQmlDebugging
&& m_runParameters.isCppDebugging()) {
- using namespace QmlDebug;
+
int qmlServerPort = m_runParameters.qmlServer.port();
QTC_ASSERT(qmlServerPort > 0, reportFailure(); return);
QString mode = QString("port:%1").arg(qmlServerPort);
- QString qmlServerArg = qmlDebugCommandLineArguments(QmlDebuggerServices, mode, true);
- prependInferiorCommandLineArgument(qmlServerArg);
+
+ CommandLine cmd{m_runParameters.inferior.executable};
+ cmd.addArg(qmlDebugCommandLineArguments(QmlDebug::QmlDebuggerServices, mode, true));
+ cmd.addArgs(m_runParameters.inferior.commandLineArguments, CommandLine::Raw);
+
+ m_runParameters.inferior.setCommandLine(cmd);
}
}
@@ -565,19 +561,19 @@ void DebuggerRunTool::start()
return;
if (m_runParameters.cppEngineType == CdbEngineType
- && Utils::is64BitWindowsBinary(m_runParameters.inferior.executable)
- && !Utils::is64BitWindowsBinary(m_runParameters.debugger.executable)) {
+ && Utils::is64BitWindowsBinary(m_runParameters.inferior.executable.toString())
+ && !Utils::is64BitWindowsBinary(m_runParameters.debugger.executable.toString())) {
reportFailure(
DebuggerPlugin::tr(
"%1 is a 64 bit executable which can not be debugged by a 32 bit Debugger.\n"
"Please select a 64 bit Debugger in the kit settings for this kit.")
- .arg(m_runParameters.inferior.executable));
+ .arg(m_runParameters.inferior.executable.toUserOutput()));
return;
}
Utils::globalMacroExpander()->registerFileVariables(
"DebuggedExecutable", tr("Debugged executable"),
- [this] { return m_runParameters.inferior.executable; }
+ [this] { return m_runParameters.inferior.executable.toString(); }
);
runControl()->setDisplayName(m_runParameters.displayName);
@@ -706,9 +702,10 @@ void DebuggerRunTool::start()
QString debuggerName = m_engine->objectName();
if (m_engine2)
debuggerName += ' ' + m_engine2->objectName();
+
const QString message = tr("Starting debugger \"%1\" for ABI \"%2\"...")
.arg(debuggerName).arg(m_runParameters.toolChainAbi.toString());
- showStatusMessage(message);
+ DebuggerMainWindow::showStatusMessage(message, 10000);
showMessage(m_engine->formatStartParameters(), LogDebug);
showMessage(DebuggerSettings::dump(), LogDebug);
@@ -794,7 +791,7 @@ bool DebuggerRunTool::fixupParameters()
for (const auto &var :
QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"}))
if (rp.inferior.environment.hasKey(var))
- rp.debugger.environment.set(var, rp.inferior.environment.value(var));
+ rp.debugger.environment.set(var, rp.inferior.environment.expandedValueForKey(var));
// validate debugger if C++ debugging is enabled
if (rp.isCppDebugging() && !rp.validationErrors.isEmpty()) {
@@ -845,7 +842,7 @@ bool DebuggerRunTool::fixupParameters()
if (rp.startMode != AttachExternal && rp.startMode != AttachCrashedExternal) {
QString qmlarg = rp.isCppDebugging() && rp.nativeMixedEnabled
? QmlDebug::qmlDebugNativeArguments(service, false)
- : QmlDebug::qmlDebugTcpArguments(service, Port(rp.qmlServer.port()));
+ : QmlDebug::qmlDebugTcpArguments(service, rp.qmlServer);
QtcProcess::addArg(&rp.inferior.commandLineArguments, qmlarg);
}
}
@@ -911,7 +908,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
m_runParameters.displayName = runControl->displayName();
if (auto symbolsAspect = runControl->aspect<SymbolFileAspect>())
- m_runParameters.symbolFile = symbolsAspect->value();
+ m_runParameters.symbolFile = symbolsAspect->filePath();
if (auto terminalAspect = runControl->aspect<TerminalAspect>())
m_runParameters.useTerminal = terminalAspect->useTerminal();
@@ -941,7 +938,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
if (!envBinary.isEmpty())
- m_runParameters.debugger.executable = QString::fromLocal8Bit(envBinary);
+ m_runParameters.debugger.executable = FilePath::fromString(QString::fromLocal8Bit(envBinary));
if (Project *project = runControl->project()) {
m_runParameters.projectSourceDirectory = project->projectDirectory();
@@ -1043,55 +1040,70 @@ GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl)
: ChannelProvider(runControl, 2)
{
setId("GdbServerPortsGatherer");
- m_device = runControl->device();
}
GdbServerPortsGatherer::~GdbServerPortsGatherer() = default;
-Port GdbServerPortsGatherer::gdbServerPort() const
-{
- QUrl url = channel(0);
- return Port(url.port());
-}
-
QUrl GdbServerPortsGatherer::gdbServer() const
{
return channel(0);
}
-Port GdbServerPortsGatherer::qmlServerPort() const
-{
- QUrl url = channel(1);
- return Port(url.port());
-}
-
QUrl GdbServerPortsGatherer::qmlServer() const
{
return channel(1);
}
-void GdbServerPortsGatherer::setDevice(IDevice::ConstPtr device)
-{
- m_device = device;
-}
-
// GdbServerRunner
GdbServerRunner::GdbServerRunner(RunControl *runControl, GdbServerPortsGatherer *portsGatherer)
- : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
+ : SimpleTargetRunner(runControl)
{
setId("GdbServerRunner");
- m_runnable = runControl->runnable();
- addStartDependency(m_portsGatherer);
-}
+ const Runnable mainRunnable = runControl->runnable();
+ addStartDependency(portsGatherer);
-GdbServerRunner::~GdbServerRunner() = default;
+ QTC_ASSERT(portsGatherer, reportFailure(); return);
-void GdbServerRunner::setRunnable(const Runnable &runnable)
-{
- m_runnable = runnable;
+ setStarter([this, runControl, mainRunnable, portsGatherer] {
+ QTC_ASSERT(portsGatherer, reportFailure(); return);
+
+ Runnable gdbserver;
+ gdbserver.environment = mainRunnable.environment;
+ gdbserver.workingDirectory = mainRunnable.workingDirectory;
+
+ QStringList args = QtcProcess::splitArgs(mainRunnable.commandLineArguments, OsTypeLinux);
+
+ const bool isQmlDebugging = portsGatherer->useQmlServer();
+ const bool isCppDebugging = portsGatherer->useGdbServer();
+
+ if (isQmlDebugging) {
+ args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
+ portsGatherer->qmlServer()));
+ }
+ if (isQmlDebugging && !isCppDebugging) {
+ gdbserver.executable = mainRunnable.executable; // FIXME: Case should not happen?
+ } else {
+ gdbserver.executable = FilePath::fromString(runControl->device()->debugServerPath());
+ if (gdbserver.executable.isEmpty())
+ gdbserver.executable = FilePath::fromString("gdbserver");
+ args.clear();
+ if (m_useMulti)
+ args.append("--multi");
+ if (m_pid.isValid())
+ args.append("--attach");
+ args.append(QString(":%1").arg(portsGatherer->gdbServer().port()));
+ if (m_pid.isValid())
+ args.append(QString::number(m_pid.pid()));
+ }
+ gdbserver.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
+
+ doStart(gdbserver, runControl->device());
+ });
}
+GdbServerRunner::~GdbServerRunner() = default;
+
void GdbServerRunner::setUseMulti(bool on)
{
m_useMulti = on;
@@ -1102,42 +1114,4 @@ void GdbServerRunner::setAttachPid(ProcessHandle pid)
m_pid = pid;
}
-void GdbServerRunner::start()
-{
- QTC_ASSERT(m_portsGatherer, reportFailure(); return);
-
- Runnable gdbserver;
- gdbserver.environment = m_runnable.environment;
- gdbserver.workingDirectory = m_runnable.workingDirectory;
-
- QStringList args = QtcProcess::splitArgs(m_runnable.commandLineArguments, OsTypeLinux);
-
- const bool isQmlDebugging = m_portsGatherer->useQmlServer();
- const bool isCppDebugging = m_portsGatherer->useGdbServer();
-
- if (isQmlDebugging) {
- args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
- m_portsGatherer->qmlServerPort()));
- }
- if (isQmlDebugging && !isCppDebugging) {
- gdbserver.executable = m_runnable.executable; // FIXME: Case should not happen?
- } else {
- gdbserver.executable = device()->debugServerPath();
- if (gdbserver.executable.isEmpty())
- gdbserver.executable = "gdbserver";
- args.clear();
- if (m_useMulti)
- args.append("--multi");
- if (m_pid.isValid())
- args.append("--attach");
- args.append(QString(":%1").arg(m_portsGatherer->gdbServerPort().number()));
- if (m_pid.isValid())
- args.append(QString::number(m_pid.pid()));
- }
- gdbserver.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
-
- SimpleTargetRunner::setRunnable(gdbserver);
- SimpleTargetRunner::start();
-}
-
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h
index f5512dd991..e546cdafcf 100644
--- a/src/plugins/debugger/debuggerruncontrol.h
+++ b/src/plugins/debugger/debuggerruncontrol.h
@@ -72,13 +72,11 @@ public:
static void setBreakOnMainNextTime();
void setInferior(const ProjectExplorer::Runnable &runnable);
- void setInferiorExecutable(const QString &executable);
+ void setInferiorExecutable(const Utils::FilePath &executable);
void setInferiorEnvironment(const Utils::Environment &env); // Used by GammaRay plugin
void setInferiorDevice(ProjectExplorer::IDevice::ConstPtr device); // Used by cdbengine
void setRunControlName(const QString &name);
void setStartMessage(const QString &msg);
- void appendInferiorCommandLineArgument(const QString &arg);
- void prependInferiorCommandLineArgument(const QString &arg);
void addQmlServerInferiorCommandLineArgumentIfNeeded();
void setCrashParameter(const QString &event);
@@ -93,7 +91,7 @@ public:
void setAttachPid(qint64 pid);
void setSysRoot(const Utils::FilePath &sysRoot);
- void setSymbolFile(const QString &symbolFile);
+ void setSymbolFile(const Utils::FilePath &symbolFile);
void setRemoteChannel(const QString &channel);
void setRemoteChannel(const QString &host, int port);
void setRemoteChannel(const QUrl &url);
@@ -124,6 +122,8 @@ public:
void setTestCase(int testCase);
void setOverrideStartScript(const QString &script);
+ void setAbi(const ProjectExplorer::Abi &abi);
+
Internal::TerminalRunner *terminalRunner() const;
private:
@@ -147,20 +147,15 @@ public:
void setUseGdbServer(bool useIt) { m_useGdbServer = useIt; }
bool useGdbServer() const { return m_useGdbServer; }
- Utils::Port gdbServerPort() const;
QUrl gdbServer() const;
void setUseQmlServer(bool useIt) { m_useQmlServer = useIt; }
bool useQmlServer() const { return m_useQmlServer; }
- Utils::Port qmlServerPort() const;
QUrl qmlServer() const;
- void setDevice(ProjectExplorer::IDevice::ConstPtr device);
-
private:
bool m_useGdbServer = false;
bool m_useQmlServer = false;
- ProjectExplorer::IDevice::ConstPtr m_device;
};
class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::SimpleTargetRunner
@@ -173,15 +168,10 @@ public:
~GdbServerRunner() override;
- void setRunnable(const ProjectExplorer::Runnable &runnable);
void setUseMulti(bool on);
void setAttachPid(Utils::ProcessHandle pid);
private:
- void start() override;
-
- GdbServerPortsGatherer *m_portsGatherer;
- ProjectExplorer::Runnable m_runnable;
Utils::ProcessHandle m_pid;
bool m_useMulti = true;
};
diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp
index 611e714abd..a815f17c70 100644
--- a/src/plugins/debugger/debuggertooltipmanager.cpp
+++ b/src/plugins/debugger/debuggertooltipmanager.cpp
@@ -59,7 +59,6 @@
#include <QApplication>
#include <QClipboard>
#include <QDebug>
-#include <QDesktopWidget>
#include <QFileInfo>
#include <QLabel>
#include <QScreen>
@@ -359,7 +358,7 @@ QVariant ToolTipWatchItem::data(int column, int role) const
void ToolTipModel::restoreTreeModel(QXmlStreamReader &r)
{
- Q_UNUSED(r);
+ Q_UNUSED(r)
#if 0
// Helper for building a QStandardItemModel of a tree form (see TreeModelVisitor).
// The recursion/building is based on the scheme: \code
diff --git a/src/plugins/debugger/debuggerunittestfiles.pri b/src/plugins/debugger/debuggerunittestfiles.pri
new file mode 100644
index 0000000000..1168b5af81
--- /dev/null
+++ b/src/plugins/debugger/debuggerunittestfiles.pri
@@ -0,0 +1,11 @@
+shared {
+ DEFINES += DEBUGGER_LIBRARY
+} else {
+ DEFINES += DEBUGGER_STATIC_LIBRARY
+}
+
+HEADERS += \
+ $$PWD/analyzer/diagnosticlocation.h \
+
+SOURCES += \
+ $$PWD/analyzer/diagnosticlocation.cpp \
diff --git a/src/plugins/debugger/disassemblerlines.cpp b/src/plugins/debugger/disassemblerlines.cpp
index dbe9c06f4f..ed77866ca7 100644
--- a/src/plugins/debugger/disassemblerlines.cpp
+++ b/src/plugins/debugger/disassemblerlines.cpp
@@ -108,7 +108,7 @@ struct SourceFileCache
Q_GLOBAL_STATIC(SourceFileCache, sourceFileCache)
-void DisassemblerLines::appendSourceLine(const QString &fileName, uint lineNumber)
+void DisassemblerLines::appendSourceLine(const QString &fileName, int lineNumber)
{
if (fileName.isEmpty() || lineNumber == 0)
@@ -124,7 +124,7 @@ void DisassemblerLines::appendSourceLine(const QString &fileName, uint lineNumbe
cache->lines = ts.readAll().split('\n');
}
}
- if (lineNumber >= uint(cache->lines.size()))
+ if (lineNumber >= cache->lines.size())
return;
DisassemblerLine dl;
dl.lineNumber = lineNumber;
diff --git a/src/plugins/debugger/disassemblerlines.h b/src/plugins/debugger/disassemblerlines.h
index 7cede27ac3..71cd5104a6 100644
--- a/src/plugins/debugger/disassemblerlines.h
+++ b/src/plugins/debugger/disassemblerlines.h
@@ -52,7 +52,7 @@ public:
QString function; // (ass) Function to which current instruction belongs.
QString fileName; // (src) Source file
uint offset = 0; // (ass) Offset of instruction in relation to current function.
- uint lineNumber = 0; // (src) Line number in source.
+ int lineNumber = 0; // (src) Line number in source.
uint hunk = 0; // (src) Number of hunk if source line was split
QByteArray rawData; // (ass) Raw bytes of the instruction
QString data; // (ass) Instruction text, (src) source text, (cmt) arbitrary.
@@ -69,7 +69,7 @@ public:
void appendLine(const DisassemblerLine &dl);
void appendComment(const QString &line);
// Mixed source/assembly: Retrieve contents of source (cached)
- void appendSourceLine(const QString &fileName, uint line);
+ void appendSourceLine(const QString &fileName, int line);
QString toString() const;
void setBytesLength(int x) { m_bytesLength = x; }
int bytesLength() const { return m_bytesLength; }
diff --git a/src/plugins/debugger/enginemanager.cpp b/src/plugins/debugger/enginemanager.cpp
index 6050dc50b9..8c2bbca146 100644
--- a/src/plugins/debugger/enginemanager.cpp
+++ b/src/plugins/debugger/enginemanager.cpp
@@ -245,7 +245,7 @@ QVariant EngineItem::data(int column, int role) const
return myName;
}
case 1:
- return rp.coreFile.isEmpty() ? rp.inferior.executable : rp.coreFile;
+ return rp.coreFile.isEmpty() ? rp.inferior.executable.toUserOutput() : rp.coreFile;
}
return QVariant();
@@ -275,7 +275,7 @@ QVariant EngineItem::data(int column, int role) const
bool EngineItem::setData(int row, const QVariant &value, int role)
{
- Q_UNUSED(row);
+ Q_UNUSED(row)
if (!m_engine)
return false;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 204a11698d..5a40aa2ee0 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -685,7 +685,7 @@ void GdbEngine::interruptInferior()
notifyInferiorStopFailed();
}
});
- signalOperation->setDebuggerCommand(runParameters().debugger.executable);
+ signalOperation->setDebuggerCommand(runParameters().debugger.executable.toString());
signalOperation->interruptProcess(inferiorPid());
} else {
interruptInferior2();
@@ -1030,6 +1030,7 @@ void GdbEngine::updateAll()
stackHandler()->setCurrentIndex(0);
runCommand({"-thread-info", CB(handleThreadInfo)});
reloadRegisters();
+ reloadPeripheralRegisters();
updateLocals();
}
@@ -1700,8 +1701,7 @@ void GdbEngine::setLinuxOsAbi()
const DebuggerRunParameters &rp = runParameters();
bool isElf = (rp.toolChainAbi.binaryFormat() == Abi::ElfFormat);
if (!isElf && !rp.inferior.executable.isEmpty()) {
- isElf = Utils::anyOf(Abi::abisOfBinary(FilePath::fromString(rp.inferior.executable)),
- [](const Abi &abi) {
+ isElf = Utils::anyOf(Abi::abisOfBinary(rp.inferior.executable), [](const Abi &abi) {
return abi.binaryFormat() == Abi::ElfFormat;
});
}
@@ -2049,9 +2049,7 @@ void GdbEngine::setTokenBarrier()
{
//QTC_ASSERT(m_nonDiscardableCount == 0, /**/);
bool good = true;
- QHashIterator<int, DebuggerCommand> it(m_commandForToken);
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_commandForToken.cbegin(), end = m_commandForToken.cend(); it != end; ++it) {
if (!(m_flagsForToken.value(it.key()) & Discardable)) {
qDebug() << "TOKEN: " << it.key() << "CMD:" << it.value().function;
good = false;
@@ -2582,7 +2580,8 @@ void GdbEngine::loadSymbolsForStack()
{
bool needUpdate = false;
const Modules &modules = modulesHandler()->modules();
- for (const StackFrame &frame : stackHandler()->frames()) {
+ stackHandler()->forItemsAtLevel<2>([modules, &needUpdate, this](StackFrameItem *frameItem) {
+ const StackFrame &frame = frameItem->frame;
if (frame.function == "??") {
//qDebug() << "LOAD FOR " << frame.address;
for (const Module &module : modules) {
@@ -2593,7 +2592,7 @@ void GdbEngine::loadSymbolsForStack()
}
}
}
- }
+ });
if (needUpdate) {
reloadStack();
updateLocals();
@@ -2905,6 +2904,7 @@ void GdbEngine::handleStackListFrames(const DebuggerResponse &response, bool isF
// logStreamOutput: "Previous frame identical to this frame (corrupt stack?)\n"
//qDebug() << "LISTING STACK FAILED: " << response.toString();
reloadRegisters();
+ reloadPeripheralRegisters();
return;
}
@@ -2925,7 +2925,7 @@ void GdbEngine::activateFrame(int frameIndex)
StackHandler *handler = stackHandler();
- if (frameIndex == handler->stackSize()) {
+ if (handler->isSpecialFrame(frameIndex)) {
reloadFullStack();
return;
}
@@ -2945,6 +2945,7 @@ void GdbEngine::activateFrame(int frameIndex)
updateLocals();
reloadRegisters();
+ reloadPeripheralRegisters();
}
void GdbEngine::handleThreadInfo(const DebuggerResponse &response)
@@ -3064,6 +3065,22 @@ void GdbEngine::reloadRegisters()
}
}
+void GdbEngine::reloadPeripheralRegisters()
+{
+ if (!isPeripheralRegistersWindowVisible())
+ return;
+
+ const QList<quint64> addresses = peripheralRegisterHandler()->activeRegisters();
+ if (addresses.isEmpty())
+ return; // Nothing to update.
+
+ for (const quint64 address : addresses) {
+ const QString fun = QStringLiteral("x/1u 0x%1")
+ .arg(QString::number(address, 16));
+ runCommand({fun, CB(handlePeripheralRegisterListValues)});
+ }
+}
+
static QString readWord(const QString &ba, int *pos)
{
const int n = ba.size();
@@ -3129,6 +3146,15 @@ void GdbEngine::setRegisterValue(const QString &name, const QString &value)
reloadRegisters();
}
+void GdbEngine::setPeripheralRegisterValue(quint64 address, quint64 value)
+{
+ const QString fun = QStringLiteral("set {int}0x%1=%2")
+ .arg(QString::number(address, 16))
+ .arg(value);
+ runCommand({fun});
+ reloadPeripheralRegisters();
+}
+
void GdbEngine::handleRegisterListNames(const DebuggerResponse &response)
{
if (response.resultClass != ResultDone) {
@@ -3229,6 +3255,28 @@ void GdbEngine::handleRegisterListValues(const DebuggerResponse &response)
handler->commitUpdates();
}
+void GdbEngine::handlePeripheralRegisterListValues(
+ const DebuggerResponse &response)
+{
+ if (response.resultClass != ResultDone)
+ return;
+
+ const QString output = response.consoleStreamOutput;
+ // Regexp to match for '0x50060800:\t0\n'.
+ const QRegularExpression re("^(0x[0-9A-F]+):\\t(\\d+)\\n$");
+ const QRegularExpressionMatch m = re.match(output);
+ if (!m.hasMatch())
+ return;
+ enum { AddressMatch = 1, ValueMatch = 2 };
+ bool aok = false;
+ bool vok = false;
+ const quint64 address = m.captured(AddressMatch).toULongLong(&aok, 16);
+ const quint64 value = m.captured(ValueMatch).toULongLong(&vok, 10);
+ if (!aok || !vok)
+ return;
+
+ peripheralRegisterHandler()->updateRegister(address, value);
+}
//////////////////////////////////////////////////////////////////////
//
@@ -3524,7 +3572,7 @@ void GdbEngine::setupEngine()
m_gdbProc.setUseCtrlCStub(runParameters().useCtrlCStub); // This is only set for QNX
const DebuggerRunParameters &rp = runParameters();
- CommandLine gdbCommand{FilePath::fromString(rp.debugger.executable), {}};
+ CommandLine gdbCommand{rp.debugger.executable};
if (isPlainEngine()) {
if (!m_outputCollector.listen()) {
@@ -3551,7 +3599,7 @@ void GdbEngine::setupEngine()
return;
}
- gdbCommand.addArgs("-i mi");
+ gdbCommand.addArgs({"-i", "mi"});
if (!boolSetting(LoadGdbInit))
gdbCommand.addArg("-n");
@@ -3636,7 +3684,7 @@ void GdbEngine::setupEngine()
Module module;
module.startAddress = 0;
module.endAddress = 0;
- module.modulePath = rp.inferior.executable;
+ module.modulePath = rp.inferior.executable.toString();
module.moduleName = "<executable>";
modulesHandler()->updateModule(module);
@@ -3686,7 +3734,7 @@ void GdbEngine::setupEngine()
//if (terminal()->isUsable())
// runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())});
- const QFileInfo gdbBinaryFile(rp.debugger.executable);
+ const QFileInfo gdbBinaryFile = rp.debugger.executable.toFileInfo();
const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python";
runCommand({"python sys.path.insert(1, '" + dumperSourcePath + "')"});
@@ -3705,6 +3753,9 @@ void GdbEngine::setupEngine()
runCommand({commands});
runCommand({"loadDumpers", CB(handlePythonSetup)});
+
+ // Reload peripheral register description.
+ peripheralRegisterHandler()->updateRegisterGroups();
}
void GdbEngine::handleGdbStartFailed()
@@ -3763,8 +3814,7 @@ void GdbEngine::reloadDebuggingHelpers()
void GdbEngine::handleGdbError(QProcess::ProcessError error)
{
- const QString program = runParameters().debugger.executable;
- QString msg = RunWorker::userMessageForProcessError(error, program);
+ QString msg = RunWorker::userMessageForProcessError(error, runParameters().debugger.executable);
QString errorString = m_gdbProc.errorString();
if (!errorString.isEmpty())
msg += '\n' + errorString;
@@ -4062,10 +4112,8 @@ void GdbEngine::setupInferior()
setLinuxOsAbi();
QString symbolFile;
- if (!rp.symbolFile.isEmpty()) {
- QFileInfo fi(rp.symbolFile);
- symbolFile = fi.absoluteFilePath();
- }
+ if (!rp.symbolFile.isEmpty())
+ symbolFile = rp.symbolFile.toFileInfo().absoluteFilePath();
//const QByteArray sysroot = sp.sysroot.toLocal8Bit();
//const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
@@ -4122,7 +4170,7 @@ void GdbEngine::setupInferior()
setLinuxOsAbi();
- QString executable = rp.inferior.executable;
+ FilePath executable = rp.inferior.executable;
if (executable.isEmpty()) {
CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(rp.debugger, rp.coreFile);
@@ -4134,7 +4182,7 @@ void GdbEngine::setupInferior()
return;
}
- executable = cinfo.foundExecutableName;
+ executable = FilePath::fromString(cinfo.foundExecutableName);
if (executable.isEmpty()) {
AsynchronousMessageBox::warning(tr("Error Loading Symbols"),
tr("No executable to load symbols from specified core."));
@@ -4144,7 +4192,7 @@ void GdbEngine::setupInferior()
}
// Do that first, otherwise no symbols are loaded.
- QFileInfo fi(executable);
+ QFileInfo fi = executable.toFileInfo();
QString path = fi.absoluteFilePath();
runCommand({"-file-exec-and-symbols \"" + path + '"',
CB(handleFileExecAndSymbols)});
@@ -4170,7 +4218,7 @@ void GdbEngine::setupInferior()
runCommand({"-exec-arguments " + args});
}
- QString executable = QFileInfo(runParameters().inferior.executable).absoluteFilePath();
+ QString executable = runParameters().inferior.executable.toFileInfo().absoluteFilePath();
runCommand({"-file-exec-and-symbols \"" + executable + '"',
CB(handleFileExecAndSymbols)});
}
@@ -4494,7 +4542,7 @@ void GdbEngine::handleTargetExtendedRemote(const DebuggerResponse &response)
runCommand({"attach " + QString::number(runParameters().attachPID.pid()),
CB(handleTargetExtendedAttach)});
} else if (!runParameters().inferior.executable.isEmpty()) {
- runCommand({"-gdb-set remote exec-file " + runParameters().inferior.executable,
+ runCommand({"-gdb-set remote exec-file " + runParameters().inferior.executable.toString(),
CB(handleTargetExtendedAttach)});
} else {
const QString title = tr("No Remote Executable or Process ID Specified");
@@ -4541,11 +4589,11 @@ void GdbEngine::handleTargetQnx(const DebuggerResponse &response)
showMessage(msgAttachedToStoppedInferior(), StatusBar);
const DebuggerRunParameters &rp = runParameters();
- const QString remoteExecutable = rp.inferior.executable;
if (rp.attachPID.isValid())
runCommand({"attach " + QString::number(rp.attachPID.pid()), CB(handleAttach)});
- else if (!remoteExecutable.isEmpty())
- runCommand({"set nto-executable " + remoteExecutable, CB(handleSetNtoExecutable)});
+ else if (!rp.inferior.executable.isEmpty())
+ runCommand({"set nto-executable " + rp.inferior.executable.toString(),
+ CB(handleSetNtoExecutable)});
else
handleInferiorPrepared();
} else {
@@ -4679,7 +4727,7 @@ CoreInfo CoreInfo::readExecutableNameFromCore(const Runnable &debugger, const QS
QStringList envLang = QProcess::systemEnvironment();
Utils::Environment::setupEnglishOutput(&envLang);
proc.setEnvironment(envLang);
- SynchronousProcessResponse response = proc.runBlocking(debugger.executable, args);
+ SynchronousProcessResponse response = proc.runBlocking({debugger.executable, args});
if (response.result == SynchronousProcessResponse::Finished) {
QString output = response.stdOut();
@@ -4723,7 +4771,7 @@ void GdbEngine::handleTargetCore(const DebuggerResponse &response)
void GdbEngine::handleCoreRoundTrip(const DebuggerResponse &response)
{
CHECK_STATE(InferiorUnrunnable);
- Q_UNUSED(response);
+ Q_UNUSED(response)
loadSymbolsForStack();
handleStop3();
QTimer::singleShot(1000, this, &GdbEngine::loadAllSymbols);
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 097b5ea81c..8f94a9ed7e 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -29,6 +29,7 @@
#include <debugger/breakhandler.h>
#include <debugger/registerhandler.h>
+#include <debugger/peripheralregisterhandler.h>
#include <debugger/watchhandler.h>
#include <debugger/watchutils.h>
#include <debugger/debuggeritem.h>
@@ -266,10 +267,13 @@ private: ////////// General Interface //////////
// Register specific stuff
//
void reloadRegisters() final;
+ void reloadPeripheralRegisters() final;
void setRegisterValue(const QString &name, const QString &value) final;
+ void setPeripheralRegisterValue(quint64 address, quint64 value) final;
void handleRegisterListNames(const DebuggerResponse &response);
void handleRegisterListing(const DebuggerResponse &response);
void handleRegisterListValues(const DebuggerResponse &response);
+ void handlePeripheralRegisterListValues(const DebuggerResponse &response);
void handleMaintPrintRegisters(const DebuggerResponse &response);
QHash<int, Register> m_registers; // Map GDB register numbers to indices
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index ee0fd4f087..d60b0951e7 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -200,19 +200,19 @@ void LldbEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
- QString lldbCmd = runParameters().debugger.executable;
+ const FilePath lldbCmd = runParameters().debugger.executable;
- showMessage("STARTING LLDB: " + lldbCmd);
+ showMessage("STARTING LLDB: " + lldbCmd.toUserOutput());
m_lldbProc.setEnvironment(runParameters().debugger.environment);
if (QFileInfo(runParameters().debugger.workingDirectory).isDir())
m_lldbProc.setWorkingDirectory(runParameters().debugger.workingDirectory);
- m_lldbProc.setCommand(CommandLine(FilePath::fromString(lldbCmd), QString()));
+ m_lldbProc.setCommand(CommandLine(lldbCmd));
m_lldbProc.start();
if (!m_lldbProc.waitForStarted()) {
const QString msg = tr("Unable to start LLDB \"%1\": %2")
- .arg(lldbCmd, m_lldbProc.errorString());
+ .arg(lldbCmd.toUserOutput(), m_lldbProc.errorString());
notifyEngineSetupFailed();
showMessage("ADAPTER START FAILED");
if (!msg.isEmpty())
@@ -268,7 +268,7 @@ void LldbEngine::setupEngine()
}
DebuggerCommand cmd2("setupInferior");
- cmd2.arg("executable", rp.inferior.executable);
+ cmd2.arg("executable", rp.inferior.executable.toString());
cmd2.arg("breakonmain", rp.breakOnMain);
cmd2.arg("useterminal", bool(terminal()));
cmd2.arg("startmode", rp.startMode);
@@ -434,7 +434,7 @@ void LldbEngine::activateFrame(int frameIndex)
return;
StackHandler *handler = stackHandler();
- if (frameIndex == handler->stackSize()) {
+ if (handler->isSpecialFrame(frameIndex)) {
fetchStack(handler->stackSize() * 10 + 3);
return;
}
@@ -814,7 +814,7 @@ QString LldbEngine::errorMessage(QProcess::ProcessError error) const
return tr("The LLDB process failed to start. Either the "
"invoked program \"%1\" is missing, or you may have insufficient "
"permissions to invoke the program.")
- .arg(runParameters().debugger.executable);
+ .arg(runParameters().debugger.executable.toUserOutput());
case QProcess::Crashed:
return tr("The LLDB process crashed some time after starting "
"successfully.");
@@ -1048,7 +1048,7 @@ void LldbEngine::changeMemory(MemoryAgent *agent, quint64 addr, const QByteArray
DebuggerCommand cmd("writeMemory");
cmd.arg("address", addr);
cmd.arg("data", QString::fromUtf8(data.toHex()));
- cmd.callback = [](const DebuggerResponse &response) { Q_UNUSED(response); };
+ cmd.callback = [](const DebuggerResponse &response) { Q_UNUSED(response) };
runCommand(cmd);
}
diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp
index 075cefd595..e264614611 100644
--- a/src/plugins/debugger/loadcoredialog.cpp
+++ b/src/plugins/debugger/loadcoredialog.cpp
@@ -258,7 +258,8 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent)
d->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
- d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging, this);
+ d->kitChooser = new KitChooser(this);
+ d->kitChooser->setShowIcons(true);
d->kitChooser->populate();
d->forceLocalCheckBox = new QCheckBox(this);
@@ -415,9 +416,9 @@ QString AttachCoreDialog::localCoreFile() const
return d->localCoreFileName->path();
}
-QString AttachCoreDialog::symbolFile() const
+FilePath AttachCoreDialog::symbolFile() const
{
- return d->symbolFileName->path();
+ return d->symbolFileName->fileName();
}
void AttachCoreDialog::setSymbolFile(const QString &symbolFileName)
diff --git a/src/plugins/debugger/loadcoredialog.h b/src/plugins/debugger/loadcoredialog.h
index 84ba46a4fd..aaa04fdab3 100644
--- a/src/plugins/debugger/loadcoredialog.h
+++ b/src/plugins/debugger/loadcoredialog.h
@@ -29,6 +29,7 @@
namespace Core { class Id; }
namespace ProjectExplorer { class Kit; }
+namespace Utils { class FilePath; }
namespace Debugger {
namespace Internal {
@@ -45,7 +46,7 @@ public:
int exec() override;
- QString symbolFile() const;
+ Utils::FilePath symbolFile() const;
QString localCoreFile() const;
QString remoteCoreFile() const;
QString overrideStartScript() const;
diff --git a/src/plugins/debugger/localsandexpressionswindow.cpp b/src/plugins/debugger/localsandexpressionswindow.cpp
index 6aef8c4481..0c6ab3d5b8 100644
--- a/src/plugins/debugger/localsandexpressionswindow.cpp
+++ b/src/plugins/debugger/localsandexpressionswindow.cpp
@@ -39,7 +39,7 @@ LocalsAndInspectorWindow::LocalsAndInspectorWindow(QWidget *locals,
QWidget *inspector, QWidget *returnWidget)
{
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
auto splitter = new Core::MiniSplitter(Qt::Vertical);
diff --git a/src/plugins/debugger/logwindow.cpp b/src/plugins/debugger/logwindow.cpp
index e671709161..dd9530744b 100644
--- a/src/plugins/debugger/logwindow.cpp
+++ b/src/plugins/debugger/logwindow.cpp
@@ -423,13 +423,13 @@ LogWindow::LogWindow(DebuggerEngine *engine)
commandBox->addWidget(repeatButton);
commandBox->addWidget(new QLabel(tr("Command:"), this));
commandBox->addWidget(m_commandEdit);
- commandBox->setMargin(2);
+ commandBox->setContentsMargins(2, 2, 2, 2);
commandBox->setSpacing(6);
auto leftBox = new QVBoxLayout;
leftBox->addWidget(m_inputText);
leftBox->addItem(commandBox);
- leftBox->setMargin(0);
+ leftBox->setContentsMargins(0, 0, 0, 0);
leftBox->setSpacing(0);
auto leftDummy = new QWidget;
@@ -441,7 +441,7 @@ LogWindow::LogWindow(DebuggerEngine *engine)
m_splitter->setStretchFactor(1, 3);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_splitter);
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
@@ -678,7 +678,7 @@ GlobalLogWindow::GlobalLogWindow()
m_splitter->setStretchFactor(1, 3);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_splitter);
layout->addWidget(new Core::FindToolBarPlaceHolder(this));
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 39acf7df96..defd54050b 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -389,7 +389,7 @@ void PdbEngine::assignValueInDebugger(WatchItem *, const QString &expression, co
void PdbEngine::updateItem(const QString &iname)
{
- Q_UNUSED(iname);
+ Q_UNUSED(iname)
updateAll();
}
diff --git a/src/plugins/debugger/peripheralregisterhandler.cpp b/src/plugins/debugger/peripheralregisterhandler.cpp
new file mode 100644
index 0000000000..1603faf3dc
--- /dev/null
+++ b/src/plugins/debugger/peripheralregisterhandler.cpp
@@ -0,0 +1,957 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** 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 "peripheralregisterhandler.h"
+
+#include "debuggeractions.h"
+#include "debuggercore.h"
+#include "debuggerdialogs.h"
+
+#include <utils/basetreeview.h>
+#include <utils/savedaction.h>
+
+#include <QItemDelegate>
+#include <QLineEdit>
+#include <QMenu>
+#include <QPainter>
+
+using namespace Utils;
+
+namespace Debugger {
+namespace Internal {
+
+namespace {
+// Keys of a properties in SVD file.
+constexpr char kAccess[] = "access";
+constexpr char kAddressOffset[] = "addressOffset";
+constexpr char kBaseAddress[] = "baseAddress";
+constexpr char kBitOffset[] = "bitOffset";
+constexpr char kBitRange[] = "bitRange";
+constexpr char kBitWidth[] = "bitWidth";
+constexpr char kDerivedFrom[] = "derivedFrom";
+constexpr char kDescription[] = "description";
+constexpr char kField[] = "field";
+constexpr char kFields[] = "fields";
+constexpr char kGroupName[] = "groupName";
+constexpr char kName[] = "name";
+constexpr char kPeripheral[] = "peripheral";
+constexpr char kPeripherals[] = "peripherals";
+constexpr char kReadOnly[] = "read-only";
+constexpr char kReadWrite[] = "read-write";
+constexpr char kRegister[] = "register";
+constexpr char kRegisters[] = "registers";
+constexpr char kResetvalue[] = "resetValue";
+constexpr char kSize[] = "size";
+constexpr char kWritOnlye[] = "write-only";
+} // namespace
+
+enum PeripheralRegisterColumns
+{
+ PeripheralRegisterNameColumn,
+ PeripheralRegisterValueColumn,
+ PeripheralRegisterAccessColumn,
+ PeripheralRegisterColumnCount
+};
+
+enum PeripheralRegisterDataRole
+{
+ PeripheralRegisterChangedRole = Qt::UserRole
+};
+
+static QString accessName(PeripheralRegisterAccess access)
+{
+ switch (access) {
+ case PeripheralRegisterAccess::ReadOnly:
+ return PeripheralRegisterHandler::tr("RO");
+ case PeripheralRegisterAccess::WriteOnly:
+ return PeripheralRegisterHandler::tr("WO");
+ case PeripheralRegisterAccess::ReadWrite:
+ return PeripheralRegisterHandler::tr("RW");
+ default:
+ return PeripheralRegisterHandler::tr("N/A");
+ }
+}
+
+static PeripheralRegisterAccess decodeAccess(const QString &accessText)
+{
+ if (accessText == QLatin1String(kReadWrite))
+ return PeripheralRegisterAccess::ReadWrite;
+ if (accessText == QLatin1String(kReadOnly))
+ return PeripheralRegisterAccess::ReadOnly;
+ if (accessText == QLatin1String(kWritOnlye))
+ return PeripheralRegisterAccess::WriteOnly;
+ return PeripheralRegisterAccess::Unknown;
+}
+
+static quint64 decodeNumeric(const QString &text)
+{
+ bool ok = false;
+ const quint64 result = text.toULongLong(&ok, 10);
+ if (ok)
+ return result;
+ return text.toUInt(&ok, 16);
+}
+
+static QString valueToString(quint64 value, int size, PeripheralRegisterFormat fmt)
+{
+ QString result;
+ if (fmt == PeripheralRegisterFormat::Hexadecimal) {
+ result = QString::number(value, 16);
+ result.prepend("0x" + QString(size / 4 - result.size(), '0'));
+ } else if (fmt == PeripheralRegisterFormat::Decimal) {
+ result = QString::number(value, 10);
+ } else if (fmt == PeripheralRegisterFormat::Octal) {
+ result = QString::number(value, 8);
+ result.prepend('0' + QString(size / 2 - result.size(), '0'));
+ } else if (fmt == PeripheralRegisterFormat::Binary) {
+ result = QString::number(value, 2);
+ result.prepend("0b" + QString(size - result.size(), '0'));
+ }
+ return result;
+}
+
+static quint64 valueFromString(const QString &string, PeripheralRegisterFormat fmt,
+ bool *ok)
+{
+ if (fmt == PeripheralRegisterFormat::Hexadecimal) {
+ const QRegularExpression re("^(0x)?([0-9A-F]+)$");
+ const QRegularExpressionMatch m = re.match(string);
+ if (m.hasMatch())
+ return m.captured(2).toULongLong(ok, 16);
+ } else if (fmt == PeripheralRegisterFormat::Decimal) {
+ const QRegularExpression re("^([0-9]+)$");
+ const QRegularExpressionMatch m = re.match(string);
+ if (m.hasMatch())
+ return m.captured(1).toULongLong(ok, 10);
+ } else if (fmt == PeripheralRegisterFormat::Octal) {
+ const QRegularExpression re("^(0)?([0-7]+)$");
+ const QRegularExpressionMatch m = re.match(string);
+ if (m.hasMatch())
+ return m.captured(2).toULongLong(ok, 8);
+ } else if (fmt == PeripheralRegisterFormat::Binary) {
+ const QRegularExpression re("^(0b)?([0-1]+)$");
+ const QRegularExpressionMatch m = re.match(string);
+ if (m.hasMatch())
+ return m.captured(2).toULongLong(ok, 2);
+ }
+
+ *ok = false;
+ return 0;
+}
+
+// PeripheralRegisterField
+
+QString PeripheralRegisterField::bitRangeString() const
+{
+ const int from = bitOffset;
+ const int to = bitOffset + bitWidth - 1;
+ return PeripheralRegisterHandler::tr("[%1..%2]").arg(to).arg(from);
+}
+
+QString PeripheralRegisterField::bitValueString(quint64 regValue) const
+{
+ const quint64 value = bitValue(regValue);
+ return valueToString(value, bitWidth, format);
+}
+
+quint64 PeripheralRegisterField::bitValue(quint64 regValue) const
+{
+ const quint64 mask = bitMask();
+ regValue &= mask;
+ regValue >>= bitOffset;
+ return regValue;
+}
+
+quint64 PeripheralRegisterField::bitMask() const
+{
+ quint64 mask = 0;
+ for (auto pos = bitOffset; pos < bitOffset + bitWidth; ++pos)
+ mask |= quint64(quint64(1) << pos);
+ return mask;
+}
+
+// PeripheralRegisterValue
+
+bool PeripheralRegisterValue::fromString(const QString &string,
+ PeripheralRegisterFormat fmt)
+{
+ bool ok = false;
+ const quint64 newVal = valueFromString(string, fmt, &ok);
+ if (!ok)
+ return false;
+ v = newVal;
+ return true;
+}
+
+QString PeripheralRegisterValue::toString(
+ int size, PeripheralRegisterFormat fmt) const
+{
+ return valueToString(v, size, fmt);
+}
+
+// PeripheralRegister
+
+QString PeripheralRegister::currentValueString() const
+{
+ return currentValue.toString(size, format);
+}
+
+QString PeripheralRegister::previousValueString() const
+{
+ return previousValue.toString(size, format);
+}
+
+QString PeripheralRegister::resetValueString() const
+{
+ return resetValue.toString(size, format);
+}
+
+QString PeripheralRegister::addressString(quint64 baseAddress) const
+{
+ return "0x" + QString::number(address(baseAddress), 16);
+}
+
+quint64 PeripheralRegister::address(quint64 baseAddress) const
+{
+ return baseAddress + addressOffset;
+}
+
+// PeripheralRegisterFieldItem
+
+class PeripheralRegisterFieldItem final
+ : public TypedTreeItem<PeripheralRegisterFieldItem>
+{
+public:
+ explicit PeripheralRegisterFieldItem(
+ DebuggerEngine *engine, const PeripheralRegisterGroup &group,
+ PeripheralRegister &reg, PeripheralRegisterField &fld);
+
+ QVariant data(int column, int role) const final;
+ bool setData(int column, const QVariant &value, int role) final;
+ Qt::ItemFlags flags(int column) const final;
+
+ void triggerChange();
+
+ DebuggerEngine *m_engine = nullptr;
+ const PeripheralRegisterGroup &m_group;
+ PeripheralRegister &m_reg;
+ PeripheralRegisterField &m_fld;
+};
+
+PeripheralRegisterFieldItem::PeripheralRegisterFieldItem(
+ DebuggerEngine *engine, const PeripheralRegisterGroup &group,
+ PeripheralRegister &reg, PeripheralRegisterField &fld)
+ : m_engine(engine), m_group(group), m_reg(reg), m_fld(fld)
+{
+}
+
+QVariant PeripheralRegisterFieldItem::data(int column, int role) const
+{
+ switch (role) {
+ case PeripheralRegisterChangedRole:
+ return m_fld.bitValue(m_reg.currentValue.v)
+ != m_fld.bitValue(m_reg.previousValue.v);
+
+ case Qt::DisplayRole:
+ switch (column) {
+ case PeripheralRegisterNameColumn:
+ return m_fld.name;
+ case PeripheralRegisterValueColumn:
+ return m_fld.bitValueString(m_reg.currentValue.v);
+ case PeripheralRegisterAccessColumn:
+ return accessName(m_fld.access);
+ }
+ break;
+
+ case Qt::ToolTipRole:
+ switch (column) {
+ case PeripheralRegisterNameColumn:
+ return QString("%1.%2\n%3\nBits: %4, %5")
+ .arg(m_reg.name)
+ .arg(m_fld.name)
+ .arg(m_fld.description)
+ .arg(m_fld.bitRangeString())
+ .arg(m_fld.bitWidth);
+ case PeripheralRegisterValueColumn:
+ return QString("Value: %1").arg(
+ m_fld.bitValueString(m_reg.currentValue.v));
+ }
+ break;
+
+ case Qt::EditRole:
+ return m_fld.bitValueString(m_reg.currentValue.v);
+
+ case Qt::TextAlignmentRole: {
+ if (column == PeripheralRegisterValueColumn)
+ return Qt::AlignRight;
+ return {};
+ }
+
+ default:
+ break;
+ }
+ return {};
+}
+
+bool PeripheralRegisterFieldItem::setData(
+ int column, const QVariant &value, int role)
+{
+ if (column == PeripheralRegisterValueColumn && role == Qt::EditRole) {
+ bool ok = false;
+ quint64 bitValue = valueFromString(value.toString(), m_fld.format, &ok);
+ if (!ok)
+ return false;
+ bitValue <<= m_fld.bitOffset;
+ const quint64 mask = m_fld.bitMask();
+ m_reg.currentValue.v &= ~mask;
+ m_reg.currentValue.v |= bitValue;
+ triggerChange();
+ return true;
+ }
+ return false;
+}
+
+Qt::ItemFlags PeripheralRegisterFieldItem::flags(int column) const
+{
+ const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ if (column != PeripheralRegisterValueColumn)
+ return notEditable;
+ if (m_fld.access == PeripheralRegisterAccess::ReadWrite
+ || m_fld.access == PeripheralRegisterAccess::WriteOnly) {
+ return notEditable | Qt::ItemIsEditable;
+ }
+ return notEditable;
+}
+
+void PeripheralRegisterFieldItem::triggerChange()
+{
+ m_engine->setPeripheralRegisterValue(m_reg.address(m_group.baseAddress),
+ m_reg.currentValue.v);
+}
+
+// PeripheralRegisterItem
+
+class PeripheralRegisterItem final
+ : public TypedTreeItem<PeripheralRegisterItem>
+{
+public:
+ explicit PeripheralRegisterItem(
+ DebuggerEngine *engine,
+ const PeripheralRegisterGroup &group,
+ PeripheralRegister &reg);
+
+ QVariant data(int column, int role) const final;
+ bool setData(int column, const QVariant &value, int role) final;
+ Qt::ItemFlags flags(int column) const final;
+
+ void triggerChange();
+
+ DebuggerEngine *m_engine = nullptr;
+ const PeripheralRegisterGroup &m_group;
+ PeripheralRegister &m_reg;
+};
+
+PeripheralRegisterItem::PeripheralRegisterItem(
+ DebuggerEngine *engine,
+ const PeripheralRegisterGroup &group,
+ PeripheralRegister &reg)
+ : m_engine(engine), m_group(group), m_reg(reg)
+{
+ for (auto &fld : m_reg.fields) {
+ const auto item = new PeripheralRegisterFieldItem(
+ m_engine, m_group, m_reg, fld);
+ appendChild(item);
+ }
+}
+
+QVariant PeripheralRegisterItem::data(int column, int role) const
+{
+ switch (role) {
+ case PeripheralRegisterChangedRole:
+ return m_reg.currentValue != m_reg.previousValue;
+
+ case Qt::DisplayRole:
+ switch (column) {
+ case PeripheralRegisterNameColumn:
+ return m_reg.name;
+ case PeripheralRegisterValueColumn:
+ return m_reg.currentValueString();
+ case PeripheralRegisterAccessColumn:
+ return accessName(m_reg.access);
+ }
+ break;
+
+ case Qt::ToolTipRole:
+ switch (column) {
+ case PeripheralRegisterNameColumn:
+ return QStringLiteral("%1 / %2\n%3\n%4 @ %5, %6")
+ .arg(m_group.name)
+ .arg(m_reg.name)
+ .arg(m_reg.description)
+ .arg(accessName(m_reg.access))
+ .arg(m_reg.addressString(m_group.baseAddress))
+ .arg(m_reg.size);
+ case PeripheralRegisterValueColumn:
+ return QStringLiteral("Current value: %1\n"
+ "Previous value: %2\n"
+ "Reset value: %3")
+ .arg(m_reg.currentValueString(),
+ m_reg.previousValueString(),
+ m_reg.resetValueString());
+ }
+ break;
+
+ case Qt::EditRole:
+ return m_reg.currentValueString();
+
+ case Qt::TextAlignmentRole: {
+ if (column == PeripheralRegisterValueColumn)
+ return Qt::AlignRight;
+ return {};
+ }
+
+ default:
+ break;
+ }
+ return {};
+}
+
+bool PeripheralRegisterItem::setData(int column, const QVariant &value, int role)
+{
+ if (column == PeripheralRegisterValueColumn && role == Qt::EditRole) {
+ if (m_reg.currentValue.fromString(value.toString(), m_reg.format)) {
+ triggerChange();
+ return true;
+ }
+ }
+ return false;
+}
+
+Qt::ItemFlags PeripheralRegisterItem::flags(int column) const
+{
+ const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ if (column != PeripheralRegisterValueColumn)
+ return notEditable;
+ if (m_reg.access == PeripheralRegisterAccess::ReadWrite
+ || m_reg.access == PeripheralRegisterAccess::WriteOnly) {
+ return notEditable | Qt::ItemIsEditable;
+ }
+ return notEditable;
+}
+
+void PeripheralRegisterItem::triggerChange()
+{
+ m_engine->setPeripheralRegisterValue(m_reg.address(m_group.baseAddress),
+ m_reg.currentValue.v);
+}
+
+// PeripheralRegisterDelegate
+
+class PeripheralRegisterDelegate final : public QItemDelegate
+{
+public:
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
+ const QModelIndex &index) const final
+ {
+ if (index.column() == PeripheralRegisterValueColumn) {
+ const auto lineEdit = new QLineEdit(parent);
+ lineEdit->setAlignment(Qt::AlignLeft);
+ lineEdit->setFrame(false);
+ return lineEdit;
+ }
+ return nullptr;
+ }
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const final
+ {
+ const auto lineEdit = qobject_cast<QLineEdit *>(editor);
+ QTC_ASSERT(lineEdit, return);
+ lineEdit->setText(index.data(Qt::EditRole).toString());
+ }
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const final
+ {
+ if (index.column() == PeripheralRegisterValueColumn) {
+ const auto lineEdit = qobject_cast<QLineEdit *>(editor);
+ QTC_ASSERT(lineEdit, return);
+ model->setData(index, lineEdit->text(), Qt::EditRole);
+ }
+ }
+
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
+ const QModelIndex &) const final
+ {
+ editor->setGeometry(option.rect);
+ }
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const final
+ {
+ if (index.column() == PeripheralRegisterValueColumn) {
+ const bool paintRed = index.data(PeripheralRegisterChangedRole).toBool();
+ const QPen oldPen = painter->pen();
+ const QColor lightColor(140, 140, 140);
+ if (paintRed)
+ painter->setPen(QColor(200, 0, 0));
+ else
+ painter->setPen(lightColor);
+ // FIXME: performance? this changes only on real font changes.
+ const QFontMetrics fm(option.font);
+ const int charWidth = qMax(fm.horizontalAdvance('x'),
+ fm.horizontalAdvance('0'));
+ const QString str = index.data(Qt::DisplayRole).toString();
+ int x = option.rect.x();
+ bool light = !paintRed;
+ for (int i = 0; i < str.size(); ++i) {
+ const QChar c = str.at(i);
+ const int uc = c.unicode();
+ if (light && (uc != 'x' && uc != '0')) {
+ light = false;
+ painter->setPen(oldPen.color());
+ }
+ if (uc == ' ') {
+ light = true;
+ painter->setPen(lightColor);
+ } else {
+ QRect r = option.rect;
+ r.setX(x);
+ r.setWidth(charWidth);
+ painter->drawText(r, Qt::AlignHCenter, c);
+ }
+ x += charWidth;
+ }
+ painter->setPen(oldPen);
+ } else {
+ QItemDelegate::paint(painter, option, index);
+ }
+ }
+};
+
+// PeripheralRegisterHandler
+
+PeripheralRegisterHandler::PeripheralRegisterHandler(DebuggerEngine *engine)
+ : m_engine(engine)
+{
+ setObjectName("PeripheralRegisterModel");
+ setHeader({tr("Name"), tr("Value"), tr("Access")});
+}
+
+static PeripheralRegisterGroups availablePeripheralRegisterGroups(
+ const QString &filePath)
+{
+ QFile f(filePath);
+ if (!f.open(QIODevice::ReadOnly))
+ return {};
+
+ QXmlStreamReader in(&f);
+
+ PeripheralRegisterGroups foundGroups;
+
+ while (!in.atEnd()) {
+ const auto token = in.readNext();
+ if (token == QXmlStreamReader::EndElement
+ && in.name() == QLatin1String(kPeripherals)) {
+ break;
+ } else if (token != QXmlStreamReader::StartElement
+ || in.name() != QLatin1String(kPeripheral)) {
+ continue;
+ }
+
+ PeripheralRegisterGroup group;
+
+ const auto fromGroupName = in.attributes().value(
+ QLatin1String(kDerivedFrom));
+ const auto foundGroupEnd = foundGroups.cend();
+ const auto foundGroupIt = std::find_if(
+ foundGroups.cbegin(), foundGroupEnd,
+ [fromGroupName](const PeripheralRegisterGroup &foundGroup) {
+ return fromGroupName == foundGroup.name;
+ });
+ if (foundGroupIt != foundGroupEnd)
+ group = *foundGroupIt;
+
+ while (!in.atEnd()) {
+ const auto token = in.readNext();
+ if (token == QXmlStreamReader::EndElement
+ && in.name() == QLatin1String(kPeripheral)) {
+ foundGroups.push_back(group);
+ break;
+ } else if (token == QXmlStreamReader::StartElement) {
+ const auto elementName = in.name();
+ if (elementName == QLatin1String(kName)) {
+ group.name = in.readElementText();
+ } else if (elementName == QLatin1String(kDescription)) {
+ group.description = in.readElementText();
+ } else if (elementName == QLatin1String(kGroupName)) {
+ group.displayName = in.readElementText();
+ } else if (elementName == QLatin1String(kBaseAddress)) {
+ group.baseAddress = decodeNumeric(in.readElementText());
+ } else if (elementName == QLatin1String(kSize)) {
+ group.size = int(decodeNumeric(in.readElementText()));
+ } else if (elementName == QLatin1String(kAccess)) {
+ group.access = decodeAccess(in.readElementText());
+ } else if (elementName == QLatin1String(kRegisters)
+ || elementName == QLatin1String(kRegister)) {
+ PeripheralRegister reg;
+ while (!in.atEnd()) {
+ const auto token = in.readNext();
+ if (token == QXmlStreamReader::EndElement
+ && in.name() == QLatin1String(kRegister)) {
+ group.registers.push_back(reg);
+ break;
+ } else if (token == QXmlStreamReader::StartElement) {
+ const auto elementName = in.name();
+ if (elementName == QLatin1String(kRegister)) {
+ continue;
+ } else if (elementName == QLatin1String(kName)) {
+ reg.name = in.readElementText();
+ } else if (elementName == QLatin1String(kDescription)) {
+ reg.description = in.readElementText();
+ } else if (elementName == QLatin1String(kAddressOffset)) {
+ reg.addressOffset = decodeNumeric(in.readElementText());
+ } else if (elementName == QLatin1String(kSize)) {
+ reg.size = int(decodeNumeric(in.readElementText()));
+ } else if (elementName == QLatin1String(kAccess)) {
+ reg.access = decodeAccess(in.readElementText());
+ } else if (elementName == QLatin1String(kResetvalue)) {
+ reg.resetValue = decodeNumeric(in.readElementText());
+ } else if (elementName == QLatin1String(kFields)
+ || elementName == QLatin1String(kField)) {
+ PeripheralRegisterField fld;
+ while (!in.atEnd()) {
+ const auto token = in.readNext();
+ if (token == QXmlStreamReader::EndElement
+ && in.name() == QLatin1String(kField)) {
+ reg.fields.push_back(fld);
+ break;
+ } else if (token == QXmlStreamReader::StartElement) {
+ const auto elementName = in.name();
+ if (elementName == QLatin1String(kField)) {
+ continue;
+ } else if (elementName == QLatin1String(kName)) {
+ fld.name = in.readElementText();
+ } else if (elementName == QLatin1String(kDescription)) {
+ fld.description = in.readElementText();
+ } else if (elementName == QLatin1String(kAccess)) {
+ fld.access = decodeAccess(in.readElementText());
+ } else if (elementName == QLatin1String(kBitRange)) {
+ const QString elementText = in.readElementText();
+ const int startBracket = elementText.indexOf('[');
+ const int endBracket = elementText.indexOf(']');
+ if (startBracket == -1 || endBracket == -1
+ || (endBracket - startBracket) <= 0) {
+ continue;
+ }
+ const QString range = elementText.mid(
+ startBracket + 1, endBracket - 1);
+ const QStringList items = range.split(':');
+ enum { MaxBit, MinBit, BitsCount };
+ if (items.count() != BitsCount)
+ continue;
+ const int from = int(decodeNumeric(items.at(MinBit)));
+ const int to = int(decodeNumeric(items.at(MaxBit)));
+ fld.bitOffset = from;
+ fld.bitWidth = to - from + 1;
+ } else if (elementName == QLatin1String(kBitOffset)) {
+ fld.bitOffset = int(decodeNumeric(in.readElementText()));
+ } else if (elementName == QLatin1String(kBitWidth)) {
+ fld.bitWidth = int(decodeNumeric(in.readElementText()));
+ } else {
+ in.skipCurrentElement();
+ }
+ }
+ }
+ } else {
+ in.skipCurrentElement();
+ }
+ }
+ }
+ } else {
+ in.skipCurrentElement();
+ }
+ }
+ }
+ }
+
+ return foundGroups;
+}
+
+void PeripheralRegisterHandler::updateRegisterGroups()
+{
+ clear();
+
+ const auto dev = m_engine->device();
+ QTC_ASSERT(dev, return);
+
+ const QString filePath = dev->peripheralDescriptionFilePath();
+ if (filePath.isEmpty())
+ return;
+
+ m_peripheralRegisterGroups = availablePeripheralRegisterGroups(filePath);
+}
+
+void PeripheralRegisterHandler::updateRegister(quint64 address, quint64 value)
+{
+ const auto regItem = m_activeRegisters.value(address);
+ if (!regItem)
+ return;
+
+ regItem->m_reg.previousValue = regItem->m_reg.currentValue;
+ regItem->m_reg.currentValue = value;
+
+ commitUpdates();
+}
+
+QList<quint64> PeripheralRegisterHandler::activeRegisters() const
+{
+ return m_activeRegisters.keys();
+}
+
+QVariant PeripheralRegisterHandler::data(const QModelIndex &idx, int role) const
+{
+ if (role == BaseTreeView::ItemDelegateRole) {
+ return QVariant::fromValue(static_cast<QAbstractItemDelegate *>(
+ new PeripheralRegisterDelegate));
+ }
+ return PeripheralRegisterModel::data(idx, role);
+}
+
+bool PeripheralRegisterHandler::setData(const QModelIndex &idx,
+ const QVariant &data, int role)
+{
+ if (role == BaseTreeView::ItemViewEventRole) {
+ const auto ev = data.value<ItemViewEvent>();
+ if (ev.type() == QEvent::ContextMenu)
+ return contextMenuEvent(ev);
+ }
+ return PeripheralRegisterModel::setData(idx, data, role);
+}
+
+bool PeripheralRegisterHandler::contextMenuEvent(const ItemViewEvent &ev)
+{
+ const DebuggerState state = m_engine->state();
+ const auto menu = new QMenu;
+
+ QMenu *groupMenu = createRegisterGroupsMenu(state);
+ menu->addMenu(groupMenu);
+
+ if (const auto regItem = itemForIndexAtLevel<PeripheralRegisterLevel>(
+ ev.sourceModelIndex())) {
+ // Show the register value format menu only
+ // if a register item chose.
+ QMenu *fmtMenu = createRegisterFormatMenu(state, regItem);
+ menu->addMenu(fmtMenu);
+ } else if (const auto fldItem = itemForIndexAtLevel<PeripheralRegisterFieldLevel>(
+ ev.sourceModelIndex())) {
+ // Show the register field value format menu only
+ // if a register field item chose.
+ QMenu *fmtMenu = createRegisterFieldFormatMenu(state, fldItem);
+ menu->addMenu(fmtMenu);
+ }
+
+ menu->addSeparator();
+ menu->addAction(action(SettingsDialog));
+ menu->popup(ev.globalPos());
+ return true;
+}
+
+QMenu *PeripheralRegisterHandler::createRegisterGroupsMenu(DebuggerState state) const
+{
+ const auto groupMenu = new QMenu(tr("View Groups"));
+ const auto actionGroup = new QActionGroup(groupMenu);
+ bool hasActions = false;
+ for (const PeripheralRegisterGroup &group : qAsConst(m_peripheralRegisterGroups)) {
+ const QString actName = QStringLiteral("%1: %2")
+ .arg(group.name, group.description);
+ QAction *act = groupMenu->addAction(actName);
+ const bool on = m_engine->hasCapability(RegisterCapability)
+ && (state == InferiorStopOk || state == InferiorUnrunnable);
+ act->setEnabled(on);
+ act->setData(group.name);
+ act->setCheckable(true);
+ act->setChecked(group.active);
+ actionGroup->addAction(act);
+ QObject::connect(act, &QAction::triggered,
+ this, &PeripheralRegisterHandler::setActiveGroup);
+ hasActions = true;
+ }
+ groupMenu->setEnabled(hasActions);
+ groupMenu->setStyleSheet("QMenu { menu-scrollable: 1; }");
+ return groupMenu;
+}
+
+QMenu *PeripheralRegisterHandler::createRegisterFormatMenu(
+ DebuggerState state, PeripheralRegisterItem *item) const
+{
+ const auto fmtMenu = new QMenu(tr("Format"));
+ const auto actionGroup = new QActionGroup(fmtMenu);
+
+ const bool on = m_engine->hasCapability(RegisterCapability)
+ && (state == InferiorStopOk || state == InferiorUnrunnable);
+
+ const PeripheralRegisterFormat fmt = item->m_reg.format;
+
+ // Hexadecimal action.
+ const auto hexAct = addCheckableAction(
+ fmtMenu, tr("Hexadecimal"), on,
+ fmt == PeripheralRegisterFormat::Hexadecimal,
+ [item] {
+ item->m_reg.format = PeripheralRegisterFormat::Hexadecimal;
+ item->update();
+ });
+ actionGroup->addAction(hexAct);
+
+ // Decimal action.
+ const auto decAct = addCheckableAction(
+ fmtMenu, tr("Decimal"), on,
+ fmt == PeripheralRegisterFormat::Decimal,
+ [item] {
+ item->m_reg.format = PeripheralRegisterFormat::Decimal;
+ item->update();
+ });
+ actionGroup->addAction(decAct);
+
+ // Octal action.
+ const auto octAct = addCheckableAction(
+ fmtMenu, tr("Octal"), on,
+ fmt == PeripheralRegisterFormat::Octal,
+ [item] {
+ item->m_reg.format = PeripheralRegisterFormat::Octal;
+ item->update();
+ });
+ actionGroup->addAction(octAct);
+
+ // Binary action.
+ const auto binAct = addCheckableAction(
+ fmtMenu, tr("Binary"), on,
+ fmt == PeripheralRegisterFormat::Binary,
+ [item] {
+ item->m_reg.format = PeripheralRegisterFormat::Binary;
+ item->update();
+ });
+ actionGroup->addAction(binAct);
+
+ return fmtMenu;
+}
+
+QMenu *PeripheralRegisterHandler::createRegisterFieldFormatMenu(
+ DebuggerState state, PeripheralRegisterFieldItem *item) const
+{
+ const auto fmtMenu = new QMenu(tr("Format"));
+ const auto actionGroup = new QActionGroup(fmtMenu);
+
+ const bool on = m_engine->hasCapability(RegisterCapability)
+ && (state == InferiorStopOk || state == InferiorUnrunnable);
+
+ const PeripheralRegisterFormat fmt = item->m_fld.format;
+
+ // Hexadecimal action.
+ const auto hexAct = addCheckableAction(
+ fmtMenu, tr("Hexadecimal"), on,
+ fmt == PeripheralRegisterFormat::Hexadecimal,
+ [item] {
+ item->m_fld.format = PeripheralRegisterFormat::Hexadecimal;
+ item->update();
+ });
+ actionGroup->addAction(hexAct);
+
+ // Decimal action.
+ const auto decAct = addCheckableAction(
+ fmtMenu, tr("Decimal"), on,
+ fmt == PeripheralRegisterFormat::Decimal,
+ [item] {
+ item->m_fld.format = PeripheralRegisterFormat::Decimal;
+ item->update();
+ });
+ actionGroup->addAction(decAct);
+
+ // Octal action.
+ const auto octAct = addCheckableAction(
+ fmtMenu, tr("Octal"), on,
+ fmt == PeripheralRegisterFormat::Octal,
+ [item] {
+ item->m_fld.format = PeripheralRegisterFormat::Octal;
+ item->update();
+ });
+ actionGroup->addAction(octAct);
+
+ // Binary action.
+ const auto binAct = addCheckableAction(
+ fmtMenu, tr("Binary"), on,
+ fmt == PeripheralRegisterFormat::Binary,
+ [item] {
+ item->m_fld.format = PeripheralRegisterFormat::Binary;
+ item->update();
+ });
+ actionGroup->addAction(binAct);
+
+ return fmtMenu;
+}
+
+void PeripheralRegisterHandler::setActiveGroup(bool checked)
+{
+ if (!checked)
+ return;
+ deactivateGroups();
+ if (const auto act = qobject_cast<QAction *>(sender())) {
+ const QString groupName = act->data().toString();
+ const auto groupEnd = m_peripheralRegisterGroups.end();
+ const auto groupIt = std::find_if(
+ m_peripheralRegisterGroups.begin(), groupEnd,
+ [groupName](const PeripheralRegisterGroup &group){
+ return group.name == groupName;
+ });
+ if (groupIt == groupEnd)
+ return; // Group not found.
+ // Set active group.
+ groupIt->active = true;
+
+ // Add all register items of active register group.
+ m_activeRegisters.reserve(groupIt->registers.count());
+ for (PeripheralRegister &reg : groupIt->registers) {
+ const auto item = new PeripheralRegisterItem(m_engine, *groupIt, reg);
+ rootItem()->appendChild(item);
+
+ const quint64 address = reg.address(groupIt->baseAddress);
+ m_activeRegisters.insert(address, item);
+ }
+
+ m_engine->reloadPeripheralRegisters();
+ }
+}
+
+void PeripheralRegisterHandler::deactivateGroups()
+{
+ clear();
+
+ for (PeripheralRegisterGroup &group : m_peripheralRegisterGroups)
+ group.active = false;
+
+ m_activeRegisters.clear();
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/peripheralregisterhandler.h b/src/plugins/debugger/peripheralregisterhandler.h
new file mode 100644
index 0000000000..a7f8924113
--- /dev/null
+++ b/src/plugins/debugger/peripheralregisterhandler.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com>
+** 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 "debuggerengine.h"
+
+#include <utils/treemodel.h>
+
+#include <QHash>
+
+QT_BEGIN_NAMESPACE
+class QMenu;
+QT_END_NAMESPACE
+
+namespace Utils { class ItemViewEvent; }
+
+namespace Debugger {
+namespace Internal {
+
+class DebuggerEngine;
+
+enum class PeripheralRegisterAccess
+{
+ Unknown,
+ ReadOnly,
+ WriteOnly,
+ ReadWrite
+};
+
+enum class PeripheralRegisterFormat
+{
+ Hexadecimal,
+ Decimal,
+ Octal,
+ Binary
+};
+
+// PeripheralRegisterField
+
+class PeripheralRegisterField final
+{
+public:
+ QString bitRangeString() const;
+ QString bitValueString(quint64 regValue) const;
+ quint64 bitValue(quint64 regValue) const;
+ quint64 bitMask() const;
+
+ QString name;
+ QString description;
+ int bitOffset = 0;
+ int bitWidth = 0;
+ PeripheralRegisterAccess access = PeripheralRegisterAccess::Unknown;
+ PeripheralRegisterFormat format = PeripheralRegisterFormat::Hexadecimal;
+};
+
+// PeripheralRegisterValue
+
+class PeripheralRegisterValue final
+{
+public:
+ PeripheralRegisterValue(quint64 v = 0) : v(v) {}
+ bool operator==(const PeripheralRegisterValue &other) { return v == other.v; }
+ bool operator!=(const PeripheralRegisterValue &other) { return !operator==(other); }
+
+ bool fromString(const QString &string, PeripheralRegisterFormat fmt);
+ QString toString(int size, PeripheralRegisterFormat fmt) const;
+
+ quint64 v = 0;
+};
+
+// PeripheralRegister
+
+class PeripheralRegister final
+{
+public:
+ QString currentValueString() const;
+ QString previousValueString() const;
+ QString resetValueString() const;
+
+ QString addressString(quint64 baseAddress) const;
+ quint64 address(quint64 baseAddress) const;
+
+ QString name;
+ QString displayName;
+ QString description;
+ quint64 addressOffset = 0;
+ int size = 0; // in bits
+ PeripheralRegisterAccess access = PeripheralRegisterAccess::Unknown;
+ PeripheralRegisterFormat format = PeripheralRegisterFormat::Hexadecimal;
+
+ QVector<PeripheralRegisterField> fields;
+
+ PeripheralRegisterValue currentValue;
+ PeripheralRegisterValue previousValue;
+ PeripheralRegisterValue resetValue;
+};
+
+// PeripheralRegisterGroup
+
+class PeripheralRegisterGroup final
+{
+public:
+ QString name;
+ QString displayName;
+ QString description;
+ quint64 baseAddress = 0;
+ int size = 0; // in bits
+ PeripheralRegisterAccess access = PeripheralRegisterAccess::Unknown;
+ bool active = false;
+ QVector<PeripheralRegister> registers;
+};
+
+// PeripheralRegisterGroups
+
+using PeripheralRegisterGroups = QVector<PeripheralRegisterGroup>;
+
+// PeripheralRegisterItem's
+
+enum { PeripheralRegisterLevel = 1, PeripheralRegisterFieldLevel = 2 };
+
+class PeripheralRegisterFieldItem;
+class PeripheralRegisterItem;
+using PeripheralRegisterRootItem = Utils::TypedTreeItem<PeripheralRegisterItem>;
+using PeripheralRegisterModel = Utils::TreeModel<PeripheralRegisterRootItem,
+ PeripheralRegisterItem,
+ PeripheralRegisterFieldItem>;
+
+// PeripheralRegisterHandler
+
+class PeripheralRegisterHandler final : public PeripheralRegisterModel
+{
+ Q_OBJECT
+public:
+ explicit PeripheralRegisterHandler(DebuggerEngine *engine);
+
+ QAbstractItemModel *model() { return this; }
+
+ void updateRegisterGroups();
+ void updateRegister(quint64 address, quint64 value);
+ void commitUpdates() { emit layoutChanged(); }
+ QList<quint64> activeRegisters() const;
+
+private:
+ QVariant data(const QModelIndex &idx, int role) const final;
+ bool setData(const QModelIndex &idx, const QVariant &data, int role) final;
+
+ bool contextMenuEvent(const Utils::ItemViewEvent &ev);
+ QMenu *createRegisterGroupsMenu(DebuggerState state) const;
+ QMenu *createRegisterFormatMenu(DebuggerState state,
+ PeripheralRegisterItem *item) const;
+ QMenu *createRegisterFieldFormatMenu(DebuggerState state,
+ PeripheralRegisterFieldItem *item) const;
+ void setActiveGroup(bool checked);
+ void deactivateGroups();
+
+ PeripheralRegisterGroups m_peripheralRegisterGroups;
+ QHash<quint64, PeripheralRegisterItem *> m_activeRegisters;
+ DebuggerEngine * const m_engine;
+};
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index a04c110fce..2914998421 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -60,6 +60,7 @@
#include <app/app_version.h>
#include <utils/treemodel.h>
#include <utils/basetreeview.h>
+#include <utils/fileinprojectfinder.h>
#include <utils/qtcassert.h>
#include <QDebug>
@@ -218,7 +219,6 @@ public:
QList<QByteArray> sendBuffer;
QHash<QString, QTextDocument*> sourceDocuments;
- QHash<QString, QWeakPointer<BaseTextEditor> > sourceEditors;
InteractiveInterpreter interpreter;
ApplicationLauncher applicationLauncher;
QmlInspectorAgent inspectorAgent;
@@ -234,7 +234,8 @@ public:
QmlDebug::QDebugMessageClient *msgClient = nullptr;
QHash<int, QmlCallback> callbackForToken;
- QMetaObject::Connection startupMessageFilterConnection;
+
+ FileInProjectFinder fileFinder;
private:
ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData, QList<int> &seenHandles);
@@ -311,17 +312,6 @@ QmlEngine::QmlEngine()
QmlEngine::~QmlEngine()
{
- QObject::disconnect(d->startupMessageFilterConnection);
- QSet<IDocument *> documentsToClose;
-
- QHash<QString, QWeakPointer<BaseTextEditor> >::iterator iter;
- for (iter = d->sourceEditors.begin(); iter != d->sourceEditors.end(); ++iter) {
- QWeakPointer<BaseTextEditor> textEditPtr = iter.value();
- if (textEditPtr)
- documentsToClose << textEditPtr.data()->document();
- }
- EditorManager::closeDocuments(Utils::toList(documentsToClose));
-
delete d;
}
@@ -376,7 +366,6 @@ void QmlEngine::beginConnection()
QTC_ASSERT(state() == EngineRunRequested, return);
- QObject::disconnect(d->startupMessageFilterConnection);
QString host = runParameters().qmlServer.host();
// Use localhost as default
@@ -539,9 +528,8 @@ void QmlEngine::startApplicationLauncher()
{
if (!d->applicationLauncher.isRunning()) {
const Runnable runnable = runParameters().inferior;
- showMessage(tr("Starting %1 %2").arg(QDir::toNativeSeparators(runnable.executable),
- runnable.commandLineArguments),
- Utils::NormalMessageFormat);
+ showMessage(tr("Starting %1").arg(runnable.commandLine().toUserOutput()),
+ NormalMessageFormat);
d->applicationLauncher.start(runnable);
}
}
@@ -664,7 +652,8 @@ void QmlEngine::activateFrame(int index)
return;
stackHandler()->setCurrentIndex(index);
- gotoLocation(stackHandler()->frames().value(index));
+ const StackFrame &frame = stackHandler()->frameAt(index);
+ gotoLocation(frame);
d->updateLocals();
}
@@ -886,12 +875,10 @@ static ConsoleItem *constructLogItemTree(const QVariant &result,
else
text = key + " : Object";
- QMap<QString, QVariant> resultMap = result.toMap();
+ const QMap<QString, QVariant> resultMap = result.toMap();
QVarLengthArray<ConsoleItem *> children(resultMap.size());
- QMapIterator<QString, QVariant> i(result.toMap());
auto it = children.begin();
- while (i.hasNext()) {
- i.next();
+ for (auto i = resultMap.cbegin(), end = resultMap.cend(); i != end; ++i) {
*(it++) = constructLogItemTree(i.value(), i.key());
}
@@ -970,7 +957,7 @@ void QmlEngine::quitDebugger()
void QmlEngine::doUpdateLocals(const UpdateParameters &params)
{
- Q_UNUSED(params);
+ Q_UNUSED(params)
d->updateLocals();
}
@@ -2450,6 +2437,18 @@ void QmlEnginePrivate::flushSendBuffer()
sendBuffer.clear();
}
+QString QmlEngine::toFileInProject(const QUrl &fileUrl)
+{
+ // make sure file finder is properly initialized
+ const DebuggerRunParameters &rp = runParameters();
+ d->fileFinder.setProjectDirectory(rp.projectSourceDirectory);
+ d->fileFinder.setProjectFiles(rp.projectSourceFiles);
+ d->fileFinder.setAdditionalSearchDirectories(rp.additionalSearchDirectories);
+ d->fileFinder.setSysroot(rp.sysRoot);
+
+ return d->fileFinder.findFile(fileUrl).first().toString();
+}
+
DebuggerEngine *createQmlEngine()
{
return new QmlEngine;
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index df31c3c6c5..5101e91bc4 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -50,6 +50,7 @@ public:
void logServiceActivity(const QString &service, const QString &logMessage);
void expressionEvaluated(quint32 queryId, const QVariant &result);
+ QString toFileInProject(const QUrl &fileUrl);
private:
void disconnected();
diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp
index 7614bc413c..d35abc5c65 100644
--- a/src/plugins/debugger/registerhandler.cpp
+++ b/src/plugins/debugger/registerhandler.cpp
@@ -434,7 +434,7 @@ public:
{
//return column == 1 ? Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable
// : Qt::ItemIsSelectable|Qt::ItemIsEnabled;
- Q_UNUSED(column);
+ Q_UNUSED(column)
return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
}
diff --git a/src/plugins/debugger/registerpostmortemaction.cpp b/src/plugins/debugger/registerpostmortemaction.cpp
index 0b74bbabab..be37504a70 100644
--- a/src/plugins/debugger/registerpostmortemaction.cpp
+++ b/src/plugins/debugger/registerpostmortemaction.cpp
@@ -75,7 +75,7 @@ RegisterPostMortemAction::RegisterPostMortemAction(QObject *parent) : Utils::Sav
void RegisterPostMortemAction::readSettings(const QSettings *)
{
- Q_UNUSED(debuggerRegistryValueNameC); // avoid warning from MinGW
+ Q_UNUSED(debuggerRegistryValueNameC) // avoid warning from MinGW
bool registered = false;
HKEY handle = NULL;
diff --git a/src/plugins/debugger/shared/backtrace.cpp b/src/plugins/debugger/shared/backtrace.cpp
index df2270e9be..74e69b3143 100644
--- a/src/plugins/debugger/shared/backtrace.cpp
+++ b/src/plugins/debugger/shared/backtrace.cpp
@@ -41,7 +41,7 @@ void dumpBacktrace(int maxdepth)
if (maxdepth == -1)
maxdepth = 200;
#if defined(Q_OS_LINUX)
- void *bt[200] = {0};
+ void *bt[200] = {nullptr};
qDebug() << "BACKTRACE:";
int size = backtrace(bt, sizeof(bt) / sizeof(bt[0]));
for (int i = 0; i < qMin(size, maxdepth); i++)
diff --git a/src/plugins/debugger/sourceutils.cpp b/src/plugins/debugger/sourceutils.cpp
index b1c254038a..a08221c4e1 100644
--- a/src/plugins/debugger/sourceutils.cpp
+++ b/src/plugins/debugger/sourceutils.cpp
@@ -153,7 +153,7 @@ using SeenHash = QHash<QString, int>;
static void blockRecursion(const Overview &overview,
const Scope *scope,
- unsigned line,
+ int line,
QStringList *uninitializedVariables,
SeenHash *seenHash,
int level = 0)
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index bd57ea0c6d..aeafc69fbf 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -68,47 +68,36 @@ StackHandler::StackHandler(DebuggerEngine *engine)
: m_engine(engine)
{
setObjectName("StackModel");
+ setHeader({tr("Level"), tr("Function"), tr("File"), tr("Line"), tr("Address") });
connect(action(ExpandStack), &QAction::triggered,
this, &StackHandler::reloadFullStack);
connect(action(MaximalStackDepth), &QAction::triggered,
this, &StackHandler::reloadFullStack);
+
+ // For now there's always only "the" current thread.
+ rootItem()->appendChild(new ThreadDummyItem);
}
StackHandler::~StackHandler() = default;
-int StackHandler::rowCount(const QModelIndex &parent) const
-{
- // Since the stack is not a tree, row count is 0 for any valid parent
- return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand);
-}
-
-int StackHandler::columnCount(const QModelIndex &parent) const
+QVariant SpecialStackItem::data(int column, int role) const
{
- return parent.isValid() ? 0 : StackColumnCount;
+ if (role == Qt::DisplayRole && column == StackLevelColumn)
+ return StackHandler::tr("...");
+ if (role == Qt::DisplayRole && column == StackFunctionNameColumn)
+ return StackHandler::tr("<More>");
+ if (role == Qt::DecorationRole && column == StackLevelColumn)
+ return Icons::EMPTY.icon();
+ return QVariant();
}
-QVariant StackHandler::data(const QModelIndex &index, int role) const
+QVariant StackFrameItem::data(int column, int role) const
{
- if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand)
- return QVariant();
-
- if (index.row() == m_stackFrames.size()) {
- if (role == Qt::DisplayRole && index.column() == StackLevelColumn)
- return tr("...");
- if (role == Qt::DisplayRole && index.column() == StackFunctionNameColumn)
- return tr("<More>");
- if (role == Qt::DecorationRole && index.column() == StackLevelColumn)
- return Icons::EMPTY.icon();
- return QVariant();
- }
-
- const StackFrame &frame = m_stackFrames.at(index.row());
-
if (role == Qt::DisplayRole) {
- switch (index.column()) {
+ switch (column) {
case StackLevelColumn:
- return QString::number(index.row() + 1);
+ return row >= 0 ? QString::number(row + 1) : QString();
case StackFunctionNameColumn:
return simplifyType(frame.function);
case StackFileNameColumn:
@@ -123,11 +112,8 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
return QVariant();
}
- if (role == Qt::DecorationRole && index.column() == StackLevelColumn) {
- // Return icon that indicates whether this is the active stack frame
- return (m_contentsValid && index.row() == m_currentIndex)
- ? Icons::LOCATION.icon() : Icons::EMPTY.icon();
- }
+ if (role == Qt::DecorationRole && column == StackLevelColumn)
+ return handler->iconForRow(row);
if (role == Qt::ToolTipRole && boolSetting(UseToolTipsInStackView))
return frame.toToolTip();
@@ -135,31 +121,18 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
return QVariant();
}
-
-QVariant StackHandler::headerData(int section, Qt::Orientation orient, int role) const
+Qt::ItemFlags StackFrameItem::flags(int column) const
{
- if (orient == Qt::Horizontal && role == Qt::DisplayRole) {
- switch (section) {
- case 0: return tr("Level");
- case 1: return tr("Function");
- case 2: return tr("File");
- case 3: return tr("Line");
- case 4: return tr("Address");
- };
- }
- return QVariant();
+ const bool isValid = frame.isUsable() || handler->operatesByInstruction();
+ return isValid && handler->isContentsValid()
+ ? TreeItem::flags(column) : Qt::ItemFlags();
}
-Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
+QIcon StackHandler::iconForRow(int row) const
{
- if (index.row() >= m_stackFrames.size() + m_canExpand)
- return nullptr;
- if (index.row() == m_stackFrames.size())
- return QAbstractTableModel::flags(index);
- const StackFrame &frame = m_stackFrames.at(index.row());
- const bool isValid = frame.isUsable() || m_engine->operatesByInstruction();
- return isValid && m_contentsValid
- ? QAbstractTableModel::flags(index) : Qt::ItemFlags();
+ // Return icon that indicates whether this is the active stack frame
+ return (m_contentsValid && row == m_currentIndex)
+ ? Icons::LOCATION.icon() : Icons::EMPTY.icon();
}
bool StackHandler::setData(const QModelIndex &idx, const QVariant &data, int role)
@@ -178,13 +151,38 @@ bool StackHandler::setData(const QModelIndex &idx, const QVariant &data, int rol
return false;
}
+ThreadDummyItem *StackHandler::dummyThreadItem() const
+{
+ QTC_ASSERT(rootItem()->childCount() == 1, return nullptr);
+ return rootItem()->childAt(0);
+}
+
StackFrame StackHandler::currentFrame() const
{
if (m_currentIndex == -1)
- return StackFrame();
- QTC_ASSERT(m_currentIndex >= 0, return StackFrame());
- QTC_ASSERT(m_currentIndex < m_stackFrames.size(), return StackFrame());
- return m_stackFrames.at(m_currentIndex);
+ return {};
+ QTC_ASSERT(m_currentIndex >= 0, return {});
+ return frameAt(m_currentIndex);
+}
+
+StackFrame StackHandler::frameAt(int index) const
+{
+ auto threadItem = dummyThreadItem();
+ QTC_ASSERT(threadItem, return {});
+ StackFrameItem *frameItem = threadItem->childAt(index);
+ QTC_ASSERT(frameItem, return {});
+ return frameItem->frame;
+}
+
+int StackHandler::stackSize() const
+{
+ return stackRowCount() - m_canExpand;
+}
+
+quint64 StackHandler::topAddress() const
+{
+ QTC_ASSERT(stackRowCount() > 0, return 0);
+ return frameAt(0).address;
}
void StackHandler::setCurrentIndex(int level)
@@ -206,24 +204,40 @@ void StackHandler::setCurrentIndex(int level)
void StackHandler::removeAll()
{
- beginResetModel();
- m_stackFrames.clear();
+ auto threadItem = dummyThreadItem();
+ QTC_ASSERT(threadItem, return);
+ threadItem->removeChildren();
+
setCurrentIndex(-1);
- endResetModel();
+}
+
+bool StackHandler::operatesByInstruction() const
+{
+ return m_engine->operatesByInstruction();
}
void StackHandler::setFrames(const StackFrames &frames, bool canExpand)
{
- beginResetModel();
- m_resetLocationScheduled = false;
+ auto threadItem = dummyThreadItem();
+ QTC_ASSERT(threadItem, return);
+
+ threadItem->removeChildren();
+
m_contentsValid = true;
m_canExpand = canExpand;
- m_stackFrames = frames;
- if (m_stackFrames.size() >= 0)
- setCurrentIndex(0);
- else
+
+ int row = 0;
+ for (const StackFrame &frame : frames)
+ threadItem->appendChild(new StackFrameItem(this, frame, row++));
+
+ if (canExpand)
+ threadItem->appendChild(new SpecialStackItem(this));
+
+ if (frames.isEmpty())
m_currentIndex = -1;
- endResetModel();
+ else
+ setCurrentIndex(0);
+
emit stackChanged();
}
@@ -270,44 +284,42 @@ void StackHandler::prependFrames(const StackFrames &frames)
{
if (frames.isEmpty())
return;
+ auto threadItem = dummyThreadItem();
+ QTC_ASSERT(threadItem, return);
const int count = frames.size();
- beginInsertRows(QModelIndex(), 0, count - 1);
for (int i = count - 1; i >= 0; --i)
- m_stackFrames.prepend(frames.at(i));
- endInsertRows();
+ threadItem->prependChild(new StackFrameItem(this, frames.at(i)));
if (m_currentIndex >= 0)
setCurrentIndex(m_currentIndex + count);
emit stackChanged();
}
+bool StackHandler::isSpecialFrame(int index) const
+{
+ return m_canExpand && index + 1 == stackRowCount();
+}
+
int StackHandler::firstUsableIndex() const
{
if (!m_engine->operatesByInstruction()) {
- for (int i = 0, n = m_stackFrames.size(); i != n; ++i)
- if (m_stackFrames.at(i).isUsable())
+ for (int i = 0, n = stackRowCount(); i != n; ++i)
+ if (frameAt(i).isUsable())
return i;
}
return 0;
}
-const StackFrames &StackHandler::frames() const
-{
- return m_stackFrames;
-}
-
void StackHandler::scheduleResetLocation()
{
- m_resetLocationScheduled = true;
m_contentsValid = false;
}
-void StackHandler::resetLocation()
+int StackHandler::stackRowCount() const
{
- if (m_resetLocationScheduled) {
- beginResetModel();
- m_resetLocationScheduled = false;
- endResetModel();
- }
+ // Only one "thread" for now.
+ auto threadItem = dummyThreadItem();
+ QTC_ASSERT(threadItem, return 0);
+ return threadItem->childCount();
}
// Input a function to be disassembled. Accept CDB syntax
@@ -357,10 +369,11 @@ void StackHandler::saveTaskFile()
}
QTextStream str(&file);
- for (const StackFrame &frame : frames()) {
+ forItemsAtLevel<2>([&str](StackFrameItem *item) {
+ const StackFrame &frame = item->frame;
if (frame.isUsable())
str << frame.file << '\t' << frame.line << "\tstack\tFrame #" << frame.level << '\n';
- }
+ });
}
bool StackHandler::contextMenuEvent(const ItemViewEvent &ev)
@@ -441,7 +454,7 @@ void StackHandler::copyContentsToClipboard()
{
QString str;
int n = rowCount();
- int m = columnCount();
+ int m = columnCount(QModelIndex());
QVector<int> largestColumnWidths(m, 0);
// First, find the widths of the largest columns,
diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h
index 02268e400a..22be87b16f 100644
--- a/src/plugins/debugger/stackhandler.h
+++ b/src/plugins/debugger/stackhandler.h
@@ -27,14 +27,14 @@
#include "stackframe.h"
-#include <QAbstractItemModel>
-
-namespace Utils { class ItemViewEvent; }
+#include <utils/basetreeview.h>
+#include <utils/treemodel.h>
namespace Debugger {
namespace Internal {
class DebuggerEngine;
+class StackHandler;
enum StackColumns
{
@@ -46,7 +46,46 @@ enum StackColumns
StackColumnCount
};
-class StackHandler : public QAbstractTableModel
+class StackFrameItem : public Utils::TreeItem
+{
+public:
+ StackFrameItem(StackHandler *handler, const StackFrame &frame, int row = -1)
+ : handler(handler), frame(frame), row(row)
+ {}
+
+ QVariant data(int column, int role) const override;
+ Qt::ItemFlags flags(int column) const override;
+
+public:
+ StackHandler *handler = nullptr;
+ StackFrame frame;
+ int row = -1;
+};
+
+
+class SpecialStackItem : public StackFrameItem
+{
+public:
+ SpecialStackItem(StackHandler *handler)
+ : StackFrameItem(handler, StackFrame{})
+ {}
+
+ QVariant data(int column, int role) const override;
+};
+
+// FIXME: Move ThreadItem over here.
+class ThreadDummyItem : public Utils::TypedTreeItem<StackFrameItem>
+{
+public:
+};
+
+using StackHandlerModel = Utils::TreeModel<
+ Utils::TypedTreeItem<ThreadDummyItem>,
+ Utils::TypedTreeItem<StackFrameItem>,
+ StackFrameItem
+>;
+
+class StackHandler : public StackHandlerModel
{
Q_OBJECT
@@ -58,34 +97,33 @@ public:
void setFramesAndCurrentIndex(const GdbMi &frames, bool isFull);
int updateTargetFrame(bool isFull);
void prependFrames(const StackFrames &frames);
- const StackFrames &frames() const;
+ bool isSpecialFrame(int index) const;
void setCurrentIndex(int index);
int currentIndex() const { return m_currentIndex; }
int firstUsableIndex() const;
StackFrame currentFrame() const;
- const StackFrame &frameAt(int index) const { return m_stackFrames.at(index); }
- int stackSize() const { return m_stackFrames.size(); }
- quint64 topAddress() const { return m_stackFrames.at(0).address; }
+ StackFrame frameAt(int index) const;
+ int stackSize() const;
+ quint64 topAddress() const;
// Called from StackHandler after a new stack list has been received
void removeAll();
QAbstractItemModel *model() { return this; }
bool isContentsValid() const { return m_contentsValid; }
+ bool operatesByInstruction() const;
void scheduleResetLocation();
- void resetLocation();
- void resetModel() { beginResetModel(); endResetModel(); }
+
+ QIcon iconForRow(int row) const;
signals:
void stackChanged();
void currentIndexChanged();
private:
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
+ int stackRowCount() const; // Including the <more...> "frame"
+
bool setData(const QModelIndex &idx, const QVariant &data, int role) override;
+ ThreadDummyItem *dummyThreadItem() const;
bool contextMenuEvent(const Utils::ItemViewEvent &event);
void reloadFullStack();
@@ -93,10 +131,8 @@ private:
void saveTaskFile();
DebuggerEngine *m_engine;
- StackFrames m_stackFrames;
int m_currentIndex = -1;
bool m_canExpand = false;
- bool m_resetLocationScheduled = false;
bool m_contentsValid = false;
};
diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp
index e25f6aa72b..7ed3da160d 100644
--- a/src/plugins/debugger/stackwindow.cpp
+++ b/src/plugins/debugger/stackwindow.cpp
@@ -49,6 +49,10 @@ StackTreeView::StackTreeView(QWidget *parent)
void StackTreeView::setModel(QAbstractItemModel *model)
{
BaseTreeView::setModel(model);
+
+ if (model)
+ setRootIndex(model->index(0, 0, QModelIndex()));
+
connect(static_cast<StackHandler*>(model), &StackHandler::stackChanged,
this, [this]() {
if (!m_contentsAdjusted)
diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp
index 654adde42f..e9faa11062 100644
--- a/src/plugins/debugger/terminal.cpp
+++ b/src/plugins/debugger/terminal.cpp
@@ -128,7 +128,7 @@ int Terminal::write(const QByteArray &msg)
#ifdef DEBUGGER_USE_TERMINAL
return ::write(m_masterFd, msg.constData(), msg.size());
#else
- Q_UNUSED(msg);
+ Q_UNUSED(msg)
return -1;
#endif
}
@@ -164,7 +164,7 @@ void Terminal::onSlaveReaderActivated(int fd)
if (got >= 0)
stdOutReady(QString::fromUtf8(buffer));
#else
- Q_UNUSED(fd);
+ Q_UNUSED(fd)
#endif
}
@@ -196,7 +196,8 @@ void TerminalRunner::start()
}
// Error message for user is delivered via a signal.
- m_stubProc.start(m_stubRunnable.executable, m_stubRunnable.commandLineArguments);
+ m_stubProc.setCommand(m_stubRunnable.commandLine());
+ m_stubProc.start();
}
void TerminalRunner::stop()
diff --git a/src/plugins/debugger/unstartedappwatcherdialog.cpp b/src/plugins/debugger/unstartedappwatcherdialog.cpp
index 25cfe10d7b..423bcf4699 100644
--- a/src/plugins/debugger/unstartedappwatcherdialog.cpp
+++ b/src/plugins/debugger/unstartedappwatcherdialog.cpp
@@ -89,7 +89,11 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
setWindowTitle(tr("Attach to Process Not Yet Started"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- m_kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging, this);
+ m_kitChooser = new KitChooser(this);
+ m_kitChooser->setKitPredicate([](const Kit *k) {
+ return ToolChainKitAspect::targetAbi(k).os() == Abi::hostAbi().os();
+ });
+ m_kitChooser->setShowIcons(true);
m_kitChooser->populate();
m_kitChooser->setVisible(true);
@@ -118,7 +122,7 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
if (isLocal(runConfig)) {
resetExecutable->setEnabled(true);
connect(resetExecutable, &QPushButton::clicked, this, [this, runnable] {
- m_pathChooser->setPath(runnable.executable);
+ m_pathChooser->setFileName(runnable.executable);
});
}
}
@@ -197,7 +201,7 @@ void UnstartedAppWatcherDialog::selectExecutable()
if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) {
const Runnable runnable = runConfig->runnable();
if (isLocal(runConfig))
- path = QFileInfo(runnable.executable).path();
+ path = runnable.executable.toFileInfo().path();
}
}
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 9eccfbdb1e..66dc416f1b 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -221,18 +221,14 @@ static void saveWatchers()
static void loadFormats()
{
- QVariant value = SessionManager::value("DefaultFormats");
- QMapIterator<QString, QVariant> it(value.toMap());
- while (it.hasNext()) {
- it.next();
+ QMap<QString, QVariant> value = SessionManager::value("DefaultFormats").toMap();
+ for (auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
if (!it.key().isEmpty())
theTypeFormats.insert(it.key(), it.value().toInt());
}
- value = SessionManager::value("IndividualFormats");
- it = QMapIterator<QString, QVariant>(value.toMap());
- while (it.hasNext()) {
- it.next();
+ value = SessionManager::value("IndividualFormats").toMap();
+ for (auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
if (!it.key().isEmpty())
theIndividualFormats.insert(it.key(), it.value().toInt());
}
@@ -241,9 +237,7 @@ static void loadFormats()
static void saveFormats()
{
QMap<QString, QVariant> formats;
- QHashIterator<QString, int> it(theTypeFormats);
- while (it.hasNext()) {
- it.next();
+ for (auto it = theTypeFormats.cbegin(), end = theTypeFormats.cend(); it != end; ++it) {
const int format = it.value();
if (format != AutomaticFormat) {
const QString key = it.key().trimmed();
@@ -254,9 +248,7 @@ static void saveFormats()
SessionManager::setValue("DefaultFormats", formats);
formats.clear();
- it = QHashIterator<QString, int>(theIndividualFormats);
- while (it.hasNext()) {
- it.next();
+ for (auto it = theIndividualFormats.cbegin(), end = theIndividualFormats.cend(); it != end; ++it) {
const int format = it.value();
const QString key = it.key().trimmed();
if (!key.isEmpty())
@@ -2395,9 +2387,7 @@ QStringList WatchHandler::watchedExpressions()
{
// Filter out invalid watchers.
QStringList watcherNames;
- QMapIterator<QString, int> it(theWatcherNames);
- while (it.hasNext()) {
- it.next();
+ for (auto it = theWatcherNames.cbegin(), end = theWatcherNames.cend(); it != end; ++it) {
const QString &watcherName = it.key();
if (!watcherName.isEmpty())
watcherNames.push_back(watcherName);
@@ -2512,9 +2502,7 @@ QString WatchHandler::typeFormatRequests() const
{
QString ba;
if (!theTypeFormats.isEmpty()) {
- QHashIterator<QString, int> it(theTypeFormats);
- while (it.hasNext()) {
- it.next();
+ for (auto it = theTypeFormats.cbegin(), end = theTypeFormats.cend(); it != end; ++it) {
const int format = it.value();
if (format != AutomaticFormat) {
ba.append(toHex(it.key()));
@@ -2532,9 +2520,7 @@ QString WatchHandler::individualFormatRequests() const
{
QString res;
if (!theIndividualFormats.isEmpty()) {
- QHashIterator<QString, int> it(theIndividualFormats);
- while (it.hasNext()) {
- it.next();
+ for (auto it = theIndividualFormats.cbegin(), end = theIndividualFormats.cend(); it != end; ++it) {
const int format = it.value();
if (format != AutomaticFormat) {
res.append(it.key());
@@ -2548,19 +2534,16 @@ QString WatchHandler::individualFormatRequests() const
return res;
}
-void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
+void WatchHandler::appendFormatRequests(DebuggerCommand *cmd) const
{
QJsonArray expanded;
- QSetIterator<QString> jt(m_model->m_expandedINames);
- while (jt.hasNext())
- expanded.append(jt.next());
+ for (const QString &name : qAsConst(m_model->m_expandedINames))
+ expanded.append(name);
cmd->arg("expanded", expanded);
QJsonObject typeformats;
- QHashIterator<QString, int> it(theTypeFormats);
- while (it.hasNext()) {
- it.next();
+ for (auto it = theTypeFormats.cbegin(), end = theTypeFormats.cend(); it != end; ++it) {
const int format = it.value();
if (format != AutomaticFormat)
typeformats.insert(it.key(), format);
@@ -2568,12 +2551,10 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
cmd->arg("typeformats", typeformats);
QJsonObject formats;
- QHashIterator<QString, int> it2(theIndividualFormats);
- while (it2.hasNext()) {
- it2.next();
- const int format = it2.value();
+ for (auto it = theIndividualFormats.cbegin(), end = theIndividualFormats.cend(); it != end; ++it) {
+ const int format = it.value();
if (format != AutomaticFormat)
- formats.insert(it2.key(), format);
+ formats.insert(it.key(), format);
}
cmd->arg("formats", formats);
}
@@ -2586,18 +2567,16 @@ static inline QJsonObject watcher(const QString &iname, const QString &exp)
return watcher;
}
-void WatchHandler::appendWatchersAndTooltipRequests(DebuggerCommand *cmd)
+void WatchHandler::appendWatchersAndTooltipRequests(DebuggerCommand *cmd) const
{
QJsonArray watchers;
const DebuggerToolTipContexts toolTips = m_engine->toolTipManager()->pendingTooltips();
for (const DebuggerToolTipContext &p : toolTips)
watchers.append(watcher(p.iname, p.expression));
- QMapIterator<QString, int> it(WatchHandler::watcherNames());
- while (it.hasNext()) {
- it.next();
+ for (auto it = theWatcherNames.cbegin(), end = theWatcherNames.cend(); it != end; ++it)
watchers.append(watcher("watch." + QString::number(it.value()), it.key()));
- }
+
cmd->arg("watchers", watchers);
}
@@ -2640,10 +2619,6 @@ void WatchHandler::scheduleResetLocation()
m_model->m_contentsValid = false;
}
-void WatchHandler::resetLocation()
-{
-}
-
void WatchHandler::setCurrentItem(const QString &iname)
{
if (WatchItem *item = m_model->findItem(iname)) {
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 39c8630d75..6d94249eea 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -86,8 +86,8 @@ public:
static QStringList watchedExpressions();
static QMap<QString, int> watcherNames();
- void appendFormatRequests(DebuggerCommand *cmd);
- void appendWatchersAndTooltipRequests(DebuggerCommand *cmd);
+ void appendFormatRequests(DebuggerCommand *cmd) const;
+ void appendWatchersAndTooltipRequests(DebuggerCommand *cmd) const;
QString typeFormatRequests() const;
QString individualFormatRequests() const;
@@ -101,7 +101,6 @@ public:
QString watcherName(const QString &exp);
void scheduleResetLocation();
- void resetLocation();
void setCurrentItem(const QString &iname);
void updateLocalsWindow();
diff --git a/src/plugins/designer/codemodelhelpers.cpp b/src/plugins/designer/codemodelhelpers.cpp
index 52bb38f5d1..5f3422e412 100644
--- a/src/plugins/designer/codemodelhelpers.cpp
+++ b/src/plugins/designer/codemodelhelpers.cpp
@@ -67,7 +67,7 @@ public:
bool visit(CPlusPlus::Function * f) override;
private:
- const size_t m_length;
+ const uint m_length;
const char *m_name;
FunctionList m_matches;
@@ -82,8 +82,8 @@ SearchFunction::SearchFunction(const char *name) :
SearchFunction::FunctionList SearchFunction::operator()(const DocumentPtr &doc)
{
m_matches.clear();
- const unsigned globalSymbolCount = doc->globalSymbolCount();
- for (unsigned i = 0; i < globalSymbolCount; ++i)
+ const int globalSymbolCount = doc->globalSymbolCount();
+ for (int i = 0; i < globalSymbolCount; ++i)
accept(doc->globalSymbolAt(i));
return m_matches;
}
@@ -92,8 +92,8 @@ bool SearchFunction::visit(CPlusPlus::Function * f)
{
if (const CPlusPlus::Name *name = f->name())
if (const CPlusPlus::Identifier *id = name->identifier())
- if (id->size() == m_length)
- if (!qstrncmp(m_name, id->chars(), uint(m_length)))
+ if (static_cast<uint>(id->size()) == m_length)
+ if (!qstrncmp(m_name, id->chars(), m_length))
m_matches.push_back(f);
return true;
}
diff --git a/src/plugins/designer/editordata.h b/src/plugins/designer/editordata.h
index c4d92f9a41..81904e405e 100644
--- a/src/plugins/designer/editordata.h
+++ b/src/plugins/designer/editordata.h
@@ -36,7 +36,7 @@ namespace Internal {
class EditorData
{
public:
- explicit operator bool() const { return formWindowEditor != 0; }
+ explicit operator bool() const { return formWindowEditor != nullptr; }
FormWindowEditor *formWindowEditor = nullptr;
SharedTools::WidgetHost *widgetHost = nullptr;
diff --git a/src/plugins/designer/formeditorstack.cpp b/src/plugins/designer/formeditorstack.cpp
index df602dda46..f109138cb3 100644
--- a/src/plugins/designer/formeditorstack.cpp
+++ b/src/plugins/designer/formeditorstack.cpp
@@ -65,7 +65,7 @@ FormEditorStack::~FormEditorStack()
void FormEditorStack::add(const EditorData &data)
{
- if (m_designerCore == 0) { // Initialize first time here
+ if (m_designerCore == nullptr) { // Initialize first time here
m_designerCore = data.widgetHost->formWindow()->core();
connect(m_designerCore->formWindowManager(), &QDesignerFormWindowManagerInterface::activeFormWindowChanged,
this, &FormEditorStack::updateFormWindowSelectionHandles);
@@ -128,7 +128,7 @@ EditorData FormEditorStack::activeEditor() const
SharedTools::WidgetHost *FormEditorStack::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const
{
const int i = indexOfFormWindow(fw);
- return i != -1 ? m_formEditors[i].widgetHost : static_cast<SharedTools::WidgetHost *>(0);
+ return i != -1 ? m_formEditors[i].widgetHost : static_cast<SharedTools::WidgetHost *>(nullptr);
}
void FormEditorStack::removeFormWindowEditor(QObject *xmlEditor)
@@ -183,7 +183,7 @@ void FormEditorStack::formSizeChanged(int w, int h)
SharedTools::WidgetHost *FormEditorStack::formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const
{
const int i = indexOfFormEditor(xmlEditor);
- return i != -1 ? m_formEditors.at(i).widgetHost : static_cast<SharedTools::WidgetHost *>(0);
+ return i != -1 ? m_formEditors.at(i).widgetHost : static_cast<SharedTools::WidgetHost *>(nullptr);
}
void FormEditorStack::modeAboutToChange(Core::Id mode)
diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp
index 09e89beed0..36db2e05ba 100644
--- a/src/plugins/designer/formeditorw.cpp
+++ b/src/plugins/designer/formeditorw.cpp
@@ -229,7 +229,7 @@ static FormEditorData *d = nullptr;
static FormEditorW *m_instance = nullptr;
FormEditorData::FormEditorData() :
- m_formeditor(QDesignerComponents::createFormEditor(0)),
+ m_formeditor(QDesignerComponents::createFormEditor(nullptr)),
m_initStage(FormEditorW::RegisterPlugins)
{
if (Designer::Constants::Internal::debug)
@@ -238,7 +238,7 @@ FormEditorData::FormEditorData() :
d = this;
std::fill(m_designerSubWindows, m_designerSubWindows + DesignerSubWindowCount,
- static_cast<QWidget *>(0));
+ static_cast<QWidget *>(nullptr));
m_formeditor->setTopLevel(ICore::mainWindow());
m_formeditor->setSettingsManager(new SettingsManager());
@@ -352,7 +352,7 @@ void FormEditorData::setupViewActions()
void FormEditorData::fullInit()
{
QTC_ASSERT(m_initStage == FormEditorW::RegisterPlugins, return);
- QElapsedTimer *initTime = 0;
+ QElapsedTimer *initTime = nullptr;
if (Designer::Constants::Internal::debug) {
initTime = new QElapsedTimer;
initTime->start();
@@ -410,7 +410,7 @@ void FormEditorData::fullInit()
m_modeWidget = new QWidget;
m_modeWidget->setObjectName("DesignerModeWidget");
QVBoxLayout *layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_toolBar);
// Avoid mode switch to 'Edit' mode when the application started by
@@ -437,32 +437,32 @@ void FormEditorData::fullInit()
void FormEditorData::initDesignerSubWindows()
{
- std::fill(m_designerSubWindows, m_designerSubWindows + DesignerSubWindowCount, static_cast<QWidget*>(0));
+ std::fill(m_designerSubWindows, m_designerSubWindows + DesignerSubWindowCount, static_cast<QWidget*>(nullptr));
- QDesignerWidgetBoxInterface *wb = QDesignerComponents::createWidgetBox(m_formeditor, 0);
+ QDesignerWidgetBoxInterface *wb = QDesignerComponents::createWidgetBox(m_formeditor, nullptr);
wb->setWindowTitle(tr("Widget Box"));
wb->setObjectName("WidgetBox");
m_formeditor->setWidgetBox(wb);
m_designerSubWindows[WidgetBoxSubWindow] = wb;
- QDesignerObjectInspectorInterface *oi = QDesignerComponents::createObjectInspector(m_formeditor, 0);
+ QDesignerObjectInspectorInterface *oi = QDesignerComponents::createObjectInspector(m_formeditor, nullptr);
oi->setWindowTitle(tr("Object Inspector"));
oi->setObjectName("ObjectInspector");
m_formeditor->setObjectInspector(oi);
m_designerSubWindows[ObjectInspectorSubWindow] = oi;
- QDesignerPropertyEditorInterface *pe = QDesignerComponents::createPropertyEditor(m_formeditor, 0);
+ QDesignerPropertyEditorInterface *pe = QDesignerComponents::createPropertyEditor(m_formeditor, nullptr);
pe->setWindowTitle(tr("Property Editor"));
pe->setObjectName("PropertyEditor");
m_formeditor->setPropertyEditor(pe);
m_designerSubWindows[PropertyEditorSubWindow] = pe;
- QWidget *se = QDesignerComponents::createSignalSlotEditor(m_formeditor, 0);
+ QWidget *se = QDesignerComponents::createSignalSlotEditor(m_formeditor, nullptr);
se->setWindowTitle(tr("Signals && Slots Editor"));
se->setObjectName("SignalsAndSlotsEditor");
m_designerSubWindows[SignalSlotEditorSubWindow] = se;
- QDesignerActionEditorInterface *ae = QDesignerComponents::createActionEditor(m_formeditor, 0);
+ QDesignerActionEditorInterface *ae = QDesignerComponents::createActionEditor(m_formeditor, nullptr);
ae->setWindowTitle(tr("Action Editor"));
ae->setObjectName("ActionEditor");
m_formeditor->setActionEditor(ae);
@@ -641,7 +641,7 @@ void FormEditorData::setupActions()
QObject::connect(m_fwm, &QDesignerFormWindowManagerInterface::activeFormWindowChanged,
[this] (QDesignerFormWindowInterface *afw) {
m_fwm->closeAllPreviews();
- setPreviewMenuEnabled(afw != 0);
+ setPreviewMenuEnabled(afw != nullptr);
});
}
@@ -770,11 +770,11 @@ IEditor *FormEditorData::createEditor()
qDebug() << "FormEditorW::createEditor";
// Create and associate form and text editor.
m_fwm->closeAllPreviews();
- QDesignerFormWindowInterface *form = m_fwm->createFormWindow(0);
- QTC_ASSERT(form, return 0);
+ QDesignerFormWindowInterface *form = m_fwm->createFormWindow(nullptr);
+ QTC_ASSERT(form, return nullptr);
QObject::connect(form, &QDesignerFormWindowInterface::toolChanged, [this] (int i) { toolChanged(i); });
- SharedTools::WidgetHost *widgetHost = new SharedTools::WidgetHost( /* parent */ 0, form);
+ SharedTools::WidgetHost *widgetHost = new SharedTools::WidgetHost( /* parent */ nullptr, form);
FormWindowEditor *formWindowEditor = m_xmlEditorFactory->create(form);
m_editorWidget->add(widgetHost, formWindowEditor);
@@ -806,7 +806,7 @@ SharedTools::WidgetHost *FormEditorW::activeWidgetHost()
ensureInitStage(FullyInitialized);
if (d->m_editorWidget)
return d->m_editorWidget->activeEditor().widgetHost;
- return 0;
+ return nullptr;
}
FormWindowEditor *FormEditorW::activeEditor()
@@ -814,7 +814,7 @@ FormWindowEditor *FormEditorW::activeEditor()
ensureInitStage(FullyInitialized);
if (d->m_editorWidget)
return d->m_editorWidget->activeEditor().formWindowEditor;
- return 0;
+ return nullptr;
}
void FormEditorData::updateShortcut(Command *command)
diff --git a/src/plugins/designer/formtemplatewizardpage.cpp b/src/plugins/designer/formtemplatewizardpage.cpp
index fb01ddc5f4..3387ec6395 100644
--- a/src/plugins/designer/formtemplatewizardpage.cpp
+++ b/src/plugins/designer/formtemplatewizardpage.cpp
@@ -55,10 +55,10 @@ FormPageFactory::FormPageFactory()
Utils::WizardPage *FormPageFactory::create(ProjectExplorer::JsonWizard *wizard, Core::Id typeId,
const QVariant &data)
{
- Q_UNUSED(wizard);
- Q_UNUSED(data);
+ Q_UNUSED(wizard)
+ Q_UNUSED(data)
- QTC_ASSERT(canCreate(typeId), return 0);
+ QTC_ASSERT(canCreate(typeId), return nullptr);
FormTemplateWizardPage *page = new FormTemplateWizardPage;
return page;
diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp
index ac2ddc06ca..b75bad127f 100644
--- a/src/plugins/designer/formwindoweditor.cpp
+++ b/src/plugins/designer/formwindoweditor.cpp
@@ -50,7 +50,7 @@ FormWindowEditor::~FormWindowEditor()
QWidget *FormWindowEditor::toolBar()
{
- return 0;
+ return nullptr;
}
QString FormWindowEditor::contents() const
diff --git a/src/plugins/designer/formwindowfile.cpp b/src/plugins/designer/formwindowfile.cpp
index f84b9e197b..2a3b77df5d 100644
--- a/src/plugins/designer/formwindowfile.cpp
+++ b/src/plugins/designer/formwindowfile.cpp
@@ -286,7 +286,7 @@ void FormWindowFile::slotFormWindowRemoved(QDesignerFormWindowInterface *w)
// as calls to isDirty() are triggered at arbitrary times
// while building.
if (w == m_formWindow)
- m_formWindow = 0;
+ m_formWindow = nullptr;
}
} // namespace Internal
diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp
index d004f4a661..4a760ff65e 100644
--- a/src/plugins/designer/qtcreatorintegration.cpp
+++ b/src/plugins/designer/qtcreatorintegration.cpp
@@ -114,7 +114,7 @@ QWidget *QtCreatorIntegration::containerWindow(QWidget * /*widget*/) const
{
if (SharedTools::WidgetHost *host = FormEditorW::activeWidgetHost())
return host->integrationContainer();
- return 0;
+ return nullptr;
}
static QList<Document::Ptr> findDocumentsIncluding(const Snapshot &docTable,
@@ -142,8 +142,8 @@ static QList<Document::Ptr> findDocumentsIncluding(const Snapshot &docTable,
// Does klass inherit baseClass?
static bool inherits(const Overview &o, const Class *klass, const QString &baseClass)
{
- const unsigned int baseClassCount = klass->baseClassCount();
- for (unsigned int b = 0; b < baseClassCount; ++b)
+ const int baseClassCount = klass->baseClassCount();
+ for (int b = 0; b < baseClassCount; ++b)
if (o.prettyName(klass->baseClassAt(b)->name()) == baseClass)
return true;
return false;
@@ -171,14 +171,14 @@ static const Class *findClass(const Namespace *parentNameSpace, const LookupCont
qDebug() << Q_FUNC_INFO << className;
const Overview o;
- const unsigned namespaceMemberCount = parentNameSpace->memberCount();
- for (unsigned i = 0; i < namespaceMemberCount; ++i) { // we go through all namespace members
+ const int namespaceMemberCount = parentNameSpace->memberCount();
+ for (int i = 0; i < namespaceMemberCount; ++i) { // we go through all namespace members
const Symbol *sym = parentNameSpace->memberAt(i);
// we have found a class - we are interested in classes only
if (const Class *cl = sym->asClass()) {
// 1) we go through class members
- const unsigned classMemberCount = cl->memberCount();
- for (unsigned j = 0; j < classMemberCount; ++j)
+ const int classMemberCount = cl->memberCount();
+ for (int j = 0; j < classMemberCount; ++j)
if (Declaration *decl = cl->memberAt(j)->asDeclaration()) {
// we want to know if the class contains a member (so we look into
// a declaration) of uiClassName type
@@ -212,7 +212,7 @@ static const Class *findClass(const Namespace *parentNameSpace, const LookupCont
} // member is namespave
} // member is no class
} // for members
- return 0;
+ return nullptr;
}
static Function *findDeclaration(const Class *cl, const QString &functionName)
@@ -242,7 +242,7 @@ static Function *findDeclaration(const Class *cl, const QString &functionName)
return fun;
}
}
- return 0;
+ return nullptr;
}
// TODO: remove me, this is taken from cppeditor.cpp. Find some common place for this function
@@ -516,13 +516,11 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName,
newDocTable.insert(i.value());
}
} else {
- const CppTools::WorkingCopy workingCopy =
- CppTools::CppModelManager::instance()->workingCopy();
const Utils::FilePath configFileName =
Utils::FilePath::fromString(CppTools::CppModelManager::configurationFileName());
- QHashIterator<Utils::FilePath, QPair<QByteArray, unsigned> > it = workingCopy.iterator();
- while (it.hasNext()) {
- it.next();
+ const CppTools::WorkingCopy::Table elements =
+ CppTools::CppModelManager::instance()->workingCopy().elements();
+ for (auto it = elements.cbegin(), end = elements.cend(); it != end; ++it) {
const Utils::FilePath &fileName = it.key();
if (fileName != configFileName)
newDocTable.insert(docTable.document(fileName));
@@ -557,7 +555,7 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName,
// Find the class definition (ui class defined as member or base class)
// in the file itself or in the directly included files (order 1).
QString namespaceName;
- const Class *cl = 0;
+ const Class *cl = nullptr;
Document::Ptr doc;
for (const Document::Ptr &d : qAsConst(docMap)) {
diff --git a/src/plugins/designer/resourcehandler.cpp b/src/plugins/designer/resourcehandler.cpp
index 84020f77ee..a86bf21792 100644
--- a/src/plugins/designer/resourcehandler.cpp
+++ b/src/plugins/designer/resourcehandler.cpp
@@ -56,7 +56,11 @@ void ResourceHandler::ensureInitialized()
m_initialized = true;
auto connector = [this](Project *p) {
- connect(p, &Project::fileListChanged, this, &ResourceHandler::updateResources);
+ connect(p,
+ &Project::fileListChanged,
+ this,
+ &ResourceHandler::updateResources,
+ Qt::QueuedConnection);
};
for (Project *p : SessionManager::projects())
diff --git a/src/plugins/designer/settingspage.cpp b/src/plugins/designer/settingspage.cpp
index 4dfa8bc550..f038b7a4db 100644
--- a/src/plugins/designer/settingspage.cpp
+++ b/src/plugins/designer/settingspage.cpp
@@ -48,7 +48,7 @@ QWidget *SettingsPage::widget()
{
m_initialized = true;
if (!m_widget)
- m_widget = m_designerPage->createPage(0);
+ m_widget = m_designerPage->createPage(nullptr);
return m_widget;
}
@@ -66,8 +66,7 @@ void SettingsPage::finish()
delete m_widget;
}
-SettingsPageProvider::SettingsPageProvider(QObject *parent)
- : IOptionsPageProvider(parent)
+SettingsPageProvider::SettingsPageProvider()
{
setCategory(Designer::Constants::SETTINGS_CATEGORY);
setDisplayCategory(QCoreApplication::translate("Designer",
diff --git a/src/plugins/designer/settingspage.h b/src/plugins/designer/settingspage.h
index 6fc13cbb01..13de3c2808 100644
--- a/src/plugins/designer/settingspage.h
+++ b/src/plugins/designer/settingspage.h
@@ -60,7 +60,7 @@ class SettingsPageProvider : public Core::IOptionsPageProvider
Q_OBJECT
public:
- explicit SettingsPageProvider(QObject *parent = nullptr);
+ SettingsPageProvider();
QList<Core::IOptionsPage *> pages() const override;
bool matches(const QString &searchKeyWord) const override;
diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp
index 0c1d6563dd..516dd89c82 100644
--- a/src/plugins/diffeditor/diffeditor.cpp
+++ b/src/plugins/diffeditor/diffeditor.cpp
@@ -138,7 +138,7 @@ void DescriptionEditorWidget::setDisplaySettings(const DisplaySettings &ds)
void DescriptionEditorWidget::setMarginSettings(const MarginSettings &ms)
{
- Q_UNUSED(ms);
+ Q_UNUSED(ms)
TextEditorWidget::setMarginSettings(MarginSettings());
}
diff --git a/src/plugins/diffeditor/diffeditordocument.cpp b/src/plugins/diffeditor/diffeditordocument.cpp
index 34378d9108..b38235adbe 100644
--- a/src/plugins/diffeditor/diffeditordocument.cpp
+++ b/src/plugins/diffeditor/diffeditordocument.cpp
@@ -187,7 +187,7 @@ bool DiffEditorDocument::ignoreWhitespace() const
bool DiffEditorDocument::setContents(const QByteArray &contents)
{
- Q_UNUSED(contents);
+ Q_UNUSED(contents)
return true;
}
diff --git a/src/plugins/diffeditor/diffview.cpp b/src/plugins/diffeditor/diffview.cpp
index c4919692f9..7c7086f52d 100644
--- a/src/plugins/diffeditor/diffview.cpp
+++ b/src/plugins/diffeditor/diffview.cpp
@@ -164,7 +164,7 @@ void UnifiedView::setCurrentDiffFileIndex(int index)
void UnifiedView::setSync(bool sync)
{
- Q_UNUSED(sync);
+ Q_UNUSED(sync)
}
SideBySideView::SideBySideView()
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
index c63d969519..a2799e7ca0 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
@@ -727,7 +727,7 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
m_splitter->addWidget(m_leftEditor);
m_splitter->addWidget(m_rightEditor);
QVBoxLayout *l = new QVBoxLayout(this);
- l->setMargin(0);
+ l->setContentsMargins(0, 0, 0, 0);
l->addWidget(m_splitter);
setFocusProxy(m_leftEditor);
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index adb77c7c0d..6a202c614c 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -321,7 +321,6 @@ private:
QString m_fileName;
};
using Marks = QHash<QChar, Mark>;
-using MarksIterator = QHashIterator<QChar, Mark>;
struct State
{
@@ -3605,8 +3604,7 @@ void FakeVimHandler::Private::updateSelection()
{
QList<QTextEdit::ExtraSelection> selections = m_extraSelections;
if (hasConfig(ConfigShowMarks)) {
- for (MarksIterator it(m_buffer->marks); it.hasNext(); ) {
- it.next();
+ for (auto it = m_buffer->marks.cbegin(), end = m_buffer->marks.cend(); it != end; ++it) {
QTextEdit::ExtraSelection sel;
sel.cursor = m_cursor;
setCursorPosition(&sel.cursor, it.value().position(document()));
@@ -5724,9 +5722,7 @@ bool FakeVimHandler::Private::handleExRegisterCommand(const ExCommand &cmd)
QByteArray regs = cmd.args.toLatin1();
if (regs.isEmpty()) {
regs = "\"0123456789";
- QHashIterator<int, Register> it(g.registers);
- while (it.hasNext()) {
- it.next();
+ for (auto it = g.registers.cbegin(), end = g.registers.cend(); it != end; ++it) {
if (it.key() > '9')
regs += char(it.key());
}
@@ -8263,7 +8259,7 @@ void FakeVimHandler::Private::selectWORDTextObject(bool inner)
void FakeVimHandler::Private::selectSentenceTextObject(bool inner)
{
- Q_UNUSED(inner);
+ Q_UNUSED(inner)
}
void FakeVimHandler::Private::selectParagraphTextObject(bool inner)
@@ -8535,10 +8531,8 @@ bool FakeVimHandler::Private::jumpToMark(QChar mark, bool backTickMode)
void FakeVimHandler::Private::updateMarks(const Marks &newMarks)
{
- for (MarksIterator it(newMarks); it.hasNext(); ) {
- it.next();
+ for (auto it = newMarks.cbegin(), end = newMarks.cend(); it != end; ++it)
m_buffer->marks[it.key()] = it.value();
- }
}
RangeMode FakeVimHandler::Private::registerRangeMode(int reg) const
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index bb73e18141..29defad573 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -284,7 +284,7 @@ protected:
QPainter p(this);
QPalette pal = m_editor->extraArea()->palette();
const QColor fg = pal.color(QPalette::Dark);
- const QColor bg = pal.color(QPalette::Background);
+ const QColor bg = pal.color(QPalette::Window);
p.setPen(fg);
// Draw relative line numbers.
@@ -970,7 +970,7 @@ public:
void setActive(const QString &needle, bool forward, FakeVimHandler *handler)
{
- Q_UNUSED(forward);
+ Q_UNUSED(forward)
m_handler = handler;
if (!m_handler)
return;
diff --git a/src/plugins/genericprojectmanager/CMakeLists.txt b/src/plugins/genericprojectmanager/CMakeLists.txt
index d41571b5ff..282b86d029 100644
--- a/src/plugins/genericprojectmanager/CMakeLists.txt
+++ b/src/plugins/genericprojectmanager/CMakeLists.txt
@@ -3,7 +3,8 @@ if (WITH_TESTS)
endif()
add_qtc_plugin(GenericProjectManager
- PLUGIN_DEPENDS Core CppTools ProjectExplorer QtSupport TextEditor ${TST_COMPONENT}
+ PLUGIN_DEPENDS Core ProjectExplorer QtSupport TextEditor ${TST_COMPONENT}
+ PLUGIN_RECOMMENDS CppTools
SOURCES ${TEST_SOURCES}
filesselectionwizardpage.cpp filesselectionwizardpage.h
genericbuildconfiguration.cpp genericbuildconfiguration.h
@@ -15,8 +16,3 @@ add_qtc_plugin(GenericProjectManager
genericprojectplugin.cpp genericprojectplugin.h
genericprojectwizard.cpp genericprojectwizard.h
)
-
-extend_qtc_plugin(GenericProjectManager
- CONDITION WITH_TESTS
- SOURCES genericprojectplugin_test.cpp
-)
diff --git a/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp b/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp
index 4c94efab5b..12d61b1611 100644
--- a/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp
+++ b/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp
@@ -58,15 +58,15 @@ GenericBuildConfiguration::GenericBuildConfiguration(Target *parent, Core::Id id
updateCacheAndEmitEnvironmentChanged();
}
-void GenericBuildConfiguration::initialize(const BuildInfo &info)
+void GenericBuildConfiguration::initialize()
{
- BuildConfiguration::initialize(info);
+ BuildConfiguration::initialize();
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
- buildSteps->appendStep(new GenericMakeStep(buildSteps, "all"));
+ buildSteps->appendStep(Constants::GENERIC_MS_ID);
BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
- cleanSteps->appendStep(new GenericMakeStep(cleanSteps, "clean"));
+ cleanSteps->appendStep(Constants::GENERIC_MS_ID);
updateCacheAndEmitEnvironmentChanged();
}
@@ -85,34 +85,20 @@ GenericBuildConfigurationFactory::GenericBuildConfigurationFactory()
setSupportedProjectMimeTypeName(Constants::GENERICMIMETYPE);
}
-GenericBuildConfigurationFactory::~GenericBuildConfigurationFactory() = default;
-
-QList<BuildInfo> GenericBuildConfigurationFactory::availableBuilds(const Target *parent) const
-{
- return {createBuildInfo(parent->kit(), parent->project()->projectDirectory())};
-}
-
-QList<BuildInfo> GenericBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
-{
- BuildInfo info = createBuildInfo(k, Project::projectDirectory(Utils::FilePath::fromString(projectPath)));
- //: The name of the build configuration created by default for a generic project.
- info.displayName = tr("Default");
- return {info};
-}
-
-BuildInfo GenericBuildConfigurationFactory::createBuildInfo(const Kit *k,
- const Utils::FilePath &buildDir) const
+QList<BuildInfo> GenericBuildConfigurationFactory::availableBuilds
+ (const Kit *k, const FilePath &projectPath, bool forSetup) const
{
BuildInfo info(this);
info.typeName = tr("Build");
- info.buildDirectory = buildDir;
+ info.buildDirectory = forSetup ? Project::projectDirectory(projectPath) : projectPath;
info.kitId = k->id();
- return info;
-}
-BuildConfiguration::BuildType GenericBuildConfiguration::buildType() const
-{
- return Unknown;
+ if (forSetup) {
+ //: The name of the build configuration created by default for a generic project.
+ info.displayName = tr("Default");
+ }
+
+ return {info};
}
void GenericBuildConfiguration::addToEnvironment(Utils::Environment &env) const
diff --git a/src/plugins/genericprojectmanager/genericbuildconfiguration.h b/src/plugins/genericprojectmanager/genericbuildconfiguration.h
index fdd97c36cf..03e590ab92 100644
--- a/src/plugins/genericprojectmanager/genericbuildconfiguration.h
+++ b/src/plugins/genericprojectmanager/genericbuildconfiguration.h
@@ -39,8 +39,7 @@ class GenericBuildConfiguration : public ProjectExplorer::BuildConfiguration
friend class ProjectExplorer::BuildConfigurationFactory;
GenericBuildConfiguration(ProjectExplorer::Target *parent, Core::Id id);
- void initialize(const ProjectExplorer::BuildInfo &info) override;
- BuildType buildType() const override;
+ void initialize() override;
void addToEnvironment(Utils::Environment &env) const final;
};
@@ -50,14 +49,11 @@ class GenericBuildConfigurationFactory : public ProjectExplorer::BuildConfigurat
public:
GenericBuildConfigurationFactory();
- ~GenericBuildConfigurationFactory() override;
private:
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override;
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
-
- ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k, const Utils::FilePath &buildDir) const;
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k,
+ const Utils::FilePath &projectPath,
+ bool forSetup) const override;
};
} // namespace Internal
diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp
index 9753140156..184aacb11c 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.cpp
+++ b/src/plugins/genericprojectmanager/genericmakestep.cpp
@@ -26,6 +26,7 @@
#include "genericmakestep.h"
#include "genericprojectconstants.h"
+#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/projectexplorerconstants.h>
using namespace ProjectExplorer;
@@ -33,50 +34,23 @@ using namespace ProjectExplorer;
namespace GenericProjectManager {
namespace Internal {
-const char GENERIC_MS_ID[] = "GenericProjectManager.GenericMakeStep";
-
-GenericMakeStep::GenericMakeStep(BuildStepList *parent, const QString &buildTarget)
- : MakeStep(parent, GENERIC_MS_ID, buildTarget, {"all", "clean"})
-{
-}
-
-//
-// GenericMakeAllStepFactory
-//
-
-GenericMakeAllStepFactory::GenericMakeAllStepFactory()
+GenericMakeStep::GenericMakeStep(BuildStepList *parent)
+ : MakeStep(parent, Constants::GENERIC_MS_ID)
{
- struct Step : GenericMakeStep
- {
- Step(BuildStepList *bsl) : GenericMakeStep(bsl, QString("all")) { }
- };
-
- registerStep<Step>(GENERIC_MS_ID);
- setDisplayName(MakeStep::defaultDisplayName());
- setSupportedProjectType(Constants::GENERICPROJECT_ID);
- setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD,
- ProjectExplorer::Constants::BUILDSTEPS_DEPLOY});
+ if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_BUILD) {
+ setBuildTarget("all");
+ } else if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
+ setBuildTarget("clean");
+ setClean(true);
+ }
+ setAvailableBuildTargets({"all", "clean"});
}
-//
-// GenericMakeCleanStepFactory
-//
-
-GenericMakeCleanStepFactory::GenericMakeCleanStepFactory()
+GenericMakeStepFactory::GenericMakeStepFactory()
{
- struct Step : GenericMakeStep
- {
- Step(BuildStepList *bsl) : GenericMakeStep(bsl)
- {
- setBuildTarget("clean", true);
- setClean(true);
- }
- };
-
- registerStep<Step>(GENERIC_MS_ID);
+ registerStep<GenericMakeStep>(Constants::GENERIC_MS_ID);
setDisplayName(MakeStep::defaultDisplayName());
setSupportedProjectType(Constants::GENERICPROJECT_ID);
- setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
}
} // namespace Internal
diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h
index 6fe6bc4798..d48b341f59 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.h
+++ b/src/plugins/genericprojectmanager/genericmakestep.h
@@ -37,19 +37,13 @@ class GenericMakeStep : public ProjectExplorer::MakeStep
Q_OBJECT
public:
- explicit GenericMakeStep(ProjectExplorer::BuildStepList *parent, const QString &buildTarget = {});
+ explicit GenericMakeStep(ProjectExplorer::BuildStepList *parent);
};
-class GenericMakeAllStepFactory : public ProjectExplorer::BuildStepFactory
+class GenericMakeStepFactory : public ProjectExplorer::BuildStepFactory
{
public:
- GenericMakeAllStepFactory();
-};
-
-class GenericMakeCleanStepFactory : public ProjectExplorer::BuildStepFactory
-{
-public:
- GenericMakeCleanStepFactory();
+ GenericMakeStepFactory();
};
} // namespace Internal
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index c15b9d85fb..1c280eb490 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -34,10 +34,9 @@
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
-#include <cpptools/cpptoolsconstants.h>
-#include <cpptools/cppmodelmanager.h>
-#include <cpptools/projectinfo.h>
-#include <cpptools/cppprojectupdater.h>
+#include <cpptools/cppprojectupdaterinterface.h>
+
+#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/buildsteplist.h>
@@ -45,7 +44,6 @@
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/target.h>
@@ -63,6 +61,7 @@
#include <QDir>
#include <QFileInfo>
#include <QHash>
+#include <QMetaObject>
#include <QSet>
#include <QStringList>
@@ -99,8 +98,8 @@ public:
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override
{
- Q_UNUSED(errorString);
- Q_UNUSED(flag);
+ Q_UNUSED(errorString)
+ Q_UNUSED(flag)
if (type == TypePermissions)
return true;
m_project->refresh(m_options);
@@ -143,9 +142,11 @@ public:
return m_project->addFiles(filePaths);
}
- bool removeFiles(const QStringList &filePaths, QStringList * = nullptr) override
+ RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList * = nullptr) override
{
- return m_project->removeFiles(filePaths);
+ return m_project->removeFiles(filePaths) ? RemovedFilesFromProject::Ok
+ : RemovedFilesFromProject::Error;
}
bool renameFile(const QString &filePath, const QString &newFilePath) override
@@ -170,15 +171,35 @@ static bool writeFile(const QString &filePath, const QString &contents)
return saver.write(contents.toUtf8()) && saver.finalize();
}
-GenericProject::GenericProject(const Utils::FilePath &fileName) :
- Project(Constants::GENERICMIMETYPE, fileName, [this]() { refresh(Everything); }),
- m_cppCodeModelUpdater(new CppTools::CppProjectUpdater),
- m_deployFileWatcher(new FileSystemWatcher(this))
+GenericProject::GenericProject(const Utils::FilePath &fileName)
+ : Project(Constants::GENERICMIMETYPE, fileName)
+ , m_deployFileWatcher(new FileSystemWatcher(this))
{
setId(Constants::GENERICPROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
+ QObject *projectUpdaterFactory = ExtensionSystem::PluginManager::getObjectByName(
+ "CppProjectUpdaterFactory");
+ if (projectUpdaterFactory) {
+ const bool successFullyCreatedProjectUpdater
+ = QMetaObject::invokeMethod(projectUpdaterFactory,
+ "create",
+ Q_RETURN_ARG(CppTools::CppProjectUpdaterInterface *,
+ m_cppCodeModelUpdater));
+ QTC_CHECK(successFullyCreatedProjectUpdater);
+ }
+
+ connect(this, &GenericProject::projectFileIsDirty, this, [this](const FilePath &p) {
+ if (p.endsWith(".files"))
+ refresh(Files);
+ else if (p.endsWith(".includes") || p.endsWith(".config") || p.endsWith(".cxxflags")
+ || p.endsWith(".cflags"))
+ refresh(Configuration);
+ else
+ refresh(Everything);
+ });
+
const QFileInfo fileInfo = projectFilePath().toFileInfo();
const QDir dir = fileInfo.dir();
@@ -186,7 +207,7 @@ GenericProject::GenericProject(const Utils::FilePath &fileName) :
m_filesFileName = QFileInfo(dir, projectName + ".files").absoluteFilePath();
m_includesFileName = QFileInfo(dir, projectName + ".includes").absoluteFilePath();
- m_configFileName = QFileInfo(dir, projectName + ".config").absoluteFilePath();
+ m_configFileName = QFileInfo(dir, projectName + ".config").absoluteFilePath();
const QFileInfo cxxflagsFileInfo(dir, projectName + ".cxxflags");
m_cxxflagsFileName = cxxflagsFileInfo.absoluteFilePath();
@@ -200,34 +221,25 @@ GenericProject::GenericProject(const Utils::FilePath &fileName) :
QTC_CHECK(writeFile(m_cflagsFileName, Constants::GENERICPROJECT_CFLAGS_FILE_TEMPLATE));
}
- m_filesIDocument
- = new ProjectDocument(Constants::GENERICMIMETYPE, FilePath::fromString(m_filesFileName),
- [this]() { refresh(Files); });
- m_includesIDocument
- = new ProjectDocument(Constants::GENERICMIMETYPE, FilePath::fromString(m_includesFileName),
- [this]() { refresh(Configuration); });
- m_configIDocument
- = new ProjectDocument(Constants::GENERICMIMETYPE, FilePath::fromString(m_configFileName),
- [this]() { refresh(Configuration); });
- m_cxxFlagsIDocument
- = new ProjectDocument(Constants::GENERICMIMETYPE, FilePath::fromString(m_cxxflagsFileName),
- [this]() { refresh(Configuration); });
- m_cFlagsIDocument
- = new ProjectDocument(Constants::GENERICMIMETYPE, FilePath::fromString(m_cflagsFileName),
- [this]() { refresh(Configuration); });
-
- connect(m_deployFileWatcher, &FileSystemWatcher::fileChanged,
- this, &GenericProject::updateDeploymentData);
+ setExtraProjectFiles({FilePath::fromString(m_filesFileName),
+ FilePath::fromString(m_includesFileName),
+ FilePath::fromString(m_configFileName),
+ FilePath::fromString(m_cxxflagsFileName),
+ FilePath::fromString(m_cflagsFileName)});
+
+ connect(m_deployFileWatcher,
+ &FileSystemWatcher::fileChanged,
+ this,
+ &GenericProject::updateDeploymentData);
+
+ connect(this, &Project::activeTargetChanged, this, [this] { refresh(Everything); });
+
+ connect(this, &Project::activeBuildConfigurationChanged, this, [this] { refresh(Everything); });
}
GenericProject::~GenericProject()
{
delete m_cppCodeModelUpdater;
- m_filesIDocument->deleteLater();
- m_includesIDocument->deleteLater();
- m_configIDocument->deleteLater();
- m_cxxFlagsIDocument->deleteLater();
- m_cFlagsIDocument->deleteLater();
}
static QStringList readLines(const QString &absoluteFileName)
@@ -289,7 +301,8 @@ bool GenericProject::addFiles(const QStringList &filePaths)
for (const QString &filePath : filePaths)
insertSorted(&newList, baseDir.relativeFilePath(filePath));
- const QSet<QString> includes = Utils::toSet(m_projectIncludePaths);
+ const auto includes = transform<QSet<QString>>(m_projectIncludePaths,
+ [](const HeaderPath &hp) { return hp.path; });
QSet<QString> toAdd;
for (const QString &filePath : filePaths) {
@@ -373,12 +386,23 @@ void GenericProject::parseProject(RefreshOptions options)
if (options & Configuration) {
m_rawProjectIncludePaths = readLines(m_includesFileName);
- m_projectIncludePaths = processEntries(m_rawProjectIncludePaths);
+ QStringList normalPaths;
+ QStringList frameworkPaths;
+ for (const QString &rawPath : qAsConst(m_rawProjectIncludePaths)) {
+ if (rawPath.startsWith("-F"))
+ frameworkPaths << rawPath.mid(2);
+ else
+ normalPaths << rawPath;
+ }
+ const auto stringsToHeaderPaths = [this](const QStringList &paths, HeaderPathType type) {
+ return transform<HeaderPaths>(processEntries(paths),
+ [type](const QString &p) { return HeaderPath(p, type);
+ });
+ };
+ m_projectIncludePaths = stringsToHeaderPaths(normalPaths, HeaderPathType::User);
+ m_projectIncludePaths << stringsToHeaderPaths(frameworkPaths, HeaderPathType::Framework);
m_cxxflags = readFlags(m_cxxflagsFileName);
m_cflags = readFlags(m_cflagsFileName);
-
- // TODO: Possibly load some configuration from the project file
- //QSettings projectInfo(m_fileName, QSettings::IniFormat);
}
}
@@ -388,7 +412,7 @@ FilePath GenericProject::findCommonSourceRoot()
return FilePath::fromFileInfo(QFileInfo(m_filesFileName).absolutePath());
QString root = m_files.front();
- for (const QString &item : m_files) {
+ for (const QString &item : qAsConst(m_files)) {
if (root.length() > item.length())
root.truncate(item.length());
@@ -404,7 +428,7 @@ FilePath GenericProject::findCommonSourceRoot()
void GenericProject::refresh(RefreshOptions options)
{
- emitParsingStarted();
+ ParseGuard guard = guardParsingRun();
parseProject(options);
if (options & Files) {
@@ -413,7 +437,7 @@ void GenericProject::refresh(RefreshOptions options)
// find the common base directory of all source files
Utils::FilePath baseDir = findCommonSourceRoot();
- for (const QString &f : m_files) {
+ for (const QString &f : qAsConst(m_files)) {
FileType fileType = FileType::Source; // ### FIXME
if (f.endsWith(".qrc"))
fileType = FileType::Resource;
@@ -437,7 +461,7 @@ void GenericProject::refresh(RefreshOptions options)
refreshCppCodeModel();
updateDeploymentData();
- emitParsingFinished(true);
+ guard.markAsSuccess();
}
/**
@@ -490,20 +514,22 @@ QStringList GenericProject::processEntries(const QStringList &paths,
void GenericProject::refreshCppCodeModel()
{
+ if (!m_cppCodeModelUpdater)
+ return;
QtSupport::CppKitInfo kitInfo(this);
QTC_ASSERT(kitInfo.isValid(), return);
- CppTools::RawProjectPart rpp;
+ RawProjectPart rpp;
rpp.setDisplayName(displayName());
rpp.setProjectFileLocation(projectFilePath().toString());
rpp.setQtVersion(kitInfo.projectPartQtVersion);
- rpp.setIncludePaths(m_projectIncludePaths);
+ rpp.setHeaderPaths(m_projectIncludePaths);
rpp.setConfigFileName(m_configFileName);
rpp.setFlagsForCxx({nullptr, m_cxxflags});
rpp.setFlagsForC({nullptr, m_cflags});
rpp.setFiles(m_files);
- m_cppCodeModelUpdater->update({this, kitInfo, {rpp}});
+ m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), {rpp}});
}
void GenericProject::updateDeploymentData()
@@ -532,37 +558,14 @@ void GenericProject::updateDeploymentData()
}
}
-void GenericProject::activeTargetWasChanged()
-{
- if (m_activeTarget) {
- disconnect(m_activeTarget, &Target::activeBuildConfigurationChanged,
- this, &GenericProject::activeBuildConfigurationWasChanged);
- }
-
- m_activeTarget = activeTarget();
-
- if (!m_activeTarget)
- return;
-
- connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
- this, &GenericProject::activeBuildConfigurationWasChanged);
- refresh(Everything);
-}
-
-void GenericProject::activeBuildConfigurationWasChanged()
-{
- refresh(Everything);
-}
-
Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *errorMessage)
{
const RestoreResult result = Project::fromMap(map, errorMessage);
if (result != RestoreResult::Ok)
return result;
- Kit *defaultKit = KitManager::defaultKit();
- if (!activeTarget() && defaultKit)
- addTarget(createTarget(defaultKit));
+ if (!activeTarget())
+ addTargetForDefaultKit();
// Sanity check: We need both a buildconfiguration and a runconfiguration!
const QList<Target *> targetList = targets();
@@ -578,14 +581,6 @@ Project::RestoreResult GenericProject::fromMap(const QVariantMap &map, QString *
t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
}
- m_activeTarget = activeTarget();
- if (m_activeTarget) {
- connect(m_activeTarget, &Target::activeBuildConfigurationChanged,
- this, &GenericProject::activeBuildConfigurationWasChanged);
- }
-
- connect(this, &Project::activeTargetChanged,
- this, &GenericProject::activeTargetWasChanged);
refresh(Everything);
return RestoreResult::Ok;
}
diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h
index 9f742f322f..37053e0de3 100644
--- a/src/plugins/genericprojectmanager/genericproject.h
+++ b/src/plugins/genericprojectmanager/genericproject.h
@@ -25,9 +25,13 @@
#pragma once
+#include <projectexplorer/headerpath.h>
#include <projectexplorer/project.h>
+#include <utils/fileutils.h>
-namespace CppTools { class CppProjectUpdater; }
+namespace CppTools {
+class CppProjectUpdaterInterface;
+}
namespace Utils { class FileSystemWatcher; }
namespace GenericProjectManager {
@@ -46,6 +50,8 @@ public:
bool setFiles(const QStringList &filePaths);
bool renameFile(const QString &filePath, const QString &newFilePath);
+ Utils::FilePath filesFilePath() const { return Utils::FilePath::fromString(m_filesFileName); }
+
enum RefreshOptions {
Files = 0x01,
Configuration = 0x02,
@@ -69,30 +75,22 @@ private:
Utils::FilePath findCommonSourceRoot();
void refreshCppCodeModel();
void updateDeploymentData();
- void activeTargetWasChanged();
- void activeBuildConfigurationWasChanged();
QString m_filesFileName;
QString m_includesFileName;
QString m_configFileName;
QString m_cxxflagsFileName;
QString m_cflagsFileName;
- ProjectExplorer::ProjectDocument *m_filesIDocument = nullptr;
- ProjectExplorer::ProjectDocument *m_includesIDocument = nullptr;
- ProjectExplorer::ProjectDocument *m_configIDocument = nullptr;
- ProjectExplorer::ProjectDocument *m_cxxFlagsIDocument = nullptr;
- ProjectExplorer::ProjectDocument *m_cFlagsIDocument = nullptr;
QStringList m_rawFileList;
QStringList m_files;
QHash<QString, QString> m_rawListEntries;
QStringList m_rawProjectIncludePaths;
- QStringList m_projectIncludePaths;
+ ProjectExplorer::HeaderPaths m_projectIncludePaths;
QStringList m_cxxflags;
QStringList m_cflags;
- CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
+ CppTools::CppProjectUpdaterInterface *m_cppCodeModelUpdater = nullptr;
- ProjectExplorer::Target *m_activeTarget = nullptr;
Utils::FileSystemWatcher * const m_deployFileWatcher = nullptr;
};
diff --git a/src/plugins/genericprojectmanager/genericprojectconstants.h b/src/plugins/genericprojectmanager/genericprojectconstants.h
index 373663cf51..7fa597f99d 100644
--- a/src/plugins/genericprojectmanager/genericprojectconstants.h
+++ b/src/plugins/genericprojectmanager/genericprojectconstants.h
@@ -30,6 +30,8 @@ namespace Constants {
const char GENERICMIMETYPE[] = "text/x-generic-project"; // ### FIXME
+const char GENERIC_MS_ID[] = "GenericProjectManager.GenericMakeStep";
+
// Contexts
const char FILES_EDITOR_ID[] = "QT4.FilesEditor";
diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.pro b/src/plugins/genericprojectmanager/genericprojectmanager.pro
index 3032f1edfc..e1e2022a39 100644
--- a/src/plugins/genericprojectmanager/genericprojectmanager.pro
+++ b/src/plugins/genericprojectmanager/genericprojectmanager.pro
@@ -17,9 +17,4 @@ SOURCES = genericproject.cpp \
genericbuildconfiguration.cpp \
filesselectionwizardpage.cpp
-equals(TEST, 1) {
- SOURCES += genericprojectplugin_test.cpp
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
RESOURCES += genericprojectmanager.qrc
diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.qbs b/src/plugins/genericprojectmanager/genericprojectmanager.qbs
index 273e58e791..e6ab357492 100644
--- a/src/plugins/genericprojectmanager/genericprojectmanager.qbs
+++ b/src/plugins/genericprojectmanager/genericprojectmanager.qbs
@@ -8,12 +8,15 @@ QtcPlugin {
Depends { name: "Utils" }
Depends { name: "Core" }
- Depends { name: "CppTools" }
Depends { name: "TextEditor" }
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
Depends { name: "app_version_header" }
+ pluginRecommends: [
+ "CppTools"
+ ]
+
pluginTestDepends: [
"CppEditor",
]
@@ -35,12 +38,4 @@ QtcPlugin {
"genericprojectwizard.cpp",
"genericprojectwizard.h",
]
-
- Group {
- name: "Tests"
- condition: qtc.testsEnabled
- files: [ "genericprojectplugin_test.cpp" ]
-
- cpp.defines: outer.concat(['SRCDIR="' + FileInfo.path(filePath) + '"'])
- }
}
diff --git a/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri b/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri
index c6cc4edf78..8ec35ce7bd 100644
--- a/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri
+++ b/src/plugins/genericprojectmanager/genericprojectmanager_dependencies.pri
@@ -5,8 +5,9 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \
coreplugin \
projectexplorer \
- cpptools \
texteditor \
qtsupport
+QTC_PLUGIN_RECOMMENDS += \
+ cpptools
QTC_TEST_DEPENDS += \
cppeditor
diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp
index 73183ffb13..0ffa12e2cf 100644
--- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp
@@ -39,16 +39,21 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmanager.h>
+#include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/selectablefilesmodel.h>
+#include <projectexplorer/taskhub.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
#include <QAction>
using namespace Core;
using namespace ProjectExplorer;
+using namespace Utils;
+namespace PEC = ProjectExplorer::Constants;
namespace GenericProjectManager {
namespace Internal {
@@ -59,8 +64,7 @@ public:
GenericProjectPluginPrivate();
ProjectFilesFactory projectFilesFactory;
- GenericMakeAllStepFactory makeAllStepFactory;
- GenericMakeCleanStepFactory makeCleanStepFactory;
+ GenericMakeStepFactory makeStepFactory;
GenericBuildConfigurationFactory buildConfigFactory;
QAction editFilesAction{GenericProjectPlugin::tr("Edit Files..."), nullptr};
@@ -85,13 +89,12 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate()
IWizardFactory::registerFactoryCreator([] { return QList<IWizardFactory *>{new GenericProjectWizard}; });
- ActionContainer *mproject =
- ActionManager::actionContainer(ProjectExplorer::Constants::M_PROJECTCONTEXT);
+ ActionContainer *mproject = ActionManager::actionContainer(PEC::M_PROJECTCONTEXT);
Command *command = ActionManager::registerAction(&editFilesAction,
"GenericProjectManager.EditFiles", Context(Constants::GENERICPROJECT_ID));
command->setAttribute(Command::CA_Hide);
- mproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_FILES);
+ mproject->addAction(command, PEC::G_PROJECT_FILES);
connect(&editFilesAction, &QAction::triggered, this, [] {
auto genericProject = qobject_cast<GenericProject *>(ProjectTree::currentProject());
@@ -101,7 +104,26 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate()
genericProject->files(Project::AllFiles),
ICore::mainWindow());
if (sfd.exec() == QDialog::Accepted)
- genericProject->setFiles(Utils::transform(sfd.selectedFiles(), &Utils::FilePath::toString));
+ genericProject->setFiles(transform(sfd.selectedFiles(), &FilePath::toString));
+ });
+
+
+ const auto removeDirAction = new QAction(tr("Remove Directory"), this);
+ Command * const cmd = ActionManager::registerAction(removeDirAction, "GenericProject.RemoveDir",
+ Context(PEC::C_PROJECT_TREE));
+ ActionManager::actionContainer(PEC::M_FOLDERCONTEXT)->addAction(cmd, PEC::G_FOLDER_OTHER);
+ connect(removeDirAction, &QAction::triggered, this, [] {
+ const auto folderNode = ProjectTree::currentNode()->asFolderNode();
+ QTC_ASSERT(folderNode, return);
+ const auto project = qobject_cast<GenericProject *>(folderNode->getProject());
+ QTC_ASSERT(project, return);
+ const QStringList filesToRemove = transform<QStringList>(
+ folderNode->findNodes([](const Node *node) { return node->asFileNode(); }),
+ [](const Node *node) { return node->filePath().toString();});
+ if (!project->removeFiles(filesToRemove)) {
+ TaskHub::addTask(Task::Error, tr("Project files list update failed."),
+ PEC::TASK_CATEGORY_BUILDSYSTEM, project->filesFilePath());
+ }
});
}
diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.h b/src/plugins/genericprojectmanager/genericprojectplugin.h
index fa59a3b516..84865383cb 100644
--- a/src/plugins/genericprojectmanager/genericprojectplugin.h
+++ b/src/plugins/genericprojectmanager/genericprojectplugin.h
@@ -38,13 +38,6 @@ class GenericProjectPlugin : public ExtensionSystem::IPlugin
public:
~GenericProjectPlugin() override;
-#ifdef WITH_TESTS
-private slots:
- void test_simple();
- void test_mixed1();
- void test_mixed2();
-#endif // WITH_TESTS
-
private:
bool initialize(const QStringList &arguments, QString *errorString) override;
void extensionsInitialized() override { }
diff --git a/src/plugins/genericprojectmanager/genericprojectplugin_test.cpp b/src/plugins/genericprojectmanager/genericprojectplugin_test.cpp
deleted file mode 100644
index 46e7eb6b90..0000000000
--- a/src/plugins/genericprojectmanager/genericprojectplugin_test.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "genericprojectplugin.h"
-
-#include <projectexplorer/project.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/session.h>
-
-#include <cpptools/cppmodelmanager.h>
-#include <cpptools/cpptoolstestcase.h>
-#include <cpptools/projectinfo.h>
-
-#include <QFileInfo>
-#include <QTest>
-
-using namespace CppTools;
-using namespace CppTools::Tests;
-using namespace GenericProjectManager;
-using namespace GenericProjectManager::Internal;
-using namespace ProjectExplorer;
-
-namespace {
-
-inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); }
-inline QString sourceProjectPath(const QString &project)
-{
- const QString fileName(_(SRCDIR "/../../../tests/genericprojectmanager/") + project);
- return QFileInfo(fileName).absoluteFilePath();
-}
-
-} // anonymous namespace
-
-void GenericProjectPlugin::test_simple()
-{
- Tests::VerifyCleanCppModelManager verify;
-
- TemporaryCopiedDir temporaryDir(sourceProjectPath(_("testdata_simpleproject")));
- QVERIFY(temporaryDir.isValid());
- const QString mainFile = temporaryDir.absolutePath("main.cpp");
- const QString projectFile = temporaryDir.absolutePath("simpleproject.creator");
-
- ProjectOpenerAndCloser projects;
- const ProjectInfo pInfo = projects.open(projectFile);
- QVERIFY(pInfo.isValid());
- QCOMPARE(pInfo.projectParts().size(), 1);
-
- ProjectPart::Ptr pPart = pInfo.projectParts().first();
- QVERIFY(pPart);
- QCOMPARE(pPart->files.size(), 1);
- QCOMPARE(pPart->files.first().path, mainFile);
- QCOMPARE(pPart->files.first().kind, ProjectFile::CXXSource);
-}
-
-static QStringList simplify(const ProjectFiles &files, const QString &prefix)
-{
- QStringList result;
-
- foreach (const ProjectFile &file, files) {
- if (file.path.startsWith(prefix))
- result.append(file.path.mid(prefix.size()));
- else
- result.append(file.path);
- }
-
- return result;
-}
-
-void GenericProjectPlugin::test_mixed1()
-{
- Tests::VerifyCleanCppModelManager verify;
-
- TemporaryCopiedDir temporaryDir(sourceProjectPath(_("testdata_mixedproject1/")));
- QVERIFY(temporaryDir.isValid());
- const QString projectFile = temporaryDir.absolutePath("mixedproject1.creator");
-
- ProjectOpenerAndCloser projects;
- const ProjectInfo pInfo = projects.open(projectFile);
- QVERIFY(pInfo.isValid());
- QCOMPARE(pInfo.projectParts().size(), 3);
-
- QVector<ProjectPart::Ptr> parts = pInfo.projectParts();
- std::sort(parts.begin(), parts.end(), [](const ProjectPart::Ptr &p1,
- const ProjectPart::Ptr &p2) {
- return p1->displayName < p2->displayName;
- });
-
- const QString dirPathWithSlash = temporaryDir.path() + QLatin1Char('/');
- const QStringList part0files = simplify(parts[0]->files, dirPathWithSlash);
- const QStringList part1files = simplify(parts[1]->files, dirPathWithSlash);
- const QStringList part2files = simplify(parts[2]->files, dirPathWithSlash);
-
- QCOMPARE(parts[0]->displayName, _("mixedproject1 (C++)"));
- QCOMPARE(parts[0]->files.size(), 4);
- QVERIFY(part0files.contains(_("main.cpp")));
- QVERIFY(part0files.contains(_("header.h")));
- QVERIFY(part0files.contains(_("MyViewController.h")));
- QVERIFY(part0files.contains(_("Glue.h")));
-
- QCOMPARE(parts[1]->displayName, _("mixedproject1 (Obj-C)"));
- QCOMPARE(parts[1]->files.size(), 4);
- QVERIFY(part1files.contains(_("MyViewController.m")));
- QVERIFY(part1files.contains(_("header.h")));
- QVERIFY(part1files.contains(_("MyViewController.h")));
- QVERIFY(part1files.contains(_("Glue.h")));
-
- QCOMPARE(parts[2]->displayName, _("mixedproject1 (Obj-C++)"));
- QCOMPARE(parts[2]->files.size(), 4);
- QVERIFY(part2files.contains(_("Glue.mm")));
- QVERIFY(part2files.contains(_("header.h")));
- QVERIFY(part2files.contains(_("MyViewController.h")));
- QVERIFY(part2files.contains(_("Glue.h")));
-}
-
-void GenericProjectPlugin::test_mixed2()
-{
- Tests::VerifyCleanCppModelManager verify;
-
- TemporaryCopiedDir temporaryDir(sourceProjectPath(_("testdata_mixedproject2/")));
- QVERIFY(temporaryDir.isValid());
- const QString projectFile = temporaryDir.absolutePath("mixedproject2.creator");
-
- ProjectOpenerAndCloser projects;
- const ProjectInfo pInfo = projects.open(projectFile);
- QVERIFY(pInfo.isValid());
- QCOMPARE(pInfo.projectParts().size(), 2);
-
- QVector<ProjectPart::Ptr> parts = pInfo.projectParts();
- std::sort(parts.begin(), parts.end(), [](const ProjectPart::Ptr &p1,
- const ProjectPart::Ptr &p2) {
- return p1->displayName < p2->displayName;
- });
-
- const QString dirPathWithSlash = temporaryDir.path() + QLatin1Char('/');
- const QStringList part0files = simplify(parts[0]->files, dirPathWithSlash);
- const QStringList part1files = simplify(parts[1]->files, dirPathWithSlash);
-
- QCOMPARE(parts[0]->displayName, _("mixedproject2 (C)"));
- QCOMPARE(parts[0]->files.size(), 1);
- QVERIFY(part0files.contains(_("impl.c")));
-
- QCOMPARE(parts[1]->displayName, _("mixedproject2 (C++)"));
- QCOMPARE(parts[1]->files.size(), 2);
- QVERIFY(part1files.contains(_("main.cpp")));
- QVERIFY(part1files.contains(_("header.hpp")));
-}
diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.cpp b/src/plugins/genericprojectmanager/genericprojectwizard.cpp
index 204a6e4f43..31776f274a 100644
--- a/src/plugins/genericprojectmanager/genericprojectwizard.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectwizard.cpp
@@ -211,7 +211,7 @@ Core::GeneratedFiles GenericProjectWizard::generateFiles(const QWizard *w,
bool GenericProjectWizard::postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l,
QString *errorMessage) const
{
- Q_UNUSED(w);
+ Q_UNUSED(w)
return ProjectExplorer::CustomProjectWizard::postGenerateOpen(l, errorMessage);
}
diff --git a/src/plugins/genericprojectmanager/images/genericprojectmanager.png b/src/plugins/genericprojectmanager/images/genericprojectmanager.png
index bdb33780cc..b75e0422f7 100644
--- a/src/plugins/genericprojectmanager/images/genericprojectmanager.png
+++ b/src/plugins/genericprojectmanager/images/genericprojectmanager.png
Binary files differ
diff --git a/src/plugins/genericprojectmanager/images/genericprojectmanager@2x.png b/src/plugins/genericprojectmanager/images/genericprojectmanager@2x.png
index 8e8e26599f..8c708b52e3 100644
--- a/src/plugins/genericprojectmanager/images/genericprojectmanager@2x.png
+++ b/src/plugins/genericprojectmanager/images/genericprojectmanager@2x.png
Binary files differ
diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp
index 8af16f80ee..3899b7dcd1 100644
--- a/src/plugins/git/branchmodel.cpp
+++ b/src/plugins/git/branchmodel.cpp
@@ -298,7 +298,7 @@ int BranchModel::rowCount(const QModelIndex &parentIdx) const
int BranchModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 2;
}
diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp
index 48f4cf9ccf..47a55be5c5 100644
--- a/src/plugins/git/changeselectiondialog.cpp
+++ b/src/plugins/git/changeselectiondialog.cpp
@@ -76,13 +76,15 @@ ChangeSelectionDialog::ChangeSelectionDialog(const QString &workingDirectory, Co
connect(m_ui->selectFromHistoryButton, &QPushButton::clicked,
this, &ChangeSelectionDialog::selectCommitFromRecentHistory);
connect(m_ui->showButton, &QPushButton::clicked,
- this, &ChangeSelectionDialog::acceptShow);
+ this, std::bind(&ChangeSelectionDialog::accept, this, Show));
connect(m_ui->cherryPickButton, &QPushButton::clicked,
- this, &ChangeSelectionDialog::acceptCherryPick);
+ this, std::bind(&ChangeSelectionDialog::accept, this, CherryPick));
connect(m_ui->revertButton, &QPushButton::clicked,
- this, &ChangeSelectionDialog::acceptRevert);
+ this, std::bind(&ChangeSelectionDialog::accept, this, Revert));
connect(m_ui->checkoutButton, &QPushButton::clicked,
- this, &ChangeSelectionDialog::acceptCheckout);
+ this, std::bind(&ChangeSelectionDialog::accept, this, Checkout));
+ connect(m_ui->archiveButton, &QPushButton::clicked,
+ this, std::bind(&ChangeSelectionDialog::accept, this, Archive));
if (id == "Git.Revert")
m_ui->revertButton->setDefault(true);
@@ -90,6 +92,8 @@ ChangeSelectionDialog::ChangeSelectionDialog(const QString &workingDirectory, Co
m_ui->cherryPickButton->setDefault(true);
else if (id == "Git.Checkout")
m_ui->checkoutButton->setDefault(true);
+ else if (id == "Git.Archive")
+ m_ui->archiveButton->setDefault(true);
else
m_ui->showButton->setDefault(true);
m_changeModel = new QStringListModel(this);
@@ -147,28 +151,10 @@ ChangeCommand ChangeSelectionDialog::command() const
return m_command;
}
-void ChangeSelectionDialog::acceptCheckout()
+void ChangeSelectionDialog::accept(ChangeCommand command)
{
- m_command = Checkout;
- accept();
-}
-
-void ChangeSelectionDialog::acceptCherryPick()
-{
- m_command = CherryPick;
- accept();
-}
-
-void ChangeSelectionDialog::acceptRevert()
-{
- m_command = Revert;
- accept();
-}
-
-void ChangeSelectionDialog::acceptShow()
-{
- m_command = Show;
- accept();
+ m_command = command;
+ QDialog::accept();
}
//! Set commit message in details
diff --git a/src/plugins/git/changeselectiondialog.h b/src/plugins/git/changeselectiondialog.h
index 1de142ac7d..84e888756b 100644
--- a/src/plugins/git/changeselectiondialog.h
+++ b/src/plugins/git/changeselectiondialog.h
@@ -42,6 +42,7 @@ namespace Internal {
enum ChangeCommand {
NoCommand,
+ Archive,
Checkout,
CherryPick,
Revert,
@@ -68,10 +69,7 @@ private:
void recalculateCompletion();
void recalculateDetails();
void changeTextChanged(const QString &text);
- void acceptCheckout();
- void acceptCherryPick();
- void acceptRevert();
- void acceptShow();
+ void accept(ChangeCommand command);
void enableButtons(bool b);
void terminateProcess();
diff --git a/src/plugins/git/changeselectiondialog.ui b/src/plugins/git/changeselectiondialog.ui
index 3ccd3f31ea..b6db63a45a 100644
--- a/src/plugins/git/changeselectiondialog.ui
+++ b/src/plugins/git/changeselectiondialog.ui
@@ -84,6 +84,13 @@
</spacer>
</item>
<item>
+ <widget class="QPushButton" name="archiveButton">
+ <property name="text">
+ <string>&amp;Archive...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QPushButton" name="checkoutButton">
<property name="text">
<string>Check&amp;out</string>
diff --git a/src/plugins/git/gerrit/gerritmodel.cpp b/src/plugins/git/gerrit/gerritmodel.cpp
index ea3e311b52..945f2b1619 100644
--- a/src/plugins/git/gerrit/gerritmodel.cpp
+++ b/src/plugins/git/gerrit/gerritmodel.cpp
@@ -314,8 +314,7 @@ void QueryContext::start()
fp->setKeepOnFinish(Core::FutureProgress::HideOnFinish);
m_progress.reportStarted();
// Order: synchronous call to error handling if something goes wrong.
- VcsOutputWindow::appendCommand(
- m_process.workingDirectory(), Utils::FilePath::fromString(m_binary), m_arguments);
+ VcsOutputWindow::appendCommand(m_process.workingDirectory(), {m_binary, m_arguments});
m_timer.start();
m_process.start(m_binary, m_arguments);
m_process.closeWriteChannel();
diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp
index 7dfdc5de61..f0aebf59d8 100644
--- a/src/plugins/git/gerrit/gerritplugin.cpp
+++ b/src/plugins/git/gerrit/gerritplugin.cpp
@@ -170,7 +170,7 @@ void FetchContext::start()
m_progress.reportStarted();
// Order: initialize future before starting the process in case error handling is invoked.
const QStringList args = m_change->gitFetchArguments(m_server);
- VcsBase::VcsOutputWindow::appendCommand(m_repository, m_git, args);
+ VcsBase::VcsOutputWindow::appendCommand(m_repository, {m_git, args});
m_process.start(m_git.toString(), args);
m_process.closeWriteChannel();
}
diff --git a/src/plugins/git/gerrit/gerritpushdialog.cpp b/src/plugins/git/gerrit/gerritpushdialog.cpp
index a59f615b57..9a251b5eda 100644
--- a/src/plugins/git/gerrit/gerritpushdialog.cpp
+++ b/src/plugins/git/gerrit/gerritpushdialog.cpp
@@ -216,7 +216,7 @@ void GerritPushDialog::setChangeRange()
QPalette palette = QApplication::palette();
if (currentRange > ReasonableDistance) {
const QColor errorColor = Utils::creatorTheme()->color(Utils::Theme::TextColorError);
- palette.setColor(QPalette::Foreground, errorColor);
+ palette.setColor(QPalette::WindowText, errorColor);
palette.setColor(QPalette::ButtonText, errorColor);
labelText.append("\n" + tr("Are you sure you selected the right target branch?"));
}
diff --git a/src/plugins/git/gerrit/gerritremotechooser.cpp b/src/plugins/git/gerrit/gerritremotechooser.cpp
index 36082a3f26..8e5e7cd882 100644
--- a/src/plugins/git/gerrit/gerritremotechooser.cpp
+++ b/src/plugins/git/gerrit/gerritremotechooser.cpp
@@ -51,7 +51,7 @@ GerritRemoteChooser::GerritRemoteChooser(QWidget *parent) :
m_remoteComboBox->setMinimumSize(QSize(40, 0));
horizontalLayout->addWidget(m_remoteComboBox);
- horizontalLayout->setMargin(0);
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
m_resetRemoteButton = new QToolButton(this);
m_resetRemoteButton->setToolTip(tr("Refresh Remote Servers"));
@@ -103,11 +103,9 @@ bool GerritRemoteChooser::updateRemotes(bool forceReload)
m_remoteComboBox->clear();
m_remotes.clear();
QString errorMessage; // Mute errors. We'll just fallback to the defaults
- QMap<QString, QString> remotesList =
+ const QMap<QString, QString> remotesList =
Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage);
- QMapIterator<QString, QString> mapIt(remotesList);
- while (mapIt.hasNext()) {
- mapIt.next();
+ for (auto mapIt = remotesList.cbegin(), end = remotesList.cend(); mapIt != end; ++mapIt) {
GerritServer server;
if (!server.fillFromRemote(mapIt.value(), *m_parameters, forceReload))
continue;
diff --git a/src/plugins/git/gerrit/gerritserver.cpp b/src/plugins/git/gerrit/gerritserver.cpp
index c07f22adcc..f642b1f9d6 100644
--- a/src/plugins/git/gerrit/gerritserver.cpp
+++ b/src/plugins/git/gerrit/gerritserver.cpp
@@ -243,7 +243,7 @@ int GerritServer::testConnection()
static GitClient *const client = GitPlugin::client();
const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC);
const SynchronousProcessResponse resp = client->vcsFullySynchronousExec(
- QString(), FilePath::fromString(curlBinary), arguments,
+ QString(), {curlBinary, arguments},
Core::ShellCommand::NoOutput);
if (resp.result == SynchronousProcessResponse::Finished) {
QString output = resp.stdOut();
@@ -345,7 +345,7 @@ void GerritServer::resolveVersion(const GerritParameters &p, bool forceReload)
arguments << p.portFlag << QString::number(port);
arguments << hostArgument() << "gerrit" << "version";
const SynchronousProcessResponse resp = client->vcsFullySynchronousExec(
- QString(), FilePath::fromString(p.ssh), arguments,
+ QString(), {p.ssh, arguments},
Core::ShellCommand::NoOutput);
QString stdOut = resp.stdOut().trimmed();
stdOut.remove("gerrit version ");
@@ -353,7 +353,7 @@ void GerritServer::resolveVersion(const GerritParameters &p, bool forceReload)
} else {
const QStringList arguments = curlArguments() << (url(RestUrl) + versionUrlC);
const SynchronousProcessResponse resp = client->vcsFullySynchronousExec(
- QString(), FilePath::fromString(curlBinary), arguments,
+ QString(), {curlBinary, arguments},
Core::ShellCommand::NoOutput);
// REST endpoint for version is only available from 2.8 and up. Do not consider invalid
// if it fails.
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 976b8aefab..74124a65f0 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -74,6 +74,7 @@
#include <QAction>
#include <QCoreApplication>
#include <QDir>
+#include <QFileDialog>
#include <QFileInfo>
#include <QHash>
#include <QMenu>
@@ -235,7 +236,7 @@ void DescriptionWidgetDecorator::highlightCurrentContents(
sel.cursor.select(QTextCursor::LineUnderCursor);
sel.format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
const QColor textColor = TextEditor::TextEditorSettings::fontSettings().formatFor(TextEditor::C_TEXT).foreground();
- sel.format.setUnderlineColor(textColor.isValid() ? textColor : textEditor->palette().color(QPalette::Foreground));
+ sel.format.setUnderlineColor(textColor.isValid() ? textColor : textEditor->palette().color(QPalette::WindowText));
textEditor->setExtraSelections(TextEditor::TextEditorWidget::OtherSelection,
QList<QTextEdit::ExtraSelection>() << sel);
}
@@ -634,6 +635,10 @@ public:
tr("Show textual graph log."));
mapSetting(graphButton, settings.boolPointer(GitSettings::graphLogKey));
+ QAction *followButton = addToggleButton("--follow", tr("Follow"),
+ tr("Show log also for previous names of the file."));
+ mapSetting(followButton, settings.boolPointer(GitSettings::followRenamesKey));
+
addButton(tr("Reload"), Utils::Icons::RELOAD.icon());
}
};
@@ -1031,7 +1036,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName,
arguments << argWidget->arguments();
if (!fileName.isEmpty())
- arguments << "--follow" << "--" << fileName;
+ arguments << "--" << fileName;
vcsExec(workingDir, arguments, editor);
}
@@ -1086,6 +1091,49 @@ void GitClient::show(const QString &source, const QString &id, const QString &na
});
}
+void GitClient::archive(const QString &workingDirectory, const QString &commit)
+{
+ QString repoDirectory = VcsManager::findTopLevelForDirectory(workingDirectory);
+ if (repoDirectory.isEmpty())
+ repoDirectory = workingDirectory;
+ QString repoName = QFileInfo(repoDirectory).fileName();
+
+ QHash<QString, QString> filters {
+ { tr("Tarball (*.tar.gz)"), ".tar.gz" },
+ { tr("Zip archive (*.zip)"), ".zip" }
+ };
+ QString selectedFilter;
+ if (HostOsInfo::isWindowsHost())
+ selectedFilter = filters.key(".zip");
+ else
+ selectedFilter = filters.key(".tar.gz");
+
+ QString archiveName = QFileDialog::getSaveFileName(
+ ICore::dialogParent(),
+ tr("Generate %1 archive").arg(repoName),
+ repoDirectory + QString("/%1-%2").arg(repoName).arg(commit.left(8)),
+ filters.keys().join(";;"),
+ &selectedFilter);
+ if (archiveName.isEmpty())
+ return;
+ QString extension = filters.value(selectedFilter);
+ QFileInfo archive(archiveName);
+ if (archive.completeSuffix() != extension) {
+ archive = QFileInfo(archive.absoluteDir().absoluteFilePath(archive.baseName() + extension));
+ }
+
+ if (archive.exists()) {
+ if (QMessageBox::warning(ICore::dialogParent(), tr("Overwrite?"),
+ tr("An item named \"%1\" already exists at this location. "
+ "Do you want to overwrite it?").arg(QDir::toNativeSeparators(archive.absoluteFilePath())),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
+ return;
+ }
+ }
+
+ vcsExec(workingDirectory, {"archive", commit, "-o", archive.absoluteFilePath()}, nullptr, true);
+}
+
VcsBaseEditorWidget *GitClient::annotate(
const QString &workingDir, const QString &file, const QString &revision,
int lineNumber, const QStringList &extraOptions)
@@ -1325,7 +1373,8 @@ bool GitClient::synchronousReset(const QString &workingDirectory,
// Initialize repository
bool GitClient::synchronousInit(const QString &workingDirectory)
{
- const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory, {"init"});
+ const SynchronousProcessResponse resp = vcsFullySynchronousExec(workingDirectory,
+ QStringList{"init"});
// '[Re]Initialized...'
VcsOutputWindow::append(resp.stdOut());
if (resp.result == SynchronousProcessResponse::Finished) {
@@ -1537,7 +1586,7 @@ QString GitClient::synchronousTopic(const QString &workingDirectory) const
// No tag or remote branch - try git describe
const SynchronousProcessResponse resp =
- vcsFullySynchronousExec(workingDirectory, {"describe"}, VcsCommand::NoOutput);
+ vcsFullySynchronousExec(workingDirectory, QStringList{"describe"}, VcsCommand::NoOutput);
if (resp.result == SynchronousProcessResponse::Finished) {
const QString stdOut = resp.stdOut().trimmed();
if (!stdOut.isEmpty())
@@ -2378,7 +2427,7 @@ bool GitClient::tryLauchingGitK(const QProcessEnvironment &env,
arguments.append(QtcProcess::splitArgs(gitkOpts, HostOsInfo::hostOs()));
if (!fileName.isEmpty())
arguments << "--" << fileName;
- VcsOutputWindow::appendCommand(workingDirectory, FilePath::fromString(binary), arguments);
+ VcsOutputWindow::appendCommand(workingDirectory, {binary, arguments});
// This should always use QProcess::startDetached (as not to kill
// the child), but that does not have an environment parameter.
bool success = false;
@@ -3106,7 +3155,7 @@ VcsCommand *GitClient::vcsExecAbortable(const QString &workingDirectory,
| VcsCommand::ShowSuccessMessage);
// For rebase, Git might request an editor (which means the process keeps running until the
// user closes it), so run without timeout.
- command->addJob(vcsBinary(), arguments, isRebase ? 0 : command->defaultTimeoutS());
+ command->addJob({vcsBinary(), arguments}, isRebase ? 0 : command->defaultTimeoutS());
ConflictHandler::attachToCommand(command, abortCommand);
if (isRebase)
GitProgressParser::attachToCommand(command);
@@ -3413,44 +3462,10 @@ void GitClient::StashInfo::end()
m_stashResult = NotStashed;
}
-// GitRemote
-
-GitRemote::GitRemote(const QString &url)
+GitRemote::GitRemote(const QString &location) : Core::IVersionControl::RepoUrl(location)
{
- static const QRegularExpression remotePattern(
- "^(?:(?<protocol>[^:]+)://)?(?:(?<user>[^@]+)@)?(?<host>[^:/]+)"
- "(?::(?<port>\\d+))?:?(?<path>.*)$");
-
- if (url.isEmpty())
- return;
-
- // Check for local remotes (refer to the root or relative path)
- // On Windows, local paths typically starts with <drive>:
- auto startsWithWindowsDrive = [](const QString &url) {
- if (!HostOsInfo::isWindowsHost() || url.size() < 2)
- return false;
- const QChar drive = url.at(0).toLower();
- return drive >= 'a' && drive <= 'z' && url.at(1) == ':';
- };
- if (url.startsWith("file://") || url.startsWith('/') || url.startsWith('.')
- || startsWithWindowsDrive(url)) {
- protocol = "file";
- path = QDir::fromNativeSeparators(url.startsWith("file://") ? url.mid(7) : url);
+ if (isValid && protocol == "file")
isValid = QDir(path).exists() || QDir(path + ".git").exists();
- return;
- }
-
- const QRegularExpressionMatch match = remotePattern.match(url);
- if (!match.hasMatch())
- return;
-
- bool ok = false;
- protocol = match.captured("protocol");
- userName = match.captured("user");
- host = match.captured("host");
- port = match.captured("port").toUShort(&ok);
- path = match.captured("path");
- isValid = ok || match.captured("port").isEmpty();
}
} // namespace Internal
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index cd31c0c46a..32f7ac0e25 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -29,6 +29,7 @@
#include "commitdata.h"
#include <coreplugin/editormanager/ieditor.h>
+#include <coreplugin/iversioncontrol.h>
#include <vcsbase/vcsbaseclient.h>
#include <utils/fileutils.h>
@@ -327,6 +328,7 @@ public:
static QString msgNoChangedFiles();
static QString msgNoCommits(bool includeRemote);
void show(const QString &source, const QString &id, const QString &name = QString());
+ void archive(const QString &workingDirectory, const QString &commit);
private:
void finishSubmoduleUpdate();
@@ -380,16 +382,10 @@ private:
QFutureSynchronizer<void> m_synchronizer; // for commit updates
};
-class GitRemote {
+class GitRemote : public Core::IVersionControl::RepoUrl
+{
public:
- GitRemote(const QString &url);
-
- QString protocol;
- QString userName;
- QString host;
- QString path;
- quint16 port = 0;
- bool isValid = false;
+ GitRemote(const QString &location);
};
} // namespace Internal
diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp
index fbe90448d7..51a539ef52 100644
--- a/src/plugins/git/giteditor.cpp
+++ b/src/plugins/git/giteditor.cpp
@@ -369,7 +369,7 @@ QString GitEditorWidget::fileNameForLine(int line) const
QString GitEditorWidget::sourceWorkingDirectory() const
{
Utils::FilePath path = Utils::FilePath::fromString(source());
- if (!path.isEmpty() && !path.toFileInfo().isDir())
+ if (!path.isEmpty() && !path.isDir())
path = path.parentDir();
while (!path.isEmpty() && !path.exists())
path = path.parentDir();
diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp
index 65d698ec0b..056903f855 100644
--- a/src/plugins/git/gitgrep.cpp
+++ b/src/plugins/git/gitgrep.cpp
@@ -196,7 +196,7 @@ public:
connect(&watcher, &QFutureWatcher<FileSearchResultList>::canceled,
command.data(), &VcsCommand::cancel);
connect(command.data(), &VcsCommand::stdOutText, this, &GitGrepRunner::read);
- SynchronousProcessResponse resp = command->runCommand(client->vcsBinary(), arguments, 0);
+ SynchronousProcessResponse resp = command->runCommand({client->vcsBinary(), arguments}, 0);
switch (resp.result) {
case SynchronousProcessResponse::TerminatedAbnormally:
case SynchronousProcessResponse::StartFailed:
@@ -240,7 +240,7 @@ GitGrep::GitGrep(QObject *parent)
{
m_widget = new QWidget;
auto layout = new QHBoxLayout(m_widget);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
m_treeLineEdit = new FancyLineEdit;
m_treeLineEdit->setPlaceholderText(tr("Tree (optional)"));
m_treeLineEdit->setToolTip(tr("Can be HEAD, tag, local or remote branch, or a commit hash.\n"
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 924f1da5e2..4c0a0e9998 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -588,6 +588,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
createChangeRelatedRepositoryAction(tr("Revert..."), "Git.Revert", context);
createChangeRelatedRepositoryAction(tr("Cherry Pick..."), "Git.CherryPick", context);
createChangeRelatedRepositoryAction(tr("Checkout..."), "Git.Checkout", context);
+ createChangeRelatedRepositoryAction(tr("Archive..."), "Git.Archive", context);
createRepositoryAction(nullptr, tr("Rebase..."), "Git.Rebase", context, true,
std::bind(&GitPlugin::branchList, this));
@@ -852,6 +853,9 @@ void GitPlugin::startChangeRelatedAction(const Id &id)
if (dialog.command() == Show) {
m_gitClient->show(workingDirectory, change);
return;
+ } else if (dialog.command() == Archive) {
+ m_gitClient->archive(workingDirectory, change);
+ return;
}
if (!DocumentManager::saveAllModifiedDocuments())
@@ -984,7 +988,7 @@ void GitPlugin::updateVersionWarning()
infoBar->addInfo(InfoBarEntry(gitVersionWarning,
tr("Unsupported version of Git found. Git %1 or later required.")
.arg(versionString(minimumRequiredVersion)),
- InfoBarEntry::GlobalSuppressionEnabled));
+ InfoBarEntry::GlobalSuppression::Enabled));
}
IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const CommitData &cd)
diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp
index ee47d3075e..ecc355fa50 100644
--- a/src/plugins/git/gitsettings.cpp
+++ b/src/plugins/git/gitsettings.cpp
@@ -45,6 +45,7 @@ const QLatin1String GitSettings::logDiffKey("LogDiff");
const QLatin1String GitSettings::repositoryBrowserCmd("RepositoryBrowserCmd");
const QLatin1String GitSettings::graphLogKey("GraphLog");
const QLatin1String GitSettings::firstParentKey("FirstParent");
+const QLatin1String GitSettings::followRenamesKey("FollowRenames");
const QLatin1String GitSettings::lastResetIndexKey("LastResetIndex");
GitSettings::GitSettings()
@@ -66,6 +67,7 @@ GitSettings::GitSettings()
declareKey(repositoryBrowserCmd, QString());
declareKey(graphLogKey, false);
declareKey(firstParentKey, false);
+ declareKey(followRenamesKey, true);
declareKey(lastResetIndexKey, 0);
}
diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h
index b6778dfca5..4bd088c852 100644
--- a/src/plugins/git/gitsettings.h
+++ b/src/plugins/git/gitsettings.h
@@ -56,6 +56,7 @@ public:
static const QLatin1String repositoryBrowserCmd;
static const QLatin1String graphLogKey;
static const QLatin1String firstParentKey;
+ static const QLatin1String followRenamesKey;
static const QLatin1String lastResetIndexKey;
Utils::FilePath gitExecutable(bool *ok = nullptr, QString *errorMessage = nullptr) const;
diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp
index 379eb67c64..123cf6753c 100644
--- a/src/plugins/git/gitversioncontrol.cpp
+++ b/src/plugins/git/gitversioncontrol.cpp
@@ -80,7 +80,7 @@ bool GitVersionControl::isVcsFileOrDirectory(const Utils::FilePath &fileName) co
{
if (fileName.fileName().compare(".git", Utils::HostOsInfo::fileNameCaseSensitivity()))
return false;
- if (fileName.toFileInfo().isDir())
+ if (fileName.isDir())
return true;
QFile file(fileName.toString());
if (!file.open(QFile::ReadOnly))
@@ -159,10 +159,15 @@ Core::ShellCommand *GitVersionControl::createInitialCheckoutCommand(const QStrin
auto command = new VcsBase::VcsCommand(baseDirectory.toString(), m_client->processEnvironment());
command->addFlags(VcsBase::VcsCommand::SuppressStdErr);
- command->addJob(m_client->vcsBinary(), args, -1);
+ command->addJob({m_client->vcsBinary(), args}, -1);
return command;
}
+GitVersionControl::RepoUrl GitVersionControl::getRepoUrl(const QString &location) const
+{
+ return GitRemote(location);
+}
+
QStringList GitVersionControl::additionalToolsPath() const
{
QStringList res = m_client->settings().searchPathList();
diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h
index 1e1025864d..7985040f8e 100644
--- a/src/plugins/git/gitversioncontrol.h
+++ b/src/plugins/git/gitversioncontrol.h
@@ -63,6 +63,8 @@ public:
const QString &localName,
const QStringList &extraArgs) final;
+ RepoUrl getRepoUrl(const QString &location) const override;
+
QStringList additionalToolsPath() const final;
void emitFilesChanged(const QStringList &);
diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp
index 8558163dfc..9878ad900b 100644
--- a/src/plugins/git/mergetool.cpp
+++ b/src/plugins/git/mergetool.cpp
@@ -62,7 +62,7 @@ bool MergeTool::start(const QString &workingDirectory, const QStringList &files)
m_process->setProcessEnvironment(env);
m_process->setProcessChannelMode(QProcess::MergedChannels);
const Utils::FilePath binary = GitPlugin::client()->vcsBinary();
- VcsOutputWindow::appendCommand(workingDirectory, binary, arguments);
+ VcsOutputWindow::appendCommand(workingDirectory, {binary, arguments});
m_process->start(binary.toString(), arguments);
if (m_process->waitForStarted()) {
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
diff --git a/src/plugins/git/remotemodel.cpp b/src/plugins/git/remotemodel.cpp
index 62d9930577..0a0f30c1b4 100644
--- a/src/plugins/git/remotemodel.cpp
+++ b/src/plugins/git/remotemodel.cpp
@@ -110,13 +110,13 @@ int RemoteModel::remoteCount() const
int RemoteModel::rowCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return remoteCount();
}
int RemoteModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 2;
}
@@ -167,7 +167,7 @@ bool RemoteModel::setData(const QModelIndex &index, const QVariant &value, int r
Qt::ItemFlags RemoteModel::flags(const QModelIndex &index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return m_flags;
}
diff --git a/src/plugins/glsleditor/glslcompletionassist.cpp b/src/plugins/glsleditor/glslcompletionassist.cpp
index 39ac8b9832..69802b7470 100644
--- a/src/plugins/glsleditor/glslcompletionassist.cpp
+++ b/src/plugins/glsleditor/glslcompletionassist.cpp
@@ -52,7 +52,6 @@
#include <QToolButton>
#include <QHBoxLayout>
#include <QApplication>
-#include <QDesktopWidget>
#include <QDebug>
using namespace TextEditor;
diff --git a/src/plugins/helloworld/CMakeLists.txt b/src/plugins/helloworld/CMakeLists.txt
index 6b9c5df88d..e14fbba2c8 100644
--- a/src/plugins/helloworld/CMakeLists.txt
+++ b/src/plugins/helloworld/CMakeLists.txt
@@ -1,4 +1,5 @@
add_qtc_plugin(HelloWorld
+ SKIP_TRANSLATION
PLUGIN_DEPENDS Core
SOURCES
helloworldplugin.cpp helloworldplugin.h
diff --git a/src/plugins/help/CMakeLists.txt b/src/plugins/help/CMakeLists.txt
index e96f15d91c..73122b15dc 100644
--- a/src/plugins/help/CMakeLists.txt
+++ b/src/plugins/help/CMakeLists.txt
@@ -19,7 +19,6 @@ add_qtc_plugin(Help
helpwidget.cpp helpwidget.h
localhelpmanager.cpp localhelpmanager.h
openpagesmanager.cpp openpagesmanager.h
- openpagesmodel.cpp openpagesmodel.h
openpagesswitcher.cpp openpagesswitcher.h
openpageswidget.cpp openpageswidget.h
remotehelpfilter.cpp remotehelpfilter.h remotehelpfilter.ui
@@ -31,6 +30,7 @@ add_qtc_plugin(Help
extend_qtc_plugin(Help
CONDITION FWWebKit AND FWAppKit
+ FEATURE_INFO "Native WebKit help viewer"
DEPENDS ${FWWebKit} ${FWAppKit}
DEFINES QTC_MAC_NATIVE_HELPVIEWER
SOURCES
@@ -41,9 +41,29 @@ extend_qtc_plugin(Help
find_package(Qt5WebEngineWidgets QUIET)
extend_qtc_plugin(Help
CONDITION TARGET Qt5::WebEngineWidgets
+ FEATURE_INFO "QtWebEngine help viewer"
DEPENDS Qt5::WebEngineWidgets
DEFINES QTC_WEBENGINE_HELPVIEWER
SOURCES
webenginehelpviewer.cpp
webenginehelpviewer.h
)
+
+if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qlitehtml/litehtml/CMakeLists.txt)
+ add_subdirectory(qlitehtml)
+else()
+ find_package(litehtml QUIET)
+ if (TARGET litehtml)
+ add_subdirectory(qlitehtml)
+ endif()
+endif()
+
+extend_qtc_plugin(Help
+ CONDITION TARGET litehtml AND TARGET qlitehtml
+ FEATURE_INFO "litehtml help viewer"
+ DEPENDS qlitehtml
+ DEFINES QTC_LITEHTML_HELPVIEWER
+ SOURCES
+ litehtmlhelpviewer.cpp
+ litehtmlhelpviewer.h
+)
diff --git a/src/plugins/help/generalsettingspage.cpp b/src/plugins/help/generalsettingspage.cpp
index 3b3e366858..93538efc09 100644
--- a/src/plugins/help/generalsettingspage.cpp
+++ b/src/plugins/help/generalsettingspage.cpp
@@ -37,6 +37,7 @@
#include <coreplugin/helpmanager.h>
#include <coreplugin/icore.h>
+#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <QCoreApplication>
@@ -122,6 +123,21 @@ QWidget *GeneralSettingsPage::widget()
m_scrollWheelZoomingEnabled = LocalHelpManager::isScrollWheelZoomingEnabled();
m_ui->scrollWheelZooming->setChecked(m_scrollWheelZoomingEnabled);
+
+ const QString tooltip = tr("Change takes effect after reloading help pages.");
+ m_ui->viewerBackendLabel->setToolTip(tooltip);
+ m_ui->viewerBackend->setToolTip(tooltip);
+ m_ui->viewerBackend->addItem(tr("Default (%1)", "Default viewer backend")
+ .arg(LocalHelpManager::defaultViewerBackend().displayName));
+ const QByteArray currentBackend = LocalHelpManager::viewerBackendId();
+ const QVector<HelpViewerFactory> backends = LocalHelpManager::viewerBackends();
+ for (const HelpViewerFactory &f : backends) {
+ m_ui->viewerBackend->addItem(f.displayName, f.id);
+ if (f.id == currentBackend)
+ m_ui->viewerBackend->setCurrentIndex(m_ui->viewerBackend->count() - 1);
+ }
+ if (backends.size() == 1)
+ m_ui->viewerBackend->setEnabled(false);
}
return m_widget;
}
@@ -168,6 +184,9 @@ void GeneralSettingsPage::apply()
m_scrollWheelZoomingEnabled = zoom;
LocalHelpManager::setScrollWheelZoomingEnabled(m_scrollWheelZoomingEnabled);
}
+
+ const QByteArray viewerBackendId = m_ui->viewerBackend->currentData().toByteArray();
+ LocalHelpManager::setViewerBackendId(viewerBackendId);
}
void GeneralSettingsPage::setCurrentPage()
diff --git a/src/plugins/help/generalsettingspage.ui b/src/plugins/help/generalsettingspage.ui
index afca6739cb..0b7dd7fd2a 100644
--- a/src/plugins/help/generalsettingspage.ui
+++ b/src/plugins/help/generalsettingspage.ui
@@ -305,6 +305,33 @@
</property>
</widget>
</item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="viewerBackendLabel">
+ <property name="text">
+ <string>Viewer backend:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="viewerBackend"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/plugins/help/help.pro b/src/plugins/help/help.pro
index 76c6db63a2..05f8da1552 100644
--- a/src/plugins/help/help.pro
+++ b/src/plugins/help/help.pro
@@ -22,7 +22,6 @@ HEADERS += \
helpplugin.h \
helpviewer.h \
openpagesmanager.h \
- openpagesmodel.h \
openpagesswitcher.h \
openpageswidget.h \
remotehelpfilter.h \
@@ -45,7 +44,6 @@ SOURCES += \
helpplugin.cpp \
helpviewer.cpp \
openpagesmanager.cpp \
- openpagesmodel.cpp \
openpagesswitcher.cpp \
openpageswidget.cpp \
remotehelpfilter.cpp \
@@ -78,6 +76,12 @@ osx {
}
}
+exists($$PWD/qlitehtml/litehtml/CMakeLists.txt)|!isEmpty(LITEHTML_INSTALL_DIR) {
+ include(qlitehtml/qlitehtml.pri)
+ HEADERS += litehtmlhelpviewer.h
+ SOURCES += litehtmlhelpviewer.cpp
+ DEFINES += QTC_LITEHTML_HELPVIEWER
+}
RESOURCES += help.qrc
include(../../shared/help/help.pri)
diff --git a/src/plugins/help/help.qbs b/src/plugins/help/help.qbs
index 38eda44aa6..7503b442b4 100644
--- a/src/plugins/help/help.qbs
+++ b/src/plugins/help/help.qbs
@@ -43,7 +43,6 @@ QtcPlugin {
"helpwidget.cpp", "helpwidget.h",
"localhelpmanager.cpp", "localhelpmanager.h",
"openpagesmanager.cpp", "openpagesmanager.h",
- "openpagesmodel.cpp", "openpagesmodel.h",
"openpagesswitcher.cpp", "openpagesswitcher.h",
"openpageswidget.cpp", "openpageswidget.h",
"remotehelpfilter.cpp", "remotehelpfilter.h", "remotehelpfilter.ui",
diff --git a/src/plugins/help/helpconstants.h b/src/plugins/help/helpconstants.h
index a212159ceb..294424af7d 100644
--- a/src/plugins/help/helpconstants.h
+++ b/src/plugins/help/helpconstants.h
@@ -49,6 +49,7 @@ const char HELP_HOME[] = "Help.Home";
const char HELP_PREVIOUS[] = "Help.Previous";
const char HELP_NEXT[] = "Help.Next";
const char HELP_ADDBOOKMARK[] = "Help.AddBookmark";
+const char HELP_OPENONLINE[] = "Help.OpenOnline";
const char HELP_INDEX[] = "Help.Index";
const char HELP_CONTENTS[] = "Help.Contents";
const char HELP_SEARCH[] = "Help.Search";
diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp
index 7e8bf80c81..ba2e42ab7f 100644
--- a/src/plugins/help/helpplugin.cpp
+++ b/src/plugins/help/helpplugin.cpp
@@ -39,20 +39,11 @@
#include "helpviewer.h"
#include "localhelpmanager.h"
#include "openpagesmanager.h"
-#include "openpagesmodel.h"
#include "remotehelpfilter.h"
#include "searchwidget.h"
#include "searchtaskhandler.h"
-#include "textbrowserhelpviewer.h"
#include "topicchooser.h"
-#ifdef QTC_MAC_NATIVE_HELPVIEWER
-#include "macwebkithelpviewer.h"
-#endif
-#ifdef QTC_WEBENGINE_HELPVIEWER
-#include "webenginehelpviewer.h"
-#endif
-
#include <bookmarkmanager.h>
#include <contentwindow.h>
#include <indexwindow.h>
@@ -163,7 +154,6 @@ public:
bool m_setupNeeded = true;
LocalHelpManager m_localHelpManager;
- OpenPagesManager m_openPagesManager;
QPointer<HelpWidget> m_externalWindow;
QRect m_externalWindowState;
@@ -451,42 +441,9 @@ HelpViewer *HelpPluginPrivate::externalHelpViewer()
HelpViewer *HelpPlugin::createHelpViewer(qreal zoom)
{
- // check for backends
- using ViewerFactory = std::function<HelpViewer *()>;
- using ViewerFactoryItem = QPair<QByteArray, ViewerFactory>; // id -> factory
- QVector<ViewerFactoryItem> factories;
-#ifdef QTC_WEBENGINE_HELPVIEWER
- factories.append(qMakePair(QByteArray("qtwebengine"), []() { return new WebEngineHelpViewer(); }));
-#endif
- factories.append(qMakePair(QByteArray("textbrowser"), []() { return new TextBrowserHelpViewer(); }));
-
-#ifdef QTC_MAC_NATIVE_HELPVIEWER
- // default setting
-#ifdef QTC_MAC_NATIVE_HELPVIEWER_DEFAULT
- factories.prepend(qMakePair(QByteArray("native"), []() { return new MacWebKitHelpViewer(); }));
-#else
- factories.append(qMakePair(QByteArray("native"), []() { return new MacWebKitHelpViewer(); }));
-#endif
-#endif
-
- HelpViewer *viewer = nullptr;
-
- // check requested backend
- const QByteArray backend = qgetenv("QTC_HELPVIEWER_BACKEND");
- if (!backend.isEmpty()) {
- const int pos = Utils::indexOf(factories, [backend](const ViewerFactoryItem &item) {
- return backend == item.first;
- });
- if (pos == -1) {
- qWarning("Help viewer backend \"%s\" not found, using default.", backend.constData());
- } else {
- viewer = factories.at(pos).second();
- }
- }
-
- if (!viewer)
- viewer = factories.first().second();
- QTC_ASSERT(viewer, return nullptr);
+ const HelpViewerFactory factory = LocalHelpManager::viewerBackend();
+ QTC_ASSERT(factory.create, return nullptr);
+ HelpViewer *viewer = factory.create();
// initialize font
viewer->setViewerFont(LocalHelpManager::fallbackFont());
@@ -701,19 +658,8 @@ HelpViewer *HelpPluginPrivate::showHelpUrl(const QUrl &url, Core::HelpManager::H
return nullptr;
if (!HelpManager::findFile(url).isValid()) {
- const QString address = url.toString();
- if (address.startsWith("qthelp://org.qt-project.")
- || address.startsWith("qthelp://com.nokia.")
- || address.startsWith("qthelp://com.trolltech.")) {
- // local help not installed, resort to external web help
- QString urlPrefix = "http://doc.qt.io/";
- if (url.authority().startsWith(qtcreatorUnversionedID))
- urlPrefix.append(QString::fromLatin1("qtcreator"));
- else
- urlPrefix.append("qt-5");
- QDesktopServices::openUrl(QUrl(urlPrefix + address.mid(address.lastIndexOf(QLatin1Char('/')))));
+ if (LocalHelpManager::openOnlineHelp(url))
return nullptr;
- }
}
HelpViewer *viewer = viewerForHelpViewerLocation(location);
diff --git a/src/plugins/help/helpviewer.cpp b/src/plugins/help/helpviewer.cpp
index d667c3b26c..27de81390b 100644
--- a/src/plugins/help/helpviewer.cpp
+++ b/src/plugins/help/helpviewer.cpp
@@ -176,7 +176,7 @@ void HelpViewer::wheelEvent(QWheelEvent *event)
{
if (m_scrollWheelZoomingEnabled && event->modifiers() == Qt::ControlModifier) {
event->accept();
- event->delta() > 0 ? scaleUp() : scaleDown();
+ event->angleDelta().y() > 0 ? scaleUp() : scaleDown();
} else {
QWidget::wheelEvent(event);
}
diff --git a/src/plugins/help/helpwidget.cpp b/src/plugins/help/helpwidget.cpp
index 64f76e4e6c..f1c33e32aa 100644
--- a/src/plugins/help/helpwidget.cpp
+++ b/src/plugins/help/helpwidget.cpp
@@ -55,8 +55,8 @@
#include <QCoreApplication>
#include <QHBoxLayout>
#include <QMenu>
-#include <QPrinter>
#include <QPrintDialog>
+#include <QPrinter>
#include <QStackedWidget>
#include <QStatusBar>
#include <QToolButton>
@@ -67,6 +67,39 @@ static const char kModeSideBarSettingsKey[] = "Help/ModeSideBar";
namespace Help {
namespace Internal {
+OpenPagesModel::OpenPagesModel(HelpWidget *parent)
+ : m_parent(parent)
+{}
+
+int OpenPagesModel::rowCount(const QModelIndex &parent) const
+{
+ return parent.isValid() ? 0 : m_parent->viewerCount();
+}
+
+int OpenPagesModel::columnCount(const QModelIndex &parent) const
+{
+ // page title + funky close button
+ return parent.isValid() ? 0 : 2;
+}
+
+QVariant OpenPagesModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount() - 1)
+ return QVariant();
+
+ switch (role) {
+ case Qt::ToolTipRole:
+ return m_parent->viewerAt(index.row())->source().toString();
+ case Qt::DisplayRole: {
+ const QString title = m_parent->viewerAt(index.row())->title();
+ return title.isEmpty() ? HelpWidget::tr("(Untitled)") : title;
+ }
+ default:
+ break;
+ }
+ return QVariant();
+}
+
static void openUrlInWindow(const QUrl &url)
{
HelpPlugin::showHelpUrl(url, Core::HelpManager::ExternalHelpAlways);
@@ -77,19 +110,23 @@ static bool isBookmarkable(const QUrl &url)
return !url.isEmpty() && url != QUrl(Help::Constants::AboutBlank);
}
-HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget *parent) :
- QWidget(parent),
- m_style(style)
+HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget *parent)
+ : QWidget(parent)
+ , m_model(this)
+ , m_style(style)
{
m_viewerStack = new QStackedWidget;
+ if (style == ModeWidget)
+ m_openPagesManager = new OpenPagesManager(this);
+
auto topLayout = new QVBoxLayout;
- topLayout->setMargin(0);
+ topLayout->setContentsMargins(0, 0, 0, 0);
topLayout->setSpacing(0);
setLayout(topLayout);
auto hLayout = new QHBoxLayout;
- hLayout->setMargin(0);
+ hLayout->setContentsMargins(0, 0, 0, 0);
hLayout->setSpacing(0);
topLayout->addLayout(hLayout, 10);
@@ -100,12 +137,12 @@ HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget
auto toolBar = new Utils::StyledBar();
auto layout = new QHBoxLayout(toolBar);
layout->setSpacing(0);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
auto rightSide = new QWidget(this);
m_sideBarSplitter->insertWidget(1, rightSide);
auto vLayout = new QVBoxLayout(rightSide);
- vLayout->setMargin(0);
+ vLayout->setContentsMargins(0, 0, 0, 0);
vLayout->setSpacing(0);
vLayout->addWidget(toolBar);
vLayout->addWidget(m_viewerStack);
@@ -208,6 +245,11 @@ HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget
layout->addWidget(new Utils::StyledSeparator(toolBar));
layout->addWidget(Core::Command::toolButtonWithAppendedShortcut(m_addBookmarkAction, cmd));
+ m_openOnlineDocumentationAction = new QAction(Utils::Icons::ONLINE_TOOLBAR.icon(), tr("Open Online Documentation..."), this);
+ cmd = Core::ActionManager::registerAction(m_openOnlineDocumentationAction, Constants::HELP_OPENONLINE, context);
+ connect(m_openOnlineDocumentationAction, &QAction::triggered, this, &HelpWidget::openOnlineDocumentation);
+ layout->addWidget(Core::Command::toolButtonWithAppendedShortcut(m_openOnlineDocumentationAction, cmd));
+
if (style == ModeWidget) {
layout->addWidget(new Utils::StyledSeparator(toolBar));
layout->addWidget(OpenPagesManager::instance().openPagesComboBox(), 10);
@@ -258,13 +300,15 @@ HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget
advancedMenu->addAction(cmd, Core::Constants::G_EDIT_FONT);
}
+ auto openButton = new QToolButton;
+ openButton->setIcon(Utils::Icons::SPLIT_HORIZONTAL_TOOLBAR.icon());
+ openButton->setPopupMode(QToolButton::InstantPopup);
+ openButton->setProperty("noArrow", true);
+ layout->addWidget(openButton);
+ auto openMenu = new QMenu(openButton);
+ openButton->setMenu(openMenu);
+
if (style != ExternalWindow) {
- auto openButton = new QToolButton;
- openButton->setIcon(Utils::Icons::SPLIT_HORIZONTAL_TOOLBAR.icon());
- openButton->setPopupMode(QToolButton::InstantPopup);
- openButton->setProperty("noArrow", true);
- layout->addWidget(openButton);
- auto openMenu = new QMenu(openButton);
if (m_switchToHelp)
openMenu->addAction(m_switchToHelp);
if (style == ModeWidget) {
@@ -282,7 +326,7 @@ HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget
emit closeButtonClicked();
}
});
- openButton->setMenu(openMenu);
+ openMenu->addSeparator();
const Utils::Icon &icon = style == ModeWidget ? Utils::Icons::CLOSE_TOOLBAR
: Utils::Icons::CLOSE_SPLIT_RIGHT;
@@ -293,10 +337,18 @@ HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget
layout->addWidget(button);
}
+ QAction *reload = openMenu->addAction(tr("Reload"));
+ connect(reload, &QAction::triggered, this, [this]() {
+ const int index = m_viewerStack->currentIndex();
+ HelpViewer *previous = currentViewer();
+ insertViewer(index, previous->source(), previous->scale());
+ removeViewerAt(index + 1);
+ setCurrentIndex(index);
+ });
+
if (style != ModeWidget) {
- HelpViewer *viewer = HelpPlugin::createHelpViewer(qreal(0.0));
- addViewer(viewer);
- setCurrentViewer(viewer);
+ addViewer({});
+ setCurrentIndex(0);
}
}
@@ -328,6 +380,12 @@ HelpWidget::~HelpWidget()
Core::ActionManager::unregisterAction(m_scaleDown, TextEditor::Constants::DECREASE_FONT_SIZE);
if (m_resetScale)
Core::ActionManager::unregisterAction(m_resetScale, TextEditor::Constants::RESET_FONT_SIZE);
+ delete m_openPagesManager;
+}
+
+QAbstractItemModel *HelpWidget::model()
+{
+ return &m_model;
}
void HelpWidget::addSideBar()
@@ -447,31 +505,43 @@ HelpViewer *HelpWidget::currentViewer() const
return qobject_cast<HelpViewer *>(m_viewerStack->currentWidget());
}
-void HelpWidget::setCurrentViewer(HelpViewer *viewer)
+int HelpWidget::currentIndex() const
{
- m_viewerStack->setCurrentWidget(viewer);
+ return m_viewerStack->currentIndex();
+}
+
+void HelpWidget::setCurrentIndex(int index)
+{
+ HelpViewer *viewer = viewerAt(index);
+ m_viewerStack->setCurrentIndex(index);
m_backAction->setEnabled(viewer->isBackwardAvailable());
m_forwardAction->setEnabled(viewer->isForwardAvailable());
m_addBookmarkAction->setEnabled(isBookmarkable(viewer->source()));
+ m_openOnlineDocumentationAction->setEnabled(
+ LocalHelpManager::canOpenOnlineHelp(viewer->source()));
if (m_style == ExternalWindow)
updateWindowTitle();
emit sourceChanged(viewer->source());
+ emit currentIndexChanged(index);
}
-int HelpWidget::currentIndex() const
+HelpViewer *HelpWidget::addViewer(const QUrl &url, qreal zoom)
{
- return m_viewerStack->currentIndex();
+ return insertViewer(m_viewerStack->count(), url, zoom);
}
-void HelpWidget::addViewer(HelpViewer *viewer)
+HelpViewer *HelpWidget::insertViewer(int index, const QUrl &url, qreal zoom)
{
- m_viewerStack->addWidget(viewer);
+ m_model.beginInsertRows({}, index, index);
+ HelpViewer *viewer = HelpPlugin::createHelpViewer(zoom);
+ m_viewerStack->insertWidget(index, viewer);
viewer->setFocus(Qt::OtherFocusReason);
viewer->setActionVisible(HelpViewer::Action::NewPage, m_style == ModeWidget);
viewer->setActionVisible(HelpViewer::Action::ExternalWindow, m_style != ExternalWindow);
connect(viewer, &HelpViewer::sourceChanged, this, [viewer, this](const QUrl &url) {
if (currentViewer() == viewer) {
m_addBookmarkAction->setEnabled(isBookmarkable(url));
+ m_openOnlineDocumentationAction->setEnabled(LocalHelpManager::canOpenOnlineHelp(url));
emit sourceChanged(url);
}
});
@@ -483,30 +553,38 @@ void HelpWidget::addViewer(HelpViewer *viewer)
if (currentViewer() == viewer)
m_backAction->setEnabled(available);
});
- connect(viewer, &HelpViewer::printRequested, this, [viewer, this]() {
- print(viewer);
- });
+ connect(viewer, &HelpViewer::printRequested, this, [viewer, this]() { print(viewer); });
if (m_style == ExternalWindow)
connect(viewer, &HelpViewer::titleChanged, this, &HelpWidget::updateWindowTitle);
+ connect(viewer, &HelpViewer::titleChanged, &m_model, [this, viewer] {
+ const int i = indexOf(viewer);
+ QTC_ASSERT(i >= 0, return );
+ m_model.dataChanged(m_model.index(i, 0), m_model.index(i, 0));
+ });
connect(viewer, &HelpViewer::loadFinished, this, &HelpWidget::highlightSearchTerms);
connect(viewer, &HelpViewer::newPageRequested, [](const QUrl &url) {
OpenPagesManager::instance().createPage(url);
});
connect(viewer, &HelpViewer::externalPageRequested, this, &openUrlInWindow);
-
updateCloseButton();
+ m_model.endInsertRows();
+ if (url.isValid())
+ viewer->setSource(url);
+ return viewer;
}
void HelpWidget::removeViewerAt(int index)
{
- QWidget *viewerWidget = m_viewerStack->widget(index);
+ HelpViewer *viewerWidget = viewerAt(index);
QTC_ASSERT(viewerWidget, return);
+ m_model.beginRemoveRows(QModelIndex(), index, index);
+ viewerWidget->stop();
m_viewerStack->removeWidget(viewerWidget);
- // do not delete, that is done in the model
- // delete viewerWidget;
+ m_model.endRemoveRows();
+ delete viewerWidget;
if (m_viewerStack->currentWidget())
- setCurrentViewer(qobject_cast<HelpViewer *>(m_viewerStack->currentWidget()));
+ setCurrentIndex(m_viewerStack->currentIndex());
updateCloseButton();
}
@@ -574,6 +652,14 @@ void HelpWidget::closeEvent(QCloseEvent *)
emit aboutToClose();
}
+int HelpWidget::indexOf(HelpViewer *viewer) const
+{
+ for (int i = 0; i < viewerCount(); ++i)
+ if (viewerAt(i) == viewer)
+ return i;
+ return -1;
+}
+
void HelpWidget::updateBackMenu()
{
m_backMenu->clear();
@@ -633,6 +719,13 @@ void HelpWidget::addBookmark()
manager->showBookmarkDialog(this, viewer->title(), url);
}
+void HelpWidget::openOnlineDocumentation()
+{
+ HelpViewer *viewer = currentViewer();
+ QTC_ASSERT(viewer, return);
+ LocalHelpManager::openOnlineHelp(viewer->source());
+}
+
void HelpWidget::copy()
{
QTC_ASSERT(currentViewer(), return);
diff --git a/src/plugins/help/helpwidget.h b/src/plugins/help/helpwidget.h
index fb084c99f3..69e19ae33f 100644
--- a/src/plugins/help/helpwidget.h
+++ b/src/plugins/help/helpwidget.h
@@ -27,8 +27,9 @@
#include <coreplugin/icontext.h>
-#include <qglobal.h>
+#include <QAbstractTableModel>
#include <QWidget>
+#include <qglobal.h>
QT_BEGIN_NAMESPACE
class QAction;
@@ -47,6 +48,24 @@ namespace Help {
namespace Internal {
class HelpViewer;
+class HelpWidget;
+class OpenPagesManager;
+
+class OpenPagesModel : public QAbstractTableModel
+{
+public:
+ OpenPagesModel(HelpWidget *parent);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+private:
+ HelpWidget *m_parent;
+
+ friend class HelpWidget;
+};
class HelpWidget : public QWidget
{
@@ -61,13 +80,14 @@ public:
HelpWidget(const Core::Context &context, WidgetStyle style, QWidget *parent = nullptr);
~HelpWidget() override;
+ QAbstractItemModel *model();
+
HelpViewer *currentViewer() const;
- void setCurrentViewer(HelpViewer *viewer);
int currentIndex() const;
- void addViewer(HelpViewer *viewer);
+ void setCurrentIndex(int index);
+ HelpViewer *addViewer(const QUrl &url, qreal zoom = 0);
void removeViewerAt(int index);
- // so central widget can save the state
int viewerCount() const;
HelpViewer *viewerAt(int index) const;
@@ -90,8 +110,11 @@ signals:
void aboutToClose();
void sourceChanged(const QUrl &url);
void filterActivated(const QString &name);
+ void currentIndexChanged(int index);
private:
+ int indexOf(HelpViewer *viewer) const;
+ HelpViewer *insertViewer(int index, const QUrl &url, qreal zoom);
void updateBackMenu();
void updateForwardMenu();
void updateWindowTitle();
@@ -99,6 +122,7 @@ private:
void goHome();
void addBookmark();
+ void openOnlineDocumentation();
void copy();
void forward();
void backward();
@@ -110,6 +134,8 @@ private:
void addSideBar();
QString sideBarSettingsKey() const;
+ OpenPagesModel m_model;
+ OpenPagesManager *m_openPagesManager = nullptr;
Core::IContext *m_context = nullptr;
WidgetStyle m_style;
QAction *m_toggleSideBarAction = nullptr;
@@ -120,6 +146,7 @@ private:
QAction *m_backAction = nullptr;
QAction *m_forwardAction = nullptr;
QAction *m_addBookmarkAction = nullptr;
+ QAction *m_openOnlineDocumentationAction = nullptr;
QComboBox *m_filterComboBox = nullptr;
QAction *m_closeAction = nullptr;
QAction *m_scaleUp = nullptr;
diff --git a/src/plugins/help/litehtmlhelpviewer.cpp b/src/plugins/help/litehtmlhelpviewer.cpp
new file mode 100644
index 0000000000..de86df33a5
--- /dev/null
+++ b/src/plugins/help/litehtmlhelpviewer.cpp
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "litehtmlhelpviewer.h"
+
+#include "helpconstants.h"
+#include "localhelpmanager.h"
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
+
+#include <QClipboard>
+#include <QGuiApplication>
+#include <QScrollBar>
+#include <QTimer>
+#include <QVBoxLayout>
+
+#include <QDebug>
+
+using namespace Help;
+using namespace Help::Internal;
+
+const int kMaxHistoryItems = 20;
+
+static QByteArray getData(const QUrl &url)
+{
+ // TODO: this is just a hack for Qt documentation
+ // which decides to use a simpler CSS if the viewer does not have JavaScript
+ // which was a hack to decide if we are viewing in QTextBrowser or QtWebEngine et al
+ QUrl actualUrl = url;
+ QString path = url.path(QUrl::FullyEncoded);
+ static const char simpleCss[] = "/offline-simple.css";
+ if (path.endsWith(simpleCss)) {
+ path.replace(simpleCss, "/offline.css");
+ actualUrl.setPath(path);
+ }
+ const LocalHelpManager::HelpData help = LocalHelpManager::helpData(actualUrl);
+ return help.data;
+}
+
+LiteHtmlHelpViewer::LiteHtmlHelpViewer(QWidget *parent)
+ : HelpViewer(parent)
+ , m_viewer(new QLiteHtmlWidget)
+{
+ m_viewer->setResourceHandler([](const QUrl &url) { return getData(url); });
+ m_viewer->viewport()->installEventFilter(this);
+ connect(m_viewer, &QLiteHtmlWidget::linkClicked, this, &LiteHtmlHelpViewer::setSource);
+ connect(m_viewer,
+ &QLiteHtmlWidget::contextMenuRequested,
+ this,
+ &LiteHtmlHelpViewer::showContextMenu);
+ auto layout = new QVBoxLayout;
+ setLayout(layout);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(m_viewer, 10);
+ setFocusProxy(m_viewer);
+ QPalette p = palette();
+ p.setColor(QPalette::Inactive, QPalette::Highlight,
+ p.color(QPalette::Active, QPalette::Highlight));
+ p.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ p.color(QPalette::Active, QPalette::HighlightedText));
+ p.setColor(QPalette::Base, Qt::white);
+ p.setColor(QPalette::Text, Qt::black);
+ setPalette(p);
+}
+
+LiteHtmlHelpViewer::~LiteHtmlHelpViewer() = default;
+
+QFont LiteHtmlHelpViewer::viewerFont() const
+{
+ return m_viewer->defaultFont();
+}
+
+void LiteHtmlHelpViewer::setViewerFont(const QFont &newFont)
+{
+ m_viewer->setDefaultFont(newFont);
+}
+
+void LiteHtmlHelpViewer::scaleUp()
+{
+ setScale(scale() * 1.1);
+}
+
+void LiteHtmlHelpViewer::scaleDown()
+{
+ setScale(scale() * .9);
+}
+
+void LiteHtmlHelpViewer::resetScale()
+{
+ m_viewer->setZoomFactor(1);
+}
+
+qreal LiteHtmlHelpViewer::scale() const
+{
+ return m_viewer->zoomFactor();
+}
+
+void LiteHtmlHelpViewer::setScale(qreal scale)
+{
+ // interpret 0 as "default"
+ m_viewer->setZoomFactor(scale == 0 ? qreal(1) : scale);
+}
+
+QString LiteHtmlHelpViewer::title() const
+{
+ return m_viewer->title();
+}
+
+QUrl LiteHtmlHelpViewer::source() const
+{
+ return m_viewer->url();
+}
+
+void LiteHtmlHelpViewer::setSource(const QUrl &url)
+{
+ if (launchWithExternalApp(url))
+ return;
+ m_forwardItems.clear();
+ emit forwardAvailable(false);
+ if (m_viewer->url().isValid()) {
+ m_backItems.push_back(currentHistoryItem());
+ while (m_backItems.size() > kMaxHistoryItems) // this should trigger only once anyhow
+ m_backItems.erase(m_backItems.begin());
+ emit backwardAvailable(true);
+ }
+ setSourceInternal(url);
+}
+
+void LiteHtmlHelpViewer::setHtml(const QString &html)
+{
+ m_viewer->setUrl({"about:invalid"});
+ m_viewer->setHtml(html);
+}
+
+QString LiteHtmlHelpViewer::selectedText() const
+{
+ return m_viewer->selectedText();
+}
+
+bool LiteHtmlHelpViewer::isForwardAvailable() const
+{
+ return !m_forwardItems.empty();
+}
+
+bool LiteHtmlHelpViewer::isBackwardAvailable() const
+{
+ return !m_backItems.empty();
+}
+
+void LiteHtmlHelpViewer::addBackHistoryItems(QMenu *backMenu)
+{
+ int backCount = 0;
+ Utils::reverseForeach(m_backItems, [this, backMenu, &backCount](const HistoryItem &item) {
+ ++backCount;
+ auto action = new QAction(backMenu);
+ action->setText(item.title);
+ connect(action, &QAction::triggered, this, [this, backCount] { goBackward(backCount); });
+ backMenu->addAction(action);
+ });
+}
+
+void LiteHtmlHelpViewer::addForwardHistoryItems(QMenu *forwardMenu)
+{
+ int forwardCount = 0;
+ for (const HistoryItem &item : m_forwardItems) {
+ ++forwardCount;
+ auto action = new QAction(forwardMenu);
+ action->setText(item.title);
+ connect(action, &QAction::triggered, this, [this, forwardCount] {
+ goForward(forwardCount);
+ });
+ forwardMenu->addAction(action);
+ }
+}
+
+bool LiteHtmlHelpViewer::findText(
+ const QString &text, Core::FindFlags flags, bool incremental, bool fromSearch, bool *wrapped)
+{
+ return m_viewer->findText(text,
+ Core::textDocumentFlagsForFindFlags(flags),
+ incremental,
+ wrapped);
+}
+
+void LiteHtmlHelpViewer::copy()
+{
+ QGuiApplication::clipboard()->setText(selectedText());
+}
+
+void LiteHtmlHelpViewer::stop() {}
+
+void LiteHtmlHelpViewer::forward()
+{
+ goForward(1);
+}
+
+void LiteHtmlHelpViewer::backward()
+{
+ goBackward(1);
+}
+void LiteHtmlHelpViewer::goForward(int count)
+{
+ HistoryItem nextItem = currentHistoryItem();
+ for (int i = 0; i < count; ++i) {
+ QTC_ASSERT(!m_forwardItems.empty(), return );
+ m_backItems.push_back(nextItem);
+ nextItem = m_forwardItems.front();
+ m_forwardItems.erase(m_forwardItems.begin());
+ }
+ emit backwardAvailable(isBackwardAvailable());
+ emit forwardAvailable(isForwardAvailable());
+ setSourceInternal(nextItem.url, nextItem.vscroll);
+}
+
+void LiteHtmlHelpViewer::goBackward(int count)
+{
+ HistoryItem previousItem = currentHistoryItem();
+ for (int i = 0; i < count; ++i) {
+ QTC_ASSERT(!m_backItems.empty(), return );
+ m_forwardItems.insert(m_forwardItems.begin(), previousItem);
+ previousItem = m_backItems.back();
+ m_backItems.pop_back();
+ }
+ emit backwardAvailable(isBackwardAvailable());
+ emit forwardAvailable(isForwardAvailable());
+ setSourceInternal(previousItem.url, previousItem.vscroll);
+}
+
+void LiteHtmlHelpViewer::print(QPrinter *printer)
+{
+ // TODO
+}
+
+bool LiteHtmlHelpViewer::eventFilter(QObject *src, QEvent *e)
+{
+ if (isScrollWheelZoomingEnabled() && e->type() == QEvent::Wheel) {
+ auto we = static_cast<QWheelEvent *>(e);
+ if (we->modifiers() == Qt::ControlModifier)
+ return true;
+ }
+ return HelpViewer::eventFilter(src, e);
+}
+
+void LiteHtmlHelpViewer::setSourceInternal(const QUrl &url, Utils::optional<int> vscroll)
+{
+ slotLoadStarted();
+ QUrl currentUrlWithoutFragment = m_viewer->url();
+ currentUrlWithoutFragment.setFragment({});
+ QUrl newUrlWithoutFragment = url;
+ newUrlWithoutFragment.setFragment({});
+ m_viewer->setUrl(url);
+ if (currentUrlWithoutFragment != newUrlWithoutFragment)
+ m_viewer->setHtml(QString::fromUtf8(getData(url)));
+ if (vscroll)
+ m_viewer->verticalScrollBar()->setValue(*vscroll);
+ else
+ m_viewer->scrollToAnchor(url.fragment(QUrl::FullyEncoded));
+ slotLoadFinished();
+ emit titleChanged();
+}
+
+void LiteHtmlHelpViewer::showContextMenu(const QPoint &pos, const QUrl &url)
+{
+ QMenu menu(nullptr);
+
+ QAction *copyAnchorAction = nullptr;
+ if (!url.isEmpty() && url.isValid()) {
+ if (isActionVisible(HelpViewer::Action::NewPage)) {
+ QAction *action = menu.addAction(
+ QCoreApplication::translate("HelpViewer", Constants::TR_OPEN_LINK_AS_NEW_PAGE));
+ connect(action, &QAction::triggered, this, [this, url]() {
+ emit newPageRequested(url);
+ });
+ }
+ if (isActionVisible(HelpViewer::Action::ExternalWindow)) {
+ QAction *action = menu.addAction(
+ QCoreApplication::translate("HelpViewer", Constants::TR_OPEN_LINK_IN_WINDOW));
+ connect(action, &QAction::triggered, this, [this, url]() {
+ emit externalPageRequested(url);
+ });
+ }
+ copyAnchorAction = menu.addAction(tr("Copy Link"));
+ } else if (!m_viewer->selectedText().isEmpty()) {
+ connect(menu.addAction(tr("Copy")), &QAction::triggered, this, &HelpViewer::copy);
+ }
+
+ if (copyAnchorAction == menu.exec(m_viewer->mapToGlobal(pos)))
+ QGuiApplication::clipboard()->setText(url.toString());
+}
+
+LiteHtmlHelpViewer::HistoryItem LiteHtmlHelpViewer::currentHistoryItem() const
+{
+ return {m_viewer->url(), m_viewer->title(), m_viewer->verticalScrollBar()->value()};
+}
+
+//bool TextBrowserHelpWidget::eventFilter(QObject *obj, QEvent *event)
+//{
+// if (obj == this) {
+// if (event->type() == QEvent::FontChange) {
+// if (!forceFont)
+// return true;
+// } else if (event->type() == QEvent::KeyPress) {
+// auto keyEvent = static_cast<QKeyEvent *>(event);
+// if (keyEvent->key() == Qt::Key_Slash) {
+// keyEvent->accept();
+// Core::Find::openFindToolBar(Core::Find::FindForwardDirection);
+// return true;
+// }
+// } else if (event->type() == QEvent::ToolTip) {
+// auto e = static_cast<const QHelpEvent *>(event);
+// QToolTip::showText(e->globalPos(), linkAt(e->pos()));
+// return true;
+// }
+// }
+// return QTextBrowser::eventFilter(obj, event);
+//}
+
+//void TextBrowserHelpWidget::mousePressEvent(QMouseEvent *e)
+//{
+// if (Utils::HostOsInfo::isLinuxHost() && m_parent->handleForwardBackwardMouseButtons(e))
+// return;
+// QTextBrowser::mousePressEvent(e);
+//}
+
+//void TextBrowserHelpWidget::mouseReleaseEvent(QMouseEvent *e)
+//{
+// if (!Utils::HostOsInfo::isLinuxHost() && m_parent->handleForwardBackwardMouseButtons(e))
+// return;
+
+// bool controlPressed = e->modifiers() & Qt::ControlModifier;
+// const QString link = linkAt(e->pos());
+// if (m_parent->isActionVisible(HelpViewer::Action::NewPage)
+// && (controlPressed || e->button() == Qt::MidButton) && !link.isEmpty()) {
+// emit m_parent->newPageRequested(QUrl(link));
+// return;
+// }
+
+// QTextBrowser::mouseReleaseEvent(e);
+//}
diff --git a/src/plugins/help/litehtmlhelpviewer.h b/src/plugins/help/litehtmlhelpviewer.h
new file mode 100644
index 0000000000..7161abd7ce
--- /dev/null
+++ b/src/plugins/help/litehtmlhelpviewer.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "centralwidget.h"
+#include "helpviewer.h"
+#include "openpagesmanager.h"
+
+#include <utils/optional.h>
+
+#include <qlitehtmlwidget.h>
+
+#include <QTextBrowser>
+
+namespace Help {
+namespace Internal {
+
+class LiteHtmlHelpViewer : public HelpViewer
+{
+ Q_OBJECT
+
+public:
+ explicit LiteHtmlHelpViewer(QWidget *parent = nullptr);
+ ~LiteHtmlHelpViewer() override;
+
+ QFont viewerFont() const override;
+ void setViewerFont(const QFont &font) override;
+
+ qreal scale() const override;
+ void setScale(qreal scale) override;
+
+ QString title() const override;
+
+ QUrl source() const override;
+ void setSource(const QUrl &url) override;
+
+ void setHtml(const QString &html) override;
+
+ QString selectedText() const override;
+ bool isForwardAvailable() const override;
+ bool isBackwardAvailable() const override;
+ void addBackHistoryItems(QMenu *backMenu) override;
+ void addForwardHistoryItems(QMenu *forwardMenu) override;
+
+ bool findText(const QString &text, Core::FindFlags flags,
+ bool incremental, bool fromSearch, bool *wrapped = nullptr) override;
+
+ void scaleUp() override;
+ void scaleDown() override;
+ void resetScale() override;
+ void copy() override;
+ void stop() override;
+ void forward() override;
+ void backward() override;
+ void print(QPrinter *printer) override;
+
+ bool eventFilter(QObject *src, QEvent *e) override;
+
+private:
+ void goForward(int count);
+ void goBackward(int count);
+ void setSourceInternal(const QUrl &url, Utils::optional<int> vscroll = Utils::nullopt);
+ void showContextMenu(const QPoint &pos, const QUrl &url);
+
+ struct HistoryItem
+ {
+ QUrl url;
+ QString title;
+ int vscroll;
+ };
+ HistoryItem currentHistoryItem() const;
+
+ QLiteHtmlWidget *m_viewer;
+ std::vector<HistoryItem> m_backItems;
+ std::vector<HistoryItem> m_forwardItems;
+};
+
+} // namespace Internal
+} // namespace Help
diff --git a/src/plugins/help/localhelpmanager.cpp b/src/plugins/help/localhelpmanager.cpp
index 140aa4a935..0a29750b85 100644
--- a/src/plugins/help/localhelpmanager.cpp
+++ b/src/plugins/help/localhelpmanager.cpp
@@ -29,13 +29,29 @@
#include "helpconstants.h"
#include "helpmanager.h"
#include "helpviewer.h"
+#include "textbrowserhelpviewer.h"
+
+#ifdef QTC_WEBENGINE_HELPVIEWER
+#include "webenginehelpviewer.h"
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+#include <QWebEngineUrlScheme>
+#endif
+#endif
+#ifdef QTC_LITEHTML_HELPVIEWER
+#include "litehtmlhelpviewer.h"
+#endif
+#ifdef QTC_MAC_NATIVE_HELPVIEWER
+#include "macwebkithelpviewer.h"
+#endif
#include <app/app_version.h>
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
+#include <utils/optional.h>
#include <utils/qtcassert.h>
+#include <QDesktopServices>
#include <QFontDatabase>
#include <QMutexLocker>
@@ -69,6 +85,10 @@ static const char kUseScrollWheelZooming[] = "Help/UseScrollWheelZooming";
static const char kLastShownPagesKey[] = "Help/LastShownPages";
static const char kLastShownPagesZoomKey[] = "Help/LastShownPagesZoom";
static const char kLastSelectedTabKey[] = "Help/LastSelectedTab";
+static const char kViewerBackend[] = "Help/ViewerBackend";
+
+static const char kQtWebEngineBackend[] = "qtwebengine";
+static const char kTextBrowserBackend[] = "textbrowser";
static const int kDefaultFallbackFontSize = 14;
@@ -275,6 +295,81 @@ void LocalHelpManager::setLastSelectedTab(int index)
Core::ICore::settings()->setValue(kLastSelectedTabKey, index);
}
+static Utils::optional<HelpViewerFactory> backendForId(const QByteArray &id)
+{
+ const QVector<HelpViewerFactory> factories = LocalHelpManager::viewerBackends();
+ const auto backend = std::find_if(std::begin(factories),
+ std::end(factories),
+ Utils::equal(&HelpViewerFactory::id, id));
+ if (backend != std::end(factories))
+ return *backend;
+ return {};
+}
+
+HelpViewerFactory LocalHelpManager::defaultViewerBackend()
+{
+ const QByteArray backend = qgetenv("QTC_HELPVIEWER_BACKEND");
+ if (!backend.isEmpty()) {
+ const Utils::optional<HelpViewerFactory> factory = backendForId(backend);
+ if (factory)
+ return *factory;
+ }
+ if (!backend.isEmpty())
+ qWarning("Help viewer backend \"%s\" not found, using default.", backend.constData());
+ const Utils::optional<HelpViewerFactory> factory = backendForId(kQtWebEngineBackend);
+ if (factory)
+ return *factory;
+ return backendForId(kTextBrowserBackend).value_or(HelpViewerFactory());
+}
+
+QVector<HelpViewerFactory> LocalHelpManager::viewerBackends()
+{
+ QVector<HelpViewerFactory> result;
+#ifdef QTC_WEBENGINE_HELPVIEWER
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ static bool schemeRegistered = false;
+ if (!schemeRegistered) {
+ schemeRegistered = true;
+ QWebEngineUrlScheme scheme("qthelp");
+ scheme.setFlags(QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::LocalAccessAllowed);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+#endif
+ result.append(
+ {kQtWebEngineBackend, tr("QtWebEngine"), []() { return new WebEngineHelpViewer; }});
+#endif
+#ifdef QTC_LITEHTML_HELPVIEWER
+ result.append({"litehtml", tr("litehtml"), []() { return new LiteHtmlHelpViewer; }});
+#endif
+#ifdef QTC_MAC_NATIVE_HELPVIEWER
+ result.append({"native", tr("WebKit"), []() { return new MacWebKitHelpViewer; }});
+#endif
+ result.append(
+ {kTextBrowserBackend, tr("QTextBrowser"), []() { return new TextBrowserHelpViewer; }});
+ return result;
+}
+
+HelpViewerFactory LocalHelpManager::viewerBackend()
+{
+ const QByteArray id = Core::ICore::settings()->value(kViewerBackend).toByteArray();
+ if (!id.isEmpty())
+ return backendForId(id).value_or(defaultViewerBackend());
+ return defaultViewerBackend();
+}
+
+void LocalHelpManager::setViewerBackendId(const QByteArray &id)
+{
+ if (id.isEmpty())
+ Core::ICore::settings()->remove(kViewerBackend);
+ else
+ Core::ICore::settings()->setValue(kViewerBackend, id);
+}
+
+QByteArray LocalHelpManager::viewerBackendId()
+{
+ return Core::ICore::settings()->value(kViewerBackend).toByteArray();
+}
+
void LocalHelpManager::setupGuiHelpEngine()
{
if (m_needsCollectionFile) {
@@ -445,3 +540,31 @@ void LocalHelpManager::updateFilterModel()
}
emit m_instance->filterIndexChanged(m_currentFilterIndex);
}
+
+bool LocalHelpManager::canOpenOnlineHelp(const QUrl &url)
+{
+ const QString address = url.toString();
+ if (address.startsWith("qthelp://org.qt-project.")
+ || address.startsWith("qthelp://com.nokia.")
+ || address.startsWith("qthelp://com.trolltech.")) {
+ return true;
+ }
+ return false;
+}
+
+bool LocalHelpManager::openOnlineHelp(const QUrl &url)
+{
+ static const QString qtcreatorUnversionedID = "org.qt-project.qtcreator";
+
+ if (canOpenOnlineHelp(url)) {
+ QString urlPrefix = "http://doc.qt.io/";
+ if (url.authority().startsWith(qtcreatorUnversionedID))
+ urlPrefix.append(QString::fromLatin1("qtcreator"));
+ else
+ urlPrefix.append("qt-5");
+ const QString address = url.toString();
+ QDesktopServices::openUrl(QUrl(urlPrefix + address.mid(address.lastIndexOf(QLatin1Char('/')))));
+ return true;
+ }
+ return false;
+}
diff --git a/src/plugins/help/localhelpmanager.h b/src/plugins/help/localhelpmanager.h
index 7b330ade30..f75de12fca 100644
--- a/src/plugins/help/localhelpmanager.h
+++ b/src/plugins/help/localhelpmanager.h
@@ -33,6 +33,8 @@
#include <QUrl>
#include <QStandardItemModel>
+#include <functional>
+
QT_FORWARD_DECLARE_CLASS(QHelpEngine)
class BookmarkManager;
@@ -40,6 +42,15 @@ class BookmarkManager;
namespace Help {
namespace Internal {
+class HelpViewer;
+
+struct HelpViewerFactory
+{
+ QByteArray id;
+ QString displayName;
+ std::function<HelpViewer *()> create;
+};
+
class LocalHelpManager : public QObject
{
Q_OBJECT
@@ -90,6 +101,12 @@ public:
static int lastSelectedTab();
static void setLastSelectedTab(int index);
+ static HelpViewerFactory defaultViewerBackend();
+ static QVector<HelpViewerFactory> viewerBackends();
+ static HelpViewerFactory viewerBackend();
+ static void setViewerBackendId(const QByteArray &id);
+ static QByteArray viewerBackendId();
+
static void setupGuiHelpEngine();
static void setEngineNeedsUpdate();
@@ -105,6 +122,9 @@ public:
static void updateFilterModel();
+ static bool canOpenOnlineHelp(const QUrl &url);
+ static bool openOnlineHelp(const QUrl &url);
+
signals:
void filterIndexChanged(int index);
void fallbackFontChanged(const QFont &font);
diff --git a/src/plugins/help/macwebkithelpviewer.mm b/src/plugins/help/macwebkithelpviewer.mm
index d0edb0e61c..ac2e721c12 100644
--- a/src/plugins/help/macwebkithelpviewer.mm
+++ b/src/plugins/help/macwebkithelpviewer.mm
@@ -335,7 +335,6 @@ static NSMenuItem *menuItem(NSURL *url, id target, SEL action, const QString &ti
case WebMenuItemTagGoBack:
case WebMenuItemTagGoForward:
case WebMenuItemTagStop:
- case WebMenuItemTagReload:
case WebMenuItemTagOther:
case WebMenuItemTagSearchInSpotlight:
case WebMenuItemTagSearchWeb:
diff --git a/src/plugins/help/openpagesmanager.cpp b/src/plugins/help/openpagesmanager.cpp
index a6b6168dcd..68c0f6bf5e 100644
--- a/src/plugins/help/openpagesmanager.cpp
+++ b/src/plugins/help/openpagesmanager.cpp
@@ -25,11 +25,10 @@
#include "openpagesmanager.h"
-#include "centralwidget.h"
#include "helpconstants.h"
#include "helpviewer.h"
+#include "helpwidget.h"
#include "localhelpmanager.h"
-#include "openpagesmodel.h"
#include "openpagesswitcher.h"
#include "openpageswidget.h"
@@ -42,6 +41,7 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/modemanager.h>
+#include <utils/qtcassert.h>
using namespace Core;
using namespace Help::Internal;
@@ -50,27 +50,37 @@ OpenPagesManager *OpenPagesManager::m_instance = nullptr;
// -- OpenPagesManager
-OpenPagesManager::OpenPagesManager(QObject *parent)
- : QObject(parent)
+OpenPagesManager::OpenPagesManager(HelpWidget *helpWidget)
+ : m_helpWidget(helpWidget)
{
Q_ASSERT(!m_instance);
m_instance = this;
- m_model = new OpenPagesModel(this);
m_comboBox = new QComboBox;
- m_comboBox->setModel(m_model);
+ m_comboBox->setModel(m_helpWidget->model());
m_comboBox->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(m_comboBox, QOverload<int>::of(&QComboBox::activated),
- this, &OpenPagesManager::setCurrentPageByRow);
- connect(m_comboBox, &QWidget::customContextMenuRequested, this,
- &OpenPagesManager::openPagesContextMenu);
-
- m_openPagesSwitcher = new OpenPagesSwitcher(m_model);
+ connect(m_comboBox,
+ QOverload<int>::of(&QComboBox::activated),
+ m_helpWidget,
+ &HelpWidget::setCurrentIndex);
+ connect(m_helpWidget, &HelpWidget::currentIndexChanged, m_comboBox, &QComboBox::setCurrentIndex);
+ connect(m_comboBox,
+ &QWidget::customContextMenuRequested,
+ this,
+ &OpenPagesManager::openPagesContextMenu);
+
+ m_openPagesSwitcher = new OpenPagesSwitcher(m_helpWidget->model());
connect(m_openPagesSwitcher, &OpenPagesSwitcher::closePage, this,
&OpenPagesManager::closePage);
- connect(m_openPagesSwitcher, &OpenPagesSwitcher::setCurrentPage,
- this, &OpenPagesManager::setCurrentPage);
+ connect(m_openPagesSwitcher,
+ &OpenPagesSwitcher::setCurrentPage,
+ m_helpWidget,
+ [this](const QModelIndex &index) { m_helpWidget->setCurrentIndex(index.row()); });
+ connect(m_helpWidget,
+ &HelpWidget::currentIndexChanged,
+ m_openPagesSwitcher,
+ &OpenPagesSwitcher::selectCurrentPage);
}
OpenPagesManager ::~OpenPagesManager()
@@ -88,9 +98,15 @@ OpenPagesManager &OpenPagesManager::instance()
QWidget *OpenPagesManager::openPagesWidget() const
{
if (!m_openPagesWidget) {
- m_openPagesWidget = new OpenPagesWidget(m_model);
- connect(m_openPagesWidget, &OpenPagesWidget::setCurrentPage,
- this, &OpenPagesManager::setCurrentPage);
+ m_openPagesWidget = new OpenPagesWidget(m_helpWidget->model());
+ connect(m_openPagesWidget,
+ &OpenPagesWidget::setCurrentPage,
+ m_helpWidget,
+ [this](const QModelIndex &index) { m_helpWidget->setCurrentIndex(index.row()); });
+ connect(m_helpWidget,
+ &HelpWidget::currentIndexChanged,
+ m_openPagesWidget,
+ &OpenPagesWidget::selectCurrentPage);
connect(m_openPagesWidget, &OpenPagesWidget::closePage,
this, &OpenPagesManager::closePage);
connect(m_openPagesWidget, &OpenPagesWidget::closePagesExcept,
@@ -104,11 +120,6 @@ QComboBox *OpenPagesManager::openPagesComboBox() const
return m_comboBox;
}
-int OpenPagesManager::pageCount() const
-{
- return m_model->rowCount();
-}
-
QStringList splitString(const QVariant &value)
{
using namespace Help::Constants;
@@ -123,49 +134,43 @@ void OpenPagesManager::setupInitialPages()
int initialPage = 0;
switch (option) {
- case LocalHelpManager::ShowHomePage: {
- m_model->addPage(homePage);
- } break;
-
- case LocalHelpManager::ShowBlankPage: {
- m_model->addPage(QUrl(Help::Constants::AboutBlank));
- } break;
-
- case LocalHelpManager::ShowLastPages: {
- const QStringList &lastShownPageList = LocalHelpManager::lastShownPages();
- const int pageCount = lastShownPageList.count();
-
- if (pageCount > 0) {
- QList<float> zoomFactors = LocalHelpManager::lastShownPagesZoom();
- while (zoomFactors.count() < pageCount)
- zoomFactors.append(0.);
-
- initialPage = LocalHelpManager::lastSelectedTab();
- for (int curPage = 0; curPage < pageCount; ++curPage) {
- const QString &curFile = lastShownPageList.at(curPage);
- if (engine.findFile(curFile).isValid()
- || curFile == Help::Constants::AboutBlank) {
- m_model->addPage(curFile, zoomFactors.at(curPage));
- } else if (curPage <= initialPage && initialPage > 0) {
- --initialPage;
- }
+ case LocalHelpManager::ShowHomePage:
+ m_helpWidget->addViewer(homePage);
+ break;
+
+ case LocalHelpManager::ShowBlankPage:
+ m_helpWidget->addViewer(QUrl(Help::Constants::AboutBlank));
+ break;
+
+ case LocalHelpManager::ShowLastPages: {
+ const QStringList &lastShownPageList = LocalHelpManager::lastShownPages();
+ const int pageCount = lastShownPageList.count();
+
+ if (pageCount > 0) {
+ QList<float> zoomFactors = LocalHelpManager::lastShownPagesZoom();
+ while (zoomFactors.count() < pageCount)
+ zoomFactors.append(0.);
+
+ initialPage = LocalHelpManager::lastSelectedTab();
+ for (int curPage = 0; curPage < pageCount; ++curPage) {
+ const QString &curFile = lastShownPageList.at(curPage);
+ if (engine.findFile(curFile).isValid() || curFile == Help::Constants::AboutBlank) {
+ m_helpWidget->addViewer(curFile, zoomFactors.at(curPage));
+ } else if (curPage <= initialPage && initialPage > 0) {
+ --initialPage;
}
}
- } break;
+ }
+ } break;
- default: break;
+ default:
+ break;
}
- if (m_model->rowCount() == 0)
- m_model->addPage(homePage);
+ if (m_helpWidget->viewerCount() == 0)
+ m_helpWidget->addViewer(homePage);
- for (int i = 0; i < m_model->rowCount(); ++i)
- CentralWidget::instance()->addViewer(m_model->pageAt(i));
-
- emit pagesChanged();
- setCurrentPageByRow((initialPage >= m_model->rowCount())
- ? m_model->rowCount() - 1 : initialPage);
- m_openPagesSwitcher->selectCurrentPage();
+ m_helpWidget->setCurrentIndex(std::max(initialPage, m_helpWidget->viewerCount() - 1));
}
HelpViewer *OpenPagesManager::createPage()
@@ -178,33 +183,12 @@ HelpViewer *OpenPagesManager::createPage(const QUrl &url)
if (url.isValid() && HelpViewer::launchWithExternalApp(url))
return nullptr;
- m_model->addPage(url);
-
- const int index = m_model->rowCount() - 1;
- HelpViewer * const page = m_model->pageAt(index);
- CentralWidget::instance()->addViewer(page);
-
- emit pagesChanged();
- setCurrentPageByRow(index);
+ HelpViewer *page = m_helpWidget->addViewer(url);
+ m_helpWidget->setCurrentIndex(m_helpWidget->viewerCount() - 1);
return page;
}
-void OpenPagesManager::setCurrentPageByRow(int index)
-{
- CentralWidget::instance()->setCurrentViewer(m_model->pageAt(index));
-
- m_comboBox->setCurrentIndex(index);
- if (m_openPagesWidget)
- m_openPagesWidget->selectCurrentPage();
-}
-
-void OpenPagesManager::setCurrentPage(const QModelIndex &index)
-{
- if (index.isValid())
- setCurrentPageByRow(index.row());
-}
-
void OpenPagesManager::closeCurrentPage()
{
if (!m_openPagesWidget)
@@ -216,10 +200,10 @@ void OpenPagesManager::closeCurrentPage()
const bool returnOnClose = LocalHelpManager::returnOnClose();
- if (m_model->rowCount() == 1 && returnOnClose) {
+ if (m_helpWidget->viewerCount() == 1 && returnOnClose) {
ModeManager::activateMode(Core::Constants::MODE_EDIT);
} else {
- Q_ASSERT(indexes.count() == 1);
+ QTC_ASSERT(indexes.count() == 1, return );
removePage(indexes.first().row());
}
}
@@ -234,9 +218,9 @@ void OpenPagesManager::closePagesExcept(const QModelIndex &index)
{
if (index.isValid()) {
int i = 0;
- HelpViewer *viewer = m_model->pageAt(index.row());
- while (m_model->rowCount() > 1) {
- if (m_model->pageAt(i) != viewer)
+ HelpViewer *viewer = m_helpWidget->viewerAt(index.row());
+ while (m_helpWidget->viewerCount() > 1) {
+ if (m_helpWidget->viewerAt(i) != viewer)
removePage(i);
else
i++;
@@ -247,7 +231,6 @@ void OpenPagesManager::closePagesExcept(const QModelIndex &index)
void OpenPagesManager::gotoNextPage()
{
if (!m_openPagesSwitcher->isVisible()) {
- m_openPagesSwitcher->selectCurrentPage();
m_openPagesSwitcher->gotoNextPage();
showTwicherOrSelectPage();
} else {
@@ -258,7 +241,6 @@ void OpenPagesManager::gotoNextPage()
void OpenPagesManager::gotoPreviousPage()
{
if (!m_openPagesSwitcher->isVisible()) {
- m_openPagesSwitcher->selectCurrentPage();
m_openPagesSwitcher->gotoPreviousPage();
showTwicherOrSelectPage();
} else {
@@ -270,22 +252,17 @@ void OpenPagesManager::gotoPreviousPage()
void OpenPagesManager::removePage(int index)
{
- Q_ASSERT(m_model->rowCount() > 1);
-
- m_model->removePage(index);
- CentralWidget::instance()->removeViewerAt(index);
+ QTC_ASSERT(index < m_helpWidget->viewerCount(), return );
- emit pagesChanged();
- if (m_openPagesWidget)
- m_openPagesWidget->selectCurrentPage();
+ m_helpWidget->removeViewerAt(index);
}
void OpenPagesManager::showTwicherOrSelectPage() const
{
if (QApplication::keyboardModifiers() != Qt::NoModifier) {
- const int width = CentralWidget::instance()->width();
- const int height = CentralWidget::instance()->height();
- const QPoint p(CentralWidget::instance()->mapToGlobal(QPoint(0, 0)));
+ const int width = m_helpWidget->width();
+ const int height = m_helpWidget->height();
+ const QPoint p(m_helpWidget->mapToGlobal(QPoint(0, 0)));
m_openPagesSwitcher->move((width - m_openPagesSwitcher->width()) / 2 + p.x(),
(height - m_openPagesSwitcher->height()) / 2 + p.y());
m_openPagesSwitcher->setVisible(true);
@@ -296,8 +273,8 @@ void OpenPagesManager::showTwicherOrSelectPage() const
void OpenPagesManager::openPagesContextMenu(const QPoint &point)
{
- const QModelIndex &index = m_model->index(m_comboBox->currentIndex(), 0);
- const QString &fileName = m_model->data(index, Qt::ToolTipRole).toString();
+ const QModelIndex &index = m_helpWidget->model()->index(m_comboBox->currentIndex(), 0);
+ const QString &fileName = m_helpWidget->model()->data(index, Qt::ToolTipRole).toString();
if (fileName.isEmpty())
return;
diff --git a/src/plugins/help/openpagesmanager.h b/src/plugins/help/openpagesmanager.h
index cc2d0d17a2..fb321d6d00 100644
--- a/src/plugins/help/openpagesmanager.h
+++ b/src/plugins/help/openpagesmanager.h
@@ -27,18 +27,21 @@
#include <QObject>
-QT_FORWARD_DECLARE_CLASS(QComboBox)
-QT_FORWARD_DECLARE_CLASS(QListView)
-QT_FORWARD_DECLARE_CLASS(QModelIndex)
-QT_FORWARD_DECLARE_CLASS(QPoint)
-QT_FORWARD_DECLARE_CLASS(QUrl)
-QT_FORWARD_DECLARE_CLASS(QWidget)
+QT_BEGIN_NAMESPACE
+class QAbstractItemModel;
+class QComboBox;
+class QListView;
+class QModelIndex;
+class QPoint;
+class QUrl;
+class QWidget;
+QT_END_NAMESPACE
namespace Help {
- namespace Internal {
+namespace Internal {
+class HelpWidget;
class HelpViewer;
-class OpenPagesModel;
class OpenPagesSwitcher;
class OpenPagesWidget;
@@ -47,7 +50,7 @@ class OpenPagesManager : public QObject
Q_OBJECT
public:
- OpenPagesManager(QObject *parent = nullptr);
+ OpenPagesManager(HelpWidget *helpWidget);
~OpenPagesManager() override;
static OpenPagesManager &instance();
@@ -55,15 +58,11 @@ public:
QWidget *openPagesWidget() const;
QComboBox *openPagesComboBox() const;
- int pageCount() const;
void setupInitialPages();
HelpViewer *createPage();
HelpViewer *createPage(const QUrl &url);
- void setCurrentPageByRow(int index);
- void setCurrentPage(const QModelIndex &index);
-
void closeCurrentPage();
void closePage(const QModelIndex &index);
void closePagesExcept(const QModelIndex &index);
@@ -71,21 +70,18 @@ public:
void gotoNextPage();
void gotoPreviousPage();
-signals:
- void pagesChanged();
-
private:
void removePage(int index);
void showTwicherOrSelectPage() const;
void openPagesContextMenu(const QPoint &point);
QComboBox *m_comboBox = nullptr;
- OpenPagesModel *m_model = nullptr;
+ HelpWidget *m_helpWidget = nullptr;
mutable OpenPagesWidget *m_openPagesWidget = nullptr;
OpenPagesSwitcher *m_openPagesSwitcher = nullptr;
static OpenPagesManager *m_instance;
};
- } // namespace Internal
+} // namespace Internal
} // namespace Help
diff --git a/src/plugins/help/openpagesmodel.cpp b/src/plugins/help/openpagesmodel.cpp
deleted file mode 100644
index 3587acfc09..0000000000
--- a/src/plugins/help/openpagesmodel.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "openpagesmodel.h"
-#include "helpplugin.h"
-#include "helpviewer.h"
-
-#include <QUrl>
-
-using namespace Help::Internal;
-
-OpenPagesModel::OpenPagesModel(QObject *parent)
- : QAbstractTableModel(parent)
-{
-}
-
-int OpenPagesModel::rowCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : m_pages.count();
-}
-
-int OpenPagesModel::columnCount(const QModelIndex &/*parent*/) const
-{
- return 2;
-}
-
-QVariant OpenPagesModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid() || index.row() >= rowCount()
- || index.column() >= columnCount() - 1)
- return QVariant();
-
- switch (role) {
- case Qt::ToolTipRole:
- return m_pages.at(index.row())->source().toString();
- case Qt::DisplayRole: {
- const QString title = m_pages.at(index.row())->title();
- return title.isEmpty() ? tr("(Untitled)") : title;
- }
- default:
- break;
- }
- return QVariant();
-}
-
-void OpenPagesModel::addPage(const QUrl &url, qreal zoom)
-{
- beginInsertRows(QModelIndex(), rowCount(), rowCount());
- HelpViewer *page = HelpPlugin::createHelpViewer(zoom);
- connect(page, &HelpViewer::titleChanged,
- this, &OpenPagesModel::handleTitleChanged);
- m_pages << page;
- endInsertRows();
- if (url.isValid())
- page->setSource(url);
-}
-
-void OpenPagesModel::removePage(int index)
-{
- Q_ASSERT(index >= 0 && index < rowCount());
- beginRemoveRows(QModelIndex(), index, index);
- HelpViewer *page = m_pages.at(index);
- page->stop();
- m_pages.removeAt(index);
- endRemoveRows();
- page->deleteLater();
-}
-
-HelpViewer *OpenPagesModel::pageAt(int index) const
-{
- Q_ASSERT(index >= 0 && index < rowCount());
- return m_pages.at(index);
-}
-
-void OpenPagesModel::handleTitleChanged()
-{
- auto page = static_cast<HelpViewer *>(sender());
- const int row = m_pages.indexOf(page);
- Q_ASSERT(row != -1 );
- const QModelIndex &item = index(row, 0);
- emit dataChanged(item, item);
-}
diff --git a/src/plugins/help/openpagesmodel.h b/src/plugins/help/openpagesmodel.h
deleted file mode 100644
index 4d990ef791..0000000000
--- a/src/plugins/help/openpagesmodel.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <QList>
-#include <QAbstractTableModel>
-
-QT_FORWARD_DECLARE_CLASS(QUrl)
-
-namespace Help {
- namespace Internal {
-
-class HelpViewer;
-
-class OpenPagesModel : public QAbstractTableModel
-{
- Q_OBJECT
-
-public:
- OpenPagesModel(QObject *parent);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
-
- void addPage(const QUrl &url, qreal zoom = 0);
- void removePage(int index);
- HelpViewer *pageAt(int index) const;
-
-private:
- void handleTitleChanged();
-
- QList<HelpViewer *> m_pages;
-};
-
- } // namespace Internal
-} // namespace Help
diff --git a/src/plugins/help/openpagesswitcher.cpp b/src/plugins/help/openpagesswitcher.cpp
index 091239c14f..50ffad3b30 100644
--- a/src/plugins/help/openpagesswitcher.cpp
+++ b/src/plugins/help/openpagesswitcher.cpp
@@ -26,7 +26,6 @@
#include "openpagesswitcher.h"
#include "centralwidget.h"
-#include "openpagesmodel.h"
#include "openpageswidget.h"
#include <utils/hostosinfo.h>
@@ -41,7 +40,7 @@ using namespace Help::Internal;
const int gWidth = 300;
const int gHeight = 200;
-OpenPagesSwitcher::OpenPagesSwitcher(OpenPagesModel *model)
+OpenPagesSwitcher::OpenPagesSwitcher(QAbstractItemModel *model)
: QFrame(nullptr, Qt::Popup)
, m_openPagesModel(model)
{
@@ -59,7 +58,7 @@ OpenPagesSwitcher::OpenPagesSwitcher(OpenPagesModel *model)
m_openPagesWidget->installEventFilter(this);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_openPagesWidget);
connect(m_openPagesWidget, &OpenPagesWidget::closePage,
@@ -86,9 +85,9 @@ void OpenPagesSwitcher::selectAndHide()
emit setCurrentPage(m_openPagesWidget->currentIndex());
}
-void OpenPagesSwitcher::selectCurrentPage()
+void OpenPagesSwitcher::selectCurrentPage(int index)
{
- m_openPagesWidget->selectCurrentPage();
+ m_openPagesWidget->selectCurrentPage(index);
}
void OpenPagesSwitcher::setVisible(bool visible)
diff --git a/src/plugins/help/openpagesswitcher.h b/src/plugins/help/openpagesswitcher.h
index 1f3d7b24b1..4e87260e0f 100644
--- a/src/plugins/help/openpagesswitcher.h
+++ b/src/plugins/help/openpagesswitcher.h
@@ -27,12 +27,14 @@
#include <QFrame>
-QT_FORWARD_DECLARE_CLASS(QModelIndex)
+QT_BEGIN_NAMESPACE
+class QAbstractItemModel;
+class QModelIndex;
+QT_END_NAMESPACE
namespace Help {
namespace Internal {
-class OpenPagesModel;
class OpenPagesWidget;
class OpenPagesSwitcher : public QFrame
@@ -40,14 +42,14 @@ class OpenPagesSwitcher : public QFrame
Q_OBJECT
public:
- OpenPagesSwitcher(OpenPagesModel *model);
+ OpenPagesSwitcher(QAbstractItemModel *model);
~OpenPagesSwitcher() override;
void gotoNextPage();
void gotoPreviousPage();
void selectAndHide();
- void selectCurrentPage();
+ void selectCurrentPage(int index);
void setVisible(bool visible) override;
void focusInEvent(QFocusEvent *event) override;
@@ -61,7 +63,7 @@ private:
void selectPageUpDown(int summand);
private:
- OpenPagesModel *m_openPagesModel = nullptr;
+ QAbstractItemModel *m_openPagesModel = nullptr;
OpenPagesWidget *m_openPagesWidget = nullptr;
};
diff --git a/src/plugins/help/openpageswidget.cpp b/src/plugins/help/openpageswidget.cpp
index 55b55353f2..48e2ce223f 100644
--- a/src/plugins/help/openpageswidget.cpp
+++ b/src/plugins/help/openpageswidget.cpp
@@ -25,9 +25,6 @@
#include "openpageswidget.h"
-#include "centralwidget.h"
-#include "openpagesmodel.h"
-
#include <coreplugin/coreconstants.h>
#include <utils/stringutils.h>
@@ -39,7 +36,7 @@ using namespace Help::Internal;
// -- OpenPagesWidget
-OpenPagesWidget::OpenPagesWidget(OpenPagesModel *sourceModel, QWidget *parent)
+OpenPagesWidget::OpenPagesWidget(QAbstractItemModel *sourceModel, QWidget *parent)
: OpenDocumentsTreeView(parent)
, m_allowContextMenu(true)
{
@@ -62,12 +59,12 @@ OpenPagesWidget::OpenPagesWidget(OpenPagesModel *sourceModel, QWidget *parent)
OpenPagesWidget::~OpenPagesWidget() = default;
-void OpenPagesWidget::selectCurrentPage()
+void OpenPagesWidget::selectCurrentPage(int index)
{
QItemSelectionModel * const selModel = selectionModel();
selModel->clearSelection();
- selModel->select(model()->index(CentralWidget::instance()->currentIndex(), 0),
- QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+ selModel->select(model()->index(index, 0),
+ QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
scrollTo(currentIndex());
}
diff --git a/src/plugins/help/openpageswidget.h b/src/plugins/help/openpageswidget.h
index c06cc2bb44..5296190609 100644
--- a/src/plugins/help/openpageswidget.h
+++ b/src/plugins/help/openpageswidget.h
@@ -30,17 +30,15 @@
namespace Help {
namespace Internal {
-class OpenPagesModel;
-
class OpenPagesWidget : public Core::OpenDocumentsTreeView
{
Q_OBJECT
public:
- explicit OpenPagesWidget(OpenPagesModel *model, QWidget *parent = nullptr);
+ explicit OpenPagesWidget(QAbstractItemModel *model, QWidget *parent = nullptr);
~OpenPagesWidget() override;
- void selectCurrentPage();
+ void selectCurrentPage(int index);
void allowContextMenu(bool ok);
signals:
diff --git a/src/plugins/help/qlitehtml/CMakeLists.txt b/src/plugins/help/qlitehtml/CMakeLists.txt
new file mode 100644
index 0000000000..c9bcd3326d
--- /dev/null
+++ b/src/plugins/help/qlitehtml/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 3.9)
+
+project(QLiteHtml)
+
+if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/litehtml/CMakeLists.txt)
+ set(ORIG_FPIC ${CMAKE_POSITION_INDEPENDENT_CODE})
+ set(ORIG_CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
+ if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo")
+ else()
+ set(CMAKE_BUILD_TYPE "Release")
+ endif()
+ if (WIN32)
+ set(LITEHTML_UTF8 ON)
+ endif()
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+ add_subdirectory(litehtml)
+ set(CMAKE_BUILD_TYPE ${ORIG_CMAKE_BUILD_TYPE})
+ set(CMAKE_POSITION_INDEPENDENT_CODE "${ORIG_FPIC}")
+else()
+ find_package(litehtml REQUIRED)
+endif()
+
+find_package(Qt5 COMPONENTS Widgets REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_CXX_STANDARD 14)
+
+add_library(qlitehtml STATIC
+ container_qpainter.cpp container_qpainter.h
+ qlitehtmlwidget.cpp qlitehtmlwidget.h
+)
+
+target_include_directories(qlitehtml PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(qlitehtml PRIVATE Qt5::Widgets litehtml)
+set_target_properties(qlitehtml PROPERTIES POSITION_INDEPENDENT_CODE ON)
diff --git a/src/plugins/help/qlitehtml/README.md b/src/plugins/help/qlitehtml/README.md
new file mode 100644
index 0000000000..9a3cefcd9e
--- /dev/null
+++ b/src/plugins/help/qlitehtml/README.md
@@ -0,0 +1,24 @@
+# Qt backend for litehtml
+
+Provides
+
+* A QPainter based rendering backend for the light-weight HTML/CSS rendering engine [litehtml].
+* A QWidget that uses the QPainter based backend and provides API for simply setting the HTML text
+ and a base URL plus hook that are used for requesting referenced resources.
+
+## How to build
+
+Build and install [litehtml]. It is recommended to build [litehtml] in release mode
+
+```
+cd litehtml
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX="$PWD/../install" -DCMAKE_BUILD_TYPE=Release -G Ninja ..
+cmake --build .
+cmake --install .
+```
+
+Add the [litehtml] installation path to the `CMAKE_PREFIX_PATH` when building the Qt backend
+
+[litehtml]: https://github.com/litehtml/litehtml
diff --git a/src/plugins/help/qlitehtml/container_qpainter.cpp b/src/plugins/help/qlitehtml/container_qpainter.cpp
new file mode 100644
index 0000000000..6801513c2d
--- /dev/null
+++ b/src/plugins/help/qlitehtml/container_qpainter.cpp
@@ -0,0 +1,1272 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of QLiteHtml.
+**
+** 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 "container_qpainter.h"
+
+#include <QClipboard>
+#include <QCursor>
+#include <QDebug>
+#include <QDir>
+#include <QFont>
+#include <QFontDatabase>
+#include <QFontMetrics>
+#include <QGuiApplication>
+#include <QLoggingCategory>
+#include <QPainter>
+#include <QRegularExpression>
+#include <QScreen>
+#include <QTextLayout>
+#include <QUrl>
+
+#include <algorithm>
+#include <set>
+
+const int kDragDistance = 5;
+
+using Font = QFont;
+using Context = QPainter;
+
+namespace {
+Q_LOGGING_CATEGORY(log, "qlitehtml", QtCriticalMsg)
+}
+
+static QFont toQFont(litehtml::uint_ptr hFont)
+{
+ return *reinterpret_cast<Font *>(hFont);
+}
+
+static QPainter *toQPainter(litehtml::uint_ptr hdc)
+{
+ return reinterpret_cast<Context *>(hdc);
+}
+
+static QRect toQRect(litehtml::position position)
+{
+ return {position.x, position.y, position.width, position.height};
+}
+
+static litehtml::elements_vector path(const litehtml::element::ptr &element)
+{
+ litehtml::elements_vector result;
+ litehtml::element::ptr current = element;
+ while (current) {
+ result.push_back(current);
+ current = current->parent();
+ }
+ std::reverse(std::begin(result), std::end(result));
+ return result;
+}
+
+static std::pair<litehtml::element::ptr, size_t> getCommonParent(const litehtml::elements_vector &a,
+ const litehtml::elements_vector &b)
+{
+ litehtml::element::ptr parent;
+ const size_t minSize = std::min(a.size(), b.size());
+ for (size_t i = 0; i < minSize; ++i) {
+ if (a.at(i) != b.at(i))
+ return {parent, i};
+ parent = a.at(i);
+ }
+ return {parent, minSize};
+}
+
+static std::pair<Selection::Element, Selection::Element> getStartAndEnd(const Selection::Element &a,
+ const Selection::Element &b)
+{
+ if (a.element == b.element) {
+ if (a.index <= b.index)
+ return {a, b};
+ return {b, a};
+ }
+ const litehtml::elements_vector aPath = path(a.element);
+ const litehtml::elements_vector bPath = path(b.element);
+ litehtml::element::ptr commonParent;
+ size_t firstDifferentIndex;
+ std::tie(commonParent, firstDifferentIndex) = getCommonParent(aPath, bPath);
+ if (!commonParent) {
+ qWarning() << "internal error: litehtml elements do not have common parent";
+ return {a, b};
+ }
+ if (commonParent == a.element)
+ return {a, a}; // 'a' already contains 'b'
+ if (commonParent == b.element)
+ return {b, b};
+ // find out if a or b is first in the child sub-trees of commonParent
+ const litehtml::element::ptr aBranch = aPath.at(firstDifferentIndex);
+ const litehtml::element::ptr bBranch = bPath.at(firstDifferentIndex);
+ for (int i = 0; i < int(commonParent->get_children_count()); ++i) {
+ const litehtml::element::ptr child = commonParent->get_child(i);
+ if (child == aBranch)
+ return {a, b};
+ if (child == bBranch)
+ return {b, a};
+ }
+ qWarning() << "internal error: failed to find out order of litehtml elements";
+ return {a, b};
+}
+
+static int findChild(const litehtml::element::ptr &child, const litehtml::element::ptr &parent)
+{
+ for (int i = 0; i < int(parent->get_children_count()); ++i)
+ if (parent->get_child(i) == child)
+ return i;
+ return -1;
+}
+
+// 1) stops right away if element == stop, otherwise stops whenever stop element is encountered
+// 2) moves down the first children from element until there is none anymore
+static litehtml::element::ptr firstLeaf(const litehtml::element::ptr &element,
+ const litehtml::element::ptr &stop)
+{
+ if (element == stop)
+ return element;
+ litehtml::element::ptr current = element;
+ while (current != stop && current->get_children_count() > 0)
+ current = current->get_child(0);
+ return current;
+}
+
+// 1) stops right away if element == stop, otherwise stops whenever stop element is encountered
+// 2) starts at next sibling (up the hierarchy chain) if possible, otherwise root
+// 3) returns first leaf of the element found in 2
+static litehtml::element::ptr nextLeaf(const litehtml::element::ptr &element,
+ const litehtml::element::ptr &stop)
+{
+ if (element == stop)
+ return element;
+ litehtml::element::ptr current = element;
+ if (current->have_parent()) {
+ // find next sibling
+ const litehtml::element::ptr parent = current->parent();
+ const int childIndex = findChild(current, parent);
+ if (childIndex < 0) {
+ qWarning() << "internal error: filed to find litehtml child element in parent";
+ return stop;
+ }
+ if (childIndex + 1 >= int(parent->get_children_count())) // no sibling, move up
+ return nextLeaf(parent, stop);
+ current = parent->get_child(childIndex + 1);
+ }
+ return firstLeaf(current, stop);
+}
+
+static Selection::Element selectionDetails(const litehtml::element::ptr &element,
+ const QString &text,
+ const QPoint &pos)
+{
+ // shortcut, which _might_ not really be correct
+ if (element->get_children_count() > 0)
+ return {element, -1, -1}; // everything selected
+ const QFont &font = toQFont(element->get_font());
+ const QFontMetrics fm(font);
+ int previous = 0;
+ for (int i = 0; i < text.size(); ++i) {
+ const int width = fm.size(0, text.left(i + 1)).width();
+ if ((width + previous) / 2 >= pos.x())
+ return {element, i, previous};
+ previous = width;
+ }
+ return {element, text.size(), previous};
+}
+
+static Selection::Element deepest_child_at_point(const litehtml::document::ptr &document,
+ const QPoint &pos,
+ const QPoint &viewportPos,
+ Selection::Mode mode)
+{
+ if (!document)
+ return {};
+
+ // the following does not find the "smallest" element, it often consists of children
+ // with individual words as text...
+ const litehtml::element::ptr element = document->root()->get_element_by_point(pos.x(),
+ pos.y(),
+ viewportPos.x(),
+ viewportPos.y());
+ // ...so try to find a better match
+ const std::function<Selection::Element(litehtml::element::ptr, QRect)> recursion =
+ [&recursion, pos, mode](const litehtml::element::ptr &element,
+ const QRect &placement) -> Selection::Element {
+ if (!element)
+ return {};
+ Selection::Element result;
+ for (int i = 0; i < int(element->get_children_count()); ++i) {
+ const litehtml::element::ptr child = element->get_child(i);
+ result = recursion(child,
+ toQRect(child->get_position()).translated(placement.topLeft()));
+ if (result.element)
+ return result;
+ }
+ if (placement.contains(pos)) {
+ litehtml::tstring text;
+ element->get_text(text);
+ if (!text.empty()) {
+ return mode == Selection::Mode::Free
+ ? selectionDetails(element,
+ QString::fromStdString(text),
+ pos - placement.topLeft())
+ : Selection::Element({element, -1, -1});
+ }
+ }
+ return {};
+ };
+ return recursion(element, element ? toQRect(element->get_placement()) : QRect());
+}
+
+// CSS: 400 == normal, 700 == bold.
+// Qt: 50 == normal, 75 == bold
+static int cssWeightToQtWeight(int cssWeight)
+{
+ if (cssWeight <= 400)
+ return cssWeight * 50 / 400;
+ if (cssWeight >= 700)
+ return 75 + (cssWeight - 700) * 25 / 300;
+ return 50 + (cssWeight - 400) * 25 / 300;
+}
+
+static QFont::Style toQFontStyle(litehtml::font_style style)
+{
+ switch (style) {
+ case litehtml::fontStyleNormal:
+ return QFont::StyleNormal;
+ case litehtml::fontStyleItalic:
+ return QFont::StyleItalic;
+ }
+ // should not happen
+ qWarning(log) << "Unknown litehtml font style:" << style;
+ return QFont::StyleNormal;
+}
+
+static QColor toQColor(const litehtml::web_color &color)
+{
+ return {color.red, color.green, color.blue, color.alpha};
+}
+
+static Qt::PenStyle borderPenStyle(litehtml::border_style style)
+{
+ switch (style) {
+ case litehtml::border_style_dotted:
+ return Qt::DotLine;
+ case litehtml::border_style_dashed:
+ return Qt::DashLine;
+ case litehtml::border_style_solid:
+ return Qt::SolidLine;
+ default:
+ qWarning(log) << "Unsupported border style:" << style;
+ }
+ return Qt::SolidLine;
+}
+
+static QPen borderPen(const litehtml::border &border)
+{
+ return {toQColor(border.color), qreal(border.width), borderPenStyle(border.style)};
+}
+
+static QCursor toQCursor(const QString &c)
+{
+ if (c == "alias")
+ return {Qt::PointingHandCursor}; // ???
+ if (c == "all-scroll")
+ return {Qt::SizeAllCursor};
+ if (c == "auto")
+ return {Qt::ArrowCursor}; // ???
+ if (c == "cell")
+ return {Qt::UpArrowCursor};
+ if (c == "context-menu")
+ return {Qt::ArrowCursor}; // ???
+ if (c == "col-resize")
+ return {Qt::SplitHCursor};
+ if (c == "copy")
+ return {Qt::DragCopyCursor};
+ if (c == "crosshair")
+ return {Qt::CrossCursor};
+ if (c == "default")
+ return {Qt::ArrowCursor};
+ if (c == "e-resize")
+ return {Qt::SizeHorCursor}; // ???
+ if (c == "ew-resize")
+ return {Qt::SizeHorCursor};
+ if (c == "grab")
+ return {Qt::OpenHandCursor};
+ if (c == "grabbing")
+ return {Qt::ClosedHandCursor};
+ if (c == "help")
+ return {Qt::WhatsThisCursor};
+ if (c == "move")
+ return {Qt::SizeAllCursor};
+ if (c == "n-resize")
+ return {Qt::SizeVerCursor}; // ???
+ if (c == "ne-resize")
+ return {Qt::SizeBDiagCursor}; // ???
+ if (c == "nesw-resize")
+ return {Qt::SizeBDiagCursor};
+ if (c == "ns-resize")
+ return {Qt::SizeVerCursor};
+ if (c == "nw-resize")
+ return {Qt::SizeFDiagCursor}; // ???
+ if (c == "nwse-resize")
+ return {Qt::SizeFDiagCursor};
+ if (c == "no-drop")
+ return {Qt::ForbiddenCursor};
+ if (c == "none")
+ return {Qt::BlankCursor};
+ if (c == "not-allowed")
+ return {Qt::ForbiddenCursor};
+ if (c == "pointer")
+ return {Qt::PointingHandCursor};
+ if (c == "progress")
+ return {Qt::BusyCursor};
+ if (c == "row-resize")
+ return {Qt::SplitVCursor};
+ if (c == "s-resize")
+ return {Qt::SizeVerCursor}; // ???
+ if (c == "se-resize")
+ return {Qt::SizeFDiagCursor}; // ???
+ if (c == "sw-resize")
+ return {Qt::SizeBDiagCursor}; // ???
+ if (c == "text")
+ return {Qt::IBeamCursor};
+ if (c == "url")
+ return {Qt::ArrowCursor}; // ???
+ if (c == "w-resize")
+ return {Qt::SizeHorCursor}; // ???
+ if (c == "wait")
+ return {Qt::BusyCursor};
+ if (c == "zoom-in")
+ return {Qt::ArrowCursor}; // ???
+ qWarning(log) << QString("unknown cursor property \"%1\"").arg(c).toUtf8().constData();
+ return {Qt::ArrowCursor};
+}
+
+bool Selection::isValid() const
+{
+ return !selection.isEmpty();
+}
+
+void Selection::update()
+{
+ const auto addElement = [this](const Selection::Element &element,
+ const Selection::Element &end = {}) {
+ litehtml::tstring elemText;
+ element.element->get_text(elemText);
+ const QString textStr = QString::fromStdString(elemText);
+ if (!textStr.isEmpty()) {
+ QRect rect = toQRect(element.element->get_placement()).adjusted(-1, -1, 1, 1);
+ if (element.index < 0) { // fully selected
+ text += textStr;
+ } else if (end.element) { // select from element "to end"
+ if (element.element == end.element) {
+ // end.index is guaranteed to be >= element.index by caller, same for x
+ text += textStr.mid(element.index, end.index - element.index);
+ const int left = rect.left();
+ rect.setLeft(left + element.x);
+ rect.setRight(left + end.x);
+ } else {
+ text += textStr.mid(element.index);
+ rect.setLeft(rect.left() + element.x);
+ }
+ } else { // select from start of element
+ text += textStr.left(element.index);
+ rect.setRight(rect.left() + element.x);
+ }
+ selection.append(rect);
+ }
+ };
+
+ if (startElem.element && endElem.element) {
+ // Edge cases:
+ // start and end elements could be reversed or children of each other
+ Selection::Element start;
+ Selection::Element end;
+ std::tie(start, end) = getStartAndEnd(startElem, endElem);
+
+ selection.clear();
+ text.clear();
+
+ // Treats start element as a leaf even if it isn't, because it already contains all its
+ // children
+ addElement(start, end);
+ if (start.element != end.element) {
+ litehtml::element::ptr current = start.element;
+ do {
+ current = nextLeaf(current, end.element);
+ if (current == end.element)
+ addElement(end);
+ else
+ addElement({current, -1, -1});
+ } while (current != end.element);
+ }
+ } else {
+ selection = {};
+ text.clear();
+ }
+ QClipboard *cb = QGuiApplication::clipboard();
+ if (cb->supportsSelection())
+ cb->setText(text, QClipboard::Selection);
+}
+
+QRect Selection::boundingRect() const
+{
+ QRect rect;
+ for (const QRect &r : selection)
+ rect = rect.united(r);
+ return rect;
+}
+
+DocumentContainer::DocumentContainer() = default;
+
+DocumentContainer::~DocumentContainer() = default;
+
+litehtml::uint_ptr DocumentContainer::create_font(const litehtml::tchar_t *faceName,
+ int size,
+ int weight,
+ litehtml::font_style italic,
+ unsigned int decoration,
+ litehtml::font_metrics *fm)
+{
+ const QStringList splitNames = QString::fromUtf8(faceName).split(',', QString::SkipEmptyParts);
+ QStringList familyNames;
+ std::transform(splitNames.cbegin(),
+ splitNames.cend(),
+ std::back_inserter(familyNames),
+ [this](const QString &s) {
+ // clean whitespace and quotes
+ QString name = s.trimmed();
+ if (name.startsWith('\"'))
+ name = name.mid(1);
+ if (name.endsWith('\"'))
+ name.chop(1);
+ const QString lowerName = name.toLower();
+ if (lowerName == "serif")
+ return serifFont();
+ if (lowerName == "sans-serif")
+ return sansSerifFont();
+ if (lowerName == "monospace")
+ return monospaceFont();
+ return name;
+ });
+ auto font = new QFont();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
+ font->setFamilies(familyNames);
+#else
+ struct CompareCaseinsensitive
+ {
+ bool operator()(const QString &a, const QString &b) const
+ {
+ return a.compare(b, Qt::CaseInsensitive) < 0;
+ }
+ };
+ static const QStringList known = QFontDatabase().families();
+ static const std::set<QString, CompareCaseinsensitive> knownFamilies(known.cbegin(),
+ known.cend());
+ font->setFamily(familyNames.last());
+ for (const QString &name : qAsConst(familyNames)) {
+ const auto found = knownFamilies.find(name);
+ if (found != knownFamilies.end()) {
+ font->setFamily(*found);
+ break;
+ }
+ }
+#endif
+ font->setPixelSize(size);
+ font->setWeight(cssWeightToQtWeight(weight));
+ font->setStyle(toQFontStyle(italic));
+ if (decoration == litehtml::font_decoration_underline)
+ font->setUnderline(true);
+ if (decoration == litehtml::font_decoration_overline)
+ font->setOverline(true);
+ if (decoration == litehtml::font_decoration_linethrough)
+ font->setStrikeOut(true);
+ if (fm) {
+ const QFontMetrics metrics(*font);
+ fm->height = metrics.height();
+ fm->ascent = metrics.ascent();
+ fm->descent = metrics.descent();
+ fm->x_height = metrics.xHeight();
+ fm->draw_spaces = true;
+ }
+ return reinterpret_cast<litehtml::uint_ptr>(font);
+}
+
+void DocumentContainer::delete_font(litehtml::uint_ptr hFont)
+{
+ auto font = reinterpret_cast<Font *>(hFont);
+ delete font;
+}
+
+int DocumentContainer::text_width(const litehtml::tchar_t *text, litehtml::uint_ptr hFont)
+{
+ const QFontMetrics fm(toQFont(hFont));
+ return fm.horizontalAdvance(QString::fromUtf8(text));
+}
+
+void DocumentContainer::draw_text(litehtml::uint_ptr hdc,
+ const litehtml::tchar_t *text,
+ litehtml::uint_ptr hFont,
+ litehtml::web_color color,
+ const litehtml::position &pos)
+{
+ auto painter = toQPainter(hdc);
+ painter->setFont(toQFont(hFont));
+ painter->setPen(toQColor(color));
+ painter->drawText(toQRect(pos), 0, QString::fromUtf8(text));
+}
+
+int DocumentContainer::pt_to_px(int pt)
+{
+ // magic factor of 11/12 to account for differences to webengine/webkit
+ return m_paintDevice->physicalDpiY() * pt * 11 / m_paintDevice->logicalDpiY() / 12;
+}
+
+int DocumentContainer::get_default_font_size() const
+{
+ return m_defaultFont.pointSize();
+}
+
+const litehtml::tchar_t *DocumentContainer::get_default_font_name() const
+{
+ return m_defaultFontFamilyName.constData();
+}
+
+void DocumentContainer::draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker &marker)
+{
+ auto painter = toQPainter(hdc);
+ if (marker.image.empty()) {
+ if (marker.marker_type == litehtml::list_style_type_square) {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(toQColor(marker.color));
+ painter->drawRect(toQRect(marker.pos));
+ } else if (marker.marker_type == litehtml::list_style_type_disc) {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(toQColor(marker.color));
+ painter->drawEllipse(toQRect(marker.pos));
+ } else if (marker.marker_type == litehtml::list_style_type_circle) {
+ painter->setPen(toQColor(marker.color));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawEllipse(toQRect(marker.pos));
+ } else {
+ // TODO we do not get information about index and font for e.g. decimal / roman
+ // at least draw a bullet
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(toQColor(marker.color));
+ painter->drawEllipse(toQRect(marker.pos));
+ qWarning(log) << "list marker of type" << marker.marker_type << "not supported";
+ }
+ } else {
+ const QPixmap pixmap = getPixmap(QString::fromStdString(marker.image),
+ QString::fromStdString(marker.baseurl));
+ painter->drawPixmap(toQRect(marker.pos), pixmap);
+ }
+}
+
+void DocumentContainer::load_image(const litehtml::tchar_t *src,
+ const litehtml::tchar_t *baseurl,
+ bool redraw_on_ready)
+{
+ const auto qtSrc = QString::fromUtf8(src);
+ const auto qtBaseUrl = QString::fromUtf8(baseurl);
+ Q_UNUSED(redraw_on_ready)
+ qDebug(log) << "load_image:" << QString("src = \"%1\";").arg(qtSrc).toUtf8().constData()
+ << QString("base = \"%1\"").arg(qtBaseUrl).toUtf8().constData();
+ const QUrl url = resolveUrl(qtSrc, qtBaseUrl);
+ if (m_pixmaps.contains(url))
+ return;
+
+ QPixmap pixmap;
+ pixmap.loadFromData(m_dataCallback(url));
+ m_pixmaps.insert(url, pixmap);
+}
+
+void DocumentContainer::get_image_size(const litehtml::tchar_t *src,
+ const litehtml::tchar_t *baseurl,
+ litehtml::size &sz)
+{
+ const auto qtSrc = QString::fromUtf8(src);
+ const auto qtBaseUrl = QString::fromUtf8(baseurl);
+ if (qtSrc.isEmpty()) // for some reason that happens
+ return;
+ qDebug(log) << "get_image_size:" << QString("src = \"%1\";").arg(qtSrc).toUtf8().constData()
+ << QString("base = \"%1\"").arg(qtBaseUrl).toUtf8().constData();
+ const QPixmap pm = getPixmap(qtSrc, qtBaseUrl);
+ sz.width = pm.width();
+ sz.height = pm.height();
+}
+
+void DocumentContainer::drawSelection(QPainter *painter, const QRect &clip) const
+{
+ painter->save();
+ painter->setClipRect(clip, Qt::IntersectClip);
+ for (const QRect &r : m_selection.selection) {
+ const QRect clientRect = r.translated(-m_scrollPosition);
+ const QPalette palette = m_paletteCallback();
+ painter->fillRect(clientRect, palette.brush(QPalette::Highlight));
+ }
+ painter->restore();
+}
+
+void DocumentContainer::buildIndex()
+{
+ m_index.elementToIndex.clear();
+ m_index.indexToElement.clear();
+ m_index.text.clear();
+
+ int index = 0;
+ litehtml::element::ptr current = firstLeaf(m_document->root(), nullptr);
+ while (current != m_document->root()) {
+ m_index.elementToIndex.insert({current, index});
+ if (current->is_visible()) {
+ litehtml::tstring text;
+ current->get_text(text);
+ if (!text.empty()) {
+ m_index.indexToElement.push_back({index, current});
+ m_index.text += QString::fromStdString(text);
+ index += text.size();
+ }
+ }
+ current = nextLeaf(current, m_document->root());
+ }
+}
+
+void DocumentContainer::draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint &bg)
+{
+ // TODO
+ auto painter = toQPainter(hdc);
+ if (bg.is_root) {
+ // TODO ?
+ drawSelection(painter, toQRect(bg.border_box));
+ return;
+ }
+ painter->save();
+ painter->setClipRect(toQRect(bg.clip_box));
+ const QRegion horizontalMiddle(
+ QRect(bg.border_box.x,
+ bg.border_box.y + bg.border_radius.top_left_y,
+ bg.border_box.width,
+ bg.border_box.height - bg.border_radius.top_left_y - bg.border_radius.bottom_left_y));
+ const QRegion horizontalTop(
+ QRect(bg.border_box.x + bg.border_radius.top_left_x,
+ bg.border_box.y,
+ bg.border_box.width - bg.border_radius.top_left_x - bg.border_radius.top_right_x,
+ bg.border_radius.top_left_y));
+ const QRegion horizontalBottom(QRect(bg.border_box.x + bg.border_radius.bottom_left_x,
+ bg.border_box.bottom() - bg.border_radius.bottom_left_y,
+ bg.border_box.width - bg.border_radius.bottom_left_x
+ - bg.border_radius.bottom_right_x,
+ bg.border_radius.bottom_left_y));
+ const QRegion topLeft(QRect(bg.border_box.left(),
+ bg.border_box.top(),
+ 2 * bg.border_radius.top_left_x,
+ 2 * bg.border_radius.top_left_y),
+ QRegion::Ellipse);
+ const QRegion topRight(QRect(bg.border_box.right() - 2 * bg.border_radius.top_right_x,
+ bg.border_box.top(),
+ 2 * bg.border_radius.top_right_x,
+ 2 * bg.border_radius.top_right_y),
+ QRegion::Ellipse);
+ const QRegion bottomLeft(QRect(bg.border_box.left(),
+ bg.border_box.bottom() - 2 * bg.border_radius.bottom_left_y,
+ 2 * bg.border_radius.bottom_left_x,
+ 2 * bg.border_radius.bottom_left_y),
+ QRegion::Ellipse);
+ const QRegion bottomRight(QRect(bg.border_box.right() - 2 * bg.border_radius.bottom_right_x,
+ bg.border_box.bottom() - 2 * bg.border_radius.bottom_right_y,
+ 2 * bg.border_radius.bottom_right_x,
+ 2 * bg.border_radius.bottom_right_y),
+ QRegion::Ellipse);
+ const QRegion clipRegion = horizontalMiddle.united(horizontalTop)
+ .united(horizontalBottom)
+ .united(topLeft)
+ .united(topRight)
+ .united(bottomLeft)
+ .united(bottomRight);
+ painter->setClipRegion(clipRegion, Qt::IntersectClip);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(toQColor(bg.color));
+ painter->drawRect(bg.border_box.x, bg.border_box.y, bg.border_box.width, bg.border_box.height);
+ drawSelection(painter, toQRect(bg.border_box));
+ if (!bg.image.empty()) {
+ const QPixmap pixmap = getPixmap(QString::fromStdString(bg.image),
+ QString::fromStdString(bg.baseurl));
+ if (bg.repeat == litehtml::background_repeat_no_repeat) {
+ painter->drawPixmap(QRect(bg.position_x,
+ bg.position_y,
+ bg.image_size.width,
+ bg.image_size.height),
+ pixmap);
+ } else if (bg.repeat == litehtml::background_repeat_repeat_x) {
+ if (bg.image_size.width > 0) {
+ int x = bg.border_box.left();
+ while (x <= bg.border_box.right()) {
+ painter->drawPixmap(QRect(x,
+ bg.border_box.top(),
+ bg.image_size.width,
+ bg.image_size.height),
+ pixmap);
+ x += bg.image_size.width;
+ }
+ }
+ } else {
+ qWarning(log) << "unsupported background repeat" << bg.repeat;
+ }
+ }
+ painter->restore();
+}
+
+void DocumentContainer::draw_borders(litehtml::uint_ptr hdc,
+ const litehtml::borders &borders,
+ const litehtml::position &draw_pos,
+ bool root)
+{
+ Q_UNUSED(root)
+ // TODO: special border styles
+ auto painter = toQPainter(hdc);
+ if (borders.top.style != litehtml::border_style_none
+ && borders.top.style != litehtml::border_style_hidden) {
+ painter->setPen(borderPen(borders.top));
+ painter->drawLine(draw_pos.left() + borders.radius.top_left_x,
+ draw_pos.top(),
+ draw_pos.right() - borders.radius.top_right_x,
+ draw_pos.top());
+ painter->drawArc(draw_pos.left(),
+ draw_pos.top(),
+ 2 * borders.radius.top_left_x,
+ 2 * borders.radius.top_left_y,
+ 90 * 16,
+ 90 * 16);
+ painter->drawArc(draw_pos.right() - 2 * borders.radius.top_right_x,
+ draw_pos.top(),
+ 2 * borders.radius.top_right_x,
+ 2 * borders.radius.top_right_y,
+ 0,
+ 90 * 16);
+ }
+ if (borders.bottom.style != litehtml::border_style_none
+ && borders.bottom.style != litehtml::border_style_hidden) {
+ painter->setPen(borderPen(borders.bottom));
+ painter->drawLine(draw_pos.left() + borders.radius.bottom_left_x,
+ draw_pos.bottom(),
+ draw_pos.right() - borders.radius.bottom_right_x,
+ draw_pos.bottom());
+ painter->drawArc(draw_pos.left(),
+ draw_pos.bottom() - 2 * borders.radius.bottom_left_y,
+ 2 * borders.radius.bottom_left_x,
+ 2 * borders.radius.bottom_left_y,
+ 180 * 16,
+ 90 * 16);
+ painter->drawArc(draw_pos.right() - 2 * borders.radius.bottom_right_x,
+ draw_pos.bottom() - 2 * borders.radius.bottom_right_y,
+ 2 * borders.radius.bottom_right_x,
+ 2 * borders.radius.bottom_right_y,
+ 270 * 16,
+ 90 * 16);
+ }
+ if (borders.left.style != litehtml::border_style_none
+ && borders.left.style != litehtml::border_style_hidden) {
+ painter->setPen(borderPen(borders.left));
+ painter->drawLine(draw_pos.left(),
+ draw_pos.top() + borders.radius.top_left_y,
+ draw_pos.left(),
+ draw_pos.bottom() - borders.radius.bottom_left_y);
+ }
+ if (borders.right.style != litehtml::border_style_none
+ && borders.right.style != litehtml::border_style_hidden) {
+ painter->setPen(borderPen(borders.right));
+ painter->drawLine(draw_pos.right(),
+ draw_pos.top() + borders.radius.top_right_y,
+ draw_pos.right(),
+ draw_pos.bottom() - borders.radius.bottom_right_y);
+ }
+}
+
+void DocumentContainer::set_caption(const litehtml::tchar_t *caption)
+{
+ m_caption = QString::fromUtf8(caption);
+}
+
+void DocumentContainer::set_base_url(const litehtml::tchar_t *base_url)
+{
+ m_baseUrl = QString::fromUtf8(base_url);
+}
+
+void DocumentContainer::link(const std::shared_ptr<litehtml::document> &doc,
+ const litehtml::element::ptr &el)
+{
+ // TODO
+ qDebug(log) << "link";
+ Q_UNUSED(doc)
+ Q_UNUSED(el)
+}
+
+void DocumentContainer::on_anchor_click(const litehtml::tchar_t *url,
+ const litehtml::element::ptr &el)
+{
+ Q_UNUSED(el)
+ if (!m_blockLinks)
+ m_linkCallback(resolveUrl(QString::fromUtf8(url), m_baseUrl));
+}
+
+void DocumentContainer::set_cursor(const litehtml::tchar_t *cursor)
+{
+ m_cursorCallback(toQCursor(QString::fromUtf8(cursor)));
+}
+
+void DocumentContainer::transform_text(litehtml::tstring &text, litehtml::text_transform tt)
+{
+ // TODO
+ qDebug(log) << "transform_text";
+ Q_UNUSED(text)
+ Q_UNUSED(tt)
+}
+
+void DocumentContainer::import_css(litehtml::tstring &text,
+ const litehtml::tstring &url,
+ litehtml::tstring &baseurl)
+{
+ const QUrl actualUrl = resolveUrl(QString::fromStdString(url), QString::fromStdString(baseurl));
+ const QString urlString = actualUrl.toString(QUrl::None);
+ const int lastSlash = urlString.lastIndexOf('/');
+ baseurl = urlString.left(lastSlash).toStdString();
+ text = QString::fromUtf8(m_dataCallback(actualUrl)).toStdString();
+}
+
+void DocumentContainer::set_clip(const litehtml::position &pos,
+ const litehtml::border_radiuses &bdr_radius,
+ bool valid_x,
+ bool valid_y)
+{
+ // TODO
+ qDebug(log) << "set_clip";
+ Q_UNUSED(pos)
+ Q_UNUSED(bdr_radius)
+ Q_UNUSED(valid_x)
+ Q_UNUSED(valid_y)
+}
+
+void DocumentContainer::del_clip()
+{
+ // TODO
+ qDebug(log) << "del_clip";
+}
+
+void DocumentContainer::get_client_rect(litehtml::position &client) const
+{
+ client = {m_clientRect.x(), m_clientRect.y(), m_clientRect.width(), m_clientRect.height()};
+}
+
+std::shared_ptr<litehtml::element> DocumentContainer::create_element(
+ const litehtml::tchar_t *tag_name,
+ const litehtml::string_map &attributes,
+ const std::shared_ptr<litehtml::document> &doc)
+{
+ // TODO
+ qDebug(log) << "create_element" << QString::fromUtf8(tag_name);
+ Q_UNUSED(attributes)
+ Q_UNUSED(doc)
+ return {};
+}
+
+void DocumentContainer::get_media_features(litehtml::media_features &media) const
+{
+ media.type = litehtml::media_type_screen;
+ // TODO
+ qDebug(log) << "get_media_features";
+}
+
+void DocumentContainer::get_language(litehtml::tstring &language, litehtml::tstring &culture) const
+{
+ // TODO
+ qDebug(log) << "get_language";
+ Q_UNUSED(language)
+ Q_UNUSED(culture)
+}
+
+void DocumentContainer::setPaintDevice(QPaintDevice *paintDevice)
+{
+ m_paintDevice = paintDevice;
+}
+
+void DocumentContainer::setScrollPosition(const QPoint &pos)
+{
+ m_scrollPosition = pos;
+}
+
+void DocumentContainer::setDocument(const QByteArray &data, litehtml::context *context)
+{
+ m_pixmaps.clear();
+ m_selection = {};
+ m_document = litehtml::document::createFromUTF8(data.constData(), this, context);
+ buildIndex();
+}
+
+litehtml::document::ptr DocumentContainer::document() const
+{
+ return m_document;
+}
+
+void DocumentContainer::render(int width, int height)
+{
+ m_clientRect = {0, 0, width, height};
+ if (!m_document)
+ return;
+ m_document->render(width);
+ m_selection.update();
+}
+
+QVector<QRect> DocumentContainer::mousePressEvent(const QPoint &documentPos,
+ const QPoint &viewportPos,
+ Qt::MouseButton button)
+{
+ if (!m_document || button != Qt::LeftButton)
+ return {};
+ QVector<QRect> redrawRects;
+ // selection
+ if (m_selection.isValid())
+ redrawRects.append(m_selection.boundingRect());
+ m_selection = {};
+ m_selection.selectionStartDocumentPos = documentPos;
+ m_selection.startElem = deepest_child_at_point(m_document,
+ documentPos,
+ viewportPos,
+ m_selection.mode);
+ // post to litehtml
+ litehtml::position::vector redrawBoxes;
+ if (m_document->on_lbutton_down(documentPos.x(),
+ documentPos.y(),
+ viewportPos.x(),
+ viewportPos.y(),
+ redrawBoxes)) {
+ for (const litehtml::position &box : redrawBoxes)
+ redrawRects.append(toQRect(box));
+ }
+ return redrawRects;
+}
+
+QVector<QRect> DocumentContainer::mouseMoveEvent(const QPoint &documentPos,
+ const QPoint &viewportPos)
+{
+ if (!m_document)
+ return {};
+ QVector<QRect> redrawRects;
+ // selection
+ if (m_selection.isSelecting
+ || (!m_selection.selectionStartDocumentPos.isNull()
+ && (m_selection.selectionStartDocumentPos - documentPos).manhattanLength()
+ >= kDragDistance
+ && m_selection.startElem.element)) {
+ const Selection::Element element = deepest_child_at_point(m_document,
+ documentPos,
+ viewportPos,
+ m_selection.mode);
+ if (element.element) {
+ m_selection.endElem = element;
+ redrawRects.append(m_selection.boundingRect()); // redraw old selection area
+ m_selection.update();
+ redrawRects.append(m_selection.boundingRect());
+ }
+ m_selection.isSelecting = true;
+ }
+ litehtml::position::vector redrawBoxes;
+ if (m_document->on_mouse_over(documentPos.x(),
+ documentPos.y(),
+ viewportPos.x(),
+ viewportPos.y(),
+ redrawBoxes)) {
+ for (const litehtml::position &box : redrawBoxes)
+ redrawRects.append(toQRect(box));
+ }
+ return redrawRects;
+}
+
+QVector<QRect> DocumentContainer::mouseReleaseEvent(const QPoint &documentPos,
+ const QPoint &viewportPos,
+ Qt::MouseButton button)
+{
+ if (!m_document || button != Qt::LeftButton)
+ return {};
+ QVector<QRect> redrawRects;
+ // selection
+ m_selection.isSelecting = false;
+ m_selection.selectionStartDocumentPos = {};
+ if (m_selection.isValid())
+ m_blockLinks = true;
+ else
+ m_selection = {};
+ litehtml::position::vector redrawBoxes;
+ if (m_document->on_lbutton_up(documentPos.x(),
+ documentPos.y(),
+ viewportPos.x(),
+ viewportPos.y(),
+ redrawBoxes)) {
+ for (const litehtml::position &box : redrawBoxes)
+ redrawRects.append(toQRect(box));
+ }
+ m_blockLinks = false;
+ return redrawRects;
+}
+
+QVector<QRect> DocumentContainer::mouseDoubleClickEvent(const QPoint &documentPos,
+ const QPoint &viewportPos,
+ Qt::MouseButton button)
+{
+ if (!m_document || button != Qt::LeftButton)
+ return {};
+ QVector<QRect> redrawRects;
+ m_selection = {};
+ m_selection.mode = Selection::Mode::Word;
+ const Selection::Element element = deepest_child_at_point(m_document,
+ documentPos,
+ viewportPos,
+ m_selection.mode);
+ if (element.element) {
+ m_selection.startElem = element;
+ m_selection.endElem = m_selection.startElem;
+ m_selection.isSelecting = true;
+ m_selection.update();
+ if (m_selection.isValid())
+ redrawRects.append(m_selection.boundingRect());
+ } else {
+ if (m_selection.isValid())
+ redrawRects.append(m_selection.boundingRect());
+ m_selection = {};
+ }
+ return redrawRects;
+}
+
+QVector<QRect> DocumentContainer::leaveEvent()
+{
+ if (!m_document)
+ return {};
+ litehtml::position::vector redrawBoxes;
+ if (m_document->on_mouse_leave(redrawBoxes)) {
+ QVector<QRect> redrawRects;
+ for (const litehtml::position &box : redrawBoxes)
+ redrawRects.append(toQRect(box));
+ return redrawRects;
+ }
+ return {};
+}
+
+QUrl DocumentContainer::linkAt(const QPoint &documentPos, const QPoint &viewportPos)
+{
+ if (!m_document)
+ return {};
+ const litehtml::element::ptr element = m_document->root()->get_element_by_point(documentPos.x(),
+ documentPos.y(),
+ viewportPos.x(),
+ viewportPos.y());
+ const char *href = element->get_attr("href");
+ if (href)
+ return resolveUrl(QString::fromUtf8(href), m_baseUrl);
+ return {};
+}
+
+QString DocumentContainer::caption() const
+{
+ return m_caption;
+}
+
+QString DocumentContainer::selectedText() const
+{
+ return m_selection.text;
+}
+
+void DocumentContainer::findText(const QString &text,
+ QTextDocument::FindFlags flags,
+ bool incremental,
+ bool *wrapped,
+ bool *success,
+ QVector<QRect> *oldSelection,
+ QVector<QRect> *newSelection)
+{
+ if (success)
+ *success = false;
+ if (oldSelection)
+ oldSelection->clear();
+ if (newSelection)
+ newSelection->clear();
+ if (!m_document)
+ return;
+ const bool backward = flags & QTextDocument::FindBackward;
+ int startIndex = backward ? -1 : 0;
+ if (m_selection.startElem.element && m_selection.endElem.element) { // selection
+ // poor-man's incremental search starts at beginning of selection,
+ // non-incremental at end (forward search) or beginning (backward search)
+ Selection::Element start;
+ Selection::Element end;
+ std::tie(start, end) = getStartAndEnd(m_selection.startElem, m_selection.endElem);
+ Selection::Element searchStart;
+ if (incremental || backward) {
+ if (start.index < 0) // fully selected
+ searchStart = {firstLeaf(start.element, nullptr), 0, -1};
+ else
+ searchStart = start;
+ } else {
+ if (end.index < 0) // fully selected
+ searchStart = {nextLeaf(end.element, nullptr), 0, -1};
+ else
+ searchStart = end;
+ }
+ const auto findInIndex = m_index.elementToIndex.find(searchStart.element);
+ if (findInIndex == std::end(m_index.elementToIndex)) {
+ qWarning() << "internal error: cannot find litehmtl element in index";
+ return;
+ }
+ startIndex = findInIndex->second + searchStart.index;
+ if (backward)
+ --startIndex;
+ }
+
+ const auto fillXPos = [](const Selection::Element &e) {
+ litehtml::tstring ttext;
+ e.element->get_text(ttext);
+ const QString text = QString::fromStdString(ttext);
+ const QFont &font = toQFont(e.element->get_font());
+ const QFontMetrics fm(font);
+ return Selection::Element{e.element, e.index, fm.size(0, text.left(e.index)).width()};
+ };
+
+ QString term = text;
+ if (flags & QTextDocument::FindWholeWords)
+ term = QString("\\b%1\\b").arg(term);
+ const QRegularExpression::PatternOptions patternOptions
+ = (flags & QTextDocument::FindCaseSensitively) ? QRegularExpression::NoPatternOption
+ : QRegularExpression::CaseInsensitiveOption;
+ const QRegularExpression expression(term, patternOptions);
+
+ int foundIndex = backward ? m_index.text.lastIndexOf(expression, startIndex)
+ : m_index.text.indexOf(expression, startIndex);
+ if (foundIndex < 0) { // wrap
+ foundIndex = backward ? m_index.text.lastIndexOf(expression)
+ : m_index.text.indexOf(expression);
+ if (wrapped && foundIndex >= 0)
+ *wrapped = true;
+ }
+ if (foundIndex >= 0) {
+ const Index::Entry startEntry = m_index.findElement(foundIndex);
+ const Index::Entry endEntry = m_index.findElement(foundIndex + text.size());
+ if (!startEntry.second || !endEntry.second) {
+ qWarning() << "internal error: search ended up with nullptr elements";
+ return;
+ }
+ if (oldSelection)
+ *oldSelection = m_selection.selection;
+ m_selection = {};
+ m_selection.startElem = fillXPos({startEntry.second, foundIndex - startEntry.first, -1});
+ m_selection.endElem = fillXPos(
+ {endEntry.second, foundIndex + text.size() - endEntry.first, -1});
+ m_selection.update();
+ if (newSelection)
+ *newSelection = m_selection.selection;
+ if (success)
+ *success = true;
+ return;
+ }
+ return;
+}
+
+void DocumentContainer::setDefaultFont(const QFont &font)
+{
+ m_defaultFont = font;
+ m_defaultFontFamilyName = m_defaultFont.family().toUtf8();
+}
+
+QFont DocumentContainer::defaultFont() const
+{
+ return m_defaultFont;
+}
+
+void DocumentContainer::setDataCallback(const DocumentContainer::DataCallback &callback)
+{
+ m_dataCallback = callback;
+}
+
+void DocumentContainer::setCursorCallback(const DocumentContainer::CursorCallback &callback)
+{
+ m_cursorCallback = callback;
+}
+
+void DocumentContainer::setLinkCallback(const DocumentContainer::LinkCallback &callback)
+{
+ m_linkCallback = callback;
+}
+
+void DocumentContainer::setPaletteCallback(const DocumentContainer::PaletteCallback &callback)
+{
+ m_paletteCallback = callback;
+}
+
+QPixmap DocumentContainer::getPixmap(const QString &imageUrl, const QString &baseUrl)
+{
+ const QString actualBaseurl = baseUrl.isEmpty() ? m_baseUrl : baseUrl;
+ const QUrl url = resolveUrl(imageUrl, baseUrl);
+ if (!m_pixmaps.contains(url)) {
+ qWarning(log) << "draw_background: pixmap not loaded for" << url;
+ return {};
+ }
+ return m_pixmaps.value(url);
+}
+
+QString DocumentContainer::serifFont() const
+{
+ // TODO make configurable
+ return {"Times New Roman"};
+}
+
+QString DocumentContainer::sansSerifFont() const
+{
+ // TODO make configurable
+ return {"Arial"};
+}
+
+QString DocumentContainer::monospaceFont() const
+{
+ // TODO make configurable
+ return {"Courier"};
+}
+
+QUrl DocumentContainer::resolveUrl(const QString &url, const QString &baseUrl) const
+{
+ const QUrl qurl(url);
+ if (qurl.isRelative() && !qurl.path(QUrl::FullyEncoded).isEmpty()) {
+ const QString actualBaseurl = baseUrl.isEmpty() ? m_baseUrl : baseUrl;
+ QUrl resolvedUrl(actualBaseurl + '/' + url);
+ resolvedUrl.setPath(QDir::cleanPath(resolvedUrl.path(QUrl::FullyEncoded)));
+ return resolvedUrl;
+ }
+ return qurl;
+}
+
+Index::Entry Index::findElement(int index) const
+{
+ const auto upper = std::upper_bound(std::begin(indexToElement),
+ std::end(indexToElement),
+ Entry{index, {}},
+ [](const Entry &a, const Entry &b) {
+ return a.first < b.first;
+ });
+ if (upper == std::begin(indexToElement)) // should not happen for index >= 0
+ return {-1, {}};
+ return *(upper - 1);
+}
diff --git a/src/plugins/help/qlitehtml/container_qpainter.h b/src/plugins/help/qlitehtml/container_qpainter.h
new file mode 100644
index 0000000000..ab70d0561e
--- /dev/null
+++ b/src/plugins/help/qlitehtml/container_qpainter.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of QLiteHtml.
+**
+** 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 <litehtml.h>
+
+#include <QFont>
+#include <QHash>
+#include <QPaintDevice>
+#include <QPalette>
+#include <QPixmap>
+#include <QRect>
+#include <QString>
+#include <QTextDocument>
+#include <QUrl>
+
+#include <functional>
+#include <unordered_map>
+
+class Selection
+{
+public:
+ struct Element
+ {
+ litehtml::element::ptr element;
+ int index = -1;
+ int x = -1;
+ };
+
+ enum class Mode { Free, Word };
+
+ bool isValid() const;
+
+ void update();
+ QRect boundingRect() const;
+
+ Element startElem;
+ Element endElem;
+ QVector<QRect> selection;
+ QString text;
+
+ QPoint selectionStartDocumentPos;
+ Mode mode = Mode::Free;
+ bool isSelecting = false;
+};
+
+struct Index
+{
+ QString text;
+ // only contains leaf elements
+ std::unordered_map<litehtml::element::ptr, int> elementToIndex;
+
+ using Entry = std::pair<int, litehtml::element::ptr>;
+ std::vector<Entry> indexToElement;
+
+ Entry findElement(int index) const;
+};
+
+class DocumentContainer : public litehtml::document_container
+{
+public:
+ DocumentContainer();
+ virtual ~DocumentContainer();
+
+public: // document_container API
+ litehtml::uint_ptr create_font(const litehtml::tchar_t *faceName,
+ int size,
+ int weight,
+ litehtml::font_style italic,
+ unsigned int decoration,
+ litehtml::font_metrics *fm) override;
+ void delete_font(litehtml::uint_ptr hFont) override;
+ int text_width(const litehtml::tchar_t *text, litehtml::uint_ptr hFont) override;
+ void draw_text(litehtml::uint_ptr hdc,
+ const litehtml::tchar_t *text,
+ litehtml::uint_ptr hFont,
+ litehtml::web_color color,
+ const litehtml::position &pos) override;
+ int pt_to_px(int pt) override;
+ int get_default_font_size() const override;
+ const litehtml::tchar_t *get_default_font_name() const override;
+ void draw_list_marker(litehtml::uint_ptr hdc, const litehtml::list_marker &marker) override;
+ void load_image(const litehtml::tchar_t *src,
+ const litehtml::tchar_t *baseurl,
+ bool redraw_on_ready) override;
+ void get_image_size(const litehtml::tchar_t *src,
+ const litehtml::tchar_t *baseurl,
+ litehtml::size &sz) override;
+ void draw_background(litehtml::uint_ptr hdc, const litehtml::background_paint &bg) override;
+ void draw_borders(litehtml::uint_ptr hdc,
+ const litehtml::borders &borders,
+ const litehtml::position &draw_pos,
+ bool root) override;
+ void set_caption(const litehtml::tchar_t *caption) override;
+ void set_base_url(const litehtml::tchar_t *base_url) override;
+ void link(const std::shared_ptr<litehtml::document> &doc,
+ const litehtml::element::ptr &el) override;
+ void on_anchor_click(const litehtml::tchar_t *url, const litehtml::element::ptr &el) override;
+ void set_cursor(const litehtml::tchar_t *cursor) override;
+ void transform_text(litehtml::tstring &text, litehtml::text_transform tt) override;
+ void import_css(litehtml::tstring &text,
+ const litehtml::tstring &url,
+ litehtml::tstring &baseurl) override;
+ void set_clip(const litehtml::position &pos,
+ const litehtml::border_radiuses &bdr_radius,
+ bool valid_x,
+ bool valid_y) override;
+ void del_clip() override;
+ void get_client_rect(litehtml::position &client) const override;
+ std::shared_ptr<litehtml::element> create_element(
+ const litehtml::tchar_t *tag_name,
+ const litehtml::string_map &attributes,
+ const std::shared_ptr<litehtml::document> &doc) override;
+ void get_media_features(litehtml::media_features &media) const override;
+ void get_language(litehtml::tstring &language, litehtml::tstring &culture) const override;
+
+public: // outside API
+ void setPaintDevice(QPaintDevice *paintDevice);
+ void setDocument(const QByteArray &data, litehtml::context *context);
+ litehtml::document::ptr document() const;
+ void setScrollPosition(const QPoint &pos);
+ void render(int width, int height);
+
+ // these return areas to redraw in document space
+ QVector<QRect> mousePressEvent(const QPoint &documentPos,
+ const QPoint &viewportPos,
+ Qt::MouseButton button);
+ QVector<QRect> mouseMoveEvent(const QPoint &documentPos, const QPoint &viewportPos);
+ QVector<QRect> mouseReleaseEvent(const QPoint &documentPos,
+ const QPoint &viewportPos,
+ Qt::MouseButton button);
+ QVector<QRect> mouseDoubleClickEvent(const QPoint &documentPos,
+ const QPoint &viewportPos,
+ Qt::MouseButton button);
+ QVector<QRect> leaveEvent();
+
+ QUrl linkAt(const QPoint &documentPos, const QPoint &viewportPos);
+
+ QString caption() const;
+ QString selectedText() const;
+
+ void findText(const QString &text,
+ QTextDocument::FindFlags flags,
+ bool incremental,
+ bool *wrapped,
+ bool *success,
+ QVector<QRect> *oldSelection,
+ QVector<QRect> *newSelection);
+
+ void setDefaultFont(const QFont &font);
+ QFont defaultFont() const;
+
+ using DataCallback = std::function<QByteArray(QUrl)>;
+ void setDataCallback(const DataCallback &callback);
+
+ using CursorCallback = std::function<void(QCursor)>;
+ void setCursorCallback(const CursorCallback &callback);
+
+ using LinkCallback = std::function<void(QUrl)>;
+ void setLinkCallback(const LinkCallback &callback);
+
+ using PaletteCallback = std::function<QPalette()>;
+ void setPaletteCallback(const PaletteCallback &callback);
+
+private:
+ QPixmap getPixmap(const QString &imageUrl, const QString &baseUrl);
+ QString serifFont() const;
+ QString sansSerifFont() const;
+ QString monospaceFont() const;
+ QUrl resolveUrl(const QString &url, const QString &baseUrl) const;
+ void drawSelection(QPainter *painter, const QRect &clip) const;
+ void buildIndex();
+
+ QPaintDevice *m_paintDevice = nullptr;
+ litehtml::document::ptr m_document;
+ Index m_index;
+ QString m_baseUrl;
+ QRect m_clientRect;
+ QPoint m_scrollPosition;
+ QString m_caption;
+ QFont m_defaultFont = QFont(sansSerifFont(), 16);
+ QByteArray m_defaultFontFamilyName = m_defaultFont.family().toUtf8();
+ QHash<QUrl, QPixmap> m_pixmaps;
+ Selection m_selection;
+ DataCallback m_dataCallback;
+ CursorCallback m_cursorCallback;
+ LinkCallback m_linkCallback;
+ PaletteCallback m_paletteCallback;
+ bool m_blockLinks = false;
+};
diff --git a/src/plugins/help/qlitehtml/litehtml b/src/plugins/help/qlitehtml/litehtml
new file mode 160000
+Subproject 2979ffbf45a22e39d16f0ef125532509824b135
diff --git a/src/plugins/help/qlitehtml/qlitehtml.pri b/src/plugins/help/qlitehtml/qlitehtml.pri
new file mode 100644
index 0000000000..54a0e78db0
--- /dev/null
+++ b/src/plugins/help/qlitehtml/qlitehtml.pri
@@ -0,0 +1,56 @@
+exists($$PWD/litehtml/CMakeLists.txt) {
+ !build_pass|win32 {
+ LITEHTML_BUILD_PATH = "$${OUT_PWD}/litehtml/build"
+ LITEHTML_SOURCE_PATH = "$${PWD}/litehtml"
+ LITEHTML_INSTALL_PATH = "$${OUT_PWD}/litehtml/install"
+
+ BUILD_TYPE = RelWithDebInfo
+ CONFIG(release, debug|release): BUILD_TYPE = Release
+
+ # Create build directory
+ system("$$sprintf($$QMAKE_MKDIR_CMD, $$shell_path($${LITEHTML_BUILD_PATH}))")
+
+ macos: CMAKE_DEPLOYMENT_TARGET = -DCMAKE_OSX_DEPLOYMENT_TARGET=$${QMAKE_MACOSX_DEPLOYMENT_TARGET}
+ win32: WINDOWS_OPTIONS = -DLITEHTML_UTF8=ON -G $$system_quote('NMake Makefiles')
+ LITEHTML_CMAKE_CMD = \
+ "$$QMAKE_CD $$system_quote($$shell_path($${LITEHTML_BUILD_PATH})) && \
+ cmake -DCMAKE_BUILD_TYPE=$$BUILD_TYPE \
+ -DCMAKE_INSTALL_PREFIX=$$system_quote($$shell_path($${LITEHTML_INSTALL_PATH})) \
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
+ $$WINDOWS_OPTIONS \
+ $$CMAKE_DEPLOYMENT_TARGET \
+ $$system_quote($$shell_path($${LITEHTML_SOURCE_PATH}))"
+ message("$${LITEHTML_CMAKE_CMD}")
+ system("$${LITEHTML_CMAKE_CMD}")
+
+ buildlitehtml.commands = "cmake --build $$system_quote($$shell_path($${LITEHTML_BUILD_PATH})) --target install"
+ win32: buildlitehtml.target = $$LITEHTML_INSTALL_PATH/lib/litehtml.lib
+ else:unix: buildlitehtml.target = $$LITEHTML_INSTALL_PATH/lib/liblitehtml.a
+ dummygumbo.depends = buildlitehtml
+ win32: dummygumbo.target = $$LITEHTML_INSTALL_PATH/lib/gumbo.lib
+ else:unix: dummygumbo.target = $$LITEHTML_INSTALL_PATH/lib/libgumbo.a
+ QMAKE_EXTRA_TARGETS += buildlitehtml dummygumbo
+ PRE_TARGETDEPS += $$buildlitehtml.target $$dummygumo.target
+ }
+ LITEHTML_INCLUDE_DIRS = $$LITEHTML_SOURCE_PATH/include $$LITEHTML_SOURCE_PATH/src
+ LITEHTML_LIB_DIR = $$LITEHTML_INSTALL_PATH/lib
+} else {
+ LITEHTML_INCLUDE_DIRS = $$LITEHTML_INSTALL_DIR/include $$LITEHTML_INSTALL_DIR/include/litehtml
+ LITEHTML_LIB_DIR = $$LITEHTML_INSTALL_DIR/lib
+}
+
+HEADERS += \
+ $$PWD/container_qpainter.h \
+ $$PWD/qlitehtmlwidget.h
+
+SOURCES += \
+ $$PWD/container_qpainter.cpp \
+ $$PWD/qlitehtmlwidget.cpp
+
+INCLUDEPATH += $$PWD $$LITEHTML_INCLUDE_DIRS
+LIBS += -L$$LITEHTML_LIB_DIR -llitehtml -lgumbo
+
+DEFINES += LITEHTML_UTF8
+
+win32: PRE_TARGETDEPS += $$LITEHTML_LIB_DIR/litehtml.lib $$LITEHTML_LIB_DIR/gumbo.lib
+else:unix: PRE_TARGETDEPS += $$LITEHTML_LIB_DIR/liblitehtml.a $$LITEHTML_LIB_DIR/libgumbo.a
diff --git a/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp b/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp
new file mode 100644
index 0000000000..1196e698ad
--- /dev/null
+++ b/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp
@@ -0,0 +1,687 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of QLiteHtml.
+**
+** 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 "qlitehtmlwidget.h"
+
+#include "container_qpainter.h"
+
+#include <QDebug>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QScrollBar>
+#include <QStyle>
+#include <QTimer>
+
+#include <litehtml.h>
+
+const int kScrollBarStep = 40;
+
+// TODO copied from litehtml/include/master.css
+const char mastercss[] = R"RAW(
+html {
+ display: block;
+height:100%;
+width:100%;
+position: relative;
+}
+
+head {
+ display: none
+}
+
+meta {
+ display: none
+}
+
+title {
+ display: none
+}
+
+link {
+ display: none
+}
+
+style {
+ display: none
+}
+
+script {
+ display: none
+}
+
+body {
+display:block;
+ margin:8px;
+ height:100%;
+width:100%;
+}
+
+p {
+display:block;
+ margin-top:1em;
+ margin-bottom:1em;
+}
+
+b, strong {
+display:inline;
+ font-weight:bold;
+}
+
+i, em {
+display:inline;
+ font-style:italic;
+}
+
+center
+{
+ text-align:center;
+display:block;
+}
+
+a:link
+{
+ text-decoration: underline;
+color: #00f;
+cursor: pointer;
+}
+
+h1, h2, h3, h4, h5, h6, div {
+display:block;
+}
+
+h1 {
+ font-weight:bold;
+ margin-top:0.67em;
+ margin-bottom:0.67em;
+ font-size: 2em;
+}
+
+h2 {
+ font-weight:bold;
+ margin-top:0.83em;
+ margin-bottom:0.83em;
+ font-size: 1.5em;
+}
+
+h3 {
+ font-weight:bold;
+ margin-top:1em;
+ margin-bottom:1em;
+ font-size:1.17em;
+}
+
+h4 {
+ font-weight:bold;
+ margin-top:1.33em;
+ margin-bottom:1.33em
+}
+
+h5 {
+ font-weight:bold;
+ margin-top:1.67em;
+ margin-bottom:1.67em;
+ font-size:.83em;
+}
+
+h6 {
+ font-weight:bold;
+ margin-top:2.33em;
+ margin-bottom:2.33em;
+ font-size:.67em;
+}
+
+br {
+display:inline-block;
+}
+
+br[clear="all"]
+{
+clear:both;
+}
+
+br[clear="left"]
+{
+clear:left;
+}
+
+br[clear="right"]
+{
+clear:right;
+}
+
+span {
+ display:inline
+}
+
+img {
+display: inline-block;
+}
+
+img[align="right"]
+{
+ float: right;
+}
+
+img[align="left"]
+{
+ float: left;
+}
+
+hr {
+display: block;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ margin-left: auto;
+ margin-right: auto;
+ border-style: inset;
+ border-width: 1px
+}
+
+
+/***************** TABLES ********************/
+
+table {
+display: table;
+ border-collapse: separate;
+ border-spacing: 2px;
+ border-top-color:gray;
+ border-left-color:gray;
+ border-bottom-color:black;
+ border-right-color:black;
+}
+
+tbody, tfoot, thead {
+display:table-row-group;
+ vertical-align:middle;
+}
+
+tr {
+display: table-row;
+ vertical-align: inherit;
+ border-color: inherit;
+}
+
+td, th {
+display: table-cell;
+ vertical-align: inherit;
+ border-width:1px;
+padding:1px;
+}
+
+th {
+ font-weight: bold;
+}
+
+table[border] {
+ border-style:solid;
+}
+
+table[border|=0] {
+ border-style:none;
+}
+
+table[border] td, table[border] th {
+ border-style:solid;
+ border-top-color:black;
+ border-left-color:black;
+ border-bottom-color:gray;
+ border-right-color:gray;
+}
+
+table[border|=0] td, table[border|=0] th {
+ border-style:none;
+}
+
+caption {
+display: table-caption;
+}
+
+td[nowrap], th[nowrap] {
+ white-space:nowrap;
+}
+
+tt, code, kbd, samp {
+ font-family: monospace
+}
+pre, xmp, plaintext, listing {
+display: block;
+ font-family: monospace;
+ white-space: pre;
+margin: 1em 0
+}
+
+/***************** LISTS ********************/
+
+ul, menu, dir {
+display: block;
+ list-style-type: disc;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ margin-left: 0;
+ margin-right: 0;
+ padding-left: 40px
+}
+
+ol {
+display: block;
+ list-style-type: decimal;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ margin-left: 0;
+ margin-right: 0;
+ padding-left: 40px
+}
+
+li {
+display: list-item;
+}
+
+ul ul, ol ul {
+ list-style-type: circle;
+}
+
+ol ol ul, ol ul ul, ul ol ul, ul ul ul {
+ list-style-type: square;
+}
+
+dd {
+display: block;
+ margin-left: 40px;
+}
+
+dl {
+display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+dt {
+display: block;
+}
+
+ol ul, ul ol, ul ul, ol ol {
+ margin-top: 0;
+ margin-bottom: 0
+}
+
+blockquote {
+display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ margin-left: 40px;
+ margin-left: 40px;
+}
+
+/*********** FORM ELEMENTS ************/
+
+form {
+display: block;
+ margin-top: 0em;
+}
+
+option {
+display: none;
+}
+
+input, textarea, keygen, select, button, isindex {
+margin: 0em;
+color: initial;
+ line-height: normal;
+ text-transform: none;
+ text-indent: 0;
+ text-shadow: none;
+display: inline-block;
+}
+input[type="hidden"] {
+display: none;
+}
+
+
+article, aside, footer, header, hgroup, nav, section
+{
+display: block;
+}
+)RAW";
+
+class QLiteHtmlWidgetPrivate
+{
+public:
+ litehtml::context context;
+ QUrl url;
+ DocumentContainer documentContainer;
+ qreal zoomFactor = 1;
+};
+
+QLiteHtmlWidget::QLiteHtmlWidget(QWidget *parent)
+ : QAbstractScrollArea(parent)
+ , d(new QLiteHtmlWidgetPrivate)
+{
+ setMouseTracking(true);
+ horizontalScrollBar()->setSingleStep(kScrollBarStep);
+ verticalScrollBar()->setSingleStep(kScrollBarStep);
+
+ d->documentContainer.setCursorCallback([this](const QCursor &c) { viewport()->setCursor(c); });
+ d->documentContainer.setPaletteCallback([this] { return palette(); });
+ d->documentContainer.setLinkCallback([this](const QUrl &url) {
+ QUrl fullUrl = url;
+ if (url.isRelative() && url.path(QUrl::FullyEncoded).isEmpty()) { // fragment/anchor only
+ fullUrl = d->url;
+ fullUrl.setFragment(url.fragment(QUrl::FullyEncoded));
+ }
+ // delay because document may not be changed directly during this callback
+ QTimer::singleShot(0, this, [this, fullUrl] { emit linkClicked(fullUrl); });
+ });
+
+ // TODO adapt mastercss to palette (default text & background color)
+ d->context.load_master_stylesheet(mastercss);
+}
+
+QLiteHtmlWidget::~QLiteHtmlWidget()
+{
+ delete d;
+}
+
+void QLiteHtmlWidget::setUrl(const QUrl &url)
+{
+ d->url = url;
+ QUrl urlWithoutAnchor = url;
+ urlWithoutAnchor.setFragment({});
+ const QString urlString = urlWithoutAnchor.toString(QUrl::None);
+ const int lastSlash = urlString.lastIndexOf('/');
+ const QString baseUrl = lastSlash >= 0 ? urlString.left(lastSlash) : urlString;
+ d->documentContainer.set_base_url(baseUrl.toUtf8().constData());
+}
+
+QUrl QLiteHtmlWidget::url() const
+{
+ return d->url;
+}
+
+void QLiteHtmlWidget::setHtml(const QString &content)
+{
+ d->documentContainer.setPaintDevice(viewport());
+ d->documentContainer.setDocument(content.toUtf8(), &d->context);
+ verticalScrollBar()->setValue(0);
+ horizontalScrollBar()->setValue(0);
+ render();
+}
+
+QString QLiteHtmlWidget::title() const
+{
+ return d->documentContainer.caption();
+}
+
+void QLiteHtmlWidget::setZoomFactor(qreal scale)
+{
+ Q_ASSERT(scale != 0);
+ d->zoomFactor = scale;
+ render();
+}
+
+qreal QLiteHtmlWidget::zoomFactor() const
+{
+ return d->zoomFactor;
+}
+
+bool QLiteHtmlWidget::findText(const QString &text,
+ QTextDocument::FindFlags flags,
+ bool incremental,
+ bool *wrapped)
+{
+ bool success = false;
+ QVector<QRect> oldSelection;
+ QVector<QRect> newSelection;
+ d->documentContainer
+ .findText(text, flags, incremental, wrapped, &success, &oldSelection, &newSelection);
+ // scroll to search result position and/or redraw as necessary
+ QRect newSelectionCombined;
+ for (const QRect &r : newSelection)
+ newSelectionCombined = newSelectionCombined.united(r);
+ if (success && verticalScrollBar()->value() > newSelectionCombined.top()) {
+ verticalScrollBar()->setValue(newSelectionCombined.top());
+ } else if (success
+ && verticalScrollBar()->value() + toVirtual(viewport()->size()).height()
+ < newSelectionCombined.bottom()) {
+ verticalScrollBar()->setValue(newSelectionCombined.bottom()
+ - toVirtual(viewport()->size()).height());
+ } else {
+ viewport()->update(fromVirtual(newSelectionCombined.translated(-scrollPosition())));
+ for (const QRect &r : oldSelection)
+ viewport()->update(fromVirtual(r.translated(-scrollPosition())));
+ }
+ return success;
+}
+
+void QLiteHtmlWidget::setDefaultFont(const QFont &font)
+{
+ d->documentContainer.setDefaultFont(font);
+ render();
+}
+
+QFont QLiteHtmlWidget::defaultFont() const
+{
+ return d->documentContainer.defaultFont();
+}
+
+void QLiteHtmlWidget::scrollToAnchor(const QString &name)
+{
+ if (!d->documentContainer.document())
+ return;
+ horizontalScrollBar()->setValue(0);
+ if (name.isEmpty()) {
+ verticalScrollBar()->setValue(0);
+ return;
+ }
+ litehtml::element::ptr element = d->documentContainer.document()->root()->select_one(
+ QString("#%1").arg(name).toStdString());
+ if (!element) {
+ element = d->documentContainer.document()->root()->select_one(
+ QString("[name=%1]").arg(name).toStdString());
+ }
+ if (element) {
+ const int y = element->get_placement().y;
+ verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum()));
+ }
+}
+
+void QLiteHtmlWidget::setResourceHandler(const QLiteHtmlWidget::ResourceHandler &handler)
+{
+ d->documentContainer.setDataCallback(handler);
+}
+
+QString QLiteHtmlWidget::selectedText() const
+{
+ return d->documentContainer.selectedText();
+}
+
+void QLiteHtmlWidget::paintEvent(QPaintEvent *event)
+{
+ if (!d->documentContainer.document())
+ return;
+ d->documentContainer.setScrollPosition(scrollPosition());
+ const QPoint pos = -scrollPosition();
+ const QRect r = toVirtual(event->rect());
+ const litehtml::position clip = {r.x(), r.y(), r.width(), r.height()};
+ QPainter p(viewport());
+ p.setWorldTransform(QTransform().scale(d->zoomFactor, d->zoomFactor));
+ d->documentContainer.document()->draw(reinterpret_cast<litehtml::uint_ptr>(&p),
+ pos.x(),
+ pos.y(),
+ &clip);
+}
+
+static litehtml::element::ptr elementForY(int y, const litehtml::document::ptr &document)
+{
+ if (!document)
+ return {};
+
+ const std::function<litehtml::element::ptr(int, litehtml::element::ptr)> recursion =
+ [&recursion](int y, const litehtml::element::ptr &element) {
+ litehtml::element::ptr result;
+ const int subY = y - element->get_position().y;
+ if (subY <= 0)
+ return element;
+ for (int i = 0; i < int(element->get_children_count()); ++i) {
+ const litehtml::element::ptr child = element->get_child(i);
+ result = recursion(subY, child);
+ if (result)
+ return result;
+ }
+ return result;
+ };
+
+ return recursion(y, document->root());
+}
+
+void QLiteHtmlWidget::resizeEvent(QResizeEvent *event)
+{
+ // remember element to which to scroll after re-rendering
+ QPoint viewportPos;
+ QPoint pos;
+ htmlPos({}, &viewportPos, &pos); // top-left
+ const litehtml::element::ptr element = elementForY(pos.y(), d->documentContainer.document());
+ QAbstractScrollArea::resizeEvent(event);
+ render();
+ if (element) {
+ verticalScrollBar()->setValue(
+ std::min(element->get_placement().y, verticalScrollBar()->maximum()));
+ }
+}
+
+void QLiteHtmlWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ QPoint viewportPos;
+ QPoint pos;
+ htmlPos(event->pos(), &viewportPos, &pos);
+ for (const QRect &r : d->documentContainer.mouseMoveEvent(pos, viewportPos))
+ viewport()->update(fromVirtual(r.translated(-scrollPosition())));
+}
+
+void QLiteHtmlWidget::mousePressEvent(QMouseEvent *event)
+{
+ QPoint viewportPos;
+ QPoint pos;
+ htmlPos(event->pos(), &viewportPos, &pos);
+ for (const QRect &r : d->documentContainer.mousePressEvent(pos, viewportPos, event->button()))
+ viewport()->update(fromVirtual(r.translated(-scrollPosition())));
+}
+
+void QLiteHtmlWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+ QPoint viewportPos;
+ QPoint pos;
+ htmlPos(event->pos(), &viewportPos, &pos);
+ for (const QRect &r : d->documentContainer.mouseReleaseEvent(pos, viewportPos, event->button()))
+ viewport()->update(fromVirtual(r.translated(-scrollPosition())));
+}
+
+void QLiteHtmlWidget::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ QPoint viewportPos;
+ QPoint pos;
+ htmlPos(event->pos(), &viewportPos, &pos);
+ for (const QRect &r :
+ d->documentContainer.mouseDoubleClickEvent(pos, viewportPos, event->button())) {
+ viewport()->update(fromVirtual(r.translated(-scrollPosition())));
+ }
+}
+
+void QLiteHtmlWidget::leaveEvent(QEvent *event)
+{
+ Q_UNUSED(event)
+ for (const QRect &r : d->documentContainer.leaveEvent())
+ viewport()->update(fromVirtual(r.translated(-scrollPosition())));
+}
+
+void QLiteHtmlWidget::contextMenuEvent(QContextMenuEvent *event)
+{
+ QPoint viewportPos;
+ QPoint pos;
+ htmlPos(event->pos(), &viewportPos, &pos);
+ emit contextMenuRequested(event->pos(), d->documentContainer.linkAt(pos, viewportPos));
+}
+
+void QLiteHtmlWidget::render()
+{
+ if (!d->documentContainer.document())
+ return;
+ const int fullWidth = width() / d->zoomFactor;
+ const QSize vViewportSize = toVirtual(viewport()->size());
+ const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, this);
+ const int w = fullWidth - scrollbarWidth - 2;
+ d->documentContainer.render(w, vViewportSize.height());
+ // scroll bars reflect virtual/scaled size of html document
+ horizontalScrollBar()->setPageStep(vViewportSize.width());
+ horizontalScrollBar()->setRange(0, std::max(0, d->documentContainer.document()->width() - w));
+ verticalScrollBar()->setPageStep(vViewportSize.height());
+ verticalScrollBar()->setRange(0,
+ std::max(0,
+ d->documentContainer.document()->height()
+ - vViewportSize.height()));
+ viewport()->update();
+}
+
+QPoint QLiteHtmlWidget::scrollPosition() const
+{
+ return {horizontalScrollBar()->value(), verticalScrollBar()->value()};
+}
+
+void QLiteHtmlWidget::htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const
+{
+ *viewportPos = toVirtual(viewport()->mapFromParent(pos));
+ *htmlPos = *viewportPos + scrollPosition();
+}
+
+QPoint QLiteHtmlWidget::toVirtual(const QPoint &p) const
+{
+ return {int(p.x() / d->zoomFactor), int(p.y() / d->zoomFactor)};
+}
+
+QPoint QLiteHtmlWidget::fromVirtual(const QPoint &p) const
+{
+ return {int(p.x() * d->zoomFactor), int(p.y() * d->zoomFactor)};
+}
+
+QSize QLiteHtmlWidget::toVirtual(const QSize &s) const
+{
+ return {int(s.width() / d->zoomFactor), int(s.height() / d->zoomFactor)};
+}
+
+QSize QLiteHtmlWidget::fromVirtual(const QSize &s) const
+{
+ return {int(s.width() * d->zoomFactor + 0.5), int(s.height() * d->zoomFactor + 0.5)};
+}
+
+QRect QLiteHtmlWidget::toVirtual(const QRect &r) const
+{
+ return {toVirtual(r.topLeft()), toVirtual(r.size())};
+}
+
+QRect QLiteHtmlWidget::fromVirtual(const QRect &r) const
+{
+ return {fromVirtual(r.topLeft()), fromVirtual(r.size())};
+}
diff --git a/src/plugins/help/qlitehtml/qlitehtmlwidget.h b/src/plugins/help/qlitehtml/qlitehtmlwidget.h
new file mode 100644
index 0000000000..97f5be6c63
--- /dev/null
+++ b/src/plugins/help/qlitehtml/qlitehtmlwidget.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of QLiteHtml.
+**
+** 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 <QAbstractScrollArea>
+#include <QTextDocument>
+
+#include <functional>
+
+class QLiteHtmlWidgetPrivate;
+
+class QLiteHtmlWidget : public QAbstractScrollArea
+{
+ Q_OBJECT
+public:
+ explicit QLiteHtmlWidget(QWidget *parent = nullptr);
+ ~QLiteHtmlWidget() override;
+
+ void setUrl(const QUrl &url);
+ QUrl url() const;
+ void setHtml(const QString &content);
+ QString title() const;
+
+ void setZoomFactor(qreal scale);
+ qreal zoomFactor() const;
+
+ bool findText(const QString &text,
+ QTextDocument::FindFlags flags,
+ bool incremental,
+ bool *wrapped = nullptr);
+
+ void setDefaultFont(const QFont &font);
+ QFont defaultFont() const;
+
+ void scrollToAnchor(const QString &name);
+
+ using ResourceHandler = std::function<QByteArray(QUrl)>;
+ void setResourceHandler(const ResourceHandler &handler);
+
+ QString selectedText() const;
+
+signals:
+ void linkClicked(const QUrl &url);
+ void contextMenuRequested(const QPoint &pos, const QUrl &url);
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void leaveEvent(QEvent *event) override;
+ void contextMenuEvent(QContextMenuEvent *event) override;
+
+private:
+ void render();
+ QPoint scrollPosition() const;
+ void htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const;
+ QPoint toVirtual(const QPoint &p) const;
+ QPoint fromVirtual(const QPoint &p) const;
+ QSize toVirtual(const QSize &s) const;
+ QSize fromVirtual(const QSize &s) const;
+ QRect toVirtual(const QRect &r) const;
+ QRect fromVirtual(const QRect &r) const;
+
+ QLiteHtmlWidgetPrivate *d;
+};
diff --git a/src/plugins/help/searchwidget.cpp b/src/plugins/help/searchwidget.cpp
index fe03f6e0e6..4d893e15d2 100644
--- a/src/plugins/help/searchwidget.cpp
+++ b/src/plugins/help/searchwidget.cpp
@@ -99,7 +99,7 @@ void SearchWidget::showEvent(QShowEvent *event)
{
if (!event->spontaneous() && !searchEngine) {
auto vLayout = new QVBoxLayout(this);
- vLayout->setMargin(0);
+ vLayout->setContentsMargins(0, 0, 0, 0);
vLayout->setSpacing(0);
searchEngine = new QHelpSearchEngine(&LocalHelpManager::helpEngine(), this);
@@ -109,7 +109,7 @@ void SearchWidget::showEvent(QShowEvent *event)
m_queryWidget = searchEngine->queryWidget();
QLayout *tbLayout = new QVBoxLayout();
tbLayout->setSpacing(6);
- tbLayout->setMargin(4);
+ tbLayout->setContentsMargins(4, 4, 4, 4);
tbLayout->addWidget(m_queryWidget);
m_indexingDocumentationLabel = new QLabel(tr("Indexing Documentation"), toolbar);
m_indexingDocumentationLabel->hide();
@@ -120,7 +120,7 @@ void SearchWidget::showEvent(QShowEvent *event)
toolbar2->setSingleRow(false);
tbLayout = new QVBoxLayout();
tbLayout->setSpacing(0);
- tbLayout->setMargin(0);
+ tbLayout->setContentsMargins(0, 0, 0, 0);
tbLayout->addWidget(resultWidget = searchEngine->resultWidget());
toolbar2->setLayout(tbLayout);
diff --git a/src/plugins/help/textbrowserhelpviewer.cpp b/src/plugins/help/textbrowserhelpviewer.cpp
index 02afab8d4d..eba428e2a5 100644
--- a/src/plugins/help/textbrowserhelpviewer.cpp
+++ b/src/plugins/help/textbrowserhelpviewer.cpp
@@ -376,8 +376,6 @@ void TextBrowserHelpWidget::contextMenuEvent(QContextMenuEvent *event)
copyAnchorAction = menu.addAction(tr("Copy Link"));
} else if (!textCursor().selectedText().isEmpty()) {
connect(menu.addAction(tr("Copy")), &QAction::triggered, this, &QTextEdit::copy);
- } else {
- connect(menu.addAction(tr("Reload")), &QAction::triggered, this, &QTextBrowser::reload);
}
if (copyAnchorAction == menu.exec(event->globalPos()))
diff --git a/src/plugins/help/webenginehelpviewer.cpp b/src/plugins/help/webenginehelpviewer.cpp
index 197f356d79..d641df1ac8 100644
--- a/src/plugins/help/webenginehelpviewer.cpp
+++ b/src/plugins/help/webenginehelpviewer.cpp
@@ -34,6 +34,7 @@
#include <QBuffer>
#include <QContextMenuEvent>
#include <QCoreApplication>
+#include <QDesktopServices>
#include <QTimer>
#include <QVBoxLayout>
#include <QWebEngineContextMenuData>
@@ -72,10 +73,40 @@ static HelpUrlSchemeHandler *helpUrlSchemeHandler()
return schemeHandler;
}
+HelpUrlRequestInterceptor::HelpUrlRequestInterceptor(QObject *parent)
+ : QWebEngineUrlRequestInterceptor(parent)
+{}
+
+void HelpUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
+{
+ if (!HelpViewer::isLocalUrl(info.requestUrl())
+ && info.navigationType() != QWebEngineUrlRequestInfo::NavigationTypeLink) {
+ info.block(true);
+ }
+}
+
+static HelpUrlRequestInterceptor *helpurlRequestInterceptor()
+{
+ static HelpUrlRequestInterceptor *interceptor = nullptr;
+ if (!interceptor)
+ interceptor = new HelpUrlRequestInterceptor(LocalHelpManager::instance());
+ return interceptor;
+}
+
WebEngineHelpViewer::WebEngineHelpViewer(QWidget *parent) :
HelpViewer(parent),
m_widget(new WebView(this))
{
+ // some of these should already be that way by default, but better be sure
+ QWebEngineSettings *settings = m_widget->settings();
+ settings->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
+ settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, false);
+ settings->setAttribute(QWebEngineSettings::XSSAuditingEnabled, true);
+ settings->setAttribute(QWebEngineSettings::PluginsEnabled, false);
+ settings->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, false);
+ settings->setAttribute(QWebEngineSettings::AllowGeolocationOnInsecureOrigins, false);
+ settings->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, false);
+
m_widget->setPage(new WebEngineHelpPage(this));
auto layout = new QVBoxLayout;
setLayout(layout);
@@ -121,6 +152,11 @@ WebEngineHelpViewer::WebEngineHelpViewer(QWidget *parent) :
QTC_ASSERT(viewProfile, return);
if (!viewProfile->urlSchemeHandler("qthelp"))
viewProfile->installUrlSchemeHandler("qthelp", helpUrlSchemeHandler());
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
+ viewProfile->setUrlRequestInterceptor(helpurlRequestInterceptor());
+#else
+ viewProfile->setRequestInterceptor(helpurlRequestInterceptor());
+#endif
}
QFont WebEngineHelpViewer::viewerFont() const
@@ -286,12 +322,23 @@ WebEngineHelpPage::WebEngineHelpPage(QObject *parent)
{
}
-WebView::WebView(WebEngineHelpViewer *viewer)
- : QWebEngineView(viewer),
- m_viewer(viewer)
+bool WebEngineHelpPage::acceptNavigationRequest(const QUrl &url,
+ QWebEnginePage::NavigationType type,
+ bool isMainFrame)
{
+ Q_UNUSED(type)
+ Q_UNUSED(isMainFrame)
+ if (HelpViewer::isLocalUrl(url))
+ return true;
+ QDesktopServices::openUrl(url);
+ return false;
}
+WebView::WebView(WebEngineHelpViewer *viewer)
+ : QWebEngineView(viewer)
+ , m_viewer(viewer)
+{}
+
bool WebView::event(QEvent *ev)
{
// work around QTBUG-43602
diff --git a/src/plugins/help/webenginehelpviewer.h b/src/plugins/help/webenginehelpviewer.h
index f781889108..259bc571a9 100644
--- a/src/plugins/help/webenginehelpviewer.h
+++ b/src/plugins/help/webenginehelpviewer.h
@@ -27,6 +27,7 @@
#include "helpviewer.h"
+#include <QWebEngineUrlRequestInterceptor>
#include <QWebEngineUrlSchemeHandler>
#include <QWebEngineView>
@@ -42,10 +43,22 @@ public:
void requestStarted(QWebEngineUrlRequestJob *job) override;
};
+class HelpUrlRequestInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ explicit HelpUrlRequestInterceptor(QObject *parent = nullptr);
+ void interceptRequest(QWebEngineUrlRequestInfo &info) override;
+};
+
class WebEngineHelpPage : public QWebEnginePage
{
public:
explicit WebEngineHelpPage(QObject *parent = nullptr);
+
+protected:
+ bool acceptNavigationRequest(const QUrl &url,
+ QWebEnginePage::NavigationType type,
+ bool isMainFrame) override;
};
class WebView : public QWebEngineView
diff --git a/src/plugins/imageviewer/imageview.cpp b/src/plugins/imageviewer/imageview.cpp
index 821074db20..611d494e88 100644
--- a/src/plugins/imageviewer/imageview.cpp
+++ b/src/plugins/imageviewer/imageview.cpp
@@ -286,7 +286,7 @@ void ImageView::doScale(qreal factor)
void ImageView::wheelEvent(QWheelEvent *event)
{
- qreal factor = qPow(Constants::DEFAULT_SCALE_FACTOR, event->delta() / 240.0);
+ qreal factor = qPow(Constants::DEFAULT_SCALE_FACTOR, event->angleDelta().y() / 240.0);
doScale(factor);
event->accept();
}
diff --git a/src/plugins/ios/CMakeLists.txt b/src/plugins/ios/CMakeLists.txt
index 87f6d1dbcb..496c5ae203 100644
--- a/src/plugins/ios/CMakeLists.txt
+++ b/src/plugins/ios/CMakeLists.txt
@@ -5,7 +5,7 @@ add_qtc_plugin(Ios
createsimulatordialog.cpp createsimulatordialog.h createsimulatordialog.ui
ios.qrc
iosbuildconfiguration.cpp iosbuildconfiguration.h
- iosbuildstep.cpp iosbuildstep.h iosbuildstep.ui
+ iosbuildstep.cpp iosbuildstep.h
iosconfigurations.cpp iosconfigurations.h
iosconstants.h
iosdeploystep.cpp iosdeploystep.h
diff --git a/src/plugins/ios/ios.pro b/src/plugins/ios/ios.pro
index d8bfd14d15..5a6d153253 100644
--- a/src/plugins/ios/ios.pro
+++ b/src/plugins/ios/ios.pro
@@ -53,7 +53,6 @@ SOURCES += \
FORMS += \
iossettingswidget.ui \
- iosbuildstep.ui \
iospresetbuildstep.ui \
createsimulatordialog.ui \
simulatoroperationdialog.ui
diff --git a/src/plugins/ios/ios.qbs b/src/plugins/ios/ios.qbs
index e338c9241f..22de033f54 100644
--- a/src/plugins/ios/ios.qbs
+++ b/src/plugins/ios/ios.qbs
@@ -22,7 +22,6 @@ QtcPlugin {
"iosbuildconfiguration.h",
"iosbuildstep.cpp",
"iosbuildstep.h",
- "iosbuildstep.ui",
"iosconfigurations.cpp",
"iosconfigurations.h",
"iosconstants.h",
diff --git a/src/plugins/ios/iosbuildconfiguration.cpp b/src/plugins/ios/iosbuildconfiguration.cpp
index 0ef0002071..4a37779ca3 100644
--- a/src/plugins/ios/iosbuildconfiguration.cpp
+++ b/src/plugins/ios/iosbuildconfiguration.cpp
@@ -184,7 +184,7 @@ IosBuildSettingsWidget::IosBuildSettingsWidget(IosBuildConfiguration *bc)
adjustSize();
auto rootLayout = new QVBoxLayout(this);
- rootLayout->setMargin(0);
+ rootLayout->setContentsMargins(0, 0, 0, 0);
rootLayout->addWidget(detailsWidget);
auto gridLayout = new QGridLayout();
diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp
index 0fbcb44305..2ca3db2743 100644
--- a/src/plugins/ios/iosbuildstep.cpp
+++ b/src/plugins/ios/iosbuildstep.cpp
@@ -25,7 +25,6 @@
#include "iosbuildstep.h"
#include "iosconstants.h"
-#include "ui_iosbuildstep.h"
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/target.h>
@@ -39,14 +38,24 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/gcctoolchain.h>
+
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtparser.h>
+
+#include <utils/fileutils.h>
#include <utils/stringutils.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
+#include <QGridLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPlainTextEdit>
+#include <QPushButton>
+
using namespace Core;
using namespace ProjectExplorer;
+using namespace Utils;
namespace Ios {
namespace Internal {
@@ -59,6 +68,101 @@ const char BUILD_USE_DEFAULT_ARGS_KEY[] = "Ios.IosBuildStep.XcodeArgumentsUseDef
const char BUILD_ARGUMENTS_KEY[] = "Ios.IosBuildStep.XcodeArguments";
const char CLEAN_KEY[] = "Ios.IosBuildStep.Clean";
+//
+// IosBuildStepConfigWidget
+//
+
+class IosBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+public:
+ IosBuildStepConfigWidget(IosBuildStep *buildStep)
+ : BuildStepConfigWidget(buildStep), m_buildStep(buildStep)
+ {
+ auto buildArgumentsLabel = new QLabel(this);
+ buildArgumentsLabel->setText(tr("Base arguments:"));
+
+ m_buildArgumentsTextEdit = new QPlainTextEdit(this);
+ m_buildArgumentsTextEdit->setPlainText(QtcProcess::joinArgs(m_buildStep->baseArguments()));
+
+ m_resetDefaultsButton = new QPushButton(this);
+ m_resetDefaultsButton->setLayoutDirection(Qt::RightToLeft);
+ m_resetDefaultsButton->setText(tr("Reset Defaults"));
+ m_resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
+
+ auto extraArgumentsLabel = new QLabel(this);
+
+ m_extraArgumentsLineEdit = new QLineEdit(this);
+ m_extraArgumentsLineEdit->setText(QtcProcess::joinArgs(m_buildStep->m_extraArguments));
+
+ auto gridLayout = new QGridLayout(this);
+ gridLayout->addWidget(buildArgumentsLabel, 0, 0, 1, 1);
+ gridLayout->addWidget(m_buildArgumentsTextEdit, 0, 1, 2, 1);
+ gridLayout->addWidget(m_resetDefaultsButton, 1, 2, 1, 1);
+ gridLayout->addWidget(extraArgumentsLabel, 2, 0, 1, 1);
+ gridLayout->addWidget(m_extraArgumentsLineEdit, 2, 1, 1, 1);
+
+ extraArgumentsLabel->setText(tr("Extra arguments:"));
+
+ setDisplayName(tr("iOS build", "iOS BuildStep display name."));
+
+ updateDetails();
+
+ connect(m_buildArgumentsTextEdit, &QPlainTextEdit::textChanged,
+ this, &IosBuildStepConfigWidget::buildArgumentsChanged);
+ connect(m_resetDefaultsButton, &QAbstractButton::clicked,
+ this, &IosBuildStepConfigWidget::resetDefaultArguments);
+ connect(m_extraArgumentsLineEdit, &QLineEdit::editingFinished,
+ this, &IosBuildStepConfigWidget::extraArgumentsChanged);
+
+ connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
+ this, &IosBuildStepConfigWidget::updateDetails);
+ connect(m_buildStep->target(), &Target::kitChanged,
+ this, &IosBuildStepConfigWidget::updateDetails);
+
+ connect(m_buildStep->buildConfiguration(), &BuildConfiguration::environmentChanged,
+ this, &IosBuildStepConfigWidget::updateDetails);
+ }
+
+private:
+ void buildArgumentsChanged()
+ {
+ m_buildStep->setBaseArguments(QtcProcess::splitArgs(m_buildArgumentsTextEdit->toPlainText()));
+ m_resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
+ updateDetails();
+ }
+
+ void resetDefaultArguments()
+ {
+ m_buildStep->setBaseArguments(m_buildStep->defaultArguments());
+ m_buildArgumentsTextEdit->setPlainText(QtcProcess::joinArgs(m_buildStep->baseArguments()));
+ m_resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
+ }
+
+ void extraArgumentsChanged()
+ {
+ m_buildStep->setExtraArguments(QtcProcess::splitArgs(m_extraArgumentsLineEdit->text()));
+ }
+
+ void updateDetails()
+ {
+ BuildConfiguration *bc = m_buildStep->buildConfiguration();
+
+ ProcessParameters param;
+ param.setMacroExpander(bc->macroExpander());
+ param.setWorkingDirectory(bc->buildDirectory());
+ param.setEnvironment(bc->environment());
+ param.setCommandLine({m_buildStep->buildCommand(), m_buildStep->allArguments()});
+
+ setSummaryText(param.summary(displayName()));
+ }
+
+ IosBuildStep *m_buildStep;
+
+ QPlainTextEdit *m_buildArgumentsTextEdit;
+ QPushButton *m_resetDefaultsButton;
+ QLineEdit *m_extraArgumentsLineEdit;
+};
+
IosBuildStep::IosBuildStep(BuildStepList *parent) :
AbstractProcessStep(parent, IOS_BUILD_STEP_ID)
{
@@ -91,9 +195,7 @@ bool IosBuildStep::init()
Utils::Environment env = bc->environment();
Utils::Environment::setupEnglishOutput(&env);
pp->setEnvironment(env);
- pp->setCommand(Utils::FilePath::fromString(buildCommand()));
- pp->setArguments(Utils::QtcProcess::joinArgs(allArguments()));
- pp->resolveAll();
+ pp->setCommandLine({buildCommand(), allArguments()});
// If we are cleaning, then build can fail with an error code, but that doesn't mean
// we should stop the clean queue
@@ -164,9 +266,9 @@ QStringList IosBuildStep::defaultArguments() const
return res;
}
-QString IosBuildStep::buildCommand() const
+FilePath IosBuildStep::buildCommand() const
{
- return QString("xcodebuild"); // add path?
+ return FilePath::fromString("xcodebuild"); // add path?
}
void IosBuildStep::doRun()
@@ -198,90 +300,6 @@ QStringList IosBuildStep::baseArguments() const
}
//
-// IosBuildStepConfigWidget
-//
-
-IosBuildStepConfigWidget::IosBuildStepConfigWidget(IosBuildStep *buildStep)
- : BuildStepConfigWidget(buildStep), m_buildStep(buildStep)
-{
- m_ui = new Ui::IosBuildStep;
- m_ui->setupUi(this);
-
- setDisplayName(tr("iOS build", "iOS BuildStep display name."));
-
- Project *pro = m_buildStep->target()->project();
-
- m_ui->buildArgumentsTextEdit->setPlainText(Utils::QtcProcess::joinArgs(
- m_buildStep->baseArguments()));
- m_ui->extraArgumentsLineEdit->setText(Utils::QtcProcess::joinArgs(
- m_buildStep->m_extraArguments));
- m_ui->resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
- updateDetails();
-
- connect(m_ui->buildArgumentsTextEdit, &QPlainTextEdit::textChanged,
- this, &IosBuildStepConfigWidget::buildArgumentsChanged);
- connect(m_ui->resetDefaultsButton, &QAbstractButton::clicked,
- this, &IosBuildStepConfigWidget::resetDefaultArguments);
- connect(m_ui->extraArgumentsLineEdit, &QLineEdit::editingFinished,
- this, &IosBuildStepConfigWidget::extraArgumentsChanged);
-
- connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
- this, &IosBuildStepConfigWidget::updateDetails);
- connect(m_buildStep->target(), &Target::kitChanged,
- this, &IosBuildStepConfigWidget::updateDetails);
- pro->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
- if (static_cast<BuildConfiguration *>(sender())->isActive())
- updateDetails();
- });
- connect(pro, &Project::activeProjectConfigurationChanged,
- this, [this](ProjectConfiguration *pc) {
- if (pc && pc->isActive())
- updateDetails();
- });
-}
-
-IosBuildStepConfigWidget::~IosBuildStepConfigWidget()
-{
- delete m_ui;
-}
-
-void IosBuildStepConfigWidget::updateDetails()
-{
- BuildConfiguration *bc = m_buildStep->buildConfiguration();
-
- ProcessParameters param;
- param.setMacroExpander(bc->macroExpander());
- param.setWorkingDirectory(bc->buildDirectory());
- param.setEnvironment(bc->environment());
- param.setCommand(Utils::FilePath::fromString(m_buildStep->buildCommand()));
- param.setArguments(Utils::QtcProcess::joinArgs(m_buildStep->allArguments()));
-
- setSummaryText(param.summary(displayName()));
-}
-
-void IosBuildStepConfigWidget::buildArgumentsChanged()
-{
- m_buildStep->setBaseArguments(Utils::QtcProcess::splitArgs(
- m_ui->buildArgumentsTextEdit->toPlainText()));
- m_ui->resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
- updateDetails();
-}
-
-void IosBuildStepConfigWidget::resetDefaultArguments()
-{
- m_buildStep->setBaseArguments(m_buildStep->defaultArguments());
- m_ui->buildArgumentsTextEdit->setPlainText(Utils::QtcProcess::joinArgs(
- m_buildStep->baseArguments()));
- m_ui->resetDefaultsButton->setEnabled(!m_buildStep->m_useDefaultArguments);
-}
-
-void IosBuildStepConfigWidget::extraArgumentsChanged()
-{
- m_buildStep->setExtraArguments(Utils::QtcProcess::splitArgs(
- m_ui->extraArgumentsLineEdit->text()));
-}
-
-//
// IosBuildStepFactory
//
diff --git a/src/plugins/ios/iosbuildstep.h b/src/plugins/ios/iosbuildstep.h
index 227f88b17a..22953d82f9 100644
--- a/src/plugins/ios/iosbuildstep.h
+++ b/src/plugins/ios/iosbuildstep.h
@@ -36,7 +36,6 @@ namespace Internal {
class IosBuildStepConfigWidget;
class IosBuildStepFactory;
-namespace Ui { class IosBuildStep; }
class IosBuildStep : public ProjectExplorer::AbstractProcessStep
{
@@ -54,7 +53,7 @@ public:
QStringList baseArguments() const;
QStringList allArguments() const;
QStringList defaultArguments() const;
- QString buildCommand() const;
+ Utils::FilePath buildCommand() const;
private:
bool init() override;
@@ -68,24 +67,6 @@ private:
bool m_clean = false;
};
-class IosBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
-{
- Q_OBJECT
-
-public:
- IosBuildStepConfigWidget(IosBuildStep *buildStep);
- ~IosBuildStepConfigWidget() override;
-
-private:
- void buildArgumentsChanged();
- void resetDefaultArguments();
- void extraArgumentsChanged();
- void updateDetails();
-
- Ui::IosBuildStep *m_ui;
- IosBuildStep *m_buildStep;
-};
-
class IosBuildStepFactory : public ProjectExplorer::BuildStepFactory
{
public:
diff --git a/src/plugins/ios/iosbuildstep.ui b/src/plugins/ios/iosbuildstep.ui
deleted file mode 100644
index ef8dec89e4..0000000000
--- a/src/plugins/ios/iosbuildstep.ui
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Ios::Internal::IosBuildStep</class>
- <widget class="QWidget" name="Ios::Internal::IosBuildStep">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>756</width>
- <height>183</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="buildArgumentsLabel">
- <property name="text">
- <string>Base arguments:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" rowspan="2">
- <widget class="QPlainTextEdit" name="buildArgumentsTextEdit"/>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="resetDefaultsButton">
- <property name="layoutDirection">
- <enum>Qt::RightToLeft</enum>
- </property>
- <property name="text">
- <string>Reset Defaults</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="extraArgumentsLabel">
- <property name="text">
- <string>Extra arguments:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="extraArgumentsLineEdit"/>
- </item>
- </layout>
- <zorder>buildArgumentsTextEdit</zorder>
- <zorder>resetDefaultsButton</zorder>
- <zorder>extraArgumentsLabel</zorder>
- <zorder>extraArgumentsLineEdit</zorder>
- <zorder>buildArgumentsLabel</zorder>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp
index a1d13c115a..3a264bb4bb 100644
--- a/src/plugins/ios/iosconfigurations.cpp
+++ b/src/plugins/ios/iosconfigurations.cpp
@@ -233,7 +233,7 @@ static QByteArray decodeProvisioningProfile(const QString &path)
p.setTimeoutS(3);
// path is assumed to be valid file path to .mobileprovision
const QStringList args = {"smime", "-inform", "der", "-verify", "-in", path};
- Utils::SynchronousProcessResponse res = p.runBlocking("openssl", args);
+ Utils::SynchronousProcessResponse res = p.runBlocking({"openssl", args});
if (res.result != Utils::SynchronousProcessResponse::Finished)
qCDebug(iosCommonLog) << "Reading signed provisioning file failed" << path;
return res.stdOut().toLatin1();
@@ -474,9 +474,8 @@ void IosConfigurations::loadProvisioningData(bool notify)
const QSettings xcodeSettings(xcodePlistPath, QSettings::NativeFormat);
const QVariantMap teamMap = xcodeSettings.value(provisioningTeamsTag).toMap();
QList<QVariantMap> teams;
- QMapIterator<QString, QVariant> accountiterator(teamMap);
- while (accountiterator.hasNext()) {
- accountiterator.next();
+ for (auto accountiterator = teamMap.cbegin(), end = teamMap.cend();
+ accountiterator != end; ++accountiterator) {
QVariantMap teamInfo = accountiterator.value().toMap();
int provisioningTeamIsFree = teamInfo.value(freeTeamTag).toBool() ? 1 : 0;
teamInfo[freeTeamTag] = provisioningTeamIsFree;
@@ -575,29 +574,6 @@ ProvisioningProfilePtr IosConfigurations::provisioningProfile(const QString &pro
Utils::equal(&ProvisioningProfile::identifier, profileID));
}
-static ClangToolChain *createToolChain(const XcodePlatform &platform,
- const XcodePlatform::ToolchainTarget &target,
- Core::Id l)
-{
- if (!l.isValid())
- return nullptr;
-
- if (l != Core::Id(ProjectExplorer::Constants::C_LANGUAGE_ID)
- && l != Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID))
- return nullptr;
-
- auto toolChain = new ClangToolChain;
- toolChain->setDetection(ToolChain::AutoDetection);
- toolChain->setLanguage(l);
- toolChain->setDisplayName(target.name);
- toolChain->setPlatformCodeGenFlags(target.backendFlags);
- toolChain->setPlatformLinkerFlags(target.backendFlags);
- toolChain->resetToolChain(l == Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID) ?
- platform.cxxCompilerPath : platform.cCompilerPath);
-
- return toolChain;
-}
-
IosToolChainFactory::IosToolChainFactory()
{
setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID,
@@ -610,13 +586,20 @@ QList<ToolChain *> IosToolChainFactory::autoDetect(const QList<ToolChain *> &exi
const QList<XcodePlatform> platforms = XcodeProbe::detectPlatforms().values();
QList<ToolChain *> toolChains;
toolChains.reserve(platforms.size());
- foreach (const XcodePlatform &platform, platforms) {
+ for (const XcodePlatform &platform : platforms) {
for (const XcodePlatform::ToolchainTarget &target : platform.targets) {
ToolChainPair platformToolchains = findToolChainForPlatform(platform, target,
existingClangToolChains);
- auto createOrAdd = [&](ClangToolChain* toolChain, Core::Id l) {
+ auto createOrAdd = [&](ClangToolChain *toolChain, Core::Id l) {
if (!toolChain) {
- toolChain = createToolChain(platform, target, l);
+ toolChain = new ClangToolChain;
+ toolChain->setDetection(ToolChain::AutoDetection);
+ toolChain->setLanguage(l);
+ toolChain->setDisplayName(target.name);
+ toolChain->setPlatformCodeGenFlags(target.backendFlags);
+ toolChain->setPlatformLinkerFlags(target.backendFlags);
+ toolChain->resetToolChain(l == ProjectExplorer::Constants::CXX_LANGUAGE_ID ?
+ platform.cxxCompilerPath : platform.cCompilerPath);
existingClangToolChains.append(toolChain);
}
toolChains.append(toolChain);
diff --git a/src/plugins/ios/iosdeploystep.cpp b/src/plugins/ios/iosdeploystep.cpp
index 2a0da618af..ba18d7eb7f 100644
--- a/src/plugins/ios/iosdeploystep.cpp
+++ b/src/plugins/ios/iosdeploystep.cpp
@@ -145,7 +145,7 @@ void IosDeployStep::handleIsTransferringApp(IosToolHandler *handler, const QStri
const QString &deviceId, int progress, int maxProgress,
const QString &info)
{
- Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+ Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId)
QTC_CHECK(m_transferStatus == TransferInProgress);
emit this->progress(progress * 100 / maxProgress, info);
}
@@ -153,7 +153,7 @@ void IosDeployStep::handleIsTransferringApp(IosToolHandler *handler, const QStri
void IosDeployStep::handleDidTransferApp(IosToolHandler *handler, const QString &bundlePath,
const QString &deviceId, IosToolHandler::OpStatus status)
{
- Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+ Q_UNUSED(handler); Q_UNUSED(bundlePath); Q_UNUSED(deviceId)
QTC_CHECK(m_transferStatus == TransferInProgress);
if (status == IosToolHandler::Success) {
m_transferStatus = TransferOk;
@@ -188,7 +188,7 @@ void IosDeployStep::handleFinished(IosToolHandler *handler)
void IosDeployStep::handleErrorMsg(IosToolHandler *handler, const QString &msg)
{
- Q_UNUSED(handler);
+ Q_UNUSED(handler)
if (msg.contains(QLatin1String("AMDeviceInstallApplication returned -402653103")))
TaskHub::addTask(Task::Warning,
tr("The Info.plist might be incorrect."),
diff --git a/src/plugins/ios/iosdevice.cpp b/src/plugins/ios/iosdevice.cpp
index 6fe7bfe40c..e3438ffb71 100644
--- a/src/plugins/ios/iosdevice.cpp
+++ b/src/plugins/ios/iosdevice.cpp
@@ -78,14 +78,22 @@ static QString CFStringRef2QString(CFStringRef s)
namespace Ios {
namespace Internal {
-IosDevice::IosDevice()
+IosDevice::IosDevice(CtorHelper)
: m_lastPort(Constants::IOS_DEVICE_PORT_START)
{
- setupId(IDevice::AutoDetected, Constants::IOS_DEVICE_ID);
setType(Constants::IOS_DEVICE_TYPE);
- setDisplayName(IosDevice::name());
+ setDefaultDisplayName(IosDevice::name());
+ setDisplayType(QCoreApplication::translate("Ios::Internal::IosDevice", "iOS"));
setMachineType(IDevice::Hardware);
+ setOsType(Utils::OsTypeMac);
setDeviceState(DeviceDisconnected);
+}
+
+IosDevice::IosDevice()
+ : IosDevice(CtorHelper{})
+{
+ setupId(IDevice::AutoDetected, Constants::IOS_DEVICE_ID);
+
Utils::PortList ports;
ports.addRange(Utils::Port(Constants::IOS_DEVICE_PORT_START),
Utils::Port(Constants::IOS_DEVICE_PORT_END));
@@ -93,22 +101,15 @@ IosDevice::IosDevice()
}
IosDevice::IosDevice(const QString &uid)
- : m_lastPort(Constants::IOS_DEVICE_PORT_START)
+ : IosDevice(CtorHelper{})
{
setupId(IDevice::AutoDetected, Core::Id(Constants::IOS_DEVICE_ID).withSuffix(uid));
- setType(Constants::IOS_DEVICE_TYPE);
- setDisplayName(IosDevice::name());
- setMachineType(IDevice::Hardware);
- setDeviceState(DeviceDisconnected);
}
-
IDevice::DeviceInfo IosDevice::deviceInformation() const
{
IDevice::DeviceInfo res;
- QMapIterator<QString, QString> i(m_extraInfo);
- while (i.hasNext()) {
- i.next();
+ for (auto i = m_extraInfo.cbegin(), end = m_extraInfo.cend(); i != end; ++i) {
IosDeviceManager::TranslationMap tMap = IosDeviceManager::translationMap();
if (tMap.contains(i.key()))
res.append(DeviceInfoItem(tMap.value(i.key()), tMap.value(i.value(), i.value())));
@@ -116,11 +117,6 @@ IDevice::DeviceInfo IosDevice::deviceInformation() const
return res;
}
-QString IosDevice::displayType() const
-{
- return QCoreApplication::translate("Ios::Internal::IosDevice", "iOS");
-}
-
IDeviceWidget *IosDevice::createWidget()
{
return nullptr;
@@ -134,24 +130,19 @@ DeviceProcessSignalOperation::Ptr IosDevice::signalOperation() const
void IosDevice::fromMap(const QVariantMap &map)
{
IDevice::fromMap(map);
- QVariantMap vMap = map.value(QLatin1String(Constants::EXTRA_INFO_KEY)).toMap();
- QMapIterator<QString, QVariant> i(vMap);
+
m_extraInfo.clear();
- while (i.hasNext()) {
- i.next();
+ const QVariantMap vMap = map.value(QLatin1String(Constants::EXTRA_INFO_KEY)).toMap();
+ for (auto i = vMap.cbegin(), end = vMap.cend(); i != end; ++i)
m_extraInfo.insert(i.key(), i.value().toString());
- }
}
QVariantMap IosDevice::toMap() const
{
QVariantMap res = IDevice::toMap();
QVariantMap vMap;
- QMapIterator<QString, QString> i(m_extraInfo);
- while (i.hasNext()) {
- i.next();
+ for (auto i = m_extraInfo.cbegin(), end = m_extraInfo.cend(); i != end; ++i)
vMap.insert(i.key(), i.value());
- }
res.insert(QLatin1String(Constants::EXTRA_INFO_KEY), vMap);
return res;
}
@@ -184,11 +175,6 @@ bool IosDevice::canAutoDetectPorts() const
return true;
}
-Utils::OsType IosDevice::osType() const
-{
- return Utils::OsTypeMac;
-}
-
// IosDeviceManager
diff --git a/src/plugins/ios/iosdevice.h b/src/plugins/ios/iosdevice.h
index 79037d8eb3..3370deb620 100644
--- a/src/plugins/ios/iosdevice.h
+++ b/src/plugins/ios/iosdevice.h
@@ -52,7 +52,6 @@ public:
ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
- QString displayType() const override;
void fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
@@ -60,7 +59,6 @@ public:
QString osVersion() const;
Utils::Port nextPort() const;
bool canAutoDetectPorts() const override;
- Utils::OsType osType() const override;
static QString name();
@@ -70,6 +68,9 @@ protected:
IosDevice();
IosDevice(const QString &uid);
+ enum CtorHelper {};
+ IosDevice(CtorHelper);
+
Dict m_extraInfo;
bool m_ignoreDevice = false;
mutable quint16 m_lastPort;
diff --git a/src/plugins/ios/iosdsymbuildstep.cpp b/src/plugins/ios/iosdsymbuildstep.cpp
index d238bcfb95..cf4e258693 100644
--- a/src/plugins/ios/iosdsymbuildstep.cpp
+++ b/src/plugins/ios/iosdsymbuildstep.cpp
@@ -39,14 +39,17 @@
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h>
+
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtparser.h>
+
#include <utils/stringutils.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
using namespace Core;
using namespace ProjectExplorer;
+using namespace Utils;
namespace Ios {
namespace Internal {
@@ -72,9 +75,7 @@ bool IosDsymBuildStep::init()
Utils::Environment env = bc->environment();
Utils::Environment::setupEnglishOutput(&env);
pp->setEnvironment(env);
- pp->setCommand(Utils::FilePath::fromString(command()));
- pp->setArguments(Utils::QtcProcess::joinArgs(arguments()));
- pp->resolveAll();
+ pp->setCommandLine({command(), arguments()});
// If we are cleaning, then build can fail with an error code, but that doesn't mean
// we should stop the clean queue
@@ -97,7 +98,7 @@ QVariantMap IosDsymBuildStep::toMap() const
map.insert(id().withSuffix(USE_DEFAULT_ARGS_PARTIAL_KEY).toString(),
isDefault());
map.insert(id().withSuffix(CLEAN_PARTIAL_KEY).toString(), m_clean);
- map.insert(id().withSuffix(COMMAND_PARTIAL_KEY).toString(), command());
+ map.insert(id().withSuffix(COMMAND_PARTIAL_KEY).toString(), command().toVariant());
return map;
}
@@ -108,8 +109,7 @@ bool IosDsymBuildStep::fromMap(const QVariantMap &map)
bool useDefaultArguments = map.value(
id().withSuffix(USE_DEFAULT_ARGS_PARTIAL_KEY).toString()).toBool();
m_clean = map.value(id().withSuffix(CLEAN_PARTIAL_KEY).toString(), m_clean).toBool();
- m_command = map.value(id().withSuffix(COMMAND_PARTIAL_KEY).toString(), m_command)
- .toString();
+ m_command = FilePath::fromVariant(map.value(id().withSuffix(COMMAND_PARTIAL_KEY).toString()));
if (useDefaultArguments) {
m_command = defaultCommand();
m_arguments = defaultArguments();
@@ -125,12 +125,12 @@ QStringList IosDsymBuildStep::defaultArguments() const
return defaultCmdList().mid(1);
}
-QString IosDsymBuildStep::defaultCommand() const
+FilePath IosDsymBuildStep::defaultCommand() const
{
if (m_clean)
- return defaultCleanCmdList().at(0);
+ return FilePath::fromString(defaultCleanCmdList().at(0));
else
- return defaultCmdList().at(0);
+ return FilePath::fromString(defaultCmdList().at(0));
}
QStringList IosDsymBuildStep::defaultCleanCmdList() const
@@ -158,14 +158,14 @@ QStringList IosDsymBuildStep::defaultCmdList() const
return QStringList({dsymutilCmd, "-o", dsymPath, runConf->localExecutable().toUserOutput()});
}
-QString IosDsymBuildStep::command() const
+FilePath IosDsymBuildStep::command() const
{
if (m_command.isEmpty())
return defaultCommand();
return m_command;
}
-void IosDsymBuildStep::setCommand(const QString &command)
+void IosDsymBuildStep::setCommand(const FilePath &command)
{
if (command == m_command)
return;
@@ -227,9 +227,7 @@ IosDsymBuildStepConfigWidget::IosDsymBuildStepConfigWidget(IosDsymBuildStep *bui
m_ui = new Ui::IosPresetBuildStep;
m_ui->setupUi(this);
- Project *pro = m_buildStep->target()->project();
-
- m_ui->commandLineEdit->setText(m_buildStep->command());
+ m_ui->commandLineEdit->setText(m_buildStep->command().toString());
m_ui->argumentsTextEdit->setPlainText(Utils::QtcProcess::joinArgs(
m_buildStep->arguments()));
m_ui->resetDefaultsButton->setEnabled(!m_buildStep->isDefault());
@@ -246,15 +244,8 @@ IosDsymBuildStepConfigWidget::IosDsymBuildStepConfigWidget(IosDsymBuildStep *bui
this, &IosDsymBuildStepConfigWidget::updateDetails);
connect(m_buildStep->target(), &Target::kitChanged,
this, &IosDsymBuildStepConfigWidget::updateDetails);
- pro->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
- if (static_cast<BuildConfiguration *>(sender())->isActive())
- updateDetails();
- });
- connect(pro, &Project::activeProjectConfigurationChanged,
- this, [this](ProjectConfiguration *pc) {
- if (pc && pc->isActive())
- updateDetails();
- });
+ connect(m_buildStep->buildConfiguration(), &BuildConfiguration::enabledChanged,
+ this, &IosDsymBuildStepConfigWidget::updateDetails);
}
IosDsymBuildStepConfigWidget::~IosDsymBuildStepConfigWidget()
@@ -270,15 +261,14 @@ void IosDsymBuildStepConfigWidget::updateDetails()
param.setMacroExpander(bc->macroExpander());
param.setWorkingDirectory(bc->buildDirectory());
param.setEnvironment(bc->environment());
- param.setCommand(Utils::FilePath::fromString(m_buildStep->command()));
- param.setArguments(Utils::QtcProcess::joinArgs(m_buildStep->arguments()));
+ param.setCommandLine({m_buildStep->command(), m_buildStep->arguments()});
setSummaryText(param.summary(displayName()));
}
void IosDsymBuildStepConfigWidget::commandChanged()
{
- m_buildStep->setCommand(m_ui->commandLineEdit->text());
+ m_buildStep->setCommand(FilePath::fromString(m_ui->commandLineEdit->text()));
m_ui->resetDefaultsButton->setEnabled(!m_buildStep->isDefault());
updateDetails();
}
@@ -295,7 +285,7 @@ void IosDsymBuildStepConfigWidget::resetDefaults()
{
m_buildStep->setCommand(m_buildStep->defaultCommand());
m_buildStep->setArguments(m_buildStep->defaultArguments());
- m_ui->commandLineEdit->setText(m_buildStep->command());
+ m_ui->commandLineEdit->setText(m_buildStep->command().toString());
m_ui->argumentsTextEdit->setPlainText(Utils::QtcProcess::joinArgs(
m_buildStep->arguments()));
m_ui->resetDefaultsButton->setEnabled(!m_buildStep->isDefault());
diff --git a/src/plugins/ios/iosdsymbuildstep.h b/src/plugins/ios/iosdsymbuildstep.h
index 1cd8abcb29..1d03205e34 100644
--- a/src/plugins/ios/iosdsymbuildstep.h
+++ b/src/plugins/ios/iosdsymbuildstep.h
@@ -27,6 +27,8 @@
#include <projectexplorer/abstractprocessstep.h>
+#include <utils/fileutils.h>
+
namespace Ios {
namespace Internal {
namespace Ui { class IosPresetBuildStep; }
@@ -46,9 +48,9 @@ public:
void setArguments(const QStringList &args);
QStringList arguments() const;
QStringList defaultArguments() const;
- QString defaultCommand() const;
- QString command() const;
- void setCommand(const QString &command);
+ Utils::FilePath defaultCommand() const;
+ Utils::FilePath command() const;
+ void setCommand(const Utils::FilePath &command);
bool isDefault() const;
private:
@@ -61,7 +63,7 @@ private:
QStringList defaultCmdList() const;
QStringList m_arguments;
- QString m_command;
+ Utils::FilePath m_command;
bool m_clean;
};
diff --git a/src/plugins/ios/iosplugin.cpp b/src/plugins/ios/iosplugin.cpp
index 080f9dcde7..50540c331f 100644
--- a/src/plugins/ios/iosplugin.cpp
+++ b/src/plugins/ios/iosplugin.cpp
@@ -95,12 +95,21 @@ public:
IosDsymBuildStepFactory dsymBuildStepFactory;
IosDeployConfigurationFactory deployConfigurationFactory;
- SimpleRunWorkerFactory<Internal::IosRunSupport, IosRunConfiguration>
- runWorkerFactory{ProjectExplorer::Constants::NORMAL_RUN_MODE};
- SimpleRunWorkerFactory<Internal::IosDebugSupport, IosRunConfiguration>
- debugWorkerFactory{ProjectExplorer::Constants::DEBUG_RUN_MODE};
- SimpleRunWorkerFactory<Internal::IosQmlProfilerSupport, IosRunConfiguration>
- qmlProfilerWorkerFactory{ProjectExplorer::Constants::QML_PROFILER_RUN_MODE};
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<IosRunSupport>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {runConfigurationFactory.id()}
+ };
+ RunWorkerFactory debugWorkerFactory{
+ RunWorkerFactory::make<IosDebugSupport>(),
+ {ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ {runConfigurationFactory.id()}
+ };
+ RunWorkerFactory qmlProfilerWorkerFactory{
+ RunWorkerFactory::make<IosQmlProfilerSupport>(),
+ {ProjectExplorer::Constants::QML_PROFILER_RUN_MODE},
+ {runConfigurationFactory.id()}
+ };
};
IosPlugin::~IosPlugin()
@@ -110,8 +119,8 @@ IosPlugin::~IosPlugin()
bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
qRegisterMetaType<Ios::IosToolHandler::Dict>("Ios::IosToolHandler::Dict");
diff --git a/src/plugins/ios/iosprobe.cpp b/src/plugins/ios/iosprobe.cpp
index 68a2f8d9b8..38d44a5097 100644
--- a/src/plugins/ios/iosprobe.cpp
+++ b/src/plugins/ios/iosprobe.cpp
@@ -36,6 +36,8 @@
static Q_LOGGING_CATEGORY(probeLog, "qtc.ios.probe", QtWarningMsg)
+using namespace Utils;
+
namespace Ios {
static QString defaultDeveloperPath = QLatin1String("/Applications/Xcode.app/Contents/Developer");
@@ -65,8 +67,8 @@ void XcodeProbe::detectDeveloperPaths()
{
Utils::SynchronousProcess selectedXcode;
selectedXcode.setTimeoutS(5);
- Utils::SynchronousProcessResponse response = selectedXcode.run(
- QLatin1String("/usr/bin/xcode-select"), QStringList("--print-path"));
+ const CommandLine xcodeSelect{"/usr/bin/xcode-select", {"--print-path"}};
+ Utils::SynchronousProcessResponse response = selectedXcode.run(xcodeSelect);
if (response.result != Utils::SynchronousProcessResponse::Finished)
qCWarning(probeLog)
<< QString::fromLatin1("Could not detect selected Xcode using xcode-select");
diff --git a/src/plugins/ios/iosqtversion.cpp b/src/plugins/ios/iosqtversion.cpp
index e508c53cfe..23fb2c5dde 100644
--- a/src/plugins/ios/iosqtversion.cpp
+++ b/src/plugins/ios/iosqtversion.cpp
@@ -74,8 +74,8 @@ Abis IosQtVersion::detectQtAbis() const
void IosQtVersion::addToEnvironment(const Kit *k, Utils::Environment &env) const
{
- Q_UNUSED(k);
- Q_UNUSED(env);
+ Q_UNUSED(k)
+ Q_UNUSED(env)
}
QString IosQtVersion::description() const
diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp
index b9d943da11..b49f383051 100644
--- a/src/plugins/ios/iosrunconfiguration.cpp
+++ b/src/plugins/ios/iosrunconfiguration.cpp
@@ -39,9 +39,6 @@
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtoutputformatter.h>
-#include <qtsupport/qtkitinformation.h>
-
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/qtcprocess.h>
@@ -114,8 +111,6 @@ IosRunConfiguration::IosRunConfiguration(Target *target, Core::Id id)
addAspect<ArgumentsAspect>();
m_deviceTypeAspect = addAspect<IosDeviceTypeAspect>(this);
-
- setOutputFormatter<QtSupport::QtOutputFormatter>();
}
void IosDeviceTypeAspect::deviceChanges()
@@ -351,7 +346,7 @@ void IosDeviceTypeAspect::setDeviceTypeIndex(int devIndex)
void IosDeviceTypeAspect::updateValues()
{
- bool showDeviceSelector = m_runConfiguration->deviceType().type != IosDeviceType::IosDevice;
+ bool showDeviceSelector = deviceType().type != IosDeviceType::IosDevice;
m_deviceTypeLabel->setVisible(showDeviceSelector);
m_deviceTypeComboBox->setVisible(showDeviceSelector);
if (showDeviceSelector && m_deviceTypeModel.rowCount() == 0) {
@@ -364,7 +359,7 @@ void IosDeviceTypeAspect::updateValues()
}
}
- IosDeviceType currentDType = m_runConfiguration->deviceType();
+ IosDeviceType currentDType = deviceType();
QVariant currentData = m_deviceTypeComboBox->currentData();
if (currentDType.type == IosDeviceType::SimulatedDevice && !currentDType.identifier.isEmpty()
&& (!currentData.isValid()
diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h
index a5072abddf..b9b44ecf5c 100644
--- a/src/plugins/ios/iosrunconfiguration.h
+++ b/src/plugins/ios/iosrunconfiguration.h
@@ -44,7 +44,6 @@ class IosRunConfiguration : public ProjectExplorer::RunConfiguration
public:
IosRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
- Utils::FilePath profilePath() const;
QString applicationName() const;
Utils::FilePath bundleDirectory() const;
Utils::FilePath localExecutable() const;
diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp
index 5c34309921..e37d28e66b 100644
--- a/src/plugins/ios/iosrunner.cpp
+++ b/src/plugins/ios/iosrunner.cpp
@@ -44,8 +44,6 @@
#include <qmldebug/qmldebugcommandlinearguments.h>
-#include <qtsupport/qtkitinformation.h>
-
#include <utils/fileutils.h>
#include <utils/qtcprocess.h>
#include <utils/url.h>
@@ -96,10 +94,10 @@ static void stopRunningRunControl(RunControl *runControl)
IosRunner::IosRunner(RunControl *runControl)
: RunWorker(runControl)
{
+ setId("IosRunner");
stopRunningRunControl(runControl);
auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
m_bundleDir = runConfig->bundleDirectory().toString();
- m_arguments = runControl->aspect<ArgumentsAspect>()->arguments(runConfig->macroExpander());
m_device = DeviceKitAspect::device(runControl->target()->kit());
m_deviceType = runConfig->deviceType();
}
@@ -200,9 +198,13 @@ void IosRunner::start()
connect(m_toolHandler, &IosToolHandler::finished,
this, &IosRunner::handleFinished);
- QStringList args = QtcProcess::splitArgs(m_arguments, OsTypeMac);
- if (m_qmlServerPort.isValid())
- args.append(QmlDebug::qmlDebugTcpArguments(m_qmlDebugServices, m_qmlServerPort));
+ const Runnable runnable = runControl()->runnable();
+ QStringList args = QtcProcess::splitArgs(runnable.commandLineArguments, OsTypeMac);
+ if (m_qmlServerPort.isValid()) {
+ QUrl qmlServer;
+ qmlServer.setPort(m_qmlServerPort.number());
+ args.append(QmlDebug::qmlDebugTcpArguments(m_qmlDebugServices, qmlServer));
+ }
m_toolHandler->requestRunApp(bundlePath(), args, runType(), deviceId());
}
@@ -218,7 +220,8 @@ void IosRunner::handleGotServerPorts(IosToolHandler *handler, const QString &bun
Port qmlPort)
{
// Called when debugging on Device.
- Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+ Q_UNUSED(bundlePath)
+ Q_UNUSED(deviceId)
if (m_toolHandler != handler)
return;
@@ -247,7 +250,8 @@ void IosRunner::handleGotInferiorPid(IosToolHandler *handler, const QString &bun
const QString &deviceId, qint64 pid)
{
// Called when debugging on Simulator.
- Q_UNUSED(bundlePath); Q_UNUSED(deviceId);
+ Q_UNUSED(bundlePath)
+ Q_UNUSED(deviceId)
if (m_toolHandler != handler)
return;
@@ -272,7 +276,7 @@ void IosRunner::handleGotInferiorPid(IosToolHandler *handler, const QString &bun
void IosRunner::handleAppOutput(IosToolHandler *handler, const QString &output)
{
- Q_UNUSED(handler);
+ Q_UNUSED(handler)
QRegExp qmlPortRe("QML Debugger: Waiting for connection on port ([0-9]+)...");
int index = qmlPortRe.indexIn(output);
QString res(output);
@@ -284,7 +288,7 @@ void IosRunner::handleAppOutput(IosToolHandler *handler, const QString &output)
void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
{
- Q_UNUSED(handler);
+ Q_UNUSED(handler)
QString res(msg);
QString lockedErr ="Unexpected reply: ELocked (454c6f636b6564) vs OK (4f4b)";
if (msg.contains("AMDeviceStartService returned -402653150")) {
@@ -308,7 +312,7 @@ void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg)
void IosRunner::handleToolExited(IosToolHandler *handler, int code)
{
- Q_UNUSED(handler);
+ Q_UNUSED(handler)
m_cleanExit = (code == 0);
}
@@ -352,6 +356,7 @@ Utils::Port IosRunner::qmlServerPort() const
IosRunSupport::IosRunSupport(RunControl *runControl)
: IosRunner(runControl)
{
+ setId("IosRunSupport");
runControl->setIcon(Icons::RUN_SMALL_TOOLBAR);
QString displayName = QString("Run on %1").arg(device().isNull() ? QString() : device()->displayName());
runControl->setDisplayName(displayName);
@@ -380,21 +385,13 @@ void IosRunSupport::stop()
IosQmlProfilerSupport::IosQmlProfilerSupport(RunControl *runControl)
: RunWorker(runControl)
{
- setId("IosAnalyzeSupport");
-
- auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
- Runnable runnable;
- runnable.executable = iosRunConfig->localExecutable().toUserOutput();
- runnable.commandLineArguments =
- runControl->aspect<ArgumentsAspect>()->arguments(iosRunConfig->macroExpander());
- runControl->setDisplayName(iosRunConfig->applicationName());
- runControl->setRunnable(runnable);
+ setId("IosQmlProfilerSupport");
m_runner = new IosRunner(runControl);
m_runner->setQmlDebugging(QmlDebug::QmlProfilerServices);
addStartDependency(m_runner);
- m_profiler = runControl->createWorker(runControl->runMode());
+ m_profiler = runControl->createWorker(ProjectExplorer::Constants::QML_PROFILER_RUNNER);
m_profiler->addStartDependency(this);
}
@@ -423,6 +420,8 @@ void IosQmlProfilerSupport::start()
IosDebugSupport::IosDebugSupport(RunControl *runControl)
: Debugger::DebuggerRunTool(runControl)
{
+ setId("IosDebugSupport");
+
m_runner = new IosRunner(runControl);
m_runner->setCppDebugging(isCppDebugging());
m_runner->setQmlDebugging(isQmlDebugging() ? QmlDebug::QmlDebuggerServices : QmlDebug::NoQmlDebugServices);
@@ -446,13 +445,13 @@ void IosDebugSupport::start()
+ "/Library/Developer/Xcode/iOS DeviceSupport/"
+ osVersion + "/Symbols");
QString deviceSdk;
- if (deviceSdk1.toFileInfo().isDir()) {
+ if (deviceSdk1.isDir()) {
deviceSdk = deviceSdk1.toString();
} else {
const FilePath deviceSdk2 = IosConfigurations::developerPath()
.pathAppended("Platforms/iPhoneOS.platform/DeviceSupport/"
+ osVersion + "/Symbols");
- if (deviceSdk2.toFileInfo().isDir()) {
+ if (deviceSdk2.isDir()) {
deviceSdk = deviceSdk2.toString();
} else {
TaskHub::addTask(Task::Warning, tr(
@@ -480,7 +479,7 @@ void IosDebugSupport::start()
const bool cppDebug = isCppDebugging();
const bool qmlDebug = isQmlDebugging();
if (cppDebug) {
- setInferiorExecutable(iosRunConfig->localExecutable().toString());
+ setInferiorExecutable(iosRunConfig->localExecutable());
setRemoteChannel("connect://localhost:" + gdbServerPort.toString());
QString bundlePath = iosRunConfig->bundleDirectory().toString();
diff --git a/src/plugins/ios/iosrunner.h b/src/plugins/ios/iosrunner.h
index 78bff4938d..8c8fab4a60 100644
--- a/src/plugins/ios/iosrunner.h
+++ b/src/plugins/ios/iosrunner.h
@@ -83,7 +83,6 @@ private:
IosToolHandler *m_toolHandler = nullptr;
QString m_bundleDir;
- QString m_arguments;
ProjectExplorer::IDevice::ConstPtr m_device;
IosDeviceType m_deviceType;
bool m_cppDebug = false;
diff --git a/src/plugins/ios/iossettingspage.cpp b/src/plugins/ios/iossettingspage.cpp
index efe98a1012..cc1ce8e6be 100644
--- a/src/plugins/ios/iossettingspage.cpp
+++ b/src/plugins/ios/iossettingspage.cpp
@@ -35,8 +35,7 @@
namespace Ios {
namespace Internal {
-IosSettingsPage::IosSettingsPage(QObject *parent)
- : Core::IOptionsPage(parent)
+IosSettingsPage::IosSettingsPage()
{
setId(Constants::IOS_SETTINGS_ID);
setDisplayName(tr("iOS"));
diff --git a/src/plugins/ios/iossettingspage.h b/src/plugins/ios/iossettingspage.h
index 6841184ad1..fd3cb96921 100644
--- a/src/plugins/ios/iossettingspage.h
+++ b/src/plugins/ios/iossettingspage.h
@@ -39,7 +39,7 @@ class IosSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit IosSettingsPage(QObject *parent = nullptr);
+ IosSettingsPage();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/ios/iossettingswidget.cpp b/src/plugins/ios/iossettingswidget.cpp
index 467ded471d..29346b4328 100644
--- a/src/plugins/ios/iossettingswidget.cpp
+++ b/src/plugins/ios/iossettingswidget.cpp
@@ -62,9 +62,8 @@ static void onSimOperation(const SimulatorInfo &simInfo, SimulatorOperationDialo
dlg->addMessage(simInfo, response, contextStr);
}
-IosSettingsWidget::IosSettingsWidget(QWidget *parent)
- : QWidget(parent),
- m_ui(new Ui::IosSettingsWidget),
+IosSettingsWidget::IosSettingsWidget()
+ : m_ui(new Ui::IosSettingsWidget),
m_simControl(new SimulatorControl(this))
{
m_ui->setupUi(this);
diff --git a/src/plugins/ios/iossettingswidget.h b/src/plugins/ios/iossettingswidget.h
index d0dc9d0af4..535a04f45e 100644
--- a/src/plugins/ios/iossettingswidget.h
+++ b/src/plugins/ios/iossettingswidget.h
@@ -33,15 +33,13 @@ namespace Ios {
namespace Internal {
namespace Ui { class IosSettingsWidget; }
-class SimulatorInfoModel;
-using SimulatorInfoList = QList<SimulatorInfo>;
class IosSettingsWidget : public QWidget
{
Q_OBJECT
public:
- IosSettingsWidget(QWidget *parent = nullptr);
+ IosSettingsWidget();
~IosSettingsWidget() override;
void saveSettings();
diff --git a/src/plugins/ios/iossimulator.cpp b/src/plugins/ios/iossimulator.cpp
index 2312a5b10c..84eebaae0f 100644
--- a/src/plugins/ios/iossimulator.cpp
+++ b/src/plugins/ios/iossimulator.cpp
@@ -50,30 +50,22 @@ IosSimulator::IosSimulator(Core::Id id)
setupId(IDevice::AutoDetected, id);
setType(Constants::IOS_SIMULATOR_TYPE);
setMachineType(IDevice::Emulator);
- setDisplayName(QCoreApplication::translate("Ios::Internal::IosSimulator", "iOS Simulator"));
+ setOsType(Utils::OsTypeMac);
+ setDefaultDisplayName(QCoreApplication::translate("Ios::Internal::IosSimulator",
+ "iOS Simulator"));
+ setDisplayType(QCoreApplication::translate("Ios::Internal::IosSimulator", "iOS Simulator"));
setDeviceState(DeviceReadyToUse);
}
IosSimulator::IosSimulator()
- : m_lastPort(Constants::IOS_SIMULATOR_PORT_START)
-{
- setupId(IDevice::AutoDetected, Constants::IOS_SIMULATOR_DEVICE_ID);
- setType(Constants::IOS_SIMULATOR_TYPE);
- setMachineType(IDevice::Emulator);
- setDisplayName(QCoreApplication::translate("Ios::Internal::IosSimulator", "iOS Simulator"));
- setDeviceState(DeviceReadyToUse);
-}
+ : IosSimulator(Constants::IOS_SIMULATOR_DEVICE_ID)
+{}
IDevice::DeviceInfo IosSimulator::deviceInformation() const
{
return IDevice::DeviceInfo();
}
-QString IosSimulator::displayType() const
-{
- return QCoreApplication::translate("Ios::Internal::IosSimulator", "iOS Simulator");
-}
-
IDeviceWidget *IosSimulator::createWidget()
{
return nullptr;
@@ -111,11 +103,6 @@ bool IosSimulator::canAutoDetectPorts() const
return true;
}
-Utils::OsType IosSimulator::osType() const
-{
- return Utils::OsTypeMac;
-}
-
// IosDeviceType
IosDeviceType::IosDeviceType(IosDeviceType::Type type, const QString &identifier, const QString &displayName) :
diff --git a/src/plugins/ios/iossimulator.h b/src/plugins/ios/iossimulator.h
index c2a390a5fe..6d21acc4e6 100644
--- a/src/plugins/ios/iossimulator.h
+++ b/src/plugins/ios/iossimulator.h
@@ -69,12 +69,10 @@ public:
using Ptr = QSharedPointer<IosSimulator>;
ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override;
- QString displayType() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
Utils::Port nextPort() const;
bool canAutoDetectPorts() const override;
- Utils::OsType osType() const override;
protected:
friend class IosSimulatorFactory;
diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp
index 646183db05..e78ec72db4 100644
--- a/src/plugins/ios/iostoolhandler.cpp
+++ b/src/plugins/ios/iostoolhandler.cpp
@@ -818,7 +818,7 @@ IosSimulatorToolHandlerPrivate::~IosSimulatorToolHandlerPrivate()
void IosSimulatorToolHandlerPrivate::requestTransferApp(const QString &appBundlePath,
const QString &deviceIdentifier, int timeout)
{
- Q_UNUSED(timeout);
+ Q_UNUSED(timeout)
m_bundlePath = appBundlePath;
m_deviceId = deviceIdentifier;
isTransferringApp(m_bundlePath, m_deviceId, 0, 100, "");
@@ -847,8 +847,8 @@ void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
IosToolHandler::RunKind runType,
const QString &deviceIdentifier, int timeout)
{
- Q_UNUSED(timeout);
- Q_UNUSED(deviceIdentifier);
+ Q_UNUSED(timeout)
+ Q_UNUSED(deviceIdentifier)
m_bundlePath = appBundlePath;
m_deviceId = m_devType.identifier;
m_runKind = runType;
@@ -880,8 +880,8 @@ void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, int timeout)
{
- Q_UNUSED(timeout);
- Q_UNUSED(deviceId);
+ Q_UNUSED(timeout)
+ Q_UNUSED(deviceId)
}
bool IosSimulatorToolHandlerPrivate::isRunning() const
@@ -962,7 +962,7 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &ext
QThread::msleep(1000);
} while (!fi.isCanceled() && kill(pid, 0) == 0);
#else
- Q_UNUSED(pid);
+ Q_UNUSED(pid)
#endif
// Future is cancelled if the app is stopped from the qt creator.
if (!fi.isCanceled())
diff --git a/src/plugins/ios/simulatorcontrol.cpp b/src/plugins/ios/simulatorcontrol.cpp
index 1e22e3a218..5ab67f70fd 100644
--- a/src/plugins/ios/simulatorcontrol.cpp
+++ b/src/plugins/ios/simulatorcontrol.cpp
@@ -44,6 +44,7 @@
#include <QLoggingCategory>
#include <QProcess>
+using namespace Utils;
using namespace std;
namespace {
@@ -78,20 +79,20 @@ static bool checkForTimeout(const chrono::high_resolution_clock::time_point &sta
return timedOut;
}
-static bool runCommand(QString command, const QStringList &args, QString *output)
+static bool runCommand(const CommandLine &command, QString *output)
{
- Utils::SynchronousProcess p;
+ SynchronousProcess p;
p.setTimeoutS(-1);
- Utils::SynchronousProcessResponse resp = p.runBlocking(command, args);
+ SynchronousProcessResponse resp = p.runBlocking(command);
if (output)
*output = resp.stdOut();
- return resp.result == Utils::SynchronousProcessResponse::Finished;
+ return resp.result == SynchronousProcessResponse::Finished;
}
static bool runSimCtlCommand(QStringList args, QString *output)
{
args.prepend("simctl");
- return runCommand("xcrun", args, output);
+ return runCommand({"xcrun", args}, output);
}
static bool launchSimulator(const QString &simUdid) {
@@ -102,10 +103,10 @@ static bool launchSimulator(const QString &simUdid) {
if (IosConfigurations::xcodeVersion() >= QVersionNumber(9)) {
// For XCode 9 boot the second device instead of launching simulator app twice.
QString psOutput;
- if (runCommand("ps", {"-A", "-o", "comm"}, &psOutput)) {
+ if (runCommand({"ps", {"-A", "-o", "comm"}}, &psOutput)) {
for (const QString &comm : psOutput.split('\n')) {
if (comm == simulatorAppPath)
- return runSimCtlCommand(QStringList({"boot", simUdid}), nullptr);
+ return runSimCtlCommand({"boot", simUdid}, nullptr);
}
} else {
qCDebug(simulatorLog) << "Cannot start Simulator device."
diff --git a/src/plugins/languageclient/CMakeLists.txt b/src/plugins/languageclient/CMakeLists.txt
index 36040c1f5c..a1366444e5 100644
--- a/src/plugins/languageclient/CMakeLists.txt
+++ b/src/plugins/languageclient/CMakeLists.txt
@@ -18,4 +18,5 @@ add_qtc_plugin(LanguageClient
languageclientutils.cpp languageclientutils.h
languageclient_global.h
locatorfilter.cpp locatorfilter.h
+ semantichighlightsupport.cpp semantichighlightsupport.h
)
diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp
index 6e5d294bb7..a9f2d6c6e5 100644
--- a/src/plugins/languageclient/client.cpp
+++ b/src/plugins/languageclient/client.cpp
@@ -28,6 +28,7 @@
#include "languageclientinterface.h"
#include "languageclientmanager.h"
#include "languageclientutils.h"
+#include "semantichighlightsupport.h"
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
@@ -39,9 +40,10 @@
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
#include <texteditor/codeassist/documentcontentcompletion.h>
-#include <texteditor/semantichighlighter.h>
+#include <texteditor/syntaxhighlighter.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
+#include <texteditor/texteditorsettings.h>
#include <texteditor/textmark.h>
#include <texteditor/ioutlinewidget.h>
#include <utils/mimetypes/mimedatabase.h>
@@ -93,29 +95,32 @@ private:
Client::Client(BaseClientInterface *clientInterface)
: m_id(Core::Id::fromString(QUuid::createUuid().toString()))
- , m_completionProvider(this)
- , m_functionHintProvider(this)
- , m_quickFixProvider(this)
, m_clientInterface(clientInterface)
, m_documentSymbolCache(this)
, m_hoverHandler(this)
{
+ m_clientProviders.completionAssistProvider = new LanguageClientCompletionAssistProvider(this);
+ m_clientProviders.functionHintProvider = new FunctionHintAssistProvider(this);
+ m_clientProviders.quickFixAssistProvider = new LanguageClientQuickFixProvider(this);
+
m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(),
&JsonRpcMessageHandler::parseContent);
QTC_ASSERT(clientInterface, return);
connect(clientInterface, &BaseClientInterface::messageReceived, this, &Client::handleMessage);
connect(clientInterface, &BaseClientInterface::error, this, &Client::setError);
connect(clientInterface, &BaseClientInterface::finished, this, &Client::finished);
+ connect(TextEditor::TextEditorSettings::instance(),
+ &TextEditor::TextEditorSettings::fontSettingsChanged,
+ this,
+ &Client::rehighlight);
}
-static void updateEditorToolBar(QList<Utils::FilePath> files)
+static void updateEditorToolBar(QList<TextEditor::TextDocument *> documents)
{
- QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocuments(
- Utils::transform(files, [](Utils::FilePath &file) {
- return Core::DocumentModel::documentForFilePath(file.toString());
- }));
- for (auto editor : editors)
- updateEditorToolBar(editor);
+ for (TextEditor::TextDocument *document : documents) {
+ for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(document))
+ updateEditorToolBar(editor);
+ }
}
Client::~Client()
@@ -123,12 +128,8 @@ Client::~Client()
using namespace TextEditor;
// FIXME: instead of replacing the completion provider in the text document store the
// completion provider as a prioritised list in the text document
- for (TextDocument *document : m_resetAssistProvider.keys()) {
- if (document->completionAssistProvider() == &m_completionProvider)
- document->setCompletionAssistProvider(m_resetAssistProvider[document]);
- document->setFunctionHintAssistProvider(nullptr);
- document->setQuickFixAssistProvider(nullptr);
- }
+ for (TextDocument *document : m_resetAssistProvider.keys())
+ resetAssistProviders(document);
for (Core::IEditor * editor : Core::DocumentModel::editorsForOpenedDocuments()) {
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
TextEditorWidget *widget = textEditor->editorWidget();
@@ -138,6 +139,12 @@ Client::~Client()
}
for (const DocumentUri &uri : m_diagnostics.keys())
removeDiagnostics(uri);
+ for (const DocumentUri &uri : m_highlights.keys()) {
+ if (TextDocument *doc = TextDocument::textDocumentForFileName(uri.toFilePath())) {
+ if (TextEditor::SyntaxHighlighter *highlighter = doc->syntaxHighlighter())
+ highlighter->clearAllExtraFormats();
+ }
+ }
updateEditorToolBar(m_openedDocument.keys());
}
@@ -176,6 +183,10 @@ static ClientCapabilities generateClientCapabilities()
symbolCapabilities.setSymbolKind(symbolKindCapabilities);
documentCapabilities.setDocumentSymbol(symbolCapabilities);
+ TextDocumentClientCapabilities::SemanticHighlightingCapabilities semanticHighlight;
+ semanticHighlight.setSemanticHighlighting(true);
+ documentCapabilities.setSemanticHighlightingCapabilities(semanticHighlight);
+
TextDocumentClientCapabilities::CompletionCapabilities completionCapabilities;
completionCapabilities.setDynamicRegistration(true);
TextDocumentClientCapabilities::CompletionCapabilities::CompletionItemKindCapabilities
@@ -235,14 +246,14 @@ void Client::initialize()
auto params = initRequest->params().value_or(InitializeParams());
params.setCapabilities(generateClientCapabilities());
if (m_project) {
- params.setRootUri(DocumentUri::fromFileName(m_project->projectDirectory()));
+ params.setRootUri(DocumentUri::fromFilePath(m_project->projectDirectory()));
params.setWorkSpaceFolders(Utils::transform(SessionManager::projects(), [](Project *pro){
return WorkSpaceFolder(pro->projectDirectory().toString(), pro->displayName());
}));
}
initRequest->setParams(params);
initRequest->setResponseCallback([this](const InitializeRequest::Response &initResponse){
- intializeCallback(initResponse);
+ initializeCallback(initResponse);
});
// directly send data otherwise the state check would fail;
initRequest->registerResponseHandler(&m_responseHandlers);
@@ -267,78 +278,47 @@ Client::State Client::state() const
return m_state;
}
-bool Client::openDocument(Core::IDocument *document)
+void Client::openDocument(TextEditor::TextDocument *document)
{
using namespace TextEditor;
if (!isSupportedDocument(document))
- return false;
+ return;
+
+ m_openedDocument[document] = document->plainText();
+ if (m_state != Initialized)
+ return;
+
const FilePath &filePath = document->filePath();
const QString method(DidOpenTextDocumentNotification::methodName);
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
if (!registered.value())
- return false;
+ return;
const TextDocumentRegistrationOptions option(
- m_dynamicCapabilities.option(method).toObject());
+ m_dynamicCapabilities.option(method).toObject());
if (option.isValid(nullptr)
- && !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) {
- return false;
+ && !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) {
+ return;
}
} else if (Utils::optional<ServerCapabilities::TextDocumentSync> _sync
= m_serverCapabilities.textDocumentSync()) {
if (auto options = Utils::get_if<TextDocumentSyncOptions>(&_sync.value())) {
if (!options->openClose().value_or(true))
- return false;
+ return;
}
}
- auto uri = DocumentUri::fromFileName(filePath);
- showDiagnostics(uri);
- auto textDocument = qobject_cast<TextDocument *>(document);
+ connect(document, &TextDocument::contentsChangedWithPosition, this,
+ [this, document](int position, int charsRemoved, int charsAdded) {
+ documentContentsChanged(document, position, charsRemoved, charsAdded);
+ });
TextDocumentItem item;
item.setLanguageId(TextDocumentItem::mimeTypeToLanguageId(document->mimeType()));
- item.setUri(uri);
- item.setText(QString::fromUtf8(document->contents()));
- item.setVersion(textDocument ? textDocument->document()->revision() : 0);
-
- if (textDocument) {
- connect(textDocument,
- &TextEditor::TextDocument::contentsChangedWithPosition,
- this,
- [this, textDocument](int position, int charsRemoved, int charsAdded) {
- documentContentsChanged(textDocument, position, charsRemoved, charsAdded);
- });
- auto *oldCompletionProvider = qobject_cast<TextEditor::DocumentContentCompletionProvider *>(
- textDocument->completionAssistProvider());
- if (oldCompletionProvider || !textDocument->completionAssistProvider()) {
- // only replace the completion assist provider if it is the default one or null
- m_completionProvider.setTriggerCharacters(
- m_serverCapabilities.completionProvider()
- .value_or(ServerCapabilities::CompletionOptions())
- .triggerCharacters()
- .value_or(QList<QString>()));
- textDocument->setCompletionAssistProvider(&m_completionProvider);
- }
- m_resetAssistProvider[textDocument] = oldCompletionProvider;
- m_functionHintProvider.setTriggerCharacters(
- m_serverCapabilities.signatureHelpProvider()
- .value_or(ServerCapabilities::SignatureHelpOptions())
- .triggerCharacters()
- .value_or(QList<QString>()));
- textDocument->setCompletionAssistProvider(&m_completionProvider);
- textDocument->setFunctionHintAssistProvider(&m_functionHintProvider);
- textDocument->setQuickFixAssistProvider(&m_quickFixProvider);
- connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
- m_resetAssistProvider.remove(textDocument);
- });
- m_openedDocument.insert(document->filePath(), textDocument->plainText());
- } else {
- m_openedDocument.insert(document->filePath(), QString());
- }
-
+ item.setUri(DocumentUri::fromFilePath(filePath));
+ item.setText(document->plainText());
+ item.setVersion(document->document()->revision());
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
- if (textDocument)
- requestDocumentSymbols(textDocument);
- return true;
+ if (LanguageClientManager::clientForDocument(document) == this)
+ activateDocument(document);
}
void Client::sendContent(const IContent &content)
@@ -354,9 +334,11 @@ void Client::sendContent(const IContent &content)
void Client::sendContent(const DocumentUri &uri, const IContent &content)
{
- if (!m_openedDocument.contains(uri.toFileName()))
- return;
- sendContent(content);
+ if (!Utils::anyOf(m_openedDocument.keys(), [uri](TextEditor::TextDocument *documnent) {
+ return uri.toFilePath() == documnent->filePath();
+ })) {
+ sendContent(content);
+ }
}
void Client::cancelRequest(const MessageId &id)
@@ -365,19 +347,56 @@ void Client::cancelRequest(const MessageId &id)
sendContent(CancelRequest(CancelParameter(id)));
}
-void Client::closeDocument(const DidCloseTextDocumentParams &params)
+void Client::closeDocument(TextEditor::TextDocument *document)
+{
+ if (m_openedDocument.remove(document) == 0)
+ return;
+ const DocumentUri &uri = DocumentUri::fromFilePath(document->filePath());
+ const DidCloseTextDocumentParams params(TextDocumentIdentifier{uri});
+ m_highlights[uri].clear();
+ sendContent(uri, DidCloseTextDocumentNotification(params));
+ deactivateDocument(document);
+}
+
+void Client::activateDocument(TextEditor::TextDocument *document)
+{
+ auto uri = DocumentUri::fromFilePath(document->filePath());
+ showDiagnostics(uri);
+ SemanticHighligtingSupport::applyHighlight(document, m_highlights.value(uri), capabilities());
+ // only replace the assist provider if the completion provider is the default one or null
+ if (!document->completionAssistProvider()
+ || qobject_cast<TextEditor::DocumentContentCompletionProvider *>(
+ document->completionAssistProvider())) {
+ m_resetAssistProvider[document] = {document->completionAssistProvider(),
+ document->functionHintAssistProvider(),
+ document->quickFixAssistProvider()};
+ document->setCompletionAssistProvider(m_clientProviders.completionAssistProvider);
+ document->setFunctionHintAssistProvider(m_clientProviders.functionHintProvider);
+ document->setQuickFixAssistProvider(m_clientProviders.quickFixAssistProvider);
+ }
+ for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(document)) {
+ updateEditorToolBar(editor);
+ if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor))
+ textEditor->editorWidget()->addHoverHandler(hoverHandler());
+ }
+}
+
+void Client::deactivateDocument(TextEditor::TextDocument *document)
{
- sendContent(params.textDocument().uri(), DidCloseTextDocumentNotification(params));
+ hideDiagnostics(document);
+ resetAssistProviders(document);
+ if (TextEditor::SyntaxHighlighter *highlighter = document->syntaxHighlighter())
+ highlighter->clearAllExtraFormats();
}
-bool Client::documentOpen(const Core::IDocument *document) const
+bool Client::documentOpen(TextEditor::TextDocument *document) const
{
- return m_openedDocument.contains(document->filePath());
+ return m_openedDocument.contains(document);
}
-void Client::documentContentsSaved(Core::IDocument *document)
+void Client::documentContentsSaved(TextEditor::TextDocument *document)
{
- if (!m_openedDocument.contains(document->filePath()))
+ if (!m_openedDocument.contains(document))
return;
bool sendMessage = true;
bool includeText = false;
@@ -403,16 +422,17 @@ void Client::documentContentsSaved(Core::IDocument *document)
if (!sendMessage)
return;
DidSaveTextDocumentParams params(
- TextDocumentIdentifier(DocumentUri::fromFileName(document->filePath())));
+ TextDocumentIdentifier(DocumentUri::fromFilePath(document->filePath())));
if (includeText)
- params.setText(QString::fromUtf8(document->contents()));
+ params.setText(document->plainText());
sendContent(DidSaveTextDocumentNotification(params));
}
void Client::documentWillSave(Core::IDocument *document)
{
const FilePath &filePath = document->filePath();
- if (!m_openedDocument.contains(filePath))
+ auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
+ if (!m_openedDocument.contains(textDocument))
return;
bool sendMessage = true;
const QString method(WillSaveTextDocumentNotification::methodName);
@@ -433,7 +453,7 @@ void Client::documentWillSave(Core::IDocument *document)
if (!sendMessage)
return;
const WillSaveTextDocumentParams params(
- TextDocumentIdentifier(DocumentUri::fromFileName(document->filePath())));
+ TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)));
sendContent(WillSaveTextDocumentNotification(params));
}
@@ -442,7 +462,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
int charsRemoved,
int charsAdded)
{
- if (!m_openedDocument.contains(document->filePath()))
+ if (!m_openedDocument.contains(document))
return;
const QString method(DidChangeTextDocumentNotification::methodName);
TextDocumentSyncKind syncKind = m_serverCapabilities.textDocumentSyncKindHelper();
@@ -456,15 +476,16 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
}
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
+ const auto uri = DocumentUri::fromFilePath(document->filePath());
+ m_highlights[uri].clear();
if (syncKind != TextDocumentSyncKind::None) {
- const auto uri = DocumentUri::fromFileName(document->filePath());
VersionedTextDocumentIdentifier docId(uri);
docId.setVersion(textDocument ? textDocument->document()->revision() : 0);
DidChangeTextDocumentParams params;
params.setTextDocument(docId);
if (syncKind == TextDocumentSyncKind::Incremental) {
DidChangeTextDocumentParams::TextDocumentContentChangeEvent change;
- QTextDocument oldDoc(m_openedDocument[document->filePath()]);
+ QTextDocument oldDoc(m_openedDocument[document]);
QTextCursor cursor(&oldDoc);
cursor.setPosition(position + charsRemoved);
cursor.setPosition(position, QTextCursor::KeepAnchor);
@@ -475,7 +496,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
} else {
params.setContentChanges({document->plainText()});
}
- m_openedDocument[document->filePath()] = document->plainText();
+ m_openedDocument[document] = document->plainText();
sendContent(DidChangeTextDocumentNotification(params));
}
@@ -484,7 +505,6 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(textDocument))
if (TextEditorWidget *widget = editor->editorWidget())
widget->setRefactorMarkers(RefactorMarker::filterOutType(widget->refactorMarkers(), id()));
- requestDocumentSymbols(textDocument);
}
}
@@ -540,106 +560,15 @@ TextEditor::HighlightingResult createHighlightingResult(const SymbolInformation
if (!info.isValid(nullptr))
return {};
const Position &start = info.location().range().start();
- return TextEditor::HighlightingResult(start.line() + 1, start.character() + 1,
- info.name().length(), info.kind());
-}
-
-void Client::requestDocumentSymbols(TextEditor::TextDocument *document)
-{
- // TODO: Do not use this information for highlighting but the overview model
- return;
- const FilePath &filePath = document->filePath();
- bool sendMessage = m_dynamicCapabilities.isRegistered(DocumentSymbolsRequest::methodName).value_or(false);
- if (sendMessage) {
- const TextDocumentRegistrationOptions option(m_dynamicCapabilities.option(DocumentSymbolsRequest::methodName));
- if (option.isValid(nullptr))
- sendMessage = option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()));
- } else {
- sendMessage = m_serverCapabilities.documentSymbolProvider().value_or(false);
- }
- if (!sendMessage)
- return;
- DocumentSymbolsRequest request(
- DocumentSymbolParams(TextDocumentIdentifier(DocumentUri::fromFileName(filePath))));
- request.setResponseCallback(
- [doc = QPointer<TextEditor::TextDocument>(document)]
- (DocumentSymbolsRequest::Response response){
- if (!doc)
- return;
- const DocumentSymbolsResult result = response.result().value_or(DocumentSymbolsResult());
- if (!holds_alternative<QList<SymbolInformation>>(result))
- return;
- const auto &symbols = get<QList<SymbolInformation>>(result);
-
- QFutureInterface<TextEditor::HighlightingResult> future;
- for (const SymbolInformation &symbol : symbols)
- future.reportResult(createHighlightingResult(symbol));
-
- const TextEditor::FontSettings &fs = doc->fontSettings();
- QHash<int, QTextCharFormat> formatMap;
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::File )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Module )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Namespace )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Package )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Class )]
- = fs.toTextCharFormat(TextEditor::C_TYPE);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Method )]
- = fs.toTextCharFormat(TextEditor::C_FUNCTION);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Property )]
- = fs.toTextCharFormat(TextEditor::C_FIELD);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Field )]
- = fs.toTextCharFormat(TextEditor::C_FIELD);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Constructor )]
- = fs.toTextCharFormat(TextEditor::C_FUNCTION);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Enum )]
- = fs.toTextCharFormat(TextEditor::C_TYPE);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Interface )]
- = fs.toTextCharFormat(TextEditor::C_TYPE);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Function )]
- = fs.toTextCharFormat(TextEditor::C_FUNCTION);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Variable )]
- = fs.toTextCharFormat(TextEditor::C_LOCAL);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Constant )]
- = fs.toTextCharFormat(TextEditor::C_LOCAL);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::String )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Number )]
- = fs.toTextCharFormat(TextEditor::C_NUMBER);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Boolean )]
- = fs.toTextCharFormat(TextEditor::C_KEYWORD);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Array )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Object )]
- = fs.toTextCharFormat(TextEditor::C_LOCAL);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Key )]
- = fs.toTextCharFormat(TextEditor::C_LOCAL);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Null )]
- = fs.toTextCharFormat(TextEditor::C_KEYWORD);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::EnumMember )]
- = fs.toTextCharFormat(TextEditor::C_ENUMERATION);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Struct )]
- = fs.toTextCharFormat(TextEditor::C_TYPE);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Event )]
- = fs.toTextCharFormat(TextEditor::C_STRING);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::Operator )]
- = fs.toTextCharFormat(TextEditor::C_OPERATOR);
- formatMap[static_cast<int>(LanguageServerProtocol::SymbolKind::TypeParameter)]
- = fs.toTextCharFormat(TextEditor::C_LOCAL);
-
- TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
- doc->syntaxHighlighter(), future.future(), 0, future.resultCount() - 1,
- formatMap);
- });
- sendContent(request);
+ return TextEditor::HighlightingResult(start.line() + 1,
+ start.character() + 1,
+ info.name().length(),
+ info.kind());
}
void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget)
{
- const auto uri = DocumentUri::fromFileName(widget->textDocument()->filePath());
+ const auto uri = DocumentUri::fromFilePath(widget->textDocument()->filePath());
if (m_dynamicCapabilities.isRegistered(DocumentHighlightsRequest::methodName).value_or(false)) {
TextDocumentRegistrationOptions option(
m_dynamicCapabilities.option(DocumentHighlightsRequest::methodName));
@@ -690,7 +619,7 @@ void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget)
void Client::requestCodeActions(const DocumentUri &uri, const QList<Diagnostic> &diagnostics)
{
- const Utils::FilePath fileName = uri.toFileName();
+ const Utils::FilePath fileName = uri.toFilePath();
TextEditor::TextDocument *doc = TextEditor::TextDocument::textDocumentForFileName(fileName);
if (!doc)
return;
@@ -719,7 +648,7 @@ void Client::requestCodeActions(const CodeActionRequest &request)
return;
const Utils::FilePath fileName
- = request.params().value_or(CodeActionParams()).textDocument().uri().toFileName();
+ = request.params().value_or(CodeActionParams()).textDocument().uri().toFilePath();
const QString method(CodeActionRequest::methodName);
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
@@ -751,7 +680,7 @@ void Client::handleCodeActionResponse(const CodeActionRequest::Response &respons
if (auto action = Utils::get_if<CodeAction>(&item))
updateCodeActionRefactoringMarker(this, *action, uri);
else if (auto command = Utils::get_if<Command>(&item)) {
- Q_UNUSED(command); // todo
+ Q_UNUSED(command) // todo
}
}
}
@@ -827,7 +756,7 @@ void Client::setSupportedLanguage(const LanguageFilter &filter)
m_languagFilter = filter;
}
-bool Client::isSupportedDocument(const Core::IDocument *document) const
+bool Client::isSupportedDocument(const TextEditor::TextDocument *document) const
{
QTC_ASSERT(document, return false);
return m_languagFilter.isSupported(document);
@@ -840,8 +769,8 @@ bool Client::isSupportedFile(const Utils::FilePath &filePath, const QString &mim
bool Client::isSupportedUri(const DocumentUri &uri) const
{
- return m_languagFilter.isSupported(uri.toFileName(),
- Utils::mimeTypeForFile(uri.toFileName().fileName()).name());
+ return m_languagFilter.isSupported(uri.toFilePath(),
+ Utils::mimeTypeForFile(uri.toFilePath().fileName()).name());
}
bool Client::needsRestart(const BaseSettings *settings) const
@@ -914,6 +843,20 @@ void Client::log(const QString &message, Core::MessageManager::PrintToOutputPane
Core::MessageManager::write(QString("LanguageClient %1: %2").arg(name(), message), flag);
}
+void Client::showDiagnostics(Core::IDocument *doc)
+{
+ showDiagnostics(DocumentUri::fromFilePath(doc->filePath()));
+}
+
+void Client::hideDiagnostics(TextEditor::TextDocument *doc)
+{
+ if (!doc)
+ return;
+ DocumentUri uri = DocumentUri::fromFilePath(doc->filePath());
+ for (TextMark *mark : m_diagnostics.value(uri))
+ doc->removeMark(mark);
+}
+
const ServerCapabilities &Client::capabilities() const
{
return m_serverCapabilities;
@@ -975,7 +918,7 @@ void Client::showMessageBox(const ShowMessageRequestParams &message, const Messa
void Client::showDiagnostics(const DocumentUri &uri)
{
if (TextEditor::TextDocument *doc
- = TextEditor::TextDocument::textDocumentForFileName(uri.toFileName())) {
+ = TextEditor::TextDocument::textDocumentForFileName(uri.toFilePath())) {
for (TextMark *mark : m_diagnostics.value(uri))
doc->addMark(mark);
}
@@ -984,7 +927,7 @@ void Client::showDiagnostics(const DocumentUri &uri)
void Client::removeDiagnostics(const DocumentUri &uri)
{
TextEditor::TextDocument *doc
- = TextEditor::TextDocument::textDocumentForFileName(uri.toFileName());
+ = TextEditor::TextDocument::textDocumentForFileName(uri.toFilePath());
for (TextMark *mark : m_diagnostics.take(uri)) {
if (doc)
@@ -993,6 +936,17 @@ void Client::removeDiagnostics(const DocumentUri &uri)
}
}
+void Client::resetAssistProviders(TextEditor::TextDocument *document)
+{
+ const AssistProviders providers = m_resetAssistProvider.take(document);
+ if (document->completionAssistProvider() == m_clientProviders.completionAssistProvider)
+ document->setCompletionAssistProvider(providers.completionAssistProvider);
+ if (document->functionHintAssistProvider() == m_clientProviders.functionHintProvider)
+ document->setFunctionHintAssistProvider(providers.functionHintProvider);
+ if (document->quickFixAssistProvider() == m_clientProviders.quickFixAssistProvider)
+ document->setQuickFixAssistProvider(providers.quickFixAssistProvider);
+}
+
void Client::handleResponse(const MessageId &id, const QByteArray &content, QTextCodec *codec)
{
if (auto handler = m_responseHandlers[id])
@@ -1013,6 +967,11 @@ void Client::handleMethod(const QString &method, MessageId id, const IContent *c
paramsValid = params.isValid(&error);
if (paramsValid)
log(params, Core::MessageManager::Flash);
+ } else if (method == SemanticHighlightNotification::methodName) {
+ auto params = dynamic_cast<const SemanticHighlightNotification *>(content)->params().value_or(SemanticHighlightingParams());
+ paramsValid = params.isValid(&error);
+ if (paramsValid)
+ handleSemanticHighlight(params);
} else if (method == ShowMessageNotification::methodName) {
auto params = dynamic_cast<const ShowMessageNotification *>(content)->params().value_or(ShowMessageParams());
paramsValid = params.isValid(&error);
@@ -1087,15 +1046,50 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams &params)
removeDiagnostics(uri);
const QList<Diagnostic> &diagnostics = params.diagnostics();
m_diagnostics[uri] =
- Utils::transform(diagnostics, [fileName = uri.toFileName()](const Diagnostic &diagnostic) {
+ Utils::transform(diagnostics, [fileName = uri.toFilePath()](const Diagnostic &diagnostic) {
return new TextMark(fileName, diagnostic);
});
- showDiagnostics(uri);
+ // TextMarks are already added in the TextEditor::TextMark constructor
+ // so hide them if we are not the active client for this document
+ if (LanguageClientManager::clientForUri(uri) != this)
+ hideDiagnostics(TextEditor::TextDocument::textDocumentForFileName(uri.toFilePath()));
+ else
+ requestCodeActions(uri, diagnostics);
+}
+
+void Client::handleSemanticHighlight(const SemanticHighlightingParams &params)
+{
+ const DocumentUri &uri = params.textDocument().uri();
+ m_highlights[uri].clear();
+ const LanguageClientValue<int> &version = params.textDocument().version();
+ TextEditor::TextDocument *doc = TextEditor::TextDocument::textDocumentForFileName(
+ uri.toFilePath());
+
+ if (!doc || LanguageClientManager::clientForDocument(doc) != this
+ || (!version.isNull() && doc->document()->revision() != version.value())) {
+ return;
+ }
+
+ const TextEditor::HighlightingResults results = SemanticHighligtingSupport::generateResults(
+ params.lines());
+
+ m_highlights[uri] = results;
- requestCodeActions(uri, diagnostics);
+ SemanticHighligtingSupport::applyHighlight(doc, results, capabilities());
}
-void Client::intializeCallback(const InitializeRequest::Response &initResponse)
+void Client::rehighlight()
+{
+ using namespace TextEditor;
+ for (auto it = m_highlights.begin(), end = m_highlights.end(); it != end; ++it) {
+ if (TextDocument *doc = TextDocument::textDocumentForFileName(it.key().toFilePath())) {
+ if (LanguageClientManager::clientForDocument(doc) == this)
+ SemanticHighligtingSupport::applyHighlight(doc, it.value(), capabilities());
+ }
+ }
+}
+
+void Client::initializeCallback(const InitializeRequest::Response &initResponse)
{
QTC_ASSERT(m_state == InitializeRequested, return);
if (optional<ResponseError<InitializeError>> error = initResponse.error()) {
@@ -1130,23 +1124,35 @@ void Client::intializeCallback(const InitializeRequest::Response &initResponse)
m_serverCapabilities = result.capabilities().value_or(ServerCapabilities());
}
+
+ if (auto completionProvider = qobject_cast<LanguageClientCompletionAssistProvider *>(
+ m_clientProviders.completionAssistProvider)) {
+ completionProvider->setTriggerCharacters(
+ m_serverCapabilities.completionProvider()
+ .value_or(ServerCapabilities::CompletionOptions())
+ .triggerCharacters()
+ .value_or(QList<QString>()));
+ }
+ if (auto functionHintAssistProvider = qobject_cast<FunctionHintAssistProvider *>(
+ m_clientProviders.completionAssistProvider)) {
+ functionHintAssistProvider->setTriggerCharacters(
+ m_serverCapabilities.signatureHelpProvider()
+ .value_or(ServerCapabilities::SignatureHelpOptions())
+ .triggerCharacters()
+ .value_or(QList<QString>()));
+ }
+
qCDebug(LOGLSPCLIENT) << "language server " << m_displayName << " initialized";
m_state = Initialized;
sendContent(InitializeNotification());
- for (auto openedDocument : Core::DocumentModel::openedDocuments()) {
- if (openDocument(openedDocument)) {
- for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(openedDocument))
- updateEditorToolBar(editor);
- }
- }
- for (Core::IEditor *editor : Core::DocumentModel::editorsForOpenedDocuments()) {
- if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor))
- textEditor->editorWidget()->addHoverHandler(&m_hoverHandler);
- }
if (m_dynamicCapabilities.isRegistered(DocumentSymbolsRequest::methodName)
.value_or(capabilities().documentSymbolProvider().value_or(false))) {
TextEditor::IOutlineWidgetFactory::updateOutline();
}
+
+ for (TextEditor::TextDocument *document : m_openedDocument.keys())
+ openDocument(document);
+
emit initialized(m_serverCapabilities);
}
diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h
index 9746607e62..ab874e8569 100644
--- a/src/plugins/languageclient/client.h
+++ b/src/plugins/languageclient/client.h
@@ -27,6 +27,7 @@
#include "documentsymbolcache.h"
#include "dynamiccapabilities.h"
+#include "languageclient_global.h"
#include "languageclientcompletionassist.h"
#include "languageclientfunctionhint.h"
#include "languageclientquickfix.h"
@@ -45,6 +46,8 @@
#include <languageserverprotocol/shutdownmessages.h>
#include <languageserverprotocol/textsynchronization.h>
+#include <texteditor/semantichighlighter.h>
+
#include <QBuffer>
#include <QHash>
#include <QProcess>
@@ -65,7 +68,7 @@ namespace LanguageClient {
class BaseClientInterface;
class TextMark;
-class Client : public QObject
+class LANGUAGECLIENT_EXPORT Client : public QObject
{
Q_OBJECT
@@ -93,10 +96,12 @@ public:
bool reachable() const { return m_state == Initialized; }
// document synchronization
- bool openDocument(Core::IDocument *document);
- void closeDocument(const LanguageServerProtocol::DidCloseTextDocumentParams &params);
- bool documentOpen(const Core::IDocument *document) const;
- void documentContentsSaved(Core::IDocument *document);
+ void openDocument(TextEditor::TextDocument *document);
+ void closeDocument(TextEditor::TextDocument *document);
+ void activateDocument(TextEditor::TextDocument *document);
+ void deactivateDocument(TextEditor::TextDocument *document);
+ bool documentOpen(TextEditor::TextDocument *document) const;
+ void documentContentsSaved(TextEditor::TextDocument *document);
void documentWillSave(Core::IDocument *document);
void documentContentsChanged(TextEditor::TextDocument *document,
int position,
@@ -106,7 +111,6 @@ public:
void unregisterCapabilities(const QList<LanguageServerProtocol::Unregistration> &unregistrations);
bool findLinkAt(LanguageServerProtocol::GotoDefinitionRequest &request);
bool findUsages(LanguageServerProtocol::FindReferencesRequest &request);
- void requestDocumentSymbols(TextEditor::TextDocument *document);
void cursorPositionChanged(TextEditor::TextEditorWidget *widget);
void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri,
@@ -128,7 +132,7 @@ public:
void cancelRequest(const LanguageServerProtocol::MessageId &id);
void setSupportedLanguage(const LanguageFilter &filter);
- bool isSupportedDocument(const Core::IDocument *document) const;
+ bool isSupportedDocument(const TextEditor::TextDocument *document) const;
bool isSupportedFile(const Utils::FilePath &filePath, const QString &mimeType) const;
bool isSupportedUri(const LanguageServerProtocol::DocumentUri &uri) const;
@@ -153,11 +157,15 @@ public:
Core::MessageManager::PrintToOutputPaneFlag flag = Core::MessageManager::NoModeSwitch)
{ log(responseError.toString(), flag); }
+ void showDiagnostics(Core::IDocument *doc);
+ void hideDiagnostics(TextEditor::TextDocument *doc);
+
const LanguageServerProtocol::ServerCapabilities &capabilities() const;
const DynamicCapabilities &dynamicCapabilities() const;
const BaseClientInterface *clientInterface() const;
DocumentSymbolCache *documentSymbolCache();
HoverHandler *hoverHandler();
+ void rehighlight();
signals:
void initialized(LanguageServerProtocol::ServerCapabilities capabilities);
@@ -174,8 +182,9 @@ private:
const LanguageServerProtocol::IContent *content);
void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams &params);
+ void handleSemanticHighlight(const LanguageServerProtocol::SemanticHighlightingParams &params);
- void intializeCallback(const LanguageServerProtocol::InitializeRequest::Response &initResponse);
+ void initializeCallback(const LanguageServerProtocol::InitializeRequest::Response &initResponse);
void shutDownCallback(const LanguageServerProtocol::ShutdownRequest::Response &shutdownResponse);
bool sendWorkspceFolderChanges() const;
void log(const LanguageServerProtocol::ShowMessageParams &message,
@@ -186,6 +195,7 @@ private:
void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
+ void resetAssistProviders(TextEditor::TextDocument *document);
using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &,
LanguageServerProtocol::ResponseHandlers,
@@ -196,20 +206,26 @@ private:
QHash<QByteArray, ContentHandler> m_contentHandler;
QString m_displayName;
LanguageFilter m_languagFilter;
- QMap<Utils::FilePath, QString> m_openedDocument;
+ QMap<TextEditor::TextDocument *, QString> m_openedDocument;
Core::Id m_id;
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
DynamicCapabilities m_dynamicCapabilities;
- LanguageClientCompletionAssistProvider m_completionProvider;
- FunctionHintAssistProvider m_functionHintProvider;
- LanguageClientQuickFixProvider m_quickFixProvider;
- QMap<TextEditor::TextDocument *, QPointer<TextEditor::CompletionAssistProvider>> m_resetAssistProvider;
+ struct AssistProviders
+ {
+ QPointer<TextEditor::CompletionAssistProvider> completionAssistProvider;
+ QPointer<TextEditor::CompletionAssistProvider> functionHintProvider;
+ QPointer<TextEditor::IAssistProvider> quickFixAssistProvider;
+ };
+
+ AssistProviders m_clientProviders;
+ QMap<TextEditor::TextDocument *, AssistProviders> m_resetAssistProvider;
QHash<LanguageServerProtocol::DocumentUri, LanguageServerProtocol::MessageId> m_highlightRequests;
int m_restartsLeft = 5;
QScopedPointer<BaseClientInterface> m_clientInterface;
QMap<LanguageServerProtocol::DocumentUri, QList<TextMark *>> m_diagnostics;
DocumentSymbolCache m_documentSymbolCache;
HoverHandler m_hoverHandler;
+ QHash<LanguageServerProtocol::DocumentUri, TextEditor::HighlightingResults> m_highlights;
const ProjectExplorer::Project *m_project = nullptr;
};
diff --git a/src/plugins/languageclient/documentsymbolcache.cpp b/src/plugins/languageclient/documentsymbolcache.cpp
index b922486d56..e56f534636 100644
--- a/src/plugins/languageclient/documentsymbolcache.cpp
+++ b/src/plugins/languageclient/documentsymbolcache.cpp
@@ -43,7 +43,7 @@ DocumentSymbolCache::DocumentSymbolCache(Client *client)
this,
[this](Core::IDocument *document) {
connect(document, &Core::IDocument::contentsChanged, this, [this, document]() {
- m_cache.remove(DocumentUri::fromFileName(document->filePath()));
+ m_cache.remove(DocumentUri::fromFilePath(document->filePath()));
});
});
}
diff --git a/src/plugins/languageclient/languageclient.pro b/src/plugins/languageclient/languageclient.pro
index b2d39acf16..755c0bcc29 100644
--- a/src/plugins/languageclient/languageclient.pro
+++ b/src/plugins/languageclient/languageclient.pro
@@ -17,7 +17,8 @@ HEADERS += \
languageclientquickfix.h \
languageclientsettings.h \
languageclientutils.h \
- locatorfilter.h
+ locatorfilter.h \
+ semantichighlightsupport.h
SOURCES += \
@@ -34,7 +35,8 @@ SOURCES += \
languageclientquickfix.cpp \
languageclientsettings.cpp \
languageclientutils.cpp \
- locatorfilter.cpp
+ locatorfilter.cpp \
+ semantichighlightsupport.cpp
RESOURCES += \
languageclient.qrc
diff --git a/src/plugins/languageclient/languageclient.qbs b/src/plugins/languageclient/languageclient.qbs
index 13ca210570..5ff9c34075 100644
--- a/src/plugins/languageclient/languageclient.qbs
+++ b/src/plugins/languageclient/languageclient.qbs
@@ -44,5 +44,7 @@ QtcPlugin {
"languageclientutils.h",
"locatorfilter.cpp",
"locatorfilter.h",
+ "semantichighlightsupport.cpp",
+ "semantichighlightsupport.h",
]
}
diff --git a/src/plugins/languageclient/languageclient_global.h b/src/plugins/languageclient/languageclient_global.h
index 685379804d..7df176603f 100644
--- a/src/plugins/languageclient/languageclient_global.h
+++ b/src/plugins/languageclient/languageclient_global.h
@@ -27,6 +27,12 @@
#include <QtGlobal>
+#if defined(LANGUAGECLIENT_LIBRARY)
+# define LANGUAGECLIENT_EXPORT Q_DECL_EXPORT
+#else
+# define LANGUAGECLIENT_EXPORT Q_DECL_IMPORT
+#endif
+
namespace LanguageClient {
namespace Constants {
diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp
index a036f7beb3..91a77d6b7b 100644
--- a/src/plugins/languageclient/languageclientcompletionassist.cpp
+++ b/src/plugins/languageclient/languageclientcompletionassist.cpp
@@ -330,7 +330,7 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistIn
params.setPosition({line, column});
params.setContext(context);
params.setTextDocument(
- DocumentUri::fromFileName(Utils::FilePath::fromString(interface->fileName())));
+ DocumentUri::fromFilePath(Utils::FilePath::fromString(interface->fileName())));
completionRequest.setResponseCallback([this](auto response) {
this->handleCompletionResponse(response);
});
@@ -385,7 +385,8 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
}
LanguageClientCompletionAssistProvider::LanguageClientCompletionAssistProvider(Client *client)
- : m_client(client)
+ : CompletionAssistProvider(client)
+ , m_client(client)
{ }
IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor() const
diff --git a/src/plugins/languageclient/languageclientcompletionassist.h b/src/plugins/languageclient/languageclientcompletionassist.h
index f0ad95bc88..828a33ec75 100644
--- a/src/plugins/languageclient/languageclientcompletionassist.h
+++ b/src/plugins/languageclient/languageclientcompletionassist.h
@@ -33,6 +33,8 @@ class Client;
class LanguageClientCompletionAssistProvider : public TextEditor::CompletionAssistProvider
{
+ Q_OBJECT
+
public:
LanguageClientCompletionAssistProvider(Client *client);
diff --git a/src/plugins/languageclient/languageclientfunctionhint.cpp b/src/plugins/languageclient/languageclientfunctionhint.cpp
index 9a1fe6fc8e..5e711adec6 100644
--- a/src/plugins/languageclient/languageclientfunctionhint.cpp
+++ b/src/plugins/languageclient/languageclientfunctionhint.cpp
@@ -82,7 +82,7 @@ IAssistProposal *FunctionHintProcessor::perform(const AssistInterface *interface
m_pos = interface->position();
QTextCursor cursor(interface->textDocument());
cursor.setPosition(m_pos);
- auto uri = DocumentUri::fromFileName(Utils::FilePath::fromString(interface->fileName()));
+ auto uri = DocumentUri::fromFilePath(Utils::FilePath::fromString(interface->fileName()));
SignatureHelpRequest request;
request.setParams(TextDocumentPositionParams(TextDocumentIdentifier(uri), Position(cursor)));
request.setResponseCallback([this](auto response) { this->handleSignatureResponse(response); });
@@ -102,7 +102,8 @@ void FunctionHintProcessor::handleSignatureResponse(const SignatureHelpRequest::
}
FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client)
- : m_client(client)
+ : CompletionAssistProvider(client)
+ , m_client(client)
{}
TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor() const
diff --git a/src/plugins/languageclient/languageclientfunctionhint.h b/src/plugins/languageclient/languageclientfunctionhint.h
index cf5f96d812..d7547894f1 100644
--- a/src/plugins/languageclient/languageclientfunctionhint.h
+++ b/src/plugins/languageclient/languageclientfunctionhint.h
@@ -33,6 +33,8 @@ class Client;
class FunctionHintAssistProvider : public TextEditor::CompletionAssistProvider
{
+ Q_OBJECT
+
public:
explicit FunctionHintAssistProvider(Client *client);
diff --git a/src/plugins/languageclient/languageclienthoverhandler.cpp b/src/plugins/languageclient/languageclienthoverhandler.cpp
index 166fdc3049..9f4fc3ad37 100644
--- a/src/plugins/languageclient/languageclienthoverhandler.cpp
+++ b/src/plugins/languageclient/languageclienthoverhandler.cpp
@@ -86,7 +86,7 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
}
m_report = report;
- auto uri = DocumentUri::fromFileName(editorWidget->textDocument()->filePath());
+ auto uri = DocumentUri::fromFilePath(editorWidget->textDocument()->filePath());
QTextCursor cursor = editorWidget->textCursor();
cursor.setPosition(pos);
TextDocumentPositionParams params(uri, Position(cursor));
diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp
index 7313a5bd3f..c4af8fcd0e 100644
--- a/src/plugins/languageclient/languageclientmanager.cpp
+++ b/src/plugins/languageclient/languageclientmanager.cpp
@@ -38,6 +38,7 @@
#include <texteditor/texteditor.h>
#include <texteditor/textmark.h>
#include <texteditor/textdocument.h>
+#include <utils/executeondestruction.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/theme/theme.h>
#include <utils/utilsicons.h>
@@ -57,6 +58,7 @@ LanguageClientManager::LanguageClientManager(QObject *parent)
using namespace Core;
using namespace ProjectExplorer;
JsonRpcMessageHandler::registerMessageProvider<PublishDiagnosticsNotification>();
+ JsonRpcMessageHandler::registerMessageProvider<SemanticHighlightNotification>();
JsonRpcMessageHandler::registerMessageProvider<ApplyWorkspaceEditRequest>();
JsonRpcMessageHandler::registerMessageProvider<LogMessageNotification>();
JsonRpcMessageHandler::registerMessageProvider<ShowMessageRequest>();
@@ -117,16 +119,17 @@ void LanguageClientManager::startClient(Client *client)
&DocumentLocatorFilter::updateCurrentClient);
}
-void LanguageClientManager::startClient(BaseSettings *setting, ProjectExplorer::Project *project)
+Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplorer::Project *project)
{
- QTC_ASSERT(managerInstance, return);
- QTC_ASSERT(setting, return);
- QTC_ASSERT(setting->isValid(), return);
+ QTC_ASSERT(managerInstance, return nullptr);
+ QTC_ASSERT(setting, return nullptr);
+ QTC_ASSERT(setting->isValid(), return nullptr);
Client *client = setting->createClient();
- QTC_ASSERT(client, return);
+ QTC_ASSERT(client, return nullptr);
client->setCurrentProject(project);
startClient(client);
managerInstance->m_clientsForSetting[setting->m_id].append(client);
+ return client;
}
QVector<Client *> LanguageClientManager::clients()
@@ -195,8 +198,7 @@ LanguageClientManager *LanguageClientManager::instance()
return managerInstance;
}
-QList<Client *> LanguageClientManager::clientsSupportingDocument(
- const TextEditor::TextDocument *doc)
+QList<Client *> LanguageClientManager::clientsSupportingDocument(const TextEditor::TextDocument *doc)
{
QTC_ASSERT(managerInstance, return {});
QTC_ASSERT(doc, return {};);
@@ -209,34 +211,47 @@ void LanguageClientManager::applySettings()
{
QTC_ASSERT(managerInstance, return);
qDeleteAll(managerInstance->m_currentSettings);
- managerInstance->m_currentSettings = Utils::transform(LanguageClientSettings::currentPageSettings(),
- [](BaseSettings *settings) {
- return settings->copy();
- });
+ managerInstance->m_currentSettings
+ = Utils::transform(LanguageClientSettings::currentPageSettings(), &BaseSettings::copy);
LanguageClientSettings::toSettings(Core::ICore::settings(), managerInstance->m_currentSettings);
const QList<BaseSettings *> restarts = Utils::filtered(managerInstance->m_currentSettings,
- [](BaseSettings *settings) {
- return settings->needsRestart();
- });
+ &BaseSettings::needsRestart);
for (BaseSettings *setting : restarts) {
- for (Client *client : clientForSetting(setting))
+ QList<TextEditor::TextDocument *> documents;
+ for (Client *client : clientForSetting(setting)) {
+ documents << managerInstance->m_clientForDocument.keys(client);
shutdownClient(client);
+ }
+ for (auto document : documents)
+ managerInstance->m_clientForDocument.remove(document);
if (!setting->isValid() || !setting->m_enabled)
continue;
switch (setting->m_startBehavior) {
- case BaseSettings::AlwaysOn:
- startClient(setting);
+ case BaseSettings::AlwaysOn: {
+ Client *client = startClient(setting);
+ for (TextEditor::TextDocument *document : documents)
+ managerInstance->m_clientForDocument[document] = client;
break;
- case BaseSettings::RequiresFile:
- if (Utils::anyOf(Core::DocumentModel::openedDocuments(),
- [filter = setting->m_languageFilter](Core::IDocument *doc) {
- return filter.isSupported(doc);
- })) {
- startClient(setting);
+ }
+ case BaseSettings::RequiresFile: {
+ for (Core::IDocument *document : Core::DocumentModel::openedDocuments()) {
+ if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(document)) {
+ if (setting->m_languageFilter.isSupported(document))
+ documents << textDocument;
+ }
+ }
+ if (!documents.isEmpty()) {
+ Client *client = startClient(setting);
+ for (TextEditor::TextDocument *document : documents) {
+ if (managerInstance->m_clientForDocument.value(document).isNull())
+ managerInstance->m_clientForDocument[document] = client;
+ client->openDocument(document);
+ }
}
break;
+ }
case BaseSettings::RequiresProject: {
for (Core::IDocument *doc : Core::DocumentModel::openedDocuments()) {
if (setting->m_languageFilter.isSupported(doc)) {
@@ -262,6 +277,13 @@ QList<BaseSettings *> LanguageClientManager::currentSettings()
return managerInstance->m_currentSettings;
}
+void LanguageClientManager::registerClientSettings(BaseSettings *settings)
+{
+ QTC_ASSERT(managerInstance, return);
+ LanguageClientSettings::addSettings(settings);
+ managerInstance->applySettings();
+}
+
QVector<Client *> LanguageClientManager::clientForSetting(const BaseSettings *setting)
{
QTC_ASSERT(managerInstance, return {});
@@ -285,18 +307,30 @@ const BaseSettings *LanguageClientManager::settingForClient(Client *client)
return nullptr;
}
-Client *LanguageClientManager::clientForEditor(Core::IEditor *iEditor)
+Client *LanguageClientManager::clientForDocument(TextEditor::TextDocument *document)
{
QTC_ASSERT(managerInstance, return nullptr);
+ return document == nullptr ? nullptr
+ : managerInstance->m_clientForDocument.value(document).data();
+}
- auto editor = qobject_cast<TextEditor::BaseTextEditor *>(iEditor);
- if (!editor)
- return nullptr;
+Client *LanguageClientManager::clientForFilePath(const Utils::FilePath &filePath)
+{
+ return clientForDocument(TextEditor::TextDocument::textDocumentForFileName(filePath));
+}
- return Utils::findOrDefault(managerInstance->reachableClients(),
- [doc = editor->textDocument()](Client *client) {
- return client->documentOpen(doc);
- });
+Client *LanguageClientManager::clientForUri(const DocumentUri &uri)
+{
+ return clientForFilePath(uri.toFilePath());
+}
+
+void LanguageClientManager::reOpenDocumentWithClient(TextEditor::TextDocument *document, Client *client)
+{
+ Utils::ExecuteOnDestruction outlineUpdater(&TextEditor::IOutlineWidgetFactory::updateOutline);
+ if (Client *currentClient = clientForDocument(document))
+ currentClient->deactivateDocument(document);
+ managerInstance->m_clientForDocument[document] = client;
+ client->activateDocument(document);
}
QVector<Client *> LanguageClientManager::reachableClients()
@@ -328,6 +362,8 @@ void LanguageClientManager::clientFinished(Client *client)
} else {
if (unexpectedFinish && !m_shuttingDown)
client->log(tr("Unexpectedly finished."), Core::MessageManager::Flash);
+ for (TextEditor::TextDocument *document : m_clientForDocument.keys(client))
+ m_clientForDocument.remove(document);
deleteClient(client);
if (m_shuttingDown && m_clients.isEmpty())
emit shutdownFinished();
@@ -340,39 +376,41 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor)
if (auto *textEditor = qobject_cast<BaseTextEditor *>(editor)) {
if (TextEditorWidget *widget = textEditor->editorWidget()) {
connect(widget, &TextEditorWidget::requestLinkAt, this,
- [this, filePath = editor->document()->filePath()]
+ [this, document = textEditor->textDocument()]
(const QTextCursor &cursor, Utils::ProcessLinkCallback &callback) {
- findLinkAt(filePath, cursor, callback);
+ findLinkAt(document, cursor, callback);
});
connect(widget, &TextEditorWidget::requestUsages, this,
- [this, filePath = editor->document()->filePath()]
- (const QTextCursor &cursor){
- findUsages(filePath, cursor);
- });
- connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget](){
- // TODO This would better be a compressing timer
- QTimer::singleShot(50, this,
- [this, widget = QPointer<TextEditorWidget>(widget)]() {
- if (widget) {
- for (Client *client : this->reachableClients()) {
- if (client->isSupportedDocument(widget->textDocument()))
- client->cursorPositionChanged(widget);
- }
- }
- });
+ [this, document = textEditor->textDocument()](const QTextCursor &cursor) {
+ findUsages(document, cursor);
});
+ connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget]() {
+ // TODO This would better be a compressing timer
+ QTimer::singleShot(50, this, [widget = QPointer<TextEditorWidget>(widget)]() {
+ if (!widget)
+ return;
+ if (Client *client = clientForDocument(widget->textDocument()))
+ client->cursorPositionChanged(widget);
+ });
+ });
updateEditorToolBar(editor);
- for (auto client : reachableClients())
- widget->addHoverHandler(client->hoverHandler());
+ if (TextEditor::TextDocument *document = textEditor->textDocument()) {
+ if (Client *client = m_clientForDocument[document])
+ widget->addHoverHandler(client->hoverHandler());
+ }
}
}
}
void LanguageClientManager::documentOpened(Core::IDocument *document)
{
+ auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
+ if (!textDocument)
+ return;
+
// check whether we have to start servers for this document
for (BaseSettings *setting : LanguageClientSettings::currentPageSettings()) {
- const QVector<Client *> clients = clientForSetting(setting);
+ QVector<Client *> clients = clientForSetting(setting);
if (setting->isValid() && setting->m_enabled
&& setting->m_languageFilter.isSupported(document)) {
if (setting->m_startBehavior == BaseSettings::RequiresProject) {
@@ -390,45 +428,60 @@ void LanguageClientManager::documentOpened(Core::IDocument *document)
})) {
continue;
}
- startClient(setting, project);
+ clients << startClient(setting, project);
}
} else if (setting->m_startBehavior == BaseSettings::RequiresFile && clients.isEmpty()) {
- startClient(setting);
+ clients << startClient(setting);
+ }
+ for (auto client : clients) {
+ openDocumentWithClient(textDocument, client);
+ if (!m_clientForDocument.contains(textDocument))
+ m_clientForDocument[textDocument] = client;
}
}
}
- for (Client *interface : reachableClients())
- interface->openDocument(document);
+}
+
+void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *document,
+ Client *client)
+{
+ if (client && client->state() != Client::Error)
+ client->openDocument(document);
}
void LanguageClientManager::documentClosed(Core::IDocument *document)
{
- const DidCloseTextDocumentParams params(
- TextDocumentIdentifier(DocumentUri::fromFileName(document->filePath())));
- for (Client *interface : reachableClients())
- interface->closeDocument(params);
+ if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(document)) {
+ for (Client *client : reachableClients())
+ client->closeDocument(textDocument);
+ m_clientForDocument.remove(textDocument);
+ }
}
void LanguageClientManager::documentContentsSaved(Core::IDocument *document)
{
- for (Client *interface : reachableClients())
- interface->documentContentsSaved(document);
+ if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(document)) {
+ for (Client *interface : reachableClients())
+ interface->documentContentsSaved(textDocument);
+ }
}
void LanguageClientManager::documentWillSave(Core::IDocument *document)
{
- for (Client *interface : reachableClients())
- interface->documentWillSave(document);
+ if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(document)) {
+ for (Client *interface : reachableClients())
+ interface->documentWillSave(textDocument);
+ }
}
-void LanguageClientManager::findLinkAt(const Utils::FilePath &filePath,
+void LanguageClientManager::findLinkAt(TextEditor::TextDocument *document,
const QTextCursor &cursor,
Utils::ProcessLinkCallback callback)
{
- const DocumentUri uri = DocumentUri::fromFileName(filePath);
- const TextDocumentIdentifier document(uri);
+ const DocumentUri uri = DocumentUri::fromFilePath(document->filePath());
+ const TextDocumentIdentifier documentId(uri);
const Position pos(cursor);
- TextDocumentPositionParams params(document, pos);
+ TextDocumentPositionParams params(documentId, pos);
GotoDefinitionRequest request(params);
request.setResponseCallback([callback](const GotoDefinitionRequest::Response &response){
if (Utils::optional<GotoResult> _result = response.result()) {
@@ -462,7 +515,7 @@ QList<Core::SearchResultItem> generateSearchResultItems(const LanguageClientArra
return result;
QMap<QString, QList<Core::Search::TextRange>> rangesInDocument;
for (const Location &location : locations.toList())
- rangesInDocument[location.uri().toFileName().toString()] << convertRange(location.range());
+ rangesInDocument[location.uri().toFilePath().toString()] << convertRange(location.range());
for (auto it = rangesInDocument.begin(); it != rangesInDocument.end(); ++it) {
const QString &fileName = it.key();
QFile file(fileName);
@@ -485,14 +538,14 @@ QList<Core::SearchResultItem> generateSearchResultItems(const LanguageClientArra
return result;
}
-void LanguageClientManager::findUsages(const Utils::FilePath &filePath, const QTextCursor &cursor)
+void LanguageClientManager::findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor)
{
- const DocumentUri uri = DocumentUri::fromFileName(filePath);
- const TextDocumentIdentifier document(uri);
+ const DocumentUri uri = DocumentUri::fromFilePath(document->filePath());
+ const TextDocumentIdentifier documentId(uri);
const Position pos(cursor);
QTextCursor termCursor(cursor);
termCursor.select(QTextCursor::WordUnderCursor);
- ReferenceParams params(TextDocumentPositionParams(document, pos));
+ ReferenceParams params(TextDocumentPositionParams(documentId, pos));
params.setContext(ReferenceParams::ReferenceContext(true));
FindReferencesRequest request(params);
auto callback = [this, wordUnderCursor = termCursor.selectedText()]
diff --git a/src/plugins/languageclient/languageclientmanager.h b/src/plugins/languageclient/languageclientmanager.h
index 6be720697f..6aba7594b5 100644
--- a/src/plugins/languageclient/languageclientmanager.h
+++ b/src/plugins/languageclient/languageclientmanager.h
@@ -26,6 +26,7 @@
#pragma once
#include "client.h"
+#include "languageclient_global.h"
#include "languageclientsettings.h"
#include "locatorfilter.h"
@@ -46,7 +47,7 @@ namespace LanguageClient {
class LanguageClientMark;
-class LanguageClientManager : public QObject
+class LANGUAGECLIENT_EXPORT LanguageClientManager : public QObject
{
Q_OBJECT
public:
@@ -57,7 +58,7 @@ public:
static void init();
static void startClient(Client *client);
- static void startClient(BaseSettings *setting, ProjectExplorer::Project *project = nullptr);
+ static Client *startClient(BaseSettings *setting, ProjectExplorer::Project *project = nullptr);
static QVector<Client *> clients();
static void addExclusiveRequest(const LanguageServerProtocol::MessageId &id, Client *client);
@@ -74,9 +75,13 @@ public:
static void applySettings();
static QList<BaseSettings *> currentSettings();
+ static void registerClientSettings(BaseSettings *settings);
static QVector<Client *> clientForSetting(const BaseSettings *setting);
static const BaseSettings *settingForClient(Client *setting);
- static Client *clientForEditor(Core::IEditor *editor);
+ static Client *clientForDocument(TextEditor::TextDocument *document);
+ static Client *clientForFilePath(const Utils::FilePath &filePath);
+ static Client *clientForUri(const LanguageServerProtocol::DocumentUri &uri);
+ static void reOpenDocumentWithClient(TextEditor::TextDocument *document, Client *client);
signals:
void shutdownFinished();
@@ -86,12 +91,13 @@ private:
void editorOpened(Core::IEditor *editor);
void documentOpened(Core::IDocument *document);
+ void openDocumentWithClient(TextEditor::TextDocument *document, Client *client);
void documentClosed(Core::IDocument *document);
void documentContentsSaved(Core::IDocument *document);
void documentWillSave(Core::IDocument *document);
- void findLinkAt(const Utils::FilePath &filePath, const QTextCursor &cursor,
+ void findLinkAt(TextEditor::TextDocument *document, const QTextCursor &cursor,
Utils::ProcessLinkCallback callback);
- void findUsages(const Utils::FilePath &filePath, const QTextCursor &cursor);
+ void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor);
void projectAdded(ProjectExplorer::Project *project);
void projectRemoved(ProjectExplorer::Project *project);
@@ -105,6 +111,7 @@ private:
QVector<Client *> m_clients;
QList<BaseSettings *> m_currentSettings; // owned
QMap<QString, QVector<Client *>> m_clientsForSetting;
+ QHash<TextEditor::TextDocument *, QPointer<Client>> m_clientForDocument;
QHash<LanguageServerProtocol::MessageId, QList<Client *>> m_exclusiveRequests;
DocumentLocatorFilter m_currentDocumentLocatorFilter;
WorkspaceLocatorFilter m_workspaceLocatorFilter;
diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp
index 8a15a9e0b8..a85ff0f6a8 100644
--- a/src/plugins/languageclient/languageclientoutline.cpp
+++ b/src/plugins/languageclient/languageclientoutline.cpp
@@ -134,7 +134,7 @@ LanguageClientOutlineWidget::LanguageClientOutlineWidget(Client *client,
: m_client(client)
, m_editor(editor)
, m_view(this)
- , m_uri(DocumentUri::fromFileName(editor->textDocument()->filePath()))
+ , m_uri(DocumentUri::fromFilePath(editor->textDocument()->filePath()))
{
connect(client->documentSymbolCache(),
&DocumentSymbolCache::gotSymbols,
@@ -148,7 +148,7 @@ LanguageClientOutlineWidget::LanguageClientOutlineWidget(Client *client,
client->documentSymbolCache()->requestSymbols(m_uri);
auto *layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(Core::ItemViewFind::createSearchableWrapper(&m_view));
setLayout(layout);
@@ -220,6 +220,8 @@ void LanguageClientOutlineWidget::onItemActivated(const QModelIndex &index)
static bool clientSupportsDocumentSymbols(const Client *client, const TextEditor::TextDocument *doc)
{
+ if (!client)
+ return false;
DynamicCapabilities dc = client->dynamicCapabilities();
if (dc.isRegistered(DocumentSymbolsRequest::methodName).value_or(false)) {
TextDocumentRegistrationOptions options(dc.option(DocumentSymbolsRequest::methodName));
@@ -234,22 +236,17 @@ bool LanguageClientOutlineWidgetFactory::supportsEditor(Core::IEditor *editor) c
auto doc = qobject_cast<TextEditor::TextDocument *>(editor->document());
if (!doc)
return false;
- auto clients = LanguageClientManager::clientsSupportingDocument(doc);
- return Utils::anyOf(clients, [doc](const Client *client){
- return clientSupportsDocumentSymbols(client, doc);
- });
+ return clientSupportsDocumentSymbols(LanguageClientManager::clientForDocument(doc), doc);
}
TextEditor::IOutlineWidget *LanguageClientOutlineWidgetFactory::createWidget(Core::IEditor *editor)
{
auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor);
QTC_ASSERT(textEditor, return nullptr);
- QList<Client *> clients = LanguageClientManager::clientsSupportingDocument(textEditor->textDocument());
- QTC_ASSERT(!clients.isEmpty(), return nullptr);
- clients = Utils::filtered(clients, [doc = textEditor->textDocument()](const Client *client){
- return clientSupportsDocumentSymbols(client, doc);
- });
- return new LanguageClientOutlineWidget(clients.first(), textEditor);
+ Client *client = LanguageClientManager::clientForDocument(textEditor->textDocument());
+ if (!client || !clientSupportsDocumentSymbols(client, textEditor->textDocument()))
+ return nullptr;
+ return new LanguageClientOutlineWidget(client, textEditor);
}
} // namespace LanguageClient
diff --git a/src/plugins/languageclient/languageclientquickfix.cpp b/src/plugins/languageclient/languageclientquickfix.cpp
index 70db31b871..90e9b23de6 100644
--- a/src/plugins/languageclient/languageclientquickfix.cpp
+++ b/src/plugins/languageclient/languageclientquickfix.cpp
@@ -111,7 +111,7 @@ IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInte
cursor.select(QTextCursor::LineUnderCursor);
Range range(cursor);
params.setRange(range);
- auto uri = DocumentUri::fromFileName(Utils::FilePath::fromString(interface->fileName()));
+ auto uri = DocumentUri::fromFilePath(Utils::FilePath::fromString(interface->fileName()));
params.setTextDocument(uri);
CodeActionParams::CodeActionContext context;
context.setDiagnostics(m_client->diagnosticsAt(uri, range));
@@ -148,7 +148,9 @@ void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(
setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops));
}
-LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client) : m_client(client)
+LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client)
+ : IAssistProvider(client)
+ , m_client(client)
{
QTC_CHECK(client);
}
diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp
index a1b8db2169..9f30441765 100644
--- a/src/plugins/languageclient/languageclientsettings.cpp
+++ b/src/plugins/languageclient/languageclientsettings.cpp
@@ -37,6 +37,7 @@
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
#include <utils/algorithm.h>
+#include <utils/utilsicons.h>
#include <utils/delegates.h>
#include <utils/fancylineedit.h>
#include <utils/mimetypes/mimedatabase.h>
@@ -53,10 +54,12 @@
#include <QHeaderView>
#include <QLabel>
#include <QListView>
+#include <QMimeData>
#include <QPushButton>
#include <QSettings>
#include <QSortFilterProxyModel>
#include <QStringListModel>
+#include <QToolButton>
#include <QTreeView>
constexpr char nameKey[] = "name";
@@ -69,6 +72,7 @@ constexpr char executableKey[] = "executable";
constexpr char argumentsKey[] = "arguments";
constexpr char settingsGroupKey[] = "LanguageClient";
constexpr char clientsKey[] = "clients";
+constexpr char mimeType[] = "application/language.client.setting";
namespace LanguageClient {
@@ -85,14 +89,24 @@ public:
bool insertRows(int row, int count = 1, const QModelIndex &parent = QModelIndex()) final;
bool setData(const QModelIndex &index, const QVariant &value, int role) final;
Qt::ItemFlags flags(const QModelIndex &index) const final;
+ Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; }
+ QStringList mimeTypes() const override { return {mimeType}; }
+ QMimeData *mimeData(const QModelIndexList &indexes) const override;
+ bool dropMimeData(const QMimeData *data,
+ Qt::DropAction action,
+ int row,
+ int column,
+ const QModelIndex &parent) override;
void reset(const QList<BaseSettings *> &settings);
QList<BaseSettings *> settings() const { return m_settings; }
+ void insertSettings(BaseSettings *settings);
QList<BaseSettings *> removed() const { return m_removed; }
BaseSettings *settingForIndex(const QModelIndex &index) const;
QModelIndex indexForSetting(BaseSettings *setting) const;
private:
+ static constexpr int idRole = Qt::UserRole + 1;
QList<BaseSettings *> m_settings; // owned
QList<BaseSettings *> m_removed;
};
@@ -133,6 +147,7 @@ public:
void finish() override;
QList<BaseSettings *> settings() const;
+ void addSettings(BaseSettings *settings);
private:
LanguageClientSettingsModel m_model;
@@ -149,6 +164,10 @@ LanguageClientSettingsPageWidget::LanguageClientSettingsPageWidget(LanguageClien
m_view->setHeaderHidden(true);
m_view->setSelectionMode(QAbstractItemView::SingleSelection);
m_view->setSelectionBehavior(QAbstractItemView::SelectItems);
+ m_view->setDragEnabled(true);
+ m_view->viewport()->setAcceptDrops(true);
+ m_view->setDropIndicatorShown(true);
+ m_view->setDragDropMode(QAbstractItemView::InternalMove);
connect(m_view->selectionModel(), &QItemSelectionModel::currentChanged,
this, &LanguageClientSettingsPageWidget::currentChanged);
auto buttonLayout = new QVBoxLayout();
@@ -220,8 +239,10 @@ void LanguageClientSettingsPageWidget::addItem()
void LanguageClientSettingsPageWidget::deleteItem()
{
auto index = m_view->currentIndex();
- if (index.isValid())
- m_settings.removeRows(index.row());
+ if (!index.isValid())
+ return;
+
+ m_settings.removeRows(index.row());
}
LanguageClientSettingsPage::LanguageClientSettingsPage()
@@ -285,6 +306,11 @@ QList<BaseSettings *> LanguageClientSettingsPage::settings() const
return m_model.settings();
}
+void LanguageClientSettingsPage::addSettings(BaseSettings *settings)
+{
+ m_model.insertSettings(settings);
+}
+
LanguageClientSettingsModel::~LanguageClientSettingsModel()
{
qDeleteAll(m_settings);
@@ -299,6 +325,8 @@ QVariant LanguageClientSettingsModel::data(const QModelIndex &index, int role) c
return Utils::globalMacroExpander()->expand(setting->m_name);
else if (role == Qt::CheckStateRole)
return setting->m_enabled ? Qt::Checked : Qt::Unchecked;
+ else if (role == idRole)
+ return setting->m_id;
return QVariant();
}
@@ -338,9 +366,55 @@ bool LanguageClientSettingsModel::setData(const QModelIndex &index, const QVaria
return true;
}
-Qt::ItemFlags LanguageClientSettingsModel::flags(const QModelIndex &/*index*/) const
+Qt::ItemFlags LanguageClientSettingsModel::flags(const QModelIndex &index) const
{
- return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
+ const Qt::ItemFlags dragndropFlags = index.isValid() ? Qt::ItemIsDragEnabled
+ : Qt::ItemIsDropEnabled;
+ return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | dragndropFlags;
+}
+
+QMimeData *LanguageClientSettingsModel::mimeData(const QModelIndexList &indexes) const
+{
+ QTC_ASSERT(indexes.count() == 1, return nullptr);
+
+ QMimeData *mimeData = new QMimeData;
+ QByteArray encodedData;
+
+ QDataStream stream(&encodedData, QIODevice::WriteOnly);
+
+ for (const QModelIndex &index : indexes) {
+ if (index.isValid())
+ stream << data(index, idRole).toString();
+ }
+
+ mimeData->setData(mimeType, indexes.first().data(idRole).toString().toUtf8());
+ return mimeData;
+}
+
+bool LanguageClientSettingsModel::dropMimeData(
+ const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+ if (!canDropMimeData(data, action, row, column, parent))
+ return false;
+
+ if (action == Qt::IgnoreAction)
+ return true;
+
+ const QString id = QString::fromUtf8(data->data(mimeType));
+ auto setting = Utils::findOrDefault(m_settings, [id](const BaseSettings *setting) {
+ return setting->m_id == id;
+ });
+ if (!setting)
+ return false;
+
+ if (row == -1)
+ row = parent.isValid() ? parent.row() : rowCount(QModelIndex());
+
+ beginInsertRows(parent, row, row);
+ m_settings.insert(row, setting->copy());
+ endInsertRows();
+
+ return true;
}
void LanguageClientSettingsModel::reset(const QList<BaseSettings *> &settings)
@@ -353,6 +427,14 @@ void LanguageClientSettingsModel::reset(const QList<BaseSettings *> &settings)
endResetModel();
}
+void LanguageClientSettingsModel::insertSettings(BaseSettings *settings)
+{
+ int row = rowCount();
+ beginInsertRows(QModelIndex(), row, row);
+ m_settings.insert(row, settings);
+ endInsertRows();
+}
+
BaseSettings *LanguageClientSettingsModel::settingForIndex(const QModelIndex &index) const
{
if (!index.isValid() || index.row() >= m_settings.size())
@@ -461,6 +543,11 @@ QList<BaseSettings *> LanguageClientSettings::currentPageSettings()
return settingsPage().settings();
}
+void LanguageClientSettings::addSettings(BaseSettings *settings)
+{
+ settingsPage().addSettings(settings);
+}
+
void LanguageClientSettings::toSettings(QSettings *settings,
const QList<BaseSettings *> &languageClientSettings)
{
diff --git a/src/plugins/languageclient/languageclientsettings.h b/src/plugins/languageclient/languageclientsettings.h
index 1036348cb7..27437d1538 100644
--- a/src/plugins/languageclient/languageclientsettings.h
+++ b/src/plugins/languageclient/languageclientsettings.h
@@ -25,6 +25,8 @@
#pragma once
+#include "languageclient_global.h"
+
#include <coreplugin/dialogs/ioptionspage.h>
#include <QAbstractItemModel>
@@ -48,12 +50,10 @@ namespace ProjectExplorer { class Project; }
namespace LanguageClient {
-constexpr char noLanguageFilter[] = "No Filter";
-
class Client;
class BaseClientInterface;
-struct LanguageFilter
+struct LANGUAGECLIENT_EXPORT LanguageFilter
{
QStringList mimeTypes;
QStringList filePattern;
@@ -61,7 +61,7 @@ struct LanguageFilter
bool isSupported(const Core::IDocument *document) const;
};
-class BaseSettings
+class LANGUAGECLIENT_EXPORT BaseSettings
{
public:
BaseSettings() = default;
@@ -102,7 +102,7 @@ private:
bool canStart(QList<const Core::IDocument *> documents) const;
};
-class StdIOSettings : public BaseSettings
+class LANGUAGECLIENT_EXPORT StdIOSettings : public BaseSettings
{
public:
StdIOSettings() = default;
@@ -135,6 +135,7 @@ public:
static void init();
static QList<BaseSettings *> fromSettings(QSettings *settings);
static QList<BaseSettings *> currentPageSettings();
+ static void addSettings(BaseSettings *settings);
static void toSettings(QSettings *settings, const QList<BaseSettings *> &languageClientSettings);
};
diff --git a/src/plugins/languageclient/languageclientutils.cpp b/src/plugins/languageclient/languageclientutils.cpp
index 317af50f74..cdb114b2f1 100644
--- a/src/plugins/languageclient/languageclientutils.cpp
+++ b/src/plugins/languageclient/languageclientutils.cpp
@@ -40,6 +40,7 @@
#include <utils/utilsicons.h>
#include <QFile>
+#include <QMenu>
#include <QTextDocument>
#include <QToolBar>
#include <QToolButton>
@@ -79,7 +80,7 @@ bool applyTextDocumentEdit(const TextDocumentEdit &edit)
if (edits.isEmpty())
return true;
const DocumentUri &uri = edit.id().uri();
- if (TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFileName())) {
+ if (TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFilePath())) {
LanguageClientValue<int> version = edit.id().version();
if (!version.isNull() && version.value(0) < doc->document()->revision())
return false;
@@ -93,7 +94,7 @@ bool applyTextEdits(const DocumentUri &uri, const QList<TextEdit> &edits)
return true;
RefactoringChanges changes;
RefactoringFilePtr file;
- file = changes.file(uri.toFileName().toString());
+ file = changes.file(uri.toFilePath().toString());
file->setChangeSet(editsToChangeSet(edits, file->document()));
return file->apply();
}
@@ -136,7 +137,7 @@ void updateCodeActionRefactoringMarker(Client *client,
const CodeAction &action,
const DocumentUri &uri)
{
- TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFileName());
+ TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFilePath());
if (!doc)
return;
const QVector<BaseTextEditor *> editors = BaseTextEditor::textEditorsForDocument(doc);
@@ -200,30 +201,34 @@ void updateEditorToolBar(Core::IEditor *editor)
if (!widget)
return;
- const Core::IDocument *document = editor->document();
- QStringList clientsWithDoc;
- for (auto client : LanguageClientManager::clients()) {
- if (client->documentOpen(document))
- clientsWithDoc << client->name();
- }
+ TextDocument *document = textEditor->textDocument();
+ Client *client = LanguageClientManager::clientForDocument(textEditor->textDocument());
static QMap<QWidget *, QAction *> actions;
if (actions.contains(widget)) {
auto action = actions[widget];
- if (clientsWithDoc.isEmpty()) {
+ if (client) {
+ action->setText(client->name());
+ } else {
widget->toolBar()->removeAction(action);
actions.remove(widget);
- } else {
- action->setText(clientsWithDoc.join(';'));
}
- } else if (!clientsWithDoc.isEmpty()) {
- const QIcon icon
- = Utils::Icon({{":/languageclient/images/languageclient.png",
- Utils::Theme::IconsBaseColor}})
- .icon();
- actions[widget] = widget->toolBar()->addAction(icon, clientsWithDoc.join(';'), []() {
- Core::ICore::showOptionsDialog(Constants::LANGUAGECLIENT_SETTINGS_PAGE);
+ } else if (client) {
+ const QIcon icon = Utils::Icon({{":/languageclient/images/languageclient.png",
+ Utils::Theme::IconsBaseColor}})
+ .icon();
+ actions[widget] = widget->toolBar()->addAction(icon, client->name(), [document]() {
+ auto menu = new QMenu;
+ for (auto client : LanguageClientManager::clientsSupportingDocument(document))
+ menu->addAction(client->name(), [client = QPointer<Client>(client), document]() {
+ if (client)
+ LanguageClientManager::reOpenDocumentWithClient(document, client);
+ });
+ menu->addAction("Manage...", []() {
+ Core::ICore::showOptionsDialog(Constants::LANGUAGECLIENT_SETTINGS_PAGE);
+ });
+ menu->popup(QCursor::pos());
});
QObject::connect(widget, &QWidget::destroyed, [widget]() {
actions.remove(widget);
diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp
index 973e098274..2f8d874469 100644
--- a/src/plugins/languageclient/locatorfilter.cpp
+++ b/src/plugins/languageclient/locatorfilter.cpp
@@ -56,24 +56,20 @@ DocumentLocatorFilter::DocumentLocatorFilter()
void DocumentLocatorFilter::updateCurrentClient()
{
- Core::IEditor *editor = Core::EditorManager::currentEditor();
resetSymbols();
disconnect(m_resetSymbolsConnection);
- if (Client *client = LanguageClientManager::clientForEditor(editor)) {
+ TextEditor::TextDocument *document = TextEditor::TextDocument::currentTextDocument();
+ if (Client *client = LanguageClientManager::clientForDocument(document)) {
if (m_symbolCache != client->documentSymbolCache()) {
disconnect(m_updateSymbolsConnection);
m_symbolCache = client->documentSymbolCache();
- m_updateSymbolsConnection = connect(m_symbolCache,
- &DocumentSymbolCache::gotSymbols,
- this,
- &DocumentLocatorFilter::updateSymbols);
+ m_updateSymbolsConnection = connect(m_symbolCache, &DocumentSymbolCache::gotSymbols,
+ this, &DocumentLocatorFilter::updateSymbols);
}
- m_resetSymbolsConnection = connect(editor->document(),
- &Core::IDocument::contentsChanged,
- this,
- &DocumentLocatorFilter::resetSymbols);
- m_currentUri = DocumentUri::fromFileName(editor->document()->filePath());
+ m_resetSymbolsConnection = connect(document, &Core::IDocument::contentsChanged,
+ this, &DocumentLocatorFilter::resetSymbols);
+ m_currentUri = DocumentUri::fromFilePath(document->filePath());
} else {
disconnect(m_updateSymbolsConnection);
m_symbolCache.clear();
@@ -192,7 +188,7 @@ void DocumentLocatorFilter::accept(Core::LocatorFilterEntry selection,
{
if (selection.internalData.canConvert<Utils::LineColumn>()) {
auto lineColumn = qvariant_cast<Utils::LineColumn>(selection.internalData);
- Core::EditorManager::openEditorAt(m_currentUri.toFileName().toString(),
+ Core::EditorManager::openEditorAt(m_currentUri.toFilePath().toString(),
lineColumn.line + 1,
lineColumn.column);
} else if (selection.internalData.canConvert<Utils::Link>()) {
diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp
new file mode 100644
index 0000000000..59b415455f
--- /dev/null
+++ b/src/plugins/languageclient/semantichighlightsupport.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "semantichighlightsupport.h"
+
+#include <QTextDocument>
+
+using namespace LanguageServerProtocol;
+
+namespace LanguageClient {
+namespace SemanticHighligtingSupport {
+
+static Q_LOGGING_CATEGORY(LOGLSPHIGHLIGHT, "qtc.languageclient.highlight", QtWarningMsg);
+
+static const QList<QList<QString>> highlightScopes(const ServerCapabilities &capabilities)
+{
+ return capabilities.semanticHighlighting()
+ .value_or(ServerCapabilities::SemanticHighlightingServerCapabilities())
+ .scopes().value_or(QList<QList<QString>>());
+}
+
+static Utils::optional<TextEditor::TextStyle> styleForScopes(const QList<QString> &scopes)
+{
+ // missing "Minimal Scope Coverage" scopes
+
+ // entity.other.inherited-class
+ // entity.name.section
+ // entity.name.tag
+ // entity.other.attribute-name
+ // variable.language
+ // variable.parameter
+ // variable.function
+ // constant.numeric
+ // constant.language
+ // constant.character.escape
+ // support
+ // storage.modifier
+ // keyword.control
+ // keyword.operator
+ // keyword.declaration
+ // invalid
+ // invalid.deprecated
+
+ static const QMap<QString, TextEditor::TextStyle> styleForScopes = {
+ {"entity.name", TextEditor::C_TYPE},
+ {"entity.name.function", TextEditor::C_FUNCTION},
+ {"entity.name.label", TextEditor::C_LABEL},
+ {"keyword", TextEditor::C_KEYWORD},
+ {"storage.type", TextEditor::C_KEYWORD},
+ {"constant.numeric", TextEditor::C_NUMBER},
+ {"string", TextEditor::C_STRING},
+ {"comment", TextEditor::C_COMMENT},
+ {"comment.block.documentation", TextEditor::C_DOXYGEN_COMMENT},
+ {"variable.function", TextEditor::C_FUNCTION},
+ {"variable.other", TextEditor::C_LOCAL},
+ {"variable.other.member", TextEditor::C_FIELD},
+ {"variable.parameter", TextEditor::C_LOCAL},
+ };
+
+ for (QString scope : scopes) {
+ while (!scope.isEmpty()) {
+ auto style = styleForScopes.find(scope);
+ if (style != styleForScopes.end())
+ return style.value();
+ const int index = scope.lastIndexOf('.');
+ if (index <= 0)
+ break;
+ scope = scope.left(index);
+ }
+ }
+ return Utils::nullopt;
+}
+
+static QHash<int, QTextCharFormat> scopesToFormatHash(QList<QList<QString>> scopes,
+ const TextEditor::FontSettings &fontSettings)
+{
+ QHash<int, QTextCharFormat> scopesToFormat;
+ for (int i = 0; i < scopes.size(); ++i) {
+ if (Utils::optional<TextEditor::TextStyle> style = styleForScopes(scopes[i]))
+ scopesToFormat[i] = fontSettings.toTextCharFormat(style.value());
+ }
+ return scopesToFormat;
+}
+
+TextEditor::HighlightingResult tokenToHighlightingResult(int line,
+ const SemanticHighlightToken &token)
+{
+ return TextEditor::HighlightingResult(unsigned(line) + 1,
+ unsigned(token.character) + 1,
+ token.length,
+ int(token.scope));
+}
+
+TextEditor::HighlightingResults generateResults(const QList<SemanticHighlightingInformation> &lines)
+{
+ TextEditor::HighlightingResults results;
+
+ for (const SemanticHighlightingInformation &info : lines) {
+ const int line = info.line();
+ for (const SemanticHighlightToken &token :
+ info.tokens().value_or(QList<SemanticHighlightToken>())) {
+ results << tokenToHighlightingResult(line, token);
+ }
+ }
+
+ return results;
+}
+
+void applyHighlight(TextEditor::TextDocument *doc,
+ const TextEditor::HighlightingResults &results,
+ const ServerCapabilities &capabilities)
+{
+ if (!doc->syntaxHighlighter())
+ return;
+ if (LOGLSPHIGHLIGHT().isDebugEnabled()) {
+ auto scopes = highlightScopes(capabilities);
+ qCDebug(LOGLSPHIGHLIGHT) << "semantic highlight for" << doc->filePath();
+ for (auto result : results) {
+ auto b = doc->document()->findBlockByNumber(int(result.line - 1));
+ const QString &text = b.text().mid(int(result.column - 1), int(result.length));
+ auto resultScupes = scopes[result.kind];
+ auto style = styleForScopes(resultScupes).value_or(TextEditor::C_TEXT);
+ qCDebug(LOGLSPHIGHLIGHT) << result.line - 1 << '\t'
+ << result.column - 1 << '\t'
+ << result.length << '\t'
+ << TextEditor::Constants::nameForStyle(style) << '\t'
+ << text
+ << resultScupes;
+ }
+ }
+
+ TextEditor::SemanticHighlighter::setExtraAdditionalFormats(
+ doc->syntaxHighlighter(),
+ results,
+ scopesToFormatHash(highlightScopes(capabilities), doc->fontSettings()));
+}
+
+} // namespace SemanticHighligtingSupport
+} // namespace LanguageClient
diff --git a/src/plugins/languageclient/semantichighlightsupport.h b/src/plugins/languageclient/semantichighlightsupport.h
new file mode 100644
index 0000000000..b9d4fe1555
--- /dev/null
+++ b/src/plugins/languageclient/semantichighlightsupport.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "languageclient_global.h"
+
+#include <languageserverprotocol/languagefeatures.h>
+#include <languageserverprotocol/servercapabilities.h>
+#include <texteditor/semantichighlighter.h>
+#include <texteditor/textdocument.h>
+
+namespace LanguageClient {
+namespace SemanticHighligtingSupport {
+
+TextEditor::HighlightingResults generateResults(
+ const QList<LanguageServerProtocol::SemanticHighlightingInformation> &lines);
+
+void applyHighlight(TextEditor::TextDocument *doc,
+ const TextEditor::HighlightingResults &results,
+ const LanguageServerProtocol::ServerCapabilities &capabilities);
+
+} // namespace SemanticHighligtingSupport
+} // namespace LanguageClient
diff --git a/src/plugins/macros/macroevent.cpp b/src/plugins/macros/macroevent.cpp
index 10b4c0a632..4b0d93c34e 100644
--- a/src/plugins/macros/macroevent.cpp
+++ b/src/plugins/macros/macroevent.cpp
@@ -76,11 +76,8 @@ void MacroEvent::save(QDataStream &stream) const
{
stream << m_id.name();
stream << m_values.count();
- QMapIterator<quint8, QVariant> i(m_values);
- while (i.hasNext()) {
- i.next();
+ for (auto i = m_values.cbegin(), end = m_values.cend(); i != end; ++i)
stream << i.key() << i.value();
- }
}
Core::Id MacroEvent::id() const
diff --git a/src/plugins/macros/macrolocatorfilter.cpp b/src/plugins/macros/macrolocatorfilter.cpp
index 9c45c461fd..7e8bed5040 100644
--- a/src/plugins/macros/macrolocatorfilter.cpp
+++ b/src/plugins/macros/macrolocatorfilter.cpp
@@ -56,10 +56,8 @@ QList<Core::LocatorFilterEntry> MacroLocatorFilter::matchesFor(QFutureInterface<
const Qt::CaseSensitivity entryCaseSensitivity = caseSensitivity(entry);
const QMap<QString, Macro*> &macros = MacroManager::macros();
- QMapIterator<QString, Macro*> it(macros);
- while (it.hasNext()) {
- it.next();
+ for (auto it = macros.cbegin(), end = macros.cend(); it != end; ++it) {
const QString displayName = it.key();
const QString description = it.value()->description();
diff --git a/src/plugins/macros/macrooptionswidget.cpp b/src/plugins/macros/macrooptionswidget.cpp
index 96c1adb13e..a4e2940281 100644
--- a/src/plugins/macros/macrooptionswidget.cpp
+++ b/src/plugins/macros/macrooptionswidget.cpp
@@ -88,10 +88,7 @@ void MacroOptionsWidget::createTable()
{
QDir dir(MacroManager::macrosDirectory());
const Core::Id base = Core::Id(Constants::PREFIX_MACRO);
- QMapIterator<QString, Macro *> it(MacroManager::macros());
- while (it.hasNext()) {
- it.next();
- Macro *macro = it.value();
+ for (Macro *macro : MacroManager::macros()) {
QFileInfo fileInfo(macro->fileName());
if (fileInfo.absoluteDir() == dir.absolutePath()) {
auto macroItem = new QTreeWidgetItem(m_ui->treeWidget);
@@ -140,11 +137,8 @@ void MacroOptionsWidget::apply()
}
// Change macro
- QMapIterator<QString, QString> it(m_macroToChange);
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_macroToChange.cbegin(), end = m_macroToChange.cend(); it != end; ++it)
MacroManager::instance()->changeMacro(it.key(), it.value());
- }
// Reinitialize the page
initialize();
diff --git a/src/plugins/macros/macrosplugin.cpp b/src/plugins/macros/macrosplugin.cpp
index 4dbc46905e..bb8f086914 100644
--- a/src/plugins/macros/macrosplugin.cpp
+++ b/src/plugins/macros/macrosplugin.cpp
@@ -63,8 +63,8 @@ MacrosPlugin::~MacrosPlugin()
bool MacrosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
d = new MacrosPluginPrivate;
diff --git a/src/plugins/macros/texteditormacrohandler.cpp b/src/plugins/macros/texteditormacrohandler.cpp
index c1e06c76bf..fac0796e7d 100644
--- a/src/plugins/macros/texteditormacrohandler.cpp
+++ b/src/plugins/macros/texteditormacrohandler.cpp
@@ -136,7 +136,7 @@ void TextEditorMacroHandler::changeEditor(Core::IEditor *editor)
void TextEditorMacroHandler::closeEditor(Core::IEditor *editor)
{
- Q_UNUSED(editor);
+ Q_UNUSED(editor)
if (isRecording() && m_currentEditor && m_currentEditor->widget())
m_currentEditor->widget()->removeEventFilter(this);
m_currentEditor = nullptr;
diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp
index 7d9b8dd209..8fae47bc16 100644
--- a/src/plugins/mercurial/mercurialclient.cpp
+++ b/src/plugins/mercurial/mercurialclient.cpp
@@ -170,8 +170,8 @@ bool MercurialClient::synchronousClone(const QString &workingDir,
const QString &dstLocation,
const QStringList &extraOptions)
{
- Q_UNUSED(workingDir);
- Q_UNUSED(extraOptions);
+ Q_UNUSED(workingDir)
+ Q_UNUSED(extraOptions)
QDir workingDirectory(srcLocation);
const unsigned flags = VcsCommand::SshPasswordPrompt |
VcsCommand::ShowStdOut |
@@ -232,7 +232,7 @@ bool MercurialClient::synchronousPull(const QString &workingDir, const QString &
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(QLatin1String("LANGUAGE"), QLatin1String("C"));
const SynchronousProcessResponse resp = VcsBasePlugin::runVcs(
- workingDir, vcsBinary(), args, vcsTimeoutS(), flags, nullptr, env);
+ workingDir, {vcsBinary(), args}, vcsTimeoutS(), flags, nullptr, env);
const bool ok = resp.result == SynchronousProcessResponse::Finished;
parsePullOutput(resp.stdOut().trimmed());
@@ -391,7 +391,7 @@ void MercurialClient::commit(const QString &repositoryRoot, const QStringList &f
void MercurialClient::diff(const QString &workingDir, const QStringList &files,
const QStringList &extraOptions)
{
- Q_UNUSED(extraOptions);
+ Q_UNUSED(extraOptions)
QString fileName;
@@ -442,7 +442,7 @@ void MercurialClient::revertAll(const QString &workingDir, const QString &revisi
bool MercurialClient::isVcsDirectory(const FilePath &fileName) const
{
- return fileName.toFileInfo().isDir()
+ return fileName.isDir()
&& !fileName.fileName().compare(Constants::MERCURIALREPO, HostOsInfo::fileNameCaseSensitivity());
}
diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp
index 48395ad488..36783aaba5 100644
--- a/src/plugins/mercurial/mercurialcontrol.cpp
+++ b/src/plugins/mercurial/mercurialcontrol.cpp
@@ -172,7 +172,7 @@ Core::ShellCommand *MercurialControl::createInitialCheckoutCommand(const QString
args << QLatin1String("clone") << extraArgs << url << localName;
auto command = new VcsBase::VcsCommand(baseDirectory.toString(),
mercurialClient->processEnvironment());
- command->addJob(mercurialClient->vcsBinary(), args, -1);
+ command->addJob({mercurialClient->vcsBinary(), args}, -1);
return command;
}
diff --git a/src/plugins/modeleditor/classviewcontroller.cpp b/src/plugins/modeleditor/classviewcontroller.cpp
index ae8340d311..dccb0b8795 100644
--- a/src/plugins/modeleditor/classviewcontroller.cpp
+++ b/src/plugins/modeleditor/classviewcontroller.cpp
@@ -65,8 +65,8 @@ void ClassViewController::appendClassDeclarationsFromDocument(CPlusPlus::Documen
int line, int column,
QSet<QString> *classNames)
{
- unsigned int total = document->globalSymbolCount();
- for (unsigned int i = 0; i < total; ++i) {
+ int total = document->globalSymbolCount();
+ for (int i = 0; i < total; ++i) {
CPlusPlus::Symbol *symbol = document->globalSymbolAt(i);
appendClassDeclarationsFromSymbol(symbol, line, column, classNames);
}
@@ -77,9 +77,7 @@ void ClassViewController::appendClassDeclarationsFromSymbol(CPlusPlus::Symbol *s
QSet<QString> *classNames)
{
if (symbol->isClass()
- && (line <= 0
- || (symbol->line() == static_cast<unsigned int>(line)
- && symbol->column() == static_cast<unsigned int>(column + 1))))
+ && (line <= 0 || (symbol->line() == line && symbol->column() == column + 1)))
{
CPlusPlus::Overview overview;
QString className = overview.prettyName(
@@ -91,8 +89,8 @@ void ClassViewController::appendClassDeclarationsFromSymbol(CPlusPlus::Symbol *s
if (symbol->isScope()) {
CPlusPlus::Scope *scope = symbol->asScope();
- unsigned int total = scope->memberCount();
- for (unsigned int i = 0; i < total; ++i) {
+ int total = scope->memberCount();
+ for (int i = 0; i < total; ++i) {
CPlusPlus::Symbol *member = scope->memberAt(i);
appendClassDeclarationsFromSymbol(member, line, column, classNames);
}
diff --git a/src/plugins/modeleditor/dragtool.cpp b/src/plugins/modeleditor/dragtool.cpp
index f7ece9c487..fd4d75fca0 100644
--- a/src/plugins/modeleditor/dragtool.cpp
+++ b/src/plugins/modeleditor/dragtool.cpp
@@ -95,7 +95,7 @@ QSize DragTool::sizeHint() const
void DragTool::paintEvent(QPaintEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
QMargins margins = contentsMargins();
QPixmap pixmap = d->icon.pixmap(d->iconSize, isEnabled() ? QIcon::Normal : QIcon::Disabled, QIcon::Off);
QPainter painter(this);
@@ -122,13 +122,13 @@ void DragTool::paintEvent(QPaintEvent *event)
void DragTool::enterEvent(QEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
update();
}
void DragTool::leaveEvent(QEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
update();
}
@@ -157,7 +157,7 @@ void DragTool::mousePressEvent(QMouseEvent *event)
d->disableFrame = true;
update();
Qt::DropAction dropAction = drag->exec();
- Q_UNUSED(dropAction);
+ Q_UNUSED(dropAction)
d->disableFrame = false;
update();
}
@@ -166,7 +166,7 @@ void DragTool::mousePressEvent(QMouseEvent *event)
void DragTool::mouseMoveEvent(QMouseEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
const bool containsMouse = rect().contains(QWidget::mapFromGlobal(QCursor::pos()));
if ((d->framePainted && !containsMouse) || (!d->framePainted && containsMouse))
update();
diff --git a/src/plugins/modeleditor/editordiagramview.cpp b/src/plugins/modeleditor/editordiagramview.cpp
index bf15165c80..c7c93db493 100644
--- a/src/plugins/modeleditor/editordiagramview.cpp
+++ b/src/plugins/modeleditor/editordiagramview.cpp
@@ -71,10 +71,15 @@ void EditorDiagramView::wheelEvent(QWheelEvent *wheelEvent)
{
if (wheelEvent->modifiers() == Qt::ControlModifier) {
int degree = wheelEvent->angleDelta().y() / 8;
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
+ QPoint zoomOrigin = wheelEvent->pos();
+#else
+ QPoint zoomOrigin = wheelEvent->position().toPoint();
+#endif
if (degree > 0)
- emit zoomIn(wheelEvent->pos());
+ emit zoomIn(zoomOrigin);
else if (degree < 0)
- emit zoomOut(wheelEvent->pos());
+ emit zoomOut(zoomOrigin);
}
}
diff --git a/src/plugins/modeleditor/elementtasks.cpp b/src/plugins/modeleditor/elementtasks.cpp
index f20134fb28..1dca6d0d55 100644
--- a/src/plugins/modeleditor/elementtasks.cpp
+++ b/src/plugins/modeleditor/elementtasks.cpp
@@ -93,7 +93,7 @@ void ElementTasks::openElement(const qmt::MElement *element)
void ElementTasks::openElement(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
OpenDiagramElementVisitor visitor;
visitor.setModelController(d->documentController->modelController());
@@ -129,7 +129,7 @@ bool ElementTasks::hasClassDefinition(const qmt::MElement *element) const
bool ElementTasks::hasClassDefinition(const qmt::DElement *element,
const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(
element->modelUid());
@@ -164,7 +164,7 @@ void ElementTasks::openClassDefinition(const qmt::MElement *element)
void ElementTasks::openClassDefinition(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -175,13 +175,13 @@ void ElementTasks::openClassDefinition(const qmt::DElement *element, const qmt::
bool ElementTasks::hasHeaderFile(const qmt::MElement *element) const
{
// TODO implement
- Q_UNUSED(element);
+ Q_UNUSED(element)
return false;
}
bool ElementTasks::hasHeaderFile(const qmt::DElement *element, const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -192,13 +192,13 @@ bool ElementTasks::hasHeaderFile(const qmt::DElement *element, const qmt::MDiagr
bool ElementTasks::hasSourceFile(const qmt::MElement *element) const
{
// TODO implement
- Q_UNUSED(element);
+ Q_UNUSED(element)
return false;
}
bool ElementTasks::hasSourceFile(const qmt::DElement *element, const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -209,12 +209,12 @@ bool ElementTasks::hasSourceFile(const qmt::DElement *element, const qmt::MDiagr
void ElementTasks::openHeaderFile(const qmt::MElement *element)
{
// TODO implement
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void ElementTasks::openHeaderFile(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -225,12 +225,12 @@ void ElementTasks::openHeaderFile(const qmt::DElement *element, const qmt::MDiag
void ElementTasks::openSourceFile(const qmt::MElement *element)
{
// TODO implement
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void ElementTasks::openSourceFile(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -241,13 +241,13 @@ void ElementTasks::openSourceFile(const qmt::DElement *element, const qmt::MDiag
bool ElementTasks::hasFolder(const qmt::MElement *element) const
{
// TODO implement
- Q_UNUSED(element);
+ Q_UNUSED(element)
return false;
}
bool ElementTasks::hasFolder(const qmt::DElement *element, const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -258,12 +258,12 @@ bool ElementTasks::hasFolder(const qmt::DElement *element, const qmt::MDiagram *
void ElementTasks::showFolder(const qmt::MElement *element)
{
// TODO implement
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void ElementTasks::showFolder(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -281,7 +281,7 @@ bool ElementTasks::hasDiagram(const qmt::MElement *element) const
bool ElementTasks::hasDiagram(const qmt::DElement *element, const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -303,7 +303,7 @@ void ElementTasks::openDiagram(const qmt::MElement *element)
void ElementTasks::openDiagram(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -330,7 +330,7 @@ bool ElementTasks::hasParentDiagram(const qmt::MElement *element) const
bool ElementTasks::hasParentDiagram(const qmt::DElement *element, const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
if (!element)
return false;
@@ -362,7 +362,7 @@ void ElementTasks::openParentDiagram(const qmt::MElement *element)
void ElementTasks::openParentDiagram(const qmt::DElement *element, const qmt::MElement *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
if (!element)
return;
@@ -381,7 +381,7 @@ bool ElementTasks::mayCreateDiagram(const qmt::MElement *element) const
bool ElementTasks::mayCreateDiagram(const qmt::DElement *element,
const qmt::MDiagram *diagram) const
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
@@ -414,7 +414,7 @@ void ElementTasks::createAndOpenDiagram(const qmt::MElement *element)
void ElementTasks::createAndOpenDiagram(const qmt::DElement *element, const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
qmt::MElement *melement = d->documentController->modelController()->findElement(element->modelUid());
if (!melement)
diff --git a/src/plugins/modeleditor/modeldocument.cpp b/src/plugins/modeleditor/modeldocument.cpp
index 875a8bc5c3..a84bdd6863 100644
--- a/src/plugins/modeleditor/modeldocument.cpp
+++ b/src/plugins/modeleditor/modeldocument.cpp
@@ -69,7 +69,7 @@ ModelDocument::~ModelDocument()
Core::IDocument::OpenResult ModelDocument::open(QString *errorString, const QString &fileName,
const QString &realFileName)
{
- Q_UNUSED(fileName);
+ Q_UNUSED(fileName)
OpenResult result = load(errorString, realFileName);
return result;
diff --git a/src/plugins/modeleditor/modeleditor.cpp b/src/plugins/modeleditor/modeleditor.cpp
index 67ee3a6294..08facc1c48 100644
--- a/src/plugins/modeleditor/modeleditor.cpp
+++ b/src/plugins/modeleditor/modeleditor.cpp
@@ -449,7 +449,7 @@ void ModelEditor::initDocument()
qmt::MDiagram *ModelEditor::currentDiagram() const
{
if (!d->diagramView->diagramSceneModel())
- return 0;
+ return nullptr;
return d->diagramView->diagramSceneModel()->diagram();
}
@@ -830,7 +830,7 @@ void ModelEditor::clearProperties()
d->propertiesView->clearSelection();
if (d->propertiesGroupWidget) {
QWidget *scrollWidget = d->propertiesScrollArea->takeWidget();
- Q_UNUSED(scrollWidget); // avoid warning in release mode
+ Q_UNUSED(scrollWidget) // avoid warning in release mode
QMT_CHECK(scrollWidget == d->propertiesGroupWidget);
d->propertiesGroupWidget->deleteLater();
d->propertiesGroupWidget = nullptr;
@@ -952,8 +952,8 @@ void ModelEditor::onTreeModelReset()
void ModelEditor::onTreeViewSelectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
- Q_UNUSED(selected);
- Q_UNUSED(deselected);
+ Q_UNUSED(selected)
+ Q_UNUSED(deselected)
synchronizeDiagramWithBrowser();
updateSelectedArea(SelectedArea::TreeView);
@@ -986,14 +986,14 @@ void ModelEditor::onCurrentDiagramChanged(const qmt::MDiagram *diagram)
void ModelEditor::onDiagramActivated(const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
updateSelectedArea(SelectedArea::Diagram);
}
void ModelEditor::onDiagramClipboardChanged(bool isEmpty)
{
- Q_UNUSED(isEmpty);
+ Q_UNUSED(isEmpty)
if (this == Core::EditorManager::currentEditor())
updateSelectedArea(d->selectedArea);
@@ -1021,15 +1021,15 @@ void ModelEditor::onDiagramSelectionChanged(const qmt::MDiagram *diagram)
void ModelEditor::onDiagramModified(const qmt::MDiagram *diagram)
{
- Q_UNUSED(diagram);
+ Q_UNUSED(diagram)
updateSelectedArea(d->selectedArea);
}
void ModelEditor::onRightSplitterMoved(int pos, int index)
{
- Q_UNUSED(pos);
- Q_UNUSED(index);
+ Q_UNUSED(pos)
+ Q_UNUSED(index)
d->uiController->onRightSplitterChanged(d->rightSplitter->saveState());
}
@@ -1041,8 +1041,8 @@ void ModelEditor::onRightSplitterChanged(const QByteArray &state)
void ModelEditor::onRightHorizSplitterMoved(int pos, int index)
{
- Q_UNUSED(pos);
- Q_UNUSED(index);
+ Q_UNUSED(pos)
+ Q_UNUSED(index)
d->uiController->onRightHorizSplitterChanged(d->rightHorizSplitter->saveState());
}
@@ -1241,7 +1241,7 @@ void ModelEditor::closeCurrentDiagram(bool addToHistory)
if (addToHistory)
addToNavigationHistory(diagram);
d->diagramStack->setCurrentWidget(d->noDiagramLabel);
- d->diagramView->setDiagramSceneModel(0);
+ d->diagramView->setDiagramSceneModel(nullptr);
diagramsManager->unbindDiagramSceneModel(diagram);
}
}
@@ -1255,7 +1255,7 @@ void ModelEditor::closeDiagram(const qmt::MDiagram *diagram)
if (sceneModel && diagram == sceneModel->diagram()) {
addToNavigationHistory(diagram);
d->diagramStack->setCurrentWidget(d->noDiagramLabel);
- d->diagramView->setDiagramSceneModel(0);
+ d->diagramView->setDiagramSceneModel(nullptr);
diagramsManager->unbindDiagramSceneModel(diagram);
}
}
diff --git a/src/plugins/modeleditor/modeleditor_plugin.cpp b/src/plugins/modeleditor/modeleditor_plugin.cpp
index 8e08854f4d..de80992032 100644
--- a/src/plugins/modeleditor/modeleditor_plugin.cpp
+++ b/src/plugins/modeleditor/modeleditor_plugin.cpp
@@ -84,8 +84,8 @@ ModelEditorPlugin::~ModelEditorPlugin()
bool ModelEditorPlugin::initialize(const QStringList &arguments, QString *errorString)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorString);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
d->modelsManager = new ModelsManager(this);
d->uiController = new UiController(this);
diff --git a/src/plugins/modeleditor/modelindexer.cpp b/src/plugins/modeleditor/modelindexer.cpp
index e03fb4eb03..163c0d9c5a 100644
--- a/src/plugins/modeleditor/modelindexer.cpp
+++ b/src/plugins/modeleditor/modelindexer.cpp
@@ -356,7 +356,7 @@ QString ModelIndexer::findModel(const qmt::Uid &modelUid)
QString ModelIndexer::findDiagram(const qmt::Uid &modelUid, const qmt::Uid &diagramUid)
{
- Q_UNUSED(modelUid); // avoid warning in release mode
+ Q_UNUSED(modelUid) // avoid warning in release mode
QMutexLocker locker(&d->indexerMutex);
QSet<IndexedDiagramReference *> indexedDiagramReferences = d->indexedDiagramReferencesByDiagramUid.value(diagramUid);
@@ -370,8 +370,11 @@ QString ModelIndexer::findDiagram(const qmt::Uid &modelUid, const qmt::Uid &diag
void ModelIndexer::onProjectAdded(ProjectExplorer::Project *project)
{
- connect(project, &ProjectExplorer::Project::fileListChanged,
- this, [=]() { this->onProjectFileListChanged(project); });
+ connect(project,
+ &ProjectExplorer::Project::fileListChanged,
+ this,
+ [=]() { this->onProjectFileListChanged(project); },
+ Qt::QueuedConnection);
scanProject(project);
}
diff --git a/src/plugins/modeleditor/modelsmanager.cpp b/src/plugins/modeleditor/modelsmanager.cpp
index 768d65b2b3..e2eb9d2e9f 100644
--- a/src/plugins/modeleditor/modelsmanager.cpp
+++ b/src/plugins/modeleditor/modelsmanager.cpp
@@ -230,7 +230,7 @@ void ModelsManager::setDiagramClipboard(ExtDocumentController *documentControlle
void ModelsManager::onAboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node)
{
- Q_UNUSED(project);
+ Q_UNUSED(project)
bool canOpenDiagram = false;
diff --git a/src/plugins/modeleditor/openelementvisitor.cpp b/src/plugins/modeleditor/openelementvisitor.cpp
index 2429297528..1b5c043263 100644
--- a/src/plugins/modeleditor/openelementvisitor.cpp
+++ b/src/plugins/modeleditor/openelementvisitor.cpp
@@ -129,17 +129,17 @@ void OpenDiagramElementVisitor::visitDConnection(const qmt::DConnection *connect
void OpenDiagramElementVisitor::visitDAnnotation(const qmt::DAnnotation *annotation)
{
- Q_UNUSED(annotation);
+ Q_UNUSED(annotation)
}
void OpenDiagramElementVisitor::visitDBoundary(const qmt::DBoundary *boundary)
{
- Q_UNUSED(boundary);
+ Q_UNUSED(boundary)
}
void OpenDiagramElementVisitor::visitDSwimlane(const qmt::DSwimlane *swimlane)
{
- Q_UNUSED(swimlane);
+ Q_UNUSED(swimlane)
}
void OpenModelElementVisitor::setElementTasks(ElementTasks *elementTasks)
@@ -149,12 +149,12 @@ void OpenModelElementVisitor::setElementTasks(ElementTasks *elementTasks)
void OpenModelElementVisitor::visitMElement(const qmt::MElement *element)
{
- Q_UNUSED(element);
+ Q_UNUSED(element)
}
void OpenModelElementVisitor::visitMObject(const qmt::MObject *object)
{
- Q_UNUSED(object);
+ Q_UNUSED(object)
}
void OpenModelElementVisitor::visitMPackage(const qmt::MPackage *package)
@@ -192,27 +192,27 @@ void OpenModelElementVisitor::visitMItem(const qmt::MItem *item)
void OpenModelElementVisitor::visitMRelation(const qmt::MRelation *relation)
{
- Q_UNUSED(relation);
+ Q_UNUSED(relation)
}
void OpenModelElementVisitor::visitMDependency(const qmt::MDependency *dependency)
{
- Q_UNUSED(dependency);
+ Q_UNUSED(dependency)
}
void OpenModelElementVisitor::visitMInheritance(const qmt::MInheritance *inheritance)
{
- Q_UNUSED(inheritance);
+ Q_UNUSED(inheritance)
}
void OpenModelElementVisitor::visitMAssociation(const qmt::MAssociation *association)
{
- Q_UNUSED(association);
+ Q_UNUSED(association)
}
void OpenModelElementVisitor::visitMConnection(const qmt::MConnection *connection)
{
- Q_UNUSED(connection);
+ Q_UNUSED(connection)
}
} // namespace Internal
diff --git a/src/plugins/nim/CMakeLists.txt b/src/plugins/nim/CMakeLists.txt
index ac450f76f4..a26e787578 100644
--- a/src/plugins/nim/CMakeLists.txt
+++ b/src/plugins/nim/CMakeLists.txt
@@ -8,11 +8,11 @@ add_qtc_plugin(Nim
nim.qrc
nimconstants.h
nimplugin.cpp nimplugin.h
+ project/nimbuildsystem.cpp project/nimbuildsystem.h
project/nimbuildconfiguration.cpp project/nimbuildconfiguration.h
project/nimcompilerbuildstep.cpp project/nimcompilerbuildstep.h
project/nimcompilerbuildstepconfigwidget.cpp project/nimcompilerbuildstepconfigwidget.h project/nimcompilerbuildstepconfigwidget.ui
project/nimcompilercleanstep.cpp project/nimcompilercleanstep.h
- project/nimcompilercleanstepconfigwidget.cpp project/nimcompilercleanstepconfigwidget.h project/nimcompilercleanstepconfigwidget.ui
project/nimproject.cpp project/nimproject.h
project/nimprojectnode.cpp project/nimprojectnode.h
project/nimrunconfiguration.cpp project/nimrunconfiguration.h
diff --git a/src/plugins/nim/editor/nimindenter.cpp b/src/plugins/nim/editor/nimindenter.cpp
index 84dad703b1..7cf24f3c0f 100644
--- a/src/plugins/nim/editor/nimindenter.cpp
+++ b/src/plugins/nim/editor/nimindenter.cpp
@@ -51,8 +51,8 @@ void NimIndenter::indentBlock(const QTextBlock &block,
const TextEditor::TabSettings &settings,
int cursorPositionInEditor)
{
- Q_UNUSED(typedChar);
- Q_UNUSED(cursorPositionInEditor);
+ Q_UNUSED(typedChar)
+ Q_UNUSED(cursorPositionInEditor)
const QString currentLine = block.text();
diff --git a/src/plugins/nim/nim.pro b/src/plugins/nim/nim.pro
index 2cb7bb2de3..31b2adb173 100644
--- a/src/plugins/nim/nim.pro
+++ b/src/plugins/nim/nim.pro
@@ -16,13 +16,13 @@ HEADERS += \
editor/nimindenter.h \
tools/nimlexer.h \
tools/sourcecodestream.h \
+ project/nimbuildsystem.h \
project/nimproject.h \
project/nimprojectnode.h \
project/nimbuildconfiguration.h \
project/nimcompilerbuildstep.h \
project/nimcompilerbuildstepconfigwidget.h \
project/nimcompilercleanstep.h \
- project/nimcompilercleanstepconfigwidget.h \
project/nimrunconfiguration.h \
editor/nimeditorfactory.h \
settings/nimcodestylesettingspage.h \
@@ -46,13 +46,13 @@ SOURCES += \
editor/nimhighlighter.cpp \
editor/nimindenter.cpp \
tools/nimlexer.cpp \
+ project/nimbuildsystem.cpp \
project/nimproject.cpp \
project/nimprojectnode.cpp \
project/nimbuildconfiguration.cpp \
project/nimcompilerbuildstep.cpp \
project/nimcompilerbuildstepconfigwidget.cpp \
project/nimcompilercleanstep.cpp \
- project/nimcompilercleanstepconfigwidget.cpp \
project/nimrunconfiguration.cpp \
editor/nimeditorfactory.cpp \
settings/nimcodestylesettingspage.cpp \
@@ -70,6 +70,5 @@ SOURCES += \
FORMS += \
project/nimcompilerbuildstepconfigwidget.ui \
- project/nimcompilercleanstepconfigwidget.ui \
settings/nimcodestylepreferenceswidget.ui \
settings/nimtoolssettingswidget.ui
diff --git a/src/plugins/nim/nim.qbs b/src/plugins/nim/nim.qbs
index cf5dc40930..6964993cea 100644
--- a/src/plugins/nim/nim.qbs
+++ b/src/plugins/nim/nim.qbs
@@ -36,11 +36,11 @@ QtcPlugin {
name: "Project"
prefix: "project/"
files: [
+ "nimbuildsystem.cpp", "nimbuildsystem.h",
"nimbuildconfiguration.h", "nimbuildconfiguration.cpp",
"nimcompilerbuildstep.h", "nimcompilerbuildstep.cpp",
"nimcompilerbuildstepconfigwidget.h", "nimcompilerbuildstepconfigwidget.cpp", "nimcompilerbuildstepconfigwidget.ui",
"nimcompilercleanstep.h", "nimcompilercleanstep.cpp",
- "nimcompilercleanstepconfigwidget.h", "nimcompilercleanstepconfigwidget.cpp", "nimcompilercleanstepconfigwidget.ui",
"nimproject.h", "nimproject.cpp",
"nimprojectnode.h", "nimprojectnode.cpp",
"nimrunconfiguration.h", "nimrunconfiguration.cpp",
diff --git a/src/plugins/nim/nimconstants.h b/src/plugins/nim/nimconstants.h
index 552e01d4b3..03f945689a 100644
--- a/src/plugins/nim/nimconstants.h
+++ b/src/plugins/nim/nimconstants.h
@@ -58,11 +58,6 @@ const char C_NIMCOMPILERBUILDSTEPWIDGET_SUMMARY[] = QT_TRANSLATE_NOOP("NimCompil
// NimCompilerCleanStep
const char C_NIMCOMPILERCLEANSTEP_ID[] = "Nim.NimCompilerCleanStep";
-const char C_NIMCOMPILERCLEANSTEP_DISPLAY[] = QT_TRANSLATE_NOOP("NimCompilerCleanStepFactory", "Nim Compiler Clean Step");
-
-// NimCompilerCleanStepWidget
-const char C_NIMCOMPILERCLEANSTEPWIDGET_DISPLAY[] = QT_TRANSLATE_NOOP("NimCompilerCleanStepWidget", "Nim clean step");
-const char C_NIMCOMPILERCLEANSTEPWIDGET_SUMMARY[] = QT_TRANSLATE_NOOP("NimCompilerCleanStepWidget", "Nim clean step");
const char C_NIMLANGUAGE_ID[] = "Nim";
const char C_NIMCODESTYLESETTINGSPAGE_ID[] = "Nim.NimCodeStyleSettings";
diff --git a/src/plugins/nim/nimplugin.cpp b/src/plugins/nim/nimplugin.cpp
index d9ff187179..7740e6096e 100644
--- a/src/plugins/nim/nimplugin.cpp
+++ b/src/plugins/nim/nimplugin.cpp
@@ -67,7 +67,11 @@ public:
NimEditorFactory editorFactory;
NimBuildConfigurationFactory buildConfigFactory;
NimRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, NimRunConfiguration> runWorkerFactory;
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {runConfigFactory.id()}
+ };
NimCompilerBuildStepFactory buildStepFactory;
NimCompilerCleanStepFactory cleanStepFactory;
NimCodeStyleSettingsPage codeStyleSettingsPage;
diff --git a/src/plugins/nim/project/nimbuildconfiguration.cpp b/src/plugins/nim/project/nimbuildconfiguration.cpp
index 0827a29327..c6c745f9e6 100644
--- a/src/plugins/nim/project/nimbuildconfiguration.cpp
+++ b/src/plugins/nim/project/nimbuildconfiguration.cpp
@@ -24,12 +24,9 @@
****************************************************************************/
#include "nimbuildconfiguration.h"
+#include "nimbuildsystem.h"
#include "nimcompilerbuildstep.h"
#include "nimproject.h"
-#include "nimbuildconfiguration.h"
-#include "nimcompilerbuildstep.h"
-#include "nimcompilercleanstep.h"
-#include "nimproject.h"
#include "../nimconstants.h"
@@ -52,13 +49,14 @@ using namespace Utils;
namespace Nim {
static FilePath defaultBuildDirectory(const Kit *k,
- const QString &projectFilePath,
+ const FilePath &projectFilePath,
const QString &bc,
BuildConfiguration::BuildType buildType)
{
- QFileInfo projectFileInfo(projectFilePath);
+ QFileInfo projectFileInfo = projectFilePath.toFileInfo();
- ProjectMacroExpander expander(projectFilePath, projectFileInfo.baseName(), k, bc, buildType);
+ ProjectMacroExpander expander(projectFilePath,
+ projectFileInfo.baseName(), k, bc, buildType);
QString buildDirectory = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate());
if (FileUtils::isAbsolutePath(buildDirectory))
@@ -76,25 +74,25 @@ NimBuildConfiguration::NimBuildConfiguration(Target *target, Core::Id id)
setBuildDirectorySettingsKey("Nim.NimBuildConfiguration.BuildDirectory");
}
-void NimBuildConfiguration::initialize(const BuildInfo &info)
+void NimBuildConfiguration::initialize()
{
- BuildConfiguration::initialize(info);
+ BuildConfiguration::initialize();
- auto project = qobject_cast<NimProject *>(target()->project());
- QTC_ASSERT(project, return);
+ auto bs = qobject_cast<NimBuildSystem *>(project()->buildSystem());
+ QTC_ASSERT(bs, return );
// Create the build configuration and initialize it from build info
setBuildDirectory(defaultBuildDirectory(target()->kit(),
- project->projectFilePath().toString(),
- info.displayName,
- info.buildType));
+ project()->projectFilePath(),
+ displayName(),
+ buildType()));
// Add nim compiler build step
{
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
auto nimCompilerBuildStep = new NimCompilerBuildStep(buildSteps);
NimCompilerBuildStep::DefaultBuildOptions defaultOption;
- switch (info.buildType) {
+ switch (initialBuildType()) {
case BuildConfiguration::Release:
defaultOption = NimCompilerBuildStep::DefaultBuildOptions::Release;
break;
@@ -106,7 +104,7 @@ void NimBuildConfiguration::initialize(const BuildInfo &info)
break;
}
nimCompilerBuildStep->setDefaultCompilerOptions(defaultOption);
- Utils::FilePathList nimFiles = project->nimFiles();
+ Utils::FilePathList nimFiles = bs->nimFiles();
if (!nimFiles.isEmpty())
nimCompilerBuildStep->setTargetNimFile(nimFiles.first());
buildSteps->appendStep(nimCompilerBuildStep);
@@ -115,15 +113,10 @@ void NimBuildConfiguration::initialize(const BuildInfo &info)
// Add clean step
{
BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
- cleanSteps->appendStep(new NimCompilerCleanStep(cleanSteps));
+ cleanSteps->appendStep(Constants::C_NIMCOMPILERCLEANSTEP_ID);
}
}
-BuildConfiguration::BuildType NimBuildConfiguration::buildType() const
-{
- return BuildConfiguration::Unknown;
-}
-
FilePath NimBuildConfiguration::cacheDirectory() const
{
return buildDirectory().pathAppended("nimcache");
@@ -154,48 +147,30 @@ NimBuildConfigurationFactory::NimBuildConfigurationFactory()
setSupportedProjectMimeTypeName(Constants::C_NIM_PROJECT_MIMETYPE);
}
-QList<BuildInfo> NimBuildConfigurationFactory::availableBuilds(const Target *parent) const
-{
- QList<BuildInfo> result;
- for (auto buildType : {BuildConfiguration::Debug, BuildConfiguration::Release})
- result.push_back(createBuildInfo(parent->kit(), buildType));
- return result;
-}
-
-QList<BuildInfo> NimBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
+QList<BuildInfo> NimBuildConfigurationFactory::availableBuilds
+ (const Kit *k, const FilePath &projectPath, bool forSetup) const
{
QList<BuildInfo> result;
for (auto buildType : {BuildConfiguration::Debug, BuildConfiguration::Release}) {
- BuildInfo info = createBuildInfo(k, buildType);
- info.displayName = info.typeName;
- info.buildDirectory = defaultBuildDirectory(k, projectPath, info.typeName, buildType);
+ BuildInfo info(this);
+ info.buildType = buildType;
+ info.kitId = k->id();
+
+ if (buildType == BuildConfiguration::Debug)
+ info.typeName = tr("Debug");
+ else if (buildType == BuildConfiguration::Profile)
+ info.typeName = tr("Profile");
+ else if (buildType == BuildConfiguration::Release)
+ info.typeName = tr("Release");
+
+ if (forSetup) {
+ info.displayName = info.typeName;
+ info.buildDirectory = defaultBuildDirectory(k, projectPath, info.typeName, buildType);
+ }
result.push_back(info);
}
return result;
}
-BuildInfo NimBuildConfigurationFactory::createBuildInfo(const Kit *k, BuildConfiguration::BuildType buildType) const
-{
- BuildInfo info(this);
- info.buildType = buildType;
- info.kitId = k->id();
- info.typeName = displayName(buildType);
- return info;
-}
-
-QString NimBuildConfigurationFactory::displayName(BuildConfiguration::BuildType buildType) const
-{
- switch (buildType) {
- case ProjectExplorer::BuildConfiguration::Debug:
- return tr("Debug");
- case ProjectExplorer::BuildConfiguration::Profile:
- return tr("Profile");
- case ProjectExplorer::BuildConfiguration::Release:
- return tr("Release");
- default:
- return QString();
- }
-}
-
} // namespace Nim
diff --git a/src/plugins/nim/project/nimbuildconfiguration.h b/src/plugins/nim/project/nimbuildconfiguration.h
index 3c1819e01d..d5c4a293e4 100644
--- a/src/plugins/nim/project/nimbuildconfiguration.h
+++ b/src/plugins/nim/project/nimbuildconfiguration.h
@@ -39,8 +39,7 @@ class NimBuildConfiguration : public ProjectExplorer::BuildConfiguration
friend class ProjectExplorer::BuildConfigurationFactory;
NimBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
- void initialize(const ProjectExplorer::BuildInfo &info) override;
- ProjectExplorer::BuildConfiguration::BuildType buildType() const override;
+ void initialize() override;
public:
Utils::FilePath cacheDirectory() const;
@@ -63,15 +62,9 @@ public:
NimBuildConfigurationFactory();
private:
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override;
-
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
-
- ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k,
- ProjectExplorer::BuildConfiguration::BuildType buildType) const;
-
- QString displayName(ProjectExplorer::BuildConfiguration::BuildType buildType) const;
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k,
+ const Utils::FilePath &projectPath,
+ bool forSetup) const override;
};
}
diff --git a/src/plugins/nim/project/nimbuildsystem.cpp b/src/plugins/nim/project/nimbuildsystem.cpp
new file mode 100644
index 0000000000..d5d34452d4
--- /dev/null
+++ b/src/plugins/nim/project/nimbuildsystem.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) Filippo Cucchetto <filippocucchetto@gmail.com>
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see 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 "nimbuildsystem.h"
+
+#include "nimproject.h"
+#include "nimprojectnode.h"
+
+#include <utils/algorithm.h>
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+
+#include <QVariantMap>
+
+#if 0
+#include "nimbuildconfiguration.h"
+#include "nimtoolchain.h"
+
+#include "../nimconstants.h"
+
+#include <coreplugin/icontext.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <coreplugin/iversioncontrol.h>
+#include <coreplugin/vcsmanager.h>
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/kit.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/target.h>
+#include <projectexplorer/toolchain.h>
+#include <projectexplorer/kitinformation.h>
+#include <texteditor/textdocument.h>
+
+#include <utils/runextensions.h>
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
+
+#include <QFileInfo>
+#include <QQueue>
+#endif
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Nim {
+
+const char SETTINGS_KEY[] = "Nim.BuildSystem";
+const char EXCLUDED_FILES_KEY[] = "ExcludedFiles";
+
+NimBuildSystem::NimBuildSystem(Project *project)
+ : BuildSystem(project)
+{
+ connect(project, &Project::settingsLoaded, this, &NimBuildSystem::loadSettings);
+ connect(project, &Project::aboutToSaveSettings, this, &NimBuildSystem::saveSettings);
+
+ connect(&m_scanner, &TreeScanner::finished, this, &NimBuildSystem::updateProject);
+ m_scanner.setFilter([this](const Utils::MimeType &, const Utils::FilePath &fp) {
+ const QString path = fp.toString();
+ return excludedFiles().contains(path) || path.endsWith(".nimproject")
+ || path.contains(".nimproject.user");
+ });
+
+ connect(&m_directoryWatcher, &FileSystemWatcher::directoryChanged, this, [this]() {
+ requestParse();
+ });
+}
+
+bool NimBuildSystem::addFiles(const QStringList &filePaths)
+{
+ m_excludedFiles = Utils::filtered(m_excludedFiles, [&](const QString & f) {
+ return !filePaths.contains(f);
+ });
+ requestParse();
+ return true;
+}
+
+bool NimBuildSystem::removeFiles(const QStringList &filePaths)
+{
+ m_excludedFiles.append(filePaths);
+ m_excludedFiles = Utils::filteredUnique(m_excludedFiles);
+ requestParse();
+ return true;
+}
+
+bool NimBuildSystem::renameFile(const QString &filePath, const QString &newFilePath)
+{
+ Q_UNUSED(filePath)
+ m_excludedFiles.removeOne(newFilePath);
+ requestParse();
+ return true;
+}
+
+void NimBuildSystem::setExcludedFiles(const QStringList &list)
+{
+ m_excludedFiles = list;
+}
+
+QStringList NimBuildSystem::excludedFiles()
+{
+ return m_excludedFiles;
+}
+
+void NimBuildSystem::parseProject(BuildSystem::ParsingContext &&ctx)
+{
+ QTC_ASSERT(!m_currentContext.project, return );
+ m_currentContext = std::move(ctx);
+ QTC_CHECK(m_currentContext.project);
+
+ m_scanner.asyncScanForFiles(m_currentContext.project->projectDirectory());
+}
+
+const FilePathList NimBuildSystem::nimFiles() const
+{
+ return project()->files(
+ [](const Node *n) { return Project::AllFiles(n) && n->path().endsWith(".nim"); });
+}
+
+void NimBuildSystem::loadSettings()
+{
+ QVariantMap settings = project()->namedSettings(SETTINGS_KEY).toMap();
+ if (settings.contains(EXCLUDED_FILES_KEY))
+ m_excludedFiles = settings.value(EXCLUDED_FILES_KEY, m_excludedFiles).toStringList();
+
+ requestParse();
+}
+
+void NimBuildSystem::saveSettings()
+{
+ QVariantMap settings;
+ settings.insert(EXCLUDED_FILES_KEY, m_excludedFiles);
+ project()->setNamedSettings(SETTINGS_KEY, settings);
+}
+
+void NimBuildSystem::updateProject()
+{
+ auto newRoot = std::make_unique<NimProjectNode>(project()->projectDirectory());
+
+ QSet<QString> directories;
+ for (FileNode *node : m_scanner.release()) {
+ if (!node->path().endsWith(".nim"))
+ node->setEnabled(false); // Disable files that do not end in .nim
+ directories.insert(node->directory());
+ newRoot->addNestedNode(std::unique_ptr<FileNode>(node));
+ }
+
+ newRoot->setDisplayName(project()->displayName());
+ project()->setRootProjectNode(std::move(newRoot));
+
+ m_directoryWatcher.addDirectories(Utils::toList(directories), FileSystemWatcher::WatchAllChanges);
+
+ m_currentContext.guard.markAsSuccess();
+
+ m_currentContext = {};
+}
+
+} // namespace Nim
diff --git a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.h b/src/plugins/nim/project/nimbuildsystem.h
index 3de9964856..dde498f452 100644
--- a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.h
+++ b/src/plugins/nim/project/nimbuildsystem.h
@@ -25,27 +25,45 @@
#pragma once
-#include <projectexplorer/buildstep.h>
+#include <projectexplorer/buildsystem.h>
+#include <projectexplorer/treescanner.h>
-namespace Nim {
-
-class NimCompilerCleanStep;
+#include <utils/filesystemwatcher.h>
-namespace Ui { class NimCompilerCleanStepConfigWidget; }
+namespace Nim {
-class NimCompilerCleanStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
+class NimBuildSystem : public ProjectExplorer::BuildSystem
{
Q_OBJECT
public:
- NimCompilerCleanStepConfigWidget(NimCompilerCleanStep *cleanStep);
+ explicit NimBuildSystem(ProjectExplorer::Project *project);
+
+ bool addFiles(const QStringList &filePaths);
+ bool removeFiles(const QStringList &filePaths);
+ bool renameFile(const QString &filePath, const QString &newFilePath);
+
+ void setExcludedFiles(const QStringList &list); // Keep for compatibility with Qt Creator 4.10
+ QStringList excludedFiles(); // Make private when no longer supporting Qt Creator 4.10
- ~NimCompilerCleanStepConfigWidget();
+ void parseProject(ParsingContext &&ctx) final;
+
+ const Utils::FilePathList nimFiles() const;
private:
- void updateUi();
+ void loadSettings();
+ void saveSettings();
+
+ void collectProjectFiles();
+ void updateProject();
+
+ QStringList m_excludedFiles;
+
+ ProjectExplorer::TreeScanner m_scanner;
+
+ ParsingContext m_currentContext;
- QScopedPointer<Ui::NimCompilerCleanStepConfigWidget> m_ui;
+ Utils::FileSystemWatcher m_directoryWatcher;
};
-}
+} // namespace Nim
diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp
index 1ecc7e8c63..d9cd7599b2 100644
--- a/src/plugins/nim/project/nimcompilerbuildstep.cpp
+++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp
@@ -25,9 +25,9 @@
#include "nimcompilerbuildstep.h"
#include "nimbuildconfiguration.h"
-#include "nimconstants.h"
+#include "nimbuildsystem.h"
#include "nimcompilerbuildstepconfigwidget.h"
-#include "nimproject.h"
+#include "nimconstants.h"
#include "nimtoolchain.h"
#include <projectexplorer/buildconfiguration.h>
@@ -206,7 +206,6 @@ void NimCompilerBuildStep::updateProcessParameters()
{
updateOutFilePath();
updateCommand();
- updateArguments();
updateWorkingDirectory();
updateEnvironment();
emit processParametersChanged();
@@ -220,16 +219,6 @@ void NimCompilerBuildStep::updateOutFilePath()
setOutFilePath(bc->buildDirectory().pathAppended(targetName));
}
-void NimCompilerBuildStep::updateCommand()
-{
- QTC_ASSERT(target(), return);
- QTC_ASSERT(target()->kit(), return);
- Kit *kit = target()->kit();
- auto tc = dynamic_cast<NimToolChain*>(ToolChainKitAspect::toolChain(kit, Constants::C_NIMLANGUAGE_ID));
- QTC_ASSERT(tc, return);
- processParameters()->setCommand(tc->compilerCommand());
-}
-
void NimCompilerBuildStep::updateWorkingDirectory()
{
auto bc = qobject_cast<NimBuildConfiguration *>(buildConfiguration());
@@ -237,38 +226,38 @@ void NimCompilerBuildStep::updateWorkingDirectory()
processParameters()->setWorkingDirectory(bc->buildDirectory());
}
-void NimCompilerBuildStep::updateArguments()
+void NimCompilerBuildStep::updateCommand()
{
auto bc = qobject_cast<NimBuildConfiguration *>(buildConfiguration());
QTC_ASSERT(bc, return);
- QStringList arguments;
- arguments << QStringLiteral("c");
-
- switch (m_defaultOptions) {
- case Release:
- arguments << QStringLiteral("-d:release");
- break;
- case Debug:
- arguments << QStringLiteral("--debugInfo")
- << QStringLiteral("--lineDir:on");
- break;
- default:
- break;
- }
+ QTC_ASSERT(target(), return);
+ QTC_ASSERT(target()->kit(), return);
+ Kit *kit = target()->kit();
+ auto tc = dynamic_cast<NimToolChain*>(ToolChainKitAspect::toolChain(kit, Constants::C_NIMLANGUAGE_ID));
+ QTC_ASSERT(tc, return);
- arguments << QStringLiteral("--out:%1").arg(m_outFilePath.toString());
- arguments << QStringLiteral("--nimCache:%1").arg(bc->cacheDirectory().toString());
+ CommandLine cmd{tc->compilerCommand()};
- arguments << m_userCompilerOptions;
- arguments << m_targetNimFile.toString();
+ cmd.addArg("c");
- // Remove empty args
- auto predicate = [](const QString &str) { return str.isEmpty(); };
- auto it = std::remove_if(arguments.begin(), arguments.end(), predicate);
- arguments.erase(it, arguments.end());
+ if (m_defaultOptions == Release)
+ cmd.addArg("-d:release");
+ else if (m_defaultOptions == Debug)
+ cmd.addArgs({"--debugInfo", "--lineDir:on"});
+
+ cmd.addArg("--out:" + m_outFilePath.toString());
+ cmd.addArg("--nimCache:" + bc->cacheDirectory().toString());
+
+ for (const QString &arg : m_userCompilerOptions) {
+ if (!arg.isEmpty())
+ cmd.addArg(arg);
+ }
+
+ if (!m_targetNimFile.isEmpty())
+ cmd.addArg(m_targetNimFile.toString());
- processParameters()->setArguments(arguments.join(QChar::Space));
+ processParameters()->setCommandLine(cmd);
}
void NimCompilerBuildStep::updateEnvironment()
@@ -282,7 +271,8 @@ void NimCompilerBuildStep::updateTargetNimFile()
{
if (!m_targetNimFile.isEmpty())
return;
- const Utils::FilePathList nimFiles = static_cast<NimProject *>(project())->nimFiles();
+ const Utils::FilePathList nimFiles = static_cast<NimBuildSystem *>(project()->buildSystem())
+ ->nimFiles();
if (!nimFiles.isEmpty())
setTargetNimFile(nimFiles.at(0));
}
diff --git a/src/plugins/nim/project/nimcompilerbuildstep.h b/src/plugins/nim/project/nimcompilerbuildstep.h
index a866694c9a..b9ea46316f 100644
--- a/src/plugins/nim/project/nimcompilerbuildstep.h
+++ b/src/plugins/nim/project/nimcompilerbuildstep.h
@@ -72,7 +72,6 @@ private:
void updateProcessParameters();
void updateCommand();
void updateWorkingDirectory();
- void updateArguments();
void updateEnvironment();
void updateTargetNimFile();
diff --git a/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp b/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp
index 27acf21726..01e9e23ca6 100644
--- a/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp
+++ b/src/plugins/nim/project/nimcompilerbuildstepconfigwidget.cpp
@@ -24,16 +24,18 @@
****************************************************************************/
#include "nimcompilerbuildstepconfigwidget.h"
-#include "ui_nimcompilerbuildstepconfigwidget.h"
#include "nimbuildconfiguration.h"
+#include "nimbuildsystem.h"
#include "nimcompilerbuildstep.h"
-#include "nimproject.h"
+
+#include "ui_nimcompilerbuildstepconfigwidget.h"
#include "../nimconstants.h"
#include <projectexplorer/processparameters.h>
#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
using namespace ProjectExplorer;
using namespace Utils;
@@ -51,9 +53,10 @@ NimCompilerBuildStepConfigWidget::NimCompilerBuildStepConfigWidget(NimCompilerBu
setSummaryText(tr(Constants::C_NIMCOMPILERBUILDSTEPWIDGET_SUMMARY));
// Connect the project signals
- auto project = static_cast<NimProject *>(m_buildStep->project());
- connect(project, &NimProject::fileListChanged,
- this, &NimCompilerBuildStepConfigWidget::updateUi);
+ connect(m_buildStep->project(),
+ &Project::fileListChanged,
+ this,
+ &NimCompilerBuildStepConfigWidget::updateUi);
// Connect build step signals
connect(m_buildStep, &NimCompilerBuildStep::processParametersChanged,
@@ -74,7 +77,7 @@ NimCompilerBuildStepConfigWidget::~NimCompilerBuildStepConfigWidget() = default;
void NimCompilerBuildStepConfigWidget::onTargetChanged(int index)
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
auto data = m_ui->targetComboBox->currentData();
FilePath path = FilePath::fromString(data.toString());
m_buildStep->setTargetNimFile(path);
@@ -103,28 +106,22 @@ void NimCompilerBuildStepConfigWidget::updateCommandLineText()
{
ProcessParameters *parameters = m_buildStep->processParameters();
- QStringList command;
- command << parameters->command().toString();
- command << parameters->arguments();
-
- // Remove empty args
- auto predicate = [](const QString & str) { return str.isEmpty(); };
- auto it = std::remove_if(command.begin(), command.end(), predicate);
- command.erase(it, command.end());
+ const CommandLine cmd = parameters->command();
+ const QStringList parts = QtcProcess::splitArgs(cmd.toUserOutput());
- m_ui->commandTextEdit->setText(command.join(QChar::LineFeed));
+ m_ui->commandTextEdit->setText(parts.join(QChar::LineFeed));
}
void NimCompilerBuildStepConfigWidget::updateTargetComboBox()
{
- QTC_ASSERT(m_buildStep, return);
+ QTC_ASSERT(m_buildStep, return );
- auto project = qobject_cast<NimProject *>(m_buildStep->project());
- QTC_ASSERT(project, return);
+ const auto bs = qobject_cast<NimBuildSystem *>(m_buildStep->project()->buildSystem());
+ QTC_ASSERT(bs, return );
// Re enter the files
m_ui->targetComboBox->clear();
- foreach (const FilePath &file, project->nimFiles())
+ for (const FilePath &file : bs->nimFiles())
m_ui->targetComboBox->addItem(file.fileName(), file.toString());
const int index = m_ui->targetComboBox->findData(m_buildStep->targetNimFile().toString());
diff --git a/src/plugins/nim/project/nimcompilercleanstep.cpp b/src/plugins/nim/project/nimcompilercleanstep.cpp
index b802582108..03fa8fd67b 100644
--- a/src/plugins/nim/project/nimcompilercleanstep.cpp
+++ b/src/plugins/nim/project/nimcompilercleanstep.cpp
@@ -25,10 +25,10 @@
#include "nimcompilercleanstep.h"
#include "nimbuildconfiguration.h"
-#include "nimcompilercleanstepconfigwidget.h"
#include "../nimconstants.h"
+#include <projectexplorer/projectconfigurationaspects.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
@@ -45,11 +45,15 @@ NimCompilerCleanStep::NimCompilerCleanStep(BuildStepList *parentList)
{
setDefaultDisplayName(tr("Nim Clean Step"));
setDisplayName(tr("Nim Clean Step"));
-}
-BuildStepConfigWidget *NimCompilerCleanStep::createConfigWidget()
-{
- return new NimCompilerCleanStepConfigWidget(this);
+ auto workingDirectory = addAspect<BaseStringAspect>();
+ workingDirectory->setLabelText(tr("Working directory:"));
+ workingDirectory->setDisplayStyle(BaseStringAspect::LineEditDisplay);
+
+ setSummaryUpdater([this, workingDirectory] {
+ workingDirectory->setFilePath(buildConfiguration()->buildDirectory());
+ return displayName();
+ });
}
bool NimCompilerCleanStep::init()
@@ -122,7 +126,7 @@ NimCompilerCleanStepFactory::NimCompilerCleanStepFactory()
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
setSupportedConfiguration(Constants::C_NIMBUILDCONFIGURATION_ID);
setRepeatable(false);
- setDisplayName(NimCompilerCleanStep::tr(Nim::Constants::C_NIMCOMPILERCLEANSTEP_DISPLAY));
+ setDisplayName(NimCompilerCleanStep::tr("Nim Compiler Clean Step"));
}
} // Nim
diff --git a/src/plugins/nim/project/nimcompilercleanstep.h b/src/plugins/nim/project/nimcompilercleanstep.h
index 2cbde61beb..8acf4e0ae5 100644
--- a/src/plugins/nim/project/nimcompilercleanstep.h
+++ b/src/plugins/nim/project/nimcompilercleanstep.h
@@ -38,8 +38,6 @@ class NimCompilerCleanStep : public ProjectExplorer::BuildStep
public:
NimCompilerCleanStep(ProjectExplorer::BuildStepList *parentList);
- ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
-
private:
bool init() override;
void doRun() override;
diff --git a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp b/src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp
deleted file mode 100644
index 0b82052202..0000000000
--- a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) Filippo Cucchetto <filippocucchetto@gmail.com>
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see 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 "nimcompilercleanstepconfigwidget.h"
-#include "ui_nimcompilercleanstepconfigwidget.h"
-#include "nimcompilercleanstep.h"
-
-#include "../nimconstants.h"
-
-#include "projectexplorer/buildconfiguration.h"
-
-using namespace ProjectExplorer;
-
-namespace Nim {
-
-NimCompilerCleanStepConfigWidget::NimCompilerCleanStepConfigWidget(NimCompilerCleanStep *cleanStep)
- : BuildStepConfigWidget(cleanStep)
- , m_ui(new Ui::NimCompilerCleanStepConfigWidget())
-{
- m_ui->setupUi(this);
- setDisplayName(tr(Constants::C_NIMCOMPILERCLEANSTEPWIDGET_DISPLAY));
- setSummaryText(tr(Constants::C_NIMCOMPILERCLEANSTEPWIDGET_SUMMARY));
- connect(cleanStep->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
- this, &NimCompilerCleanStepConfigWidget::updateUi);
- updateUi();
-}
-
-NimCompilerCleanStepConfigWidget::~NimCompilerCleanStepConfigWidget() = default;
-
-void NimCompilerCleanStepConfigWidget::updateUi()
-{
- auto buildDiretory = step()->buildConfiguration()->buildDirectory();
- m_ui->workingDirectoryLineEdit->setText(buildDiretory.toString());
-}
-
-}
-
diff --git a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui b/src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui
deleted file mode 100644
index 20dd2e05d0..0000000000
--- a/src/plugins/nim/project/nimcompilercleanstepconfigwidget.ui
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Nim::NimCompilerCleanStepConfigWidget</class>
- <widget class="QWidget" name="Nim::NimCompilerCleanStepConfigWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>300</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string/>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="workingDirectoryLabel">
- <property name="text">
- <string>Working directory:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="workingDirectoryLineEdit">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp
index a6cad1657f..08f1019c8a 100644
--- a/src/plugins/nim/project/nimproject.cpp
+++ b/src/plugins/nim/project/nimproject.cpp
@@ -24,42 +24,20 @@
****************************************************************************/
#include "nimproject.h"
-#include "nimbuildconfiguration.h"
-#include "nimprojectnode.h"
-#include "nimtoolchain.h"
#include "../nimconstants.h"
+#include "nimbuildsystem.h"
+#include "nimtoolchain.h"
#include <coreplugin/icontext.h>
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <coreplugin/iversioncontrol.h>
-#include <coreplugin/vcsmanager.h>
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/kit.h>
-#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/projectnodes.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
#include <projectexplorer/kitinformation.h>
-#include <texteditor/textdocument.h>
-
-#include <utils/algorithm.h>
-#include <utils/qtcassert.h>
-#include <utils/runextensions.h>
-
-#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/editormanager/ieditor.h>
-
-#include <QFileInfo>
-#include <QQueue>
+#include <projectexplorer/projectexplorerconstants.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace Nim {
-const int MIN_TIME_BETWEEN_PROJECT_SCANS = 4500;
-
NimProject::NimProject(const FilePath &fileName) : Project(Constants::C_NIM_MIMETYPE, fileName)
{
setId(Constants::C_NIMPROJECT_ID);
@@ -67,87 +45,7 @@ NimProject::NimProject(const FilePath &fileName) : Project(Constants::C_NIM_MIME
// ensure debugging is enabled (Nim plugin translates nim code to C code)
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
- m_projectScanTimer.setSingleShot(true);
- connect(&m_projectScanTimer, &QTimer::timeout, this, &NimProject::collectProjectFiles);
- connect(this, &Project::settingsLoaded, this, &NimProject::collectProjectFiles);
-
- connect(&m_futureWatcher, &QFutureWatcher<QList<FileNode *>>::finished, this,
- &NimProject::updateProject);
-}
-
-void NimProject::scheduleProjectScan()
-{
- auto elapsedTime = m_lastProjectScan.elapsed();
- if (elapsedTime < MIN_TIME_BETWEEN_PROJECT_SCANS) {
- if (!m_projectScanTimer.isActive()) {
- m_projectScanTimer.setInterval(MIN_TIME_BETWEEN_PROJECT_SCANS - elapsedTime);
- m_projectScanTimer.start();
- }
- } else {
- collectProjectFiles();
- }
-}
-
-bool NimProject::addFiles(const QStringList &filePaths)
-{
- m_excludedFiles = Utils::filtered(m_excludedFiles, [&](const QString & f) {
- return !filePaths.contains(f);
- });
- scheduleProjectScan();
- return true;
-}
-
-bool NimProject::removeFiles(const QStringList &filePaths)
-{
- m_excludedFiles.append(filePaths);
- m_excludedFiles = Utils::filteredUnique(m_excludedFiles);
- scheduleProjectScan();
- return true;
-}
-
-bool NimProject::renameFile(const QString &filePath, const QString &newFilePath)
-{
- Q_UNUSED(filePath)
- m_excludedFiles.removeOne(newFilePath);
- scheduleProjectScan();
- return true;
-}
-
-void NimProject::collectProjectFiles()
-{
- m_lastProjectScan.start();
- QTC_ASSERT(!m_futureWatcher.future().isRunning(), return);
- FilePath prjDir = projectDirectory();
- QFuture<QList<ProjectExplorer::FileNode *>> future = Utils::runAsync([prjDir,
- excluded = m_excludedFiles] {
- return FileNode::scanForFiles(prjDir, [excluded](const FilePath & fn) -> FileNode * {
- const QString fileName = fn.fileName();
- if (excluded.contains(fn.toString())
- || fileName.endsWith(".nimproject", HostOsInfo::fileNameCaseSensitivity())
- || fileName.contains(".nimproject.user", HostOsInfo::fileNameCaseSensitivity()))
- return nullptr;
- return new FileNode(fn, FileType::Source);
- });
- });
- m_futureWatcher.setFuture(future);
- Core::ProgressManager::addTask(future, tr("Scanning for Nim files"), "Nim.Project.Scan");
-}
-
-void NimProject::updateProject()
-{
- emitParsingStarted();
-
- auto newRoot = std::make_unique<NimProjectNode>(*this, projectDirectory());
-
- QList<FileNode *> files = m_futureWatcher.future().result();
-
- for (FileNode *node : files)
- newRoot->addNestedNode(std::unique_ptr<FileNode>(node));
-
- newRoot->setDisplayName(displayName());
- setRootProjectNode(std::move(newRoot));
-
- emitParsingFinished(true);
+ setBuildSystem(std::make_unique<NimBuildSystem>(this));
}
Tasks NimProject::projectIssues(const Kit *k) const
@@ -164,24 +62,20 @@ Tasks NimProject::projectIssues(const Kit *k) const
return result;
}
-FilePathList NimProject::nimFiles() const
-{
- return files([](const ProjectExplorer::Node *n) {
- return AllFiles(n) && n->filePath().endsWith(".nim");
- });
-}
-
QVariantMap NimProject::toMap() const
{
QVariantMap result = Project::toMap();
- result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = m_excludedFiles;
+ result[Constants::C_NIMPROJECT_EXCLUDEDFILES] = static_cast<NimBuildSystem *>(buildSystem())
+ ->excludedFiles();
return result;
}
Project::RestoreResult NimProject::fromMap(const QVariantMap &map, QString *errorMessage)
{
- m_excludedFiles = map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList();
- return Project::fromMap(map, errorMessage);
+ auto result = Project::fromMap(map, errorMessage);
+ static_cast<NimBuildSystem *>(buildSystem())
+ ->setExcludedFiles(map.value(Constants::C_NIMPROJECT_EXCLUDEDFILES).toStringList());
+ return result;
}
} // namespace Nim
diff --git a/src/plugins/nim/project/nimproject.h b/src/plugins/nim/project/nimproject.h
index d0143de2fd..afe33cf940 100644
--- a/src/plugins/nim/project/nimproject.h
+++ b/src/plugins/nim/project/nimproject.h
@@ -34,6 +34,8 @@
namespace Nim {
+class NimBuildSystem;
+
class NimProject : public ProjectExplorer::Project
{
Q_OBJECT
@@ -42,25 +44,13 @@ public:
explicit NimProject(const Utils::FilePath &fileName);
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
- Utils::FilePathList nimFiles() const;
- QVariantMap toMap() const final;
- bool addFiles(const QStringList &filePaths);
- bool removeFiles(const QStringList &filePaths);
- bool renameFile(const QString &filePath, const QString &newFilePath);
+ // Keep for compatibility with Qt Creator 4.10
+ QVariantMap toMap() const final;
protected:
+ // Keep for compatibility with Qt Creator 4.10
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
-
-private:
- void scheduleProjectScan();
- void collectProjectFiles();
- void updateProject();
-
- QStringList m_excludedFiles;
- QFutureWatcher<QList<ProjectExplorer::FileNode *>> m_futureWatcher;
- QElapsedTimer m_lastProjectScan;
- QTimer m_projectScanTimer;
};
-}
+} // namespace Nim
diff --git a/src/plugins/nim/project/nimprojectnode.cpp b/src/plugins/nim/project/nimprojectnode.cpp
index 6a6385b67e..5232ea500c 100644
--- a/src/plugins/nim/project/nimprojectnode.cpp
+++ b/src/plugins/nim/project/nimprojectnode.cpp
@@ -24,17 +24,18 @@
****************************************************************************/
#include "nimprojectnode.h"
-#include "nimproject.h"
+
+#include "nimbuildsystem.h"
+
+#include <projectexplorer/projecttree.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace Nim {
-NimProjectNode::NimProjectNode(NimProject &project,
- const FilePath &projectFilePath)
+NimProjectNode::NimProjectNode(const FilePath &projectFilePath)
: ProjectNode(projectFilePath)
- , m_project(project)
{}
bool NimProjectNode::supportsAction(ProjectAction action, const Node *node) const
@@ -53,12 +54,14 @@ bool NimProjectNode::supportsAction(ProjectAction action, const Node *node) cons
bool NimProjectNode::addFiles(const QStringList &filePaths, QStringList *)
{
- return m_project.addFiles(filePaths);
+ return buildSystem()->addFiles(filePaths);
}
-bool NimProjectNode::removeFiles(const QStringList &filePaths, QStringList *)
+RemovedFilesFromProject NimProjectNode::removeFiles(const QStringList &filePaths,
+ QStringList *)
{
- return m_project.removeFiles(filePaths);
+ return buildSystem()->removeFiles(filePaths) ? RemovedFilesFromProject::Ok
+ : RemovedFilesFromProject::Error;
}
bool NimProjectNode::deleteFiles(const QStringList &)
@@ -68,7 +71,13 @@ bool NimProjectNode::deleteFiles(const QStringList &)
bool NimProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
{
- return m_project.renameFile(filePath, newFilePath);
+ return buildSystem()->renameFile(filePath, newFilePath);
}
+NimBuildSystem *NimProjectNode::buildSystem() const
+{
+ return qobject_cast<NimBuildSystem *>(
+ ProjectTree::instance()->projectForNode(this)->buildSystem());
}
+
+} // namespace Nim
diff --git a/src/plugins/nim/project/nimprojectnode.h b/src/plugins/nim/project/nimprojectnode.h
index 6a950bdf4f..98ea5aeff1 100644
--- a/src/plugins/nim/project/nimprojectnode.h
+++ b/src/plugins/nim/project/nimprojectnode.h
@@ -31,21 +31,22 @@ namespace Utils { class FilePath; }
namespace Nim {
-class NimProject;
+class NimBuildSystem;
class NimProjectNode : public ProjectExplorer::ProjectNode
{
public:
- NimProjectNode(NimProject &project, const Utils::FilePath &projectFilePath);
+ NimProjectNode(const Utils::FilePath &projectFilePath);
bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool addFiles(const QStringList &filePaths, QStringList *) override;
- bool removeFiles(const QStringList &filePaths, QStringList *) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *) override;
bool deleteFiles(const QStringList &) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
private:
- NimProject &m_project;
+ NimBuildSystem *buildSystem() const;
};
}
diff --git a/src/plugins/nim/project/nimrunconfiguration.cpp b/src/plugins/nim/project/nimrunconfiguration.cpp
index 7849f4dc19..9bfcc275bb 100644
--- a/src/plugins/nim/project/nimrunconfiguration.cpp
+++ b/src/plugins/nim/project/nimrunconfiguration.cpp
@@ -63,7 +63,8 @@ NimRunConfiguration::NimRunConfiguration(Target *target, Core::Id id)
void NimRunConfiguration::updateConfiguration()
{
auto buildConfiguration = qobject_cast<NimBuildConfiguration *>(activeBuildConfiguration());
- QTC_ASSERT(buildConfiguration, return);
+ if (!buildConfiguration)
+ return;
setActiveBuildConfiguration(buildConfiguration);
const QFileInfo outFileInfo = buildConfiguration->outFilePath().toFileInfo();
aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(outFileInfo.absoluteFilePath()));
diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp
index 3e7fcbef72..6a922f9553 100644
--- a/src/plugins/nim/project/nimtoolchain.cpp
+++ b/src/plugins/nim/project/nimtoolchain.cpp
@@ -49,19 +49,7 @@ NimToolChain::NimToolChain(Core::Id typeId)
, m_version(std::make_tuple(-1,-1,-1))
{
setLanguage(Constants::C_NIMLANGUAGE_ID);
-}
-
-NimToolChain::NimToolChain(const NimToolChain &other)
- : ToolChain(other.typeId())
- , m_compilerCommand(other.m_compilerCommand)
- , m_version(other.m_version)
-{
- setLanguage(Constants::C_NIMLANGUAGE_ID);
-}
-
-QString NimToolChain::typeDisplayName() const
-{
- return NimToolChainFactory::tr("Nim");
+ setTypeDisplayName(NimToolChainFactory::tr("Nim"));
}
Abi NimToolChain::targetAbi() const
@@ -97,12 +85,14 @@ WarningFlags NimToolChain::warningFlags(const QStringList &) const
return WarningFlags::NoWarnings;
}
-ToolChain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &) const
{
return ToolChain::BuiltInHeaderPathsRunner();
}
-HeaderPaths NimToolChain::builtInHeaderPaths(const QStringList &, const FilePath &) const
+HeaderPaths NimToolChain::builtInHeaderPaths(const QStringList &, const FilePath &,
+ const Environment &) const
{
return {};
}
diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h
index b35e073ccd..4b9f6c9cd7 100644
--- a/src/plugins/nim/project/nimtoolchain.h
+++ b/src/plugins/nim/project/nimtoolchain.h
@@ -36,7 +36,6 @@ public:
NimToolChain();
explicit NimToolChain(Core::Id typeId);
- QString typeDisplayName() const override;
ProjectExplorer::Abi targetAbi() const override;
bool isValid() const override;
@@ -45,9 +44,11 @@ public:
Utils::LanguageExtensions languageExtensions(const QStringList &flags) const final;
ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &) const override;
ProjectExplorer::HeaderPaths builtInHeaderPaths(const QStringList &flags,
- const Utils::FilePath &sysRoot) const final;
+ const Utils::FilePath &sysRoot,
+ const Utils::Environment &) const final;
void addToEnvironment(Utils::Environment &env) const final;
Utils::FilePath makeCommand(const Utils::Environment &env) const final;
Utils::FilePath compilerCommand() const final;
@@ -62,8 +63,6 @@ public:
static bool parseVersion(const Utils::FilePath &path, std::tuple<int, int, int> &version);
private:
- NimToolChain(const NimToolChain &other);
-
Utils::FilePath m_compilerCommand;
std::tuple<int, int, int> m_version;
};
diff --git a/src/plugins/nim/project/nimtoolchainfactory.cpp b/src/plugins/nim/project/nimtoolchainfactory.cpp
index 5fc94c4926..7467ab7789 100644
--- a/src/plugins/nim/project/nimtoolchainfactory.cpp
+++ b/src/plugins/nim/project/nimtoolchainfactory.cpp
@@ -73,13 +73,13 @@ QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alr
return result;
}
-QList<ToolChain *> NimToolChainFactory::autoDetect(const FilePath &compilerPath, const Core::Id &language)
+QList<ToolChain *> NimToolChainFactory::detectForImport(const ToolChainDescription &tcd)
{
QList<ToolChain *> result;
- if (language == Constants::C_NIMLANGUAGE_ID) {
+ if (tcd.language == Constants::C_NIMLANGUAGE_ID) {
auto tc = new NimToolChain;
tc->setDetection(ToolChain::ManualDetection); // FIXME: sure?
- tc->setCompilerCommand(compilerPath);
+ tc->setCompilerCommand(tcd.compilerPath);
result.append(tc);
}
return result;
diff --git a/src/plugins/nim/project/nimtoolchainfactory.h b/src/plugins/nim/project/nimtoolchainfactory.h
index 70a49cbb37..0b79653400 100644
--- a/src/plugins/nim/project/nimtoolchainfactory.h
+++ b/src/plugins/nim/project/nimtoolchainfactory.h
@@ -42,7 +42,7 @@ public:
NimToolChainFactory();
QList<ProjectExplorer::ToolChain *> autoDetect(const QList<ProjectExplorer::ToolChain *> &alreadyKnown) final;
- QList<ProjectExplorer::ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language) final;
+ QList<ProjectExplorer::ToolChain *> detectForImport(const ProjectExplorer::ToolChainDescription &tcd) final;
};
class NimToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget
diff --git a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp
index 299c6d13e5..d7b7eac6c1 100644
--- a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp
+++ b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp
@@ -63,7 +63,7 @@ QWidget *NimCodeStylePreferencesFactory::createEditor(TextEditor::ICodeStylePref
QWidget *parent) const
{
auto result = new NimCodeStylePreferencesWidget(preferences, parent);
- result->layout()->setMargin(0);
+ result->layout()->setContentsMargins(0, 0, 0, 0);
return result;
}
diff --git a/src/plugins/nim/settings/nimcodestylesettingspage.cpp b/src/plugins/nim/settings/nimcodestylesettingspage.cpp
index 0c3d6dd0f2..d93f4d3ed0 100644
--- a/src/plugins/nim/settings/nimcodestylesettingspage.cpp
+++ b/src/plugins/nim/settings/nimcodestylesettingspage.cpp
@@ -42,9 +42,8 @@ using namespace TextEditor;
namespace Nim {
-NimCodeStyleSettingsPage::NimCodeStyleSettingsPage(QWidget *parent)
- : Core::IOptionsPage(parent)
- , m_nimCodeStylePreferences(nullptr)
+NimCodeStyleSettingsPage::NimCodeStyleSettingsPage()
+ : m_nimCodeStylePreferences(nullptr)
, m_widget(nullptr)
{
setId(Nim::Constants::C_NIMCODESTYLESETTINGSPAGE_ID);
diff --git a/src/plugins/nim/settings/nimcodestylesettingspage.h b/src/plugins/nim/settings/nimcodestylesettingspage.h
index 5f492c4ad0..2f1f779ecb 100644
--- a/src/plugins/nim/settings/nimcodestylesettingspage.h
+++ b/src/plugins/nim/settings/nimcodestylesettingspage.h
@@ -41,7 +41,7 @@ class NimCodeStyleSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit NimCodeStyleSettingsPage(QWidget *parent = nullptr);
+ NimCodeStyleSettingsPage();
~NimCodeStyleSettingsPage() override;
QWidget *widget() override;
diff --git a/src/plugins/nim/suggest/server.cpp b/src/plugins/nim/suggest/server.cpp
index 8e9b79b827..bd8a9fb1a4 100644
--- a/src/plugins/nim/suggest/server.cpp
+++ b/src/plugins/nim/suggest/server.cpp
@@ -107,7 +107,7 @@ void NimSuggestServer::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
clearState();
- Q_UNUSED(exitCode);
+ Q_UNUSED(exitCode)
if (exitStatus == QProcess::ExitStatus::CrashExit)
emit crashed();
else
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 580c52d78f..b7c0be4bed 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -996,7 +996,7 @@ PerforceResponse PerforcePlugin::synchronousProcess(const QString &workingDir,
}
}
process.setTimeOutMessageBoxEnabled(true);
- const SynchronousProcessResponse sp_resp = process.run(settings().p4BinaryPath(), args);
+ const SynchronousProcessResponse sp_resp = process.run({settings().p4BinaryPath(), args});
PerforceResponse response;
response.error = true;
@@ -1118,7 +1118,7 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QString &workingDir,
actualArgs.append(args);
if (flags & CommandToWindow)
- VcsOutputWindow::appendCommand(workingDir, FilePath::fromString(settings().p4BinaryPath()), actualArgs);
+ VcsOutputWindow::appendCommand(workingDir, {settings().p4BinaryPath(), actualArgs});
if (flags & ShowBusyCursor)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
diff --git a/src/plugins/perforce/perforcesubmiteditor.cpp b/src/plugins/perforce/perforcesubmiteditor.cpp
index 38b1a04f1a..29b72462b0 100644
--- a/src/plugins/perforce/perforcesubmiteditor.cpp
+++ b/src/plugins/perforce/perforcesubmiteditor.cpp
@@ -54,11 +54,8 @@ QByteArray PerforceSubmitEditor::fileContents() const
const_cast<PerforceSubmitEditor*>(this)->updateEntries();
QString text;
QTextStream out(&text);
- QMapIterator<QString, QString> it(m_entries);
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it)
out << it.key() << ":" << it.value();
- }
return text.toLocal8Bit();
}
diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp
index 87d08806b5..b8cc77d069 100644
--- a/src/plugins/perforce/perforceversioncontrol.cpp
+++ b/src/plugins/perforce/perforceversioncontrol.cpp
@@ -51,7 +51,7 @@ Core::Id PerforceVersionControl::id() const
bool PerforceVersionControl::isVcsFileOrDirectory(const Utils::FilePath &fileName) const
{
- Q_UNUSED(fileName);
+ Q_UNUSED(fileName)
return false; // Perforce does not seem to litter its files into the source tree.
}
@@ -83,7 +83,7 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const
Core::IVersionControl::OpenSupportMode PerforceVersionControl::openSupportMode(const QString &fileName) const
{
- Q_UNUSED(fileName);
+ Q_UNUSED(fileName)
return OpenOptional;
}
diff --git a/src/plugins/perfprofiler/PerfProfilerFlameGraphView.qml b/src/plugins/perfprofiler/PerfProfilerFlameGraphView.qml
index 689d233731..58677b311a 100644
--- a/src/plugins/perfprofiler/PerfProfilerFlameGraphView.qml
+++ b/src/plugins/perfprofiler/PerfProfilerFlameGraphView.qml
@@ -28,7 +28,6 @@ import "../tracing/"
FlameGraphView {
id: root
- sizeRole: PerfProfilerFlameGraphModel.SamplesRole
model: flameGraphModel
diff --git a/src/plugins/perfprofiler/perfconfigwidget.cpp b/src/plugins/perfprofiler/perfconfigwidget.cpp
index 1fe3acf58d..bdf2a0540e 100644
--- a/src/plugins/perfprofiler/perfconfigwidget.cpp
+++ b/src/plugins/perfprofiler/perfconfigwidget.cpp
@@ -187,7 +187,7 @@ void PerfConfigWidget::readTracePoints()
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
if (messageBox.exec() == QMessageBox::Yes) {
ProjectExplorer::Runnable runnable;
- runnable.executable = QLatin1String("perf");
+ runnable.executable = Utils::FilePath::fromString("perf");
runnable.commandLineArguments = QLatin1String("probe -l");
m_process->start(runnable);
@@ -246,7 +246,7 @@ void PerfConfigWidget::handleProcessError(QProcess::ProcessError error)
QWidget *SettingsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
- Q_UNUSED(option);
+ Q_UNUSED(option)
const int row = index.row();
const int column = index.column();
const PerfConfigEventsModel *model = qobject_cast<const PerfConfigEventsModel *>(index.model());
@@ -406,7 +406,7 @@ void SettingsDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
void SettingsDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
editor->setGeometry(option.rect);
}
diff --git a/src/plugins/perfprofiler/perfprofilerconstants.h b/src/plugins/perfprofiler/perfprofilerconstants.h
index 32e174cf5d..f29cecc7ca 100644
--- a/src/plugins/perfprofiler/perfprofilerconstants.h
+++ b/src/plugins/perfprofiler/perfprofilerconstants.h
@@ -56,6 +56,7 @@ const char PerfCallgraphModeId[] = "Analyzer.Perf.CallgraphMode";
const char PerfEventsId[] = "Analyzer.Perf.Events";
const char PerfExtraArgumentsId[] = "Analyzer.Perf.ExtraArguments";
const char PerfSettingsId[] = "Analyzer.Perf.Settings";
+const char PerfRecordArgumentsId[] = "Analyzer.Perf.RecordArguments";
const unsigned int PerfDefaultPeriod = 250;
const unsigned int PerfDefaultStackSize = 4096;
diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
index 79ebb32ba1..d9f4cc3052 100644
--- a/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
+++ b/src/plugins/perfprofiler/perfprofilerflamegraphmodel.cpp
@@ -149,7 +149,7 @@ int PerfProfilerFlameGraphModel::rowCount(const QModelIndex &parent) const
int PerfProfilerFlameGraphModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 1;
}
@@ -227,7 +227,7 @@ void PerfProfilerFlameGraphData::updateTraceData(const PerfEvent &event, const P
PerfProfilerFlameGraphModel::Data *data,
int numSamples)
{
- Q_UNUSED(type);
+ Q_UNUSED(type)
for (int i = 0, end = event.numAttributes(); i < end; ++i) {
const PerfEventType::Attribute &attribute = manager->attribute(event.attributeId(i));
if (attribute.type != PerfEventType::TypeTracepoint)
diff --git a/src/plugins/perfprofiler/perfprofilerplugin.cpp b/src/plugins/perfprofiler/perfprofilerplugin.cpp
index 26f2272204..e9440e6141 100644
--- a/src/plugins/perfprofiler/perfprofilerplugin.cpp
+++ b/src/plugins/perfprofiler/perfprofilerplugin.cpp
@@ -66,15 +66,13 @@ public:
PerfProfilerPluginPrivate()
{
RunConfiguration::registerAspect<PerfRunConfigurationAspect>();
-
- RunControl::registerWorkerCreator(ProjectExplorer::Constants::PERFPROFILER_RUN_MODE,
- [](RunControl *runControl){ return new PerfProfilerRunner(runControl); });
-
- auto constraint = [](RunConfiguration *) { return true; };
- RunControl::registerWorker<PerfProfilerRunner>
- (ProjectExplorer::Constants::PERFPROFILER_RUN_MODE, constraint);
}
+ RunWorkerFactory profilerWorkerFactory{
+ RunWorkerFactory::make<PerfProfilerRunner>(),
+ {ProjectExplorer::Constants::PERFPROFILER_RUN_MODE}
+ };
+
PerfOptionsPage optionsPage;
PerfProfilerTool profilerTool;
};
diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp
index 6f521c306a..b39509cbbe 100644
--- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp
+++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp
@@ -150,11 +150,11 @@ public:
QStringList arguments;
arguments << "record";
arguments += m_perfRecordArguments;
- arguments << "-o" << "-" << "--" << perfRunnable.executable
+ arguments << "-o" << "-" << "--" << perfRunnable.executable.toString()
<< Utils::QtcProcess::splitArgs(perfRunnable.commandLineArguments,
Utils::OsTypeLinux);
- perfRunnable.executable = "perf";
+ perfRunnable.executable = FilePath::fromString("perf");
perfRunnable.commandLineArguments = Utils::QtcProcess::joinArgs(arguments,
Utils::OsTypeLinux);
m_process->start(perfRunnable);
@@ -185,11 +185,10 @@ PerfProfilerRunner::PerfProfilerRunner(RunControl *runControl)
// If the parser is gone, there is no point in going on.
m_perfParserWorker->setEssential(true);
- if (auto perfRecorder = device()->workerCreator("PerfRecorder")) {
- m_perfRecordWorker = perfRecorder(runControl);
-
+ if ((m_perfRecordWorker = runControl->createWorker("PerfRecorder"))) {
m_perfParserWorker->addStartDependency(m_perfRecordWorker);
addStartDependency(m_perfParserWorker);
+
} else {
m_perfRecordWorker = new LocalPerfRecordWorker(runControl);
diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp b/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp
index f33b570a25..134f88be98 100644
--- a/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp
+++ b/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp
@@ -108,7 +108,7 @@ PerfProfilerStatisticsModel::PerfProfilerStatisticsModel(Relation relation, QObj
int PerfProfilerStatisticsModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return m_columns.length();
}
@@ -163,7 +163,7 @@ void PerfProfilerStatisticsMainModel::finalize(PerfProfilerStatisticsData *data)
int PerfProfilerStatisticsMainModel::rowCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return m_data.length();
}
@@ -213,7 +213,7 @@ void PerfProfilerStatisticsData::loadEvent(const PerfEvent &event, const PerfEve
if (event.timestamp() < 0)
return;
- Q_UNUSED(type);
+ Q_UNUSED(type)
++totalSamples;
auto data = mainData.end();
const QVector<qint32> &stack = event.frames();
@@ -370,7 +370,7 @@ PerfProfilerStatisticsRelativesModel::PerfProfilerStatisticsRelativesModel(
int PerfProfilerStatisticsRelativesModel::rowCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return m_data.value(m_currentRelative).data.length();
}
diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp
index 3b60e682f4..d023444b2e 100644
--- a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp
+++ b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp
@@ -57,7 +57,7 @@ public:
QString displayText(const QVariant &value, const QLocale &locale) const
{
- Q_UNUSED(locale);
+ Q_UNUSED(locale)
return QString::fromLatin1("0x%1").arg(value.toULongLong(), 16, 16, QLatin1Char('0'));
}
};
diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp
index bb71f925da..3cb39f968e 100644
--- a/src/plugins/perfprofiler/perfprofilertool.cpp
+++ b/src/plugins/perfprofiler/perfprofilertool.cpp
@@ -355,7 +355,6 @@ void PerfProfilerTool::createViews()
m_perspective.addToolBarWidget(m_tracePointsButton);
m_perspective.setAboutToActivateCallback(Perspective::Callback());
- emit viewsCreated();
}
PerfProfilerTool *PerfProfilerTool::instance()
diff --git a/src/plugins/perfprofiler/perfprofilertool.h b/src/plugins/perfprofiler/perfprofilertool.h
index 8f36cfc7d0..cd8c01764c 100644
--- a/src/plugins/perfprofiler/perfprofilertool.h
+++ b/src/plugins/perfprofiler/perfprofilertool.h
@@ -32,7 +32,7 @@
#include "perftimelinemodelmanager.h"
#include <debugger/debuggermainwindow.h>
-#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/runcontrol.h>
#include <tracing/timelinezoomcontrol.h>
#include <utils/fileinprojectfinder.h>
@@ -72,7 +72,6 @@ public:
signals:
void recordingChanged(bool recording);
void aggregatedChanged(bool aggregated);
- void viewsCreated();
private:
void createViews();
diff --git a/src/plugins/perfprofiler/perfprofilertracefile.cpp b/src/plugins/perfprofiler/perfprofilertracefile.cpp
index c6ea883c79..9b58f21f62 100644
--- a/src/plugins/perfprofiler/perfprofilertracefile.cpp
+++ b/src/plugins/perfprofiler/perfprofilertracefile.cpp
@@ -497,7 +497,7 @@ void PerfProfilerTraceFile::writeToDevice()
CompressedDataStream bufferStream(m_device.data());
int i = 0;
traceManager->replayPerfEvents([&](const PerfEvent &event, const PerfEventType &type) {
- Q_UNUSED(type);
+ Q_UNUSED(type)
Packet packet(&bufferStream);
packet << event;
diff --git a/src/plugins/perfprofiler/perfsettings.cpp b/src/plugins/perfprofiler/perfsettings.cpp
index c4600854c5..b58e377ad3 100644
--- a/src/plugins/perfprofiler/perfsettings.cpp
+++ b/src/plugins/perfprofiler/perfsettings.cpp
@@ -34,13 +34,14 @@
namespace PerfProfiler {
PerfSettings::PerfSettings(ProjectExplorer::Target *target)
- : ISettingsAspect([this, target] {
+{
+ setConfigWidgetCreator([this, target] {
auto widget = new Internal::PerfConfigWidget(this);
widget->setTracePointsButtonVisible(target != nullptr);
widget->setTarget(target);
return widget;
- })
-{
+ });
+
readGlobalSettings();
}
@@ -89,6 +90,7 @@ void PerfSettings::toMap(QVariantMap &map) const
map[QLatin1String(Constants::PerfCallgraphModeId)] = m_callgraphMode;
map[QLatin1String(Constants::PerfEventsId)] = m_events;
map[QLatin1String(Constants::PerfExtraArgumentsId)] = m_extraArguments;
+ map[QLatin1String(Constants::PerfRecordArgumentsId)] = perfRecordArguments();
}
void PerfSettings::fromMap(const QVariantMap &map)
diff --git a/src/plugins/perfprofiler/perftimelinemodelmanager.cpp b/src/plugins/perfprofiler/perftimelinemodelmanager.cpp
index 85171e85dd..48af0ccf37 100644
--- a/src/plugins/perfprofiler/perftimelinemodelmanager.cpp
+++ b/src/plugins/perfprofiler/perftimelinemodelmanager.cpp
@@ -113,7 +113,7 @@ void PerfTimelineModelManager::finalize()
void PerfTimelineModelManager::loadEvent(const PerfEvent &event, const PerfEventType &type)
{
- Q_UNUSED(type);
+ Q_UNUSED(type)
const int parallel = m_traceManager->threads().size();
auto i = m_unfinished.find(event.tid());
if (i == m_unfinished.end()) {
diff --git a/src/plugins/perfprofiler/perftimelineresourcesrenderpass.cpp b/src/plugins/perfprofiler/perftimelineresourcesrenderpass.cpp
index d53c6f162e..ba88f4b462 100644
--- a/src/plugins/perfprofiler/perftimelineresourcesrenderpass.cpp
+++ b/src/plugins/perfprofiler/perftimelineresourcesrenderpass.cpp
@@ -140,8 +140,8 @@ Timeline::TimelineRenderPass::State *PerfTimelineResourcesRenderPass::update(
Timeline::TimelineRenderPass::State *oldState, int indexFrom, int indexTo,
bool stateChanged, float spacing) const
{
- Q_UNUSED(stateChanged);
- Q_UNUSED(spacing);
+ Q_UNUSED(stateChanged)
+ Q_UNUSED(spacing)
const PerfTimelineModel *model = qobject_cast<const PerfTimelineModel *>(renderer->model());
diff --git a/src/plugins/perfprofiler/perftracepointdialog.cpp b/src/plugins/perfprofiler/perftracepointdialog.cpp
index 5dc638bbbe..2dd6e35162 100644
--- a/src/plugins/perfprofiler/perftracepointdialog.cpp
+++ b/src/plugins/perfprofiler/perftracepointdialog.cpp
@@ -106,10 +106,10 @@ void PerfTracePointDialog::runScript()
Runnable runnable;
const QString elevate = m_ui->privilegesChooser->currentText();
if (elevate != QLatin1String("n.a.")) {
- runnable.executable = elevate;
+ runnable.executable = Utils::FilePath::fromString(elevate);
runnable.commandLineArguments = "sh";
} else {
- runnable.executable = "sh";
+ runnable.executable = Utils::FilePath::fromString("sh");
}
connect(m_process.get(), &DeviceProcess::started,
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 102e8eda76..ee2b1b5cf7 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -10,6 +10,7 @@ SUBDIRS = \
texteditor \
cppeditor \
bineditor \
+ boot2qt \
diffeditor \
imageviewer \
bookmarks \
@@ -33,7 +34,7 @@ SUBDIRS = \
qmljseditor \
qmlprojectmanager \
glsleditor \
- pythoneditor \
+ python \
nim \
mercurial \
bazaar \
@@ -60,7 +61,8 @@ SUBDIRS = \
cppcheck \
compilationdatabaseprojectmanager \
qmlpreview \
- studiowelcome
+ studiowelcome \
+ webassembly
qtHaveModule(serialport) {
SUBDIRS += serialterminal
@@ -69,9 +71,9 @@ qtHaveModule(serialport) {
}
qtHaveModule(quick) {
- SUBDIRS += qmlprofiler perfprofiler
+ SUBDIRS += qmlprofiler perfprofiler ctfvisualizer
} else {
- warning("QmlProfiler and PerfProfiler plugins have been disabled since the Qt Quick module is not available.")
+ warning("QmlProfiler, PerfProfiler and CTF Visualizer plugins have been disabled since the Qt Quick module is not available.")
}
qtHaveModule(help) {
diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs
index a0c44b33ca..a048f7b892 100644
--- a/src/plugins/plugins.qbs
+++ b/src/plugins/plugins.qbs
@@ -12,6 +12,7 @@ Project {
"beautifier/beautifier.qbs",
"bineditor/bineditor.qbs",
"bookmarks/bookmarks.qbs",
+ "boot2qt/boot2qt.qbs",
"clangcodemodel/clangcodemodel.qbs",
"clangformat/clangformat.qbs",
"clangpchmanager/clangpchmanager.qbs",
@@ -28,6 +29,7 @@ Project {
"cppcheck/cppcheck.qbs",
"cppeditor/cppeditor.qbs",
"cpptools/cpptools.qbs",
+ "ctfvisualizer/ctfvisualizer.qbs",
"cvs/cvs.qbs",
"debugger/debugger.qbs",
"debugger/ptracepreload.qbs",
@@ -51,7 +53,7 @@ Project {
"perfprofiler/perfprofiler.qbs",
"projectexplorer/projectexplorer.qbs",
"qbsprojectmanager/qbsprojectmanager.qbs",
- "pythoneditor/pythoneditor.qbs",
+ "python/python.qbs",
"qmldesigner/qmldesigner.qbs",
"qmljseditor/qmljseditor.qbs",
"qmljstools/qmljstools.qbs",
@@ -73,6 +75,7 @@ Project {
"updateinfo/updateinfo.qbs",
"valgrind/valgrind.qbs",
"vcsbase/vcsbase.qbs",
+ "webassembly/webassembly.qbs",
"welcome/welcome.qbs",
"winrt/winrt.qbs"
].concat(project.additionalPlugins)
diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt
index c9413c2385..aae6811779 100644
--- a/src/plugins/projectexplorer/CMakeLists.txt
+++ b/src/plugins/projectexplorer/CMakeLists.txt
@@ -21,7 +21,9 @@ add_qtc_plugin(ProjectExplorer
buildstep.cpp buildstep.h
buildsteplist.cpp buildsteplist.h
buildstepspage.cpp buildstepspage.h
+ buildsystem.cpp buildsystem.h
buildtargetinfo.h
+ buildtargettype.h
clangparser.cpp clangparser.h
codestylesettingspropertiespage.cpp codestylesettingspropertiespage.h codestylesettingspropertiespage.ui
compileoutputwindow.cpp compileoutputwindow.h
@@ -41,10 +43,9 @@ add_qtc_plugin(ProjectExplorer
deployablefile.cpp deployablefile.h
deployconfiguration.cpp deployconfiguration.h
deploymentdata.cpp deploymentdata.h
- deploymentdatamodel.cpp deploymentdatamodel.h
- deploymentdataview.cpp deploymentdataview.h deploymentdataview.ui
+ deploymentdataview.cpp deploymentdataview.h
+ desktoprunconfiguration.cpp desktoprunconfiguration.h
devicesupport/desktopdevice.cpp devicesupport/desktopdevice.h
- devicesupport/desktopdeviceconfigurationwidget.cpp devicesupport/desktopdeviceconfigurationwidget.h devicesupport/desktopdeviceconfigurationwidget.ui
devicesupport/desktopdevicefactory.cpp devicesupport/desktopdevicefactory.h
devicesupport/desktopdeviceprocess.cpp devicesupport/desktopdeviceprocess.h
devicesupport/desktopprocesssignaloperation.cpp devicesupport/desktopprocesssignaloperation.h
@@ -109,6 +110,7 @@ add_qtc_plugin(ProjectExplorer
kitmodel.cpp kitmodel.h
kitoptionspage.cpp kitoptionspage.h
ldparser.cpp ldparser.h
+ lldparser.cpp lldparser.h
linuxiccparser.cpp linuxiccparser.h
localenvironmentaspect.cpp localenvironmentaspect.h
makestep.cpp makestep.h makestep.ui
@@ -146,6 +148,7 @@ add_qtc_plugin(ProjectExplorer
projectwelcomepage.cpp projectwelcomepage.h
projectwindow.cpp projectwindow.h
projectwizardpage.cpp projectwizardpage.h projectwizardpage.ui
+ rawprojectpart.cpp rawprojectpart.h
removetaskhandler.cpp removetaskhandler.h
runconfiguration.cpp runconfiguration.h
runconfigurationaspects.cpp runconfigurationaspects.h
diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp
index e4e4c13e64..420a10ba98 100644
--- a/src/plugins/projectexplorer/abi.cpp
+++ b/src/plugins/projectexplorer/abi.cpp
@@ -161,6 +161,8 @@ static Abi::Architecture architectureFromQt()
return Abi::ShArchitecture;
if (arch.startsWith("avr")) // Not in Qt documentation!
return Abi::AvrArchitecture;
+ if (arch.startsWith("asmjs"))
+ return Abi::AsmJsArchitecture;
return Abi::UnknownArchitecture;
}
@@ -411,6 +413,11 @@ static Abis abiOf(const QByteArray &data)
result.append(macAbiForCpu(type));
pos += 20;
}
+ } else if (getUint8(data, 0) == 'B' && getUint8(data, 1) == 'C'
+ && getUint8(data, 2) == 0xc0 && getUint8(data, 3) == 0xde) {
+ // https://llvm.org/docs/BitCodeFormat.html#llvm-ir-magic-number
+ result.append(Abi(Abi::AsmJsArchitecture, Abi::UnknownOS, Abi::UnknownFlavor,
+ Abi::EmscriptenFormat, 32));
} else if (data.size() >= 64){
// Windows PE: values are LE (except for a few exceptions which we will not use here).
@@ -436,8 +443,8 @@ static Abis abiOf(const QByteArray &data)
// --------------------------------------------------------------------------
Abi::Abi(const Architecture &a, const OS &o,
- const OSFlavor &of, const BinaryFormat &f, unsigned char w) :
- m_architecture(a), m_os(o), m_osFlavor(of), m_binaryFormat(f), m_wordWidth(w)
+ const OSFlavor &of, const BinaryFormat &f, unsigned char w, const QString &p) :
+ m_architecture(a), m_os(o), m_osFlavor(of), m_binaryFormat(f), m_wordWidth(w), m_param(p)
{
QTC_ASSERT(osSupportsFlavor(o, of), m_osFlavor = UnknownFlavor);
}
@@ -458,7 +465,7 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
int unknownCount = 0;
for (const QStringRef &p : parts) {
- if (p == "unknown" || p == "pc" || p == "none"
+ if (p == "unknown" || p == "pc"
|| p == "gnu" || p == "uclibc"
|| p == "86_64" || p == "redhat"
|| p == "w64") {
@@ -485,6 +492,12 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
flavor = GenericFlavor;
format = ElfFormat;
width = 16;
+ } else if (p == "msp430") {
+ arch = Msp430Architecture;
+ os = BareMetalOS;
+ flavor = GenericFlavor;
+ format = ElfFormat;
+ width = 16;
} else if (p.startsWith("mips")) {
arch = MipsArchitecture;
width = p.contains("64") ? 64 : 32;
@@ -543,6 +556,15 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
os = QnxOS;
flavor = GenericFlavor;
format = ElfFormat;
+ } else if (p.startsWith("emscripten")) {
+ format = EmscriptenFormat;
+ width = 32;
+ } else if (p.startsWith("asmjs")) {
+ arch = AsmJsArchitecture;
+ } else if (p == "none") {
+ os = BareMetalOS;
+ flavor = GenericFlavor;
+ format = ElfFormat;
} else {
++unknownCount;
}
@@ -579,6 +601,13 @@ QString Abi::toString() const
return dn.join('-');
}
+QString Abi::param() const
+{
+ if (m_param.isEmpty())
+ return toString();
+ return m_param;
+}
+
bool Abi::operator != (const Abi &other) const
{
return !operator ==(other);
@@ -673,6 +702,12 @@ QString Abi::toString(const Architecture &a)
return QLatin1String("itanium");
case ShArchitecture:
return QLatin1String("sh");
+ case AsmJsArchitecture:
+ return QLatin1String("asmjs");
+ case Stm8Architecture:
+ return QLatin1String("stm8");
+ case Msp430Architecture:
+ return QLatin1String("msp430");
case UnknownArchitecture:
Q_FALLTHROUGH();
default:
@@ -730,6 +765,8 @@ QString Abi::toString(const BinaryFormat &bf)
return QLatin1String("ubrof");
case OmfFormat:
return QLatin1String("omf");
+ case EmscriptenFormat:
+ return QLatin1String("emscripten");
case UnknownFormat:
Q_FALLTHROUGH();
default:
@@ -765,21 +802,21 @@ Abi Abi::fromString(const QString &abiString)
if (abiParts.count() >= 3) {
flavor = osFlavorFromString(abiParts.at(2), os);
if (abiParts.at(2) != toString(flavor))
- return Abi(architecture, os, UnknownFlavor, UnknownFormat, 0);;
+ return Abi(architecture, os, UnknownFlavor, UnknownFormat, 0);
}
Abi::BinaryFormat format = UnknownFormat;
if (abiParts.count() >= 4) {
format = binaryFormatFromString(abiParts.at(3));
if (abiParts.at(3) != toString(format))
- return Abi(architecture, os, flavor, UnknownFormat, 0);;
+ return Abi(architecture, os, flavor, UnknownFormat, 0);
}
unsigned char wordWidth = 0;
if (abiParts.count() >= 5) {
wordWidth = wordWidthFromString(abiParts.at(4));
if (abiParts.at(4) != toString(wordWidth))
- return Abi(architecture, os, flavor, format, 0);;
+ return Abi(architecture, os, flavor, format, 0);
}
return Abi(architecture, os, flavor, format, wordWidth);
@@ -807,8 +844,14 @@ Abi::Architecture Abi::architectureFromString(const QStringRef &a)
return ItaniumArchitecture;
if (a == "sh")
return ShArchitecture;
+ if (a == "stm8")
+ return Stm8Architecture;
+ if (a == "msp430")
+ return Msp430Architecture;
else if (a == "xtensa")
return XtensaArchitecture;
+ if (a == "asmjs")
+ return AsmJsArchitecture;
return UnknownArchitecture;
}
@@ -861,6 +904,8 @@ Abi::BinaryFormat Abi::binaryFormatFromString(const QStringRef &bf)
return OmfFormat;
if (bf == "qml_rt")
return RuntimeQmlFormat;
+ if (bf == "emscripten")
+ return EmscriptenFormat;
return UnknownFormat;
}
@@ -1146,6 +1191,9 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiOfBinary_data()
QTest::newRow("static QtCore: linux 64bit")
<< QString::fromLatin1("%1/static/linux-64bit-release.a").arg(prefix)
<< (QStringList() << QString::fromLatin1("x86-linux-generic-elf-64bit"));
+ QTest::newRow("static QtCore: asmjs emscripten 32bit")
+ << QString::fromLatin1("%1/static/asmjs-emscripten.a").arg(prefix)
+ << (QStringList() << QString::fromLatin1("asmjs-unknown-unknown-emscripten-32bit"));
QTest::newRow("static stdc++: mac fat")
<< QString::fromLatin1("%1/static/mac-fat.a").arg(prefix)
@@ -1346,6 +1394,10 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet_data()
QTest::newRow("avr") << int(Abi::AvrArchitecture)
<< int(Abi::BareMetalOS) << int(Abi::GenericFlavor)
<< int(Abi::ElfFormat) << 16;
+
+ QTest::newRow("asmjs-unknown-emscripten") << int(Abi::AsmJsArchitecture)
+ << int(Abi::UnknownOS) << int(Abi::UnknownFlavor)
+ << int(Abi::EmscriptenFormat) << 32;
}
void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet()
diff --git a/src/plugins/projectexplorer/abi.h b/src/plugins/projectexplorer/abi.h
index ddca225896..21794d5be7 100644
--- a/src/plugins/projectexplorer/abi.h
+++ b/src/plugins/projectexplorer/abi.h
@@ -58,6 +58,9 @@ public:
AvrArchitecture,
XtensaArchitecture,
Mcs51Architecture,
+ AsmJsArchitecture,
+ Stm8Architecture,
+ Msp430Architecture,
UnknownArchitecture
};
@@ -114,12 +117,13 @@ public:
RuntimeQmlFormat,
UbrofFormat,
OmfFormat,
+ EmscriptenFormat,
UnknownFormat
};
Abi(const Architecture &a = UnknownArchitecture, const OS &o = UnknownOS,
const OSFlavor &so = UnknownFlavor, const BinaryFormat &f = UnknownFormat,
- unsigned char w = 0);
+ unsigned char w = 0, const QString &p = {});
static Abi abiFromTargetTriplet(const QString &machineTriple);
@@ -139,6 +143,7 @@ public:
unsigned char wordWidth() const { return m_wordWidth; }
QString toString() const;
+ QString param() const;
static QString toString(const Architecture &a);
static QString toString(const OS &o);
@@ -169,6 +174,7 @@ private:
OSFlavor m_osFlavor;
BinaryFormat m_binaryFormat;
unsigned char m_wordWidth;
+ QString m_param;
};
inline int qHash(const ProjectExplorer::Abi &abi)
diff --git a/src/plugins/projectexplorer/abiwidget.cpp b/src/plugins/projectexplorer/abiwidget.cpp
index 5df9a3ee05..8171ec03d5 100644
--- a/src/plugins/projectexplorer/abiwidget.cpp
+++ b/src/plugins/projectexplorer/abiwidget.cpp
@@ -78,7 +78,7 @@ AbiWidget::AbiWidget(QWidget *parent) : QWidget(parent),
d(std::make_unique<Internal::AbiWidgetPrivate>())
{
auto *layout = new QHBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(2);
d->m_abi = new QComboBox(this);
diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp
index 1d92fa9280..de80337d55 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.cpp
+++ b/src/plugins/projectexplorer/abstractprocessstep.cpp
@@ -109,6 +109,7 @@ public:
QByteArray deferredText;
bool m_ignoreReturnValue = false;
bool m_skipFlush = false;
+ bool m_lowPriority = false;
void readData(void (AbstractProcessStep::*func)(const QString &), bool isUtf8 = false);
void processLine(const QByteArray &data,
@@ -213,7 +214,9 @@ void AbstractProcessStep::doRun()
}
}
- const CommandLine effectiveCommand{d->m_param.effectiveCommand(), d->m_param.effectiveArguments()};
+ const CommandLine effectiveCommand(d->m_param.effectiveCommand(),
+ d->m_param.effectiveArguments(),
+ CommandLine::Raw);
if (!effectiveCommand.executable().exists()) {
processStartupFailed();
finish(false);
@@ -225,6 +228,8 @@ void AbstractProcessStep::doRun()
d->m_process->setWorkingDirectory(wd.absolutePath());
d->m_process->setEnvironment(d->m_param.environment());
d->m_process->setCommand(effectiveCommand);
+ if (d->m_lowPriority)
+ d->m_process->setLowPriority();
connect(d->m_process.get(), &QProcess::readyReadStandardOutput,
this, &AbstractProcessStep::processReadyReadStdOutput);
@@ -244,6 +249,11 @@ void AbstractProcessStep::doRun()
processStarted();
}
+void AbstractProcessStep::setLowPriority()
+{
+ d->m_lowPriority = true;
+}
+
void AbstractProcessStep::doCancel()
{
Core::Reaper::reap(d->m_process.release());
diff --git a/src/plugins/projectexplorer/abstractprocessstep.h b/src/plugins/projectexplorer/abstractprocessstep.h
index b21a6bdb25..3cc7aa8bf5 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.h
+++ b/src/plugins/projectexplorer/abstractprocessstep.h
@@ -57,6 +57,7 @@ protected:
~AbstractProcessStep() override;
bool init() override;
void doRun() override;
+ void setLowPriority();
virtual void finish(bool success);
virtual void processStarted();
diff --git a/src/plugins/projectexplorer/allprojectsfilter.cpp b/src/plugins/projectexplorer/allprojectsfilter.cpp
index ab17127d73..81be5ebe47 100644
--- a/src/plugins/projectexplorer/allprojectsfilter.cpp
+++ b/src/plugins/projectexplorer/allprojectsfilter.cpp
@@ -57,9 +57,9 @@ void AllProjectsFilter::prepareSearch(const QString &entry)
{
Q_UNUSED(entry)
if (!fileIterator()) {
- QStringList paths;
+ Utils::FilePathList paths;
for (Project *project : SessionManager::projects())
- paths.append(Utils::transform(project->files(Project::AllFiles), &Utils::FilePath::toString));
+ paths.append(project->files(Project::SourceFiles));
Utils::sort(paths);
setFileIterator(new BaseFileFilter::ListIterator(paths));
}
diff --git a/src/plugins/projectexplorer/allprojectsfind.cpp b/src/plugins/projectexplorer/allprojectsfind.cpp
index d41f21f1b7..28ed75fe5f 100644
--- a/src/plugins/projectexplorer/allprojectsfind.cpp
+++ b/src/plugins/projectexplorer/allprojectsfind.cpp
@@ -88,7 +88,8 @@ Utils::FileIterator *AllProjectsFind::filesForProjects(const QStringList &nameFi
QTextCodec *projectCodec = config->useGlobalSettings()
? Core::EditorManager::defaultTextCodec()
: config->textCodec();
- const QStringList filteredFiles = filterFiles(Utils::transform(project->files(Project::AllFiles), &Utils::FilePath::toString));
+ const QStringList filteredFiles = filterFiles(
+ Utils::transform(project->files(Project::SourceFiles), &Utils::FilePath::toString));
for (const QString &fileName : filteredFiles) {
QTextCodec *codec = openEditorEncodings.value(fileName);
if (!codec)
@@ -127,7 +128,7 @@ QWidget *AllProjectsFind::createConfigWidget()
if (!m_configWidget) {
m_configWidget = new QWidget;
auto gridLayout = new QGridLayout(m_configWidget);
- gridLayout->setMargin(0);
+ gridLayout->setContentsMargins(0, 0, 0, 0);
m_configWidget->setLayout(gridLayout);
const QList<QPair<QWidget *, QWidget *>> patternWidgets = createPatternWidgets();
int row = 0;
diff --git a/src/plugins/projectexplorer/applicationlauncher.cpp b/src/plugins/projectexplorer/applicationlauncher.cpp
index 3a9cde2baf..e0a725716a 100644
--- a/src/plugins/projectexplorer/applicationlauncher.cpp
+++ b/src/plugins/projectexplorer/applicationlauncher.cpp
@@ -382,7 +382,8 @@ void ApplicationLauncherPrivate::start(const Runnable &runnable, const IDevice::
m_guiProcess.closeWriteChannel();
m_guiProcess.start();
} else {
- m_consoleProcess.start(runnable.executable, runnable.commandLineArguments);
+ m_consoleProcess.setCommand(runnable.commandLine());
+ m_consoleProcess.start();
}
} else {
QTC_ASSERT(m_state == Inactive, return);
diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp
index 8a5d120810..28133cfe71 100644
--- a/src/plugins/projectexplorer/appoutputpane.cpp
+++ b/src/plugins/projectexplorer/appoutputpane.cpp
@@ -51,6 +51,8 @@
#include <QAction>
#include <QCheckBox>
+#include <QComboBox>
+#include <QFormLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLoggingCategory>
@@ -228,7 +230,7 @@ AppOutputPane::AppOutputPane() :
// Spacer (?)
auto *layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
m_tabWidget->setDocumentMode(true);
m_tabWidget->setTabsClosable(true);
m_tabWidget->setMovable(true);
@@ -497,10 +499,18 @@ void AppOutputPane::appendMessage(RunControl *rc, const QString &out, Utils::Out
stringToWrite += out;
window->appendMessage(stringToWrite, format);
if (format != Utils::NormalMessageFormat) {
- if (m_runControlTabs.at(index).behaviorOnOutput == Flash)
+ RunControlTab &tab = m_runControlTabs[index];
+ switch (tab.behaviorOnOutput) {
+ case AppOutputPaneMode::FlashOnOutput:
flash();
- else
+ break;
+ case AppOutputPaneMode::PopupOnFirstOutput:
+ tab.behaviorOnOutput = AppOutputPaneMode::FlashOnOutput;
+ Q_FALLTHROUGH();
+ case AppOutputPaneMode::PopupOnOutput:
popup(NoModeSwitch);
+ break;
+ }
}
}
}
@@ -515,8 +525,8 @@ void AppOutputPane::setSettings(const AppOutputSettings &settings)
void AppOutputPane::storeSettings() const
{
QSettings * const s = Core::ICore::settings();
- s->setValue(POP_UP_FOR_RUN_OUTPUT_KEY, m_settings.popUpForRunOutput);
- s->setValue(POP_UP_FOR_DEBUG_OUTPUT_KEY, m_settings.popUpForDebugOutput);
+ s->setValue(POP_UP_FOR_RUN_OUTPUT_KEY, int(m_settings.runOutputMode));
+ s->setValue(POP_UP_FOR_DEBUG_OUTPUT_KEY, int(m_settings.debugOutputMode));
s->setValue(CLEAN_OLD_OUTPUT_KEY, m_settings.cleanOldOutput);
s->setValue(MERGE_CHANNELS_KEY, m_settings.mergeChannels);
s->setValue(WRAP_OUTPUT_KEY, m_settings.wrapOutput);
@@ -526,8 +536,13 @@ void AppOutputPane::storeSettings() const
void AppOutputPane::loadSettings()
{
QSettings * const s = Core::ICore::settings();
- m_settings.popUpForRunOutput = s->value(POP_UP_FOR_RUN_OUTPUT_KEY, true).toBool();
- m_settings.popUpForDebugOutput = s->value(POP_UP_FOR_DEBUG_OUTPUT_KEY, false).toBool();
+ const auto modeFromSettings = [s](const QString key, AppOutputPaneMode defaultValue) {
+ return static_cast<AppOutputPaneMode>(s->value(key, int(defaultValue)).toInt());
+ };
+ m_settings.runOutputMode = modeFromSettings(POP_UP_FOR_RUN_OUTPUT_KEY,
+ AppOutputPaneMode::PopupOnFirstOutput);
+ m_settings.debugOutputMode = modeFromSettings(POP_UP_FOR_DEBUG_OUTPUT_KEY,
+ AppOutputPaneMode::FlashOnOutput);
m_settings.cleanOldOutput = s->value(CLEAN_OLD_OUTPUT_KEY, false).toBool();
m_settings.mergeChannels = s->value(MERGE_CHANNELS_KEY, false).toBool();
m_settings.wrapOutput = s->value(WRAP_OUTPUT_KEY, true).toBool();
@@ -540,7 +555,7 @@ void AppOutputPane::showTabFor(RunControl *rc)
m_tabWidget->setCurrentIndex(tabWidgetIndexOf(indexOf(rc)));
}
-void AppOutputPane::setBehaviorOnOutput(RunControl *rc, AppOutputPane::BehaviorOnOutput mode)
+void AppOutputPane::setBehaviorOnOutput(RunControl *rc, AppOutputPaneMode mode)
{
const int index = indexOf(rc);
if (index != -1)
@@ -815,18 +830,23 @@ public:
m_cleanOldOutputCheckBox.setChecked(settings.cleanOldOutput);
m_mergeChannelsCheckBox.setText(tr("Merge stderr and stdout"));
m_mergeChannelsCheckBox.setChecked(settings.mergeChannels);
- m_popUpForRunOutputCheckBox.setText(tr("Open pane on output when running"));
- m_popUpForRunOutputCheckBox.setChecked(settings.popUpForRunOutput);
- m_popUpForDebugOutputCheckBox.setText(tr("Open pane on output when debugging"));
- m_popUpForDebugOutputCheckBox.setChecked(settings.popUpForDebugOutput);
+ for (QComboBox * const modeComboBox
+ : {&m_runOutputModeComboBox, &m_debugOutputModeComboBox}) {
+ modeComboBox->addItem(tr("Always"), int(AppOutputPaneMode::PopupOnOutput));
+ modeComboBox->addItem(tr("Never"), int(AppOutputPaneMode::FlashOnOutput));
+ modeComboBox->addItem(tr("On first output only"),
+ int(AppOutputPaneMode::PopupOnFirstOutput));
+ }
+ m_runOutputModeComboBox.setCurrentIndex(m_runOutputModeComboBox
+ .findData(int(settings.runOutputMode)));
+ m_debugOutputModeComboBox.setCurrentIndex(m_debugOutputModeComboBox
+ .findData(int(settings.debugOutputMode)));
m_maxCharsBox.setMaximum(100000000);
m_maxCharsBox.setValue(settings.maxCharCount);
const auto layout = new QVBoxLayout(this);
layout->addWidget(&m_wrapOutputCheckBox);
layout->addWidget(&m_cleanOldOutputCheckBox);
layout->addWidget(&m_mergeChannelsCheckBox);
- layout->addWidget(&m_popUpForRunOutputCheckBox);
- layout->addWidget(&m_popUpForDebugOutputCheckBox);
const auto maxCharsLayout = new QHBoxLayout;
const QString msg = tr("Limit output to %1 characters");
const QStringList parts = msg.split("%1") << QString() << QString();
@@ -834,6 +854,11 @@ public:
maxCharsLayout->addWidget(&m_maxCharsBox);
maxCharsLayout->addWidget(new QLabel(parts.at(1).trimmed()));
maxCharsLayout->addStretch(1);
+ const auto outputModeLayout = new QFormLayout;
+ outputModeLayout->addRow(tr("Open pane on output when running:"), &m_runOutputModeComboBox);
+ outputModeLayout->addRow(tr("Open pane on output when debugging:"),
+ &m_debugOutputModeComboBox);
+ layout->addLayout(outputModeLayout);
layout->addLayout(maxCharsLayout);
layout->addStretch(1);
}
@@ -844,8 +869,10 @@ public:
s.wrapOutput = m_wrapOutputCheckBox.isChecked();
s.cleanOldOutput = m_cleanOldOutputCheckBox.isChecked();
s.mergeChannels = m_mergeChannelsCheckBox.isChecked();
- s.popUpForRunOutput = m_popUpForRunOutputCheckBox.isChecked();
- s.popUpForDebugOutput = m_popUpForDebugOutputCheckBox.isChecked();
+ s.runOutputMode = static_cast<AppOutputPaneMode>(
+ m_runOutputModeComboBox.currentData().toInt());
+ s.debugOutputMode = static_cast<AppOutputPaneMode>(
+ m_debugOutputModeComboBox.currentData().toInt());
s.maxCharCount = m_maxCharsBox.value();
return s;
}
@@ -854,8 +881,8 @@ private:
QCheckBox m_wrapOutputCheckBox;
QCheckBox m_cleanOldOutputCheckBox;
QCheckBox m_mergeChannelsCheckBox;
- QCheckBox m_popUpForRunOutputCheckBox;
- QCheckBox m_popUpForDebugOutputCheckBox;
+ QComboBox m_runOutputModeComboBox;
+ QComboBox m_debugOutputModeComboBox;
QSpinBox m_maxCharsBox;
};
diff --git a/src/plugins/projectexplorer/appoutputpane.h b/src/plugins/projectexplorer/appoutputpane.h
index 6d7936042e..bd592ac72d 100644
--- a/src/plugins/projectexplorer/appoutputpane.h
+++ b/src/plugins/projectexplorer/appoutputpane.h
@@ -62,11 +62,6 @@ public:
CloseTabWithPrompt
};
- enum BehaviorOnOutput {
- Flash,
- Popup
- };
-
AppOutputPane();
~AppOutputPane() override;
@@ -88,7 +83,7 @@ public:
void createNewOutputWindow(RunControl *rc);
void showTabFor(RunControl *rc);
- void setBehaviorOnOutput(RunControl *rc, BehaviorOnOutput mode);
+ void setBehaviorOnOutput(RunControl *rc, AppOutputPaneMode mode);
bool aboutToClose() const;
void closeTabs(CloseTabMode mode);
@@ -130,7 +125,7 @@ private:
Core::OutputWindow *window = nullptr);
QPointer<RunControl> runControl;
QPointer<Core::OutputWindow> window;
- BehaviorOnOutput behaviorOnOutput = Flash;
+ AppOutputPaneMode behaviorOnOutput = AppOutputPaneMode::FlashOnOutput;
};
void closeTab(int index, CloseTabMode cm = CloseTabWithPrompt);
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index e267822b97..ccf333aa21 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -39,6 +39,7 @@
#include "projectmacroexpander.h"
#include "projecttree.h"
#include "target.h"
+#include "session.h"
#include <coreplugin/idocument.h>
@@ -52,6 +53,8 @@
#include <QDebug>
#include <QFormLayout>
+using namespace Utils;
+
static const char BUILD_STEP_LIST_COUNT[] = "ProjectExplorer.BuildConfiguration.BuildStepListCount";
static const char BUILD_STEP_LIST_PREFIX[] = "ProjectExplorer.BuildConfiguration.BuildStepList.";
static const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "ProjectExplorer.BuildConfiguration.ClearSystemEnvironment";
@@ -63,6 +66,7 @@ namespace ProjectExplorer {
BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
: ProjectConfiguration(target, id)
{
+ QTC_CHECK(target && target == this->target());
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Build Settings"));
expander->setAccumulating(true);
@@ -76,7 +80,7 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
expander->registerPrefix(Constants::VAR_CURRENTBUILD_ENV,
tr("Variables in the current build environment"),
- [this](const QString &var) { return environment().value(var); });
+ [this](const QString &var) { return environment().expandedValueForKey(var); });
updateCacheAndEmitEnvironmentChanged();
connect(target, &Target::kitChanged,
@@ -99,6 +103,17 @@ BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
connect(this, &BuildConfiguration::environmentChanged, this, [this] {
m_buildDirectoryAspect->setEnvironment(environment());
+ this->target()->buildEnvironmentChanged(this);
+ });
+
+ connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged);
+ connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
+
+ connect(this, &BuildConfiguration::enabledChanged, this, [this] {
+ if (isActive() && project() == SessionManager::startupProject()) {
+ ProjectExplorerPlugin::updateActions();
+ emit ProjectExplorerPlugin::instance()->updateRunActions();
+ }
});
}
@@ -111,14 +126,14 @@ Utils::FilePath BuildConfiguration::buildDirectory() const
Utils::FilePath BuildConfiguration::rawBuildDirectory() const
{
- return m_buildDirectoryAspect->fileName();
+ return m_buildDirectoryAspect->filePath();
}
void BuildConfiguration::setBuildDirectory(const Utils::FilePath &dir)
{
- if (dir == m_buildDirectoryAspect->fileName())
+ if (dir == m_buildDirectoryAspect->filePath())
return;
- m_buildDirectoryAspect->setFileName(dir);
+ m_buildDirectoryAspect->setFilePath(dir);
emitBuildDirectoryChanged();
}
@@ -136,14 +151,14 @@ NamedWidget *BuildConfiguration::createConfigWidget()
container->setWidget(widget);
auto vbox = new QVBoxLayout(named);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
vbox->addWidget(container);
} else {
widget = named;
}
auto formLayout = new QFormLayout(widget);
- formLayout->setMargin(0);
+ formLayout->setContentsMargins(0, 0, 0, 0);
formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
for (ProjectConfigurationAspect *aspect : aspects()) {
@@ -154,12 +169,8 @@ NamedWidget *BuildConfiguration::createConfigWidget()
return named;
}
-void BuildConfiguration::initialize(const BuildInfo &info)
+void BuildConfiguration::initialize()
{
- setDisplayName(info.displayName);
- setDefaultDisplayName(info.displayName);
- setBuildDirectory(info.buildDirectory);
-
m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_BUILD));
m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_CLEAN));
}
@@ -243,6 +254,11 @@ void BuildConfiguration::emitBuildDirectoryChanged()
}
}
+QString BuildConfiguration::initialDisplayName() const
+{
+ return m_initialDisplayName;
+}
+
ProjectExplorer::BaseStringAspect *BuildConfiguration::buildDirectoryAspect() const
{
return m_buildDirectoryAspect;
@@ -268,16 +284,6 @@ void BuildConfiguration::setBuildDirectorySettingsKey(const QString &key)
m_buildDirectoryAspect->setSettingsKey(key);
}
-Target *BuildConfiguration::target() const
-{
- return static_cast<Target *>(parent());
-}
-
-Project *BuildConfiguration::project() const
-{
- return target()->project();
-}
-
Utils::Environment BuildConfiguration::baseEnvironment() const
{
Utils::Environment result;
@@ -311,7 +317,7 @@ void BuildConfiguration::setUseSystemEnvironment(bool b)
void BuildConfiguration::addToEnvironment(Utils::Environment &env) const
{
- Q_UNUSED(env);
+ Q_UNUSED(env)
}
bool BuildConfiguration::useSystemEnvironment() const
@@ -319,12 +325,12 @@ bool BuildConfiguration::useSystemEnvironment() const
return !m_clearSystemEnvironment;
}
-QList<Utils::EnvironmentItem> BuildConfiguration::userEnvironmentChanges() const
+Utils::EnvironmentItems BuildConfiguration::userEnvironmentChanges() const
{
return m_userEnvironmentChanges;
}
-void BuildConfiguration::setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff)
+void BuildConfiguration::setUserEnvironmentChanges(const Utils::EnvironmentItems &diff)
{
if (m_userEnvironmentChanges == diff)
return;
@@ -334,17 +340,21 @@ void BuildConfiguration::setUserEnvironmentChanges(const QList<Utils::Environmen
bool BuildConfiguration::isEnabled() const
{
- return true;
+ return !project()->isParsing() && project()->hasParsingData();
}
QString BuildConfiguration::disabledReason() const
{
+ if (project()->isParsing())
+ return (tr("The project is currently being parsed."));
+ if (!project()->hasParsingData())
+ return (tr("The project was not parsed successfully."));
return QString();
}
bool BuildConfiguration::regenerateBuildFiles(Node *node)
{
- Q_UNUSED(node);
+ Q_UNUSED(node)
return false;
}
@@ -414,12 +424,13 @@ const Tasks BuildConfigurationFactory::reportIssues(ProjectExplorer::Kit *kit, c
const QList<BuildInfo> BuildConfigurationFactory::allAvailableBuilds(const Target *parent) const
{
- return availableBuilds(parent);
+ return availableBuilds(parent->kit(), parent->project()->projectFilePath(), false);
}
-const QList<BuildInfo> BuildConfigurationFactory::allAvailableSetups(const Kit *k, const QString &projectPath) const
+const QList<BuildInfo>
+ BuildConfigurationFactory::allAvailableSetups(const Kit *k, const FilePath &projectPath) const
{
- return availableSetups(k, projectPath);
+ return availableBuilds(k, projectPath, /* forSetup = */ true);
}
bool BuildConfigurationFactory::supportsTargetDeviceType(Core::Id id) const
@@ -430,12 +441,13 @@ bool BuildConfigurationFactory::supportsTargetDeviceType(Core::Id id) const
}
// setup
-BuildConfigurationFactory *BuildConfigurationFactory::find(const Kit *k, const QString &projectPath)
+BuildConfigurationFactory *BuildConfigurationFactory::find(const Kit *k, const FilePath &projectPath)
{
QTC_ASSERT(k, return nullptr);
const Core::Id deviceType = DeviceTypeKitAspect::deviceTypeId(k);
for (BuildConfigurationFactory *factory : g_buildConfigurationFactories) {
- if (Utils::mimeTypeForFile(projectPath).matchesName(factory->m_supportedProjectMimeTypeName)
+ if (Utils::mimeTypeForFile(projectPath.toString())
+ .matchesName(factory->m_supportedProjectMimeTypeName)
&& factory->supportsTargetDeviceType(deviceType))
return factory;
}
@@ -494,7 +506,18 @@ BuildConfiguration *BuildConfigurationFactory::create(Target *parent, const Buil
BuildConfiguration *bc = m_creator(parent);
if (!bc)
return nullptr;
- bc->initialize(info);
+
+ bc->setDisplayName(info.displayName);
+ bc->setDefaultDisplayName(info.displayName);
+ bc->setBuildDirectory(info.buildDirectory);
+
+ bc->m_initialBuildType = info.buildType;
+ bc->m_initialDisplayName = info.displayName;
+ bc->m_initialBuildDirectory = info.buildDirectory;
+ bc->m_extraInfo = info.extraInfo;
+
+ bc->initialize();
+
return bc;
}
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index c9ba394946..89cbc77f53 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -62,8 +62,8 @@ public:
Utils::Environment baseEnvironment() const;
QString baseEnvironmentText() const;
Utils::Environment environment() const;
- void setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff);
- QList<Utils::EnvironmentItem> userEnvironmentChanges() const;
+ void setUserEnvironmentChanges(const Utils::EnvironmentItems &diff);
+ Utils::EnvironmentItems userEnvironmentChanges() const;
bool useSystemEnvironment() const;
void setUseSystemEnvironment(bool b);
@@ -75,9 +75,6 @@ public:
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
- Target *target() const;
- Project *project() const override;
-
virtual bool isEnabled() const;
virtual QString disabledReason() const;
@@ -89,7 +86,12 @@ public:
Profile,
Release
};
- virtual BuildType buildType() const = 0;
+ virtual BuildType buildType() const { return m_initialBuildType; }
+
+ BuildType initialBuildType() const { return m_initialBuildType; } // FIXME: Remove.
+ Utils::FilePath initialBuildDirectory() const { return m_initialBuildDirectory; } // FIXME: Remove.
+ QString initialDisplayName() const; // FIXME: Remove.
+ QVariant extraInfo() const { return m_extraInfo; } // FIXME: Remove.
static QString buildTypeName(BuildType type);
@@ -111,19 +113,25 @@ signals:
void buildTypeChanged();
protected:
- virtual void initialize(const BuildInfo &info);
+ virtual void initialize();
private:
void emitBuildDirectoryChanged();
bool m_clearSystemEnvironment = false;
- QList<Utils::EnvironmentItem> m_userEnvironmentChanges;
+ Utils::EnvironmentItems m_userEnvironmentChanges;
QList<BuildStepList *> m_stepLists;
ProjectExplorer::BaseStringAspect *m_buildDirectoryAspect = nullptr;
Utils::FilePath m_lastEmmitedBuildDirectory;
mutable Utils::Environment m_cachedEnvironment;
QString m_configWidgetDisplayName;
bool m_configWidgetHasFrame = false;
+
+ // FIXME: Remove.
+ BuildConfiguration::BuildType m_initialBuildType = BuildConfiguration::Unknown;
+ Utils::FilePath m_initialBuildDirectory;
+ QString m_initialDisplayName;
+ QVariant m_extraInfo;
};
class PROJECTEXPLORER_EXPORT BuildConfigurationFactory : public QObject
@@ -140,14 +148,15 @@ public:
const QList<BuildInfo> allAvailableBuilds(const Target *parent) const;
// List of build information that can be used to initially set up a new build configuration.
- const QList<BuildInfo> allAvailableSetups(const Kit *k, const QString &projectPath) const;
+ const QList<BuildInfo>
+ allAvailableSetups(const Kit *k, const Utils::FilePath &projectPath) const;
BuildConfiguration *create(Target *parent, const BuildInfo &info) const;
static BuildConfiguration *restore(Target *parent, const QVariantMap &map);
static BuildConfiguration *clone(Target *parent, const BuildConfiguration *source);
- static BuildConfigurationFactory *find(const Kit *k, const QString &projectPath);
+ static BuildConfigurationFactory *find(const Kit *k, const Utils::FilePath &projectPath);
static BuildConfigurationFactory *find(Target *parent);
using IssueReporter = std::function<Tasks(Kit *, const QString &, const QString &)>;
@@ -156,8 +165,8 @@ public:
const QString &projectPath, const QString &buildDir) const;
protected:
- virtual QList<BuildInfo> availableBuilds(const Target *parent) const = 0;
- virtual QList<BuildInfo> availableSetups(const Kit *k, const QString &projectPath) const = 0;
+ virtual QList<BuildInfo>
+ availableBuilds(const Kit *k, const Utils::FilePath &projectPath, bool forSetup) const = 0;
bool supportsTargetDeviceType(Core::Id id) const;
void setSupportedProjectType(Core::Id id);
diff --git a/src/plugins/projectexplorer/buildenvironmentwidget.cpp b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
index 047412fbf3..4995d1bc50 100644
--- a/src/plugins/projectexplorer/buildenvironmentwidget.cpp
+++ b/src/plugins/projectexplorer/buildenvironmentwidget.cpp
@@ -39,7 +39,7 @@ BuildEnvironmentWidget::BuildEnvironmentWidget(BuildConfiguration *bc) :
m_buildConfiguration(nullptr)
{
auto vbox = new QVBoxLayout(this);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
m_clearSystemEnvironmentCheckBox = new QCheckBox(this);
m_clearSystemEnvironmentCheckBox->setText(tr("Clear system environment"));
diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp
index eece545e07..7193a2ab5a 100644
--- a/src/plugins/projectexplorer/buildmanager.cpp
+++ b/src/plugins/projectexplorer/buildmanager.cpp
@@ -32,28 +32,26 @@
#include "project.h"
#include "projectexplorer.h"
#include "projectexplorersettings.h"
+#include "session.h"
#include "target.h"
#include "task.h"
-#include "taskwindow.h"
#include "taskhub.h"
+#include "taskwindow.h"
#include <coreplugin/icore.h>
-#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
-#include <projectexplorer/session.h>
+#include <coreplugin/progressmanager/progressmanager.h>
#include <extensionsystem/pluginmanager.h>
+#include <utils/runextensions.h>
+#include <QApplication>
+#include <QElapsedTimer>
+#include <QFutureWatcher>
+#include <QHash>
+#include <QList>
#include <QPointer>
#include <QTime>
#include <QTimer>
-#include <QList>
-#include <QHash>
-#include <QFutureWatcher>
-#include <QElapsedTimer>
-
-#include <utils/runextensions.h>
-
-#include <QApplication>
using namespace Core;
@@ -76,10 +74,12 @@ public:
int m_progress = 0;
int m_maxProgress = 0;
bool m_running = false;
+ bool m_isDeploying = false;
// is set to true while canceling, so that nextBuildStep knows that the BuildStep finished because of canceling
bool m_skipDisabled = false;
bool m_canceling = false;
bool m_lastStepSucceeded = true;
+ bool m_allStepsSucceeded = true;
BuildStep *m_currentBuildStep = nullptr;
QString m_currentConfiguration;
// used to decide if we are building a project to decide when to emit buildStateChanged(Project *)
@@ -179,6 +179,11 @@ bool BuildManager::isBuilding()
return !d->m_buildQueue.isEmpty() || d->m_running;
}
+bool BuildManager::isDeploying()
+{
+ return d->m_isDeploying;
+}
+
int BuildManager::getErrorTaskCount()
{
const int errors =
@@ -218,8 +223,8 @@ void BuildManager::updateTaskCount()
void BuildManager::finish()
{
const QTime format = QTime(0, 0, 0, 0).addMSecs(d->m_elapsed.elapsed() + 500);
- QString time = format.toString(QLatin1String("h:mm:ss"));
- if (time.startsWith(QLatin1String("0:")))
+ QString time = format.toString("h:mm:ss");
+ if (time.startsWith("0:"))
time.remove(0, 2); // Don't display zero hours
m_instance->addToOutputWindow(tr("Elapsed time: %1.") .arg(time), BuildStep::OutputFormat::NormalMessage);
@@ -233,7 +238,7 @@ void BuildManager::emitCancelMessage()
void BuildManager::clearBuildQueue()
{
- foreach (BuildStep *bs, d->m_buildQueue) {
+ for (BuildStep *bs : qAsConst(d->m_buildQueue)) {
decrementActiveBuildSteps(bs);
disconnectOutput(bs);
}
@@ -242,6 +247,7 @@ void BuildManager::clearBuildQueue()
d->m_buildQueue.clear();
d->m_enabledState.clear();
d->m_running = false;
+ d->m_isDeploying = false;
d->m_previousBuildStepProject = nullptr;
d->m_currentBuildStep = nullptr;
@@ -305,6 +311,7 @@ void BuildManager::startBuildQueue()
d->m_progressFutureInterface->setProgressRange(0, d->m_maxProgress * 100);
d->m_running = true;
+ d->m_allStepsSucceeded = true;
d->m_progressFutureInterface->reportStarted();
nextStep();
} else {
@@ -336,11 +343,11 @@ void BuildManager::addToOutputWindow(const QString &string, BuildStep::OutputFor
QString stringToWrite;
if (format == BuildStep::OutputFormat::NormalMessage || format == BuildStep::OutputFormat::ErrorMessage) {
stringToWrite = QTime::currentTime().toString();
- stringToWrite += QLatin1String(": ");
+ stringToWrite += ": ";
}
stringToWrite += string;
if (newlineSettings == BuildStep::DoAppendNewline)
- stringToWrite += QLatin1Char('\n');
+ stringToWrite += '\n';
d->m_outputWindow->appendText(stringToWrite, format);
}
@@ -372,6 +379,7 @@ void BuildManager::nextBuildQueue()
nextStep();
} else {
// Build Failure
+ d->m_allStepsSucceeded = false;
Target *t = d->m_currentBuildStep->target();
const QString projectName = d->m_currentBuildStep->project()->displayName();
const QString targetName = t->displayName();
@@ -382,10 +390,28 @@ void BuildManager::nextBuildQueue()
.arg(targetName), BuildStep::OutputFormat::Stderr);
}
addToOutputWindow(tr("When executing step \"%1\"").arg(d->m_currentBuildStep->displayName()), BuildStep::OutputFormat::Stderr);
- // NBS TODO fix in qtconcurrent
- d->m_progressFutureInterface->setProgressValueAndText(d->m_progress*100, tr("Error while building/deploying project %1 (kit: %2)").arg(projectName, targetName));
- clearBuildQueue();
+ bool abort = ProjectExplorerPlugin::projectExplorerSettings().abortBuildAllOnError;
+ if (!abort) {
+ while (!d->m_buildQueue.isEmpty()
+ && d->m_buildQueue.front()->target() == t) {
+ BuildStep * const nextStepForFailedTarget = d->m_buildQueue.takeFirst();
+ disconnectOutput(nextStepForFailedTarget);
+ decrementActiveBuildSteps(nextStepForFailedTarget);
+ }
+ if (d->m_buildQueue.isEmpty())
+ abort = true;
+ }
+
+ if (abort) {
+ // NBS TODO fix in qtconcurrent
+ d->m_progressFutureInterface->setProgressValueAndText(d->m_progress * 100,
+ tr("Error while building/deploying project %1 (kit: %2)")
+ .arg(projectName, targetName));
+ clearBuildQueue();
+ } else {
+ nextStep();
+ }
}
}
@@ -431,6 +457,7 @@ void BuildManager::nextStep()
d->m_currentBuildStep->run();
} else {
d->m_running = false;
+ d->m_isDeploying = false;
d->m_previousBuildStepProject = nullptr;
d->m_progressFutureInterface->reportFinished();
d->m_progressWatcher.setFuture(QFuture<void>());
@@ -438,7 +465,7 @@ void BuildManager::nextStep()
delete d->m_progressFutureInterface;
d->m_progressFutureInterface = nullptr;
d->m_maxProgress = 0;
- emit m_instance->buildQueueFinished(true);
+ emit m_instance->buildQueueFinished(d->m_allStepsSucceeded);
}
}
@@ -453,7 +480,7 @@ bool BuildManager::buildQueueAppend(const QList<BuildStep *> &steps, QStringList
TaskHub::clearTasks(Constants::TASK_CATEGORY_AUTOTEST);
}
- foreach (const QString &str, preambleMessage)
+ for (const QString &str : preambleMessage)
addToOutputWindow(str, BuildStep::OutputFormat::NormalMessage, BuildStep::DontAppendNewline);
}
@@ -504,13 +531,14 @@ bool BuildManager::buildList(BuildStepList *bsl)
return buildLists({bsl});
}
-bool BuildManager::buildLists(QList<BuildStepList *> bsls, const QStringList &preambelMessage)
+bool BuildManager::buildLists(const QList<BuildStepList *> bsls, const QStringList &preambelMessage)
{
QList<BuildStep *> steps;
QStringList stepListNames;
- foreach (BuildStepList *list, bsls) {
+ for (BuildStepList *list : bsls) {
steps.append(list->steps());
stepListNames.append(ProjectExplorerPlugin::displayNameForStepId(list->id()));
+ d->m_isDeploying = d->m_isDeploying || list->id() == Constants::BUILDSTEPS_DEPLOY;
}
QStringList names;
diff --git a/src/plugins/projectexplorer/buildmanager.h b/src/plugins/projectexplorer/buildmanager.h
index fe452d6965..8c185c7b93 100644
--- a/src/plugins/projectexplorer/buildmanager.h
+++ b/src/plugins/projectexplorer/buildmanager.h
@@ -25,8 +25,8 @@
#pragma once
-#include "projectexplorer_export.h"
#include "buildstep.h"
+#include "projectexplorer_export.h"
#include <QObject>
#include <QStringList>
@@ -49,9 +49,10 @@ public:
static void extensionsInitialized();
static bool isBuilding();
+ static bool isDeploying();
static bool tasksAvailable();
- static bool buildLists(QList<BuildStepList *> bsls,
+ static bool buildLists(const QList<BuildStepList *> bsls,
const QStringList &preambelMessage = QStringList());
static bool buildList(BuildStepList *bsl);
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
index 481c37eef0..eabce92bee 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
@@ -83,7 +83,7 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) :
hbox->addWidget(new QLabel(tr("Edit build configuration:"), this));
m_buildConfigurationComboBox = new QComboBox(this);
m_buildConfigurationComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
- m_buildConfigurationComboBox->setModel(new BuildConfigurationModel(m_target, this));
+ m_buildConfigurationComboBox->setModel(m_target->buildConfigurationModel());
hbox->addWidget(m_buildConfigurationComboBox);
m_addButton = new QPushButton(this);
@@ -113,8 +113,8 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) :
}
m_buildConfiguration = m_target->activeBuildConfiguration();
- auto model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model());
- m_buildConfigurationComboBox->setCurrentIndex(model->indexFor(m_buildConfiguration).row());
+ m_buildConfigurationComboBox->setCurrentIndex(
+ m_target->buildConfigurationModel()->indexFor(m_buildConfiguration));
updateAddButtonMenu();
updateBuildSettings();
@@ -207,8 +207,13 @@ void BuildSettingsWidget::updateBuildSettings()
if (generalConfigWidget)
addSubWidget(generalConfigWidget);
- addSubWidget(new BuildStepsPage(m_buildConfiguration, Core::Id(Constants::BUILDSTEPS_BUILD)));
- addSubWidget(new BuildStepsPage(m_buildConfiguration, Core::Id(Constants::BUILDSTEPS_CLEAN)));
+ auto buildStepsWidget = new BuildStepListWidget(this);
+ buildStepsWidget->init(m_buildConfiguration->stepList(Constants::BUILDSTEPS_BUILD));
+ addSubWidget(buildStepsWidget);
+
+ auto cleanStepsWidget = new BuildStepListWidget(this);
+ cleanStepsWidget->init(m_buildConfiguration->stepList(Constants::BUILDSTEPS_CLEAN));
+ addSubWidget(cleanStepsWidget);
QList<NamedWidget *> subConfigWidgets = m_buildConfiguration->createSubConfigWidgets();
foreach (NamedWidget *subConfigWidget, subConfigWidgets)
@@ -217,8 +222,8 @@ void BuildSettingsWidget::updateBuildSettings()
void BuildSettingsWidget::currentIndexChanged(int index)
{
- auto model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model());
- auto buildConfiguration = qobject_cast<BuildConfiguration *>(model->projectConfigurationAt(index));
+ auto buildConfiguration = qobject_cast<BuildConfiguration *>(
+ m_target->buildConfigurationModel()->projectConfigurationAt(index));
SessionManager::setActiveBuildConfiguration(m_target, buildConfiguration, SetActive::Cascade);
}
@@ -229,8 +234,8 @@ void BuildSettingsWidget::updateActiveConfiguration()
m_buildConfiguration = m_target->activeBuildConfiguration();
- auto model = static_cast<BuildConfigurationModel *>(m_buildConfigurationComboBox->model());
- m_buildConfigurationComboBox->setCurrentIndex(model->indexFor(m_buildConfiguration).row());
+ m_buildConfigurationComboBox->setCurrentIndex(
+ m_target->buildConfigurationModel()->indexFor(m_buildConfiguration));
updateBuildSettings();
}
diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp
index 35e02b8972..38968fe514 100644
--- a/src/plugins/projectexplorer/buildstep.cpp
+++ b/src/plugins/projectexplorer/buildstep.cpp
@@ -32,6 +32,8 @@
#include "project.h"
#include "target.h"
+#include <coreplugin/variablechooser.h>
+
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
@@ -124,6 +126,7 @@ static QList<BuildStepFactory *> g_buildStepFactories;
BuildStep::BuildStep(BuildStepList *bsl, Core::Id id) :
ProjectConfiguration(bsl, id)
{
+ QTC_CHECK(bsl->target() && bsl->target() == this->target());
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Build Step"));
expander->setAccumulating(true);
@@ -147,7 +150,7 @@ BuildStepConfigWidget *BuildStep::createConfigWidget()
auto widget = new BuildStepConfigWidget(this);
auto formLayout = new QFormLayout(widget);
- formLayout->setMargin(0);
+ formLayout->setContentsMargins(0, 0, 0, 0);
formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
for (ProjectConfigurationAspect *aspect : m_aspects) {
@@ -155,6 +158,14 @@ BuildStepConfigWidget *BuildStep::createConfigWidget()
aspect->addToConfigurationLayout(formLayout);
}
+ connect(buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
+ widget, &BuildStepConfigWidget::recreateSummary);
+
+ widget->setSummaryUpdater(m_summaryUpdater);
+
+ if (m_addMacroExpander)
+ Core::VariableChooser::addSupportForChildWidgets(widget, macroExpander());
+
return widget;
}
@@ -194,16 +205,6 @@ ProjectConfiguration *BuildStep::projectConfiguration() const
return static_cast<ProjectConfiguration *>(parent()->parent());
}
-Target *BuildStep::target() const
-{
- return qobject_cast<Target *>(parent()->parent()->parent());
-}
-
-Project *BuildStep::project() const
-{
- return target()->project();
-}
-
void BuildStep::reportRunResult(QFutureInterface<bool> &fi, bool success)
{
fi.reportResult(success);
@@ -227,7 +228,7 @@ void BuildStep::setWidgetExpandedByDefault(bool widgetExpandedByDefault)
QVariant BuildStep::data(Core::Id id) const
{
- Q_UNUSED(id);
+ Q_UNUSED(id)
return {};
}
@@ -267,6 +268,16 @@ void BuildStep::doCancel()
<< "neeeds to implement the doCancel() function");
}
+void BuildStep::addMacroExpander()
+{
+ m_addMacroExpander = true;
+}
+
+void BuildStep::setSummaryUpdater(const std::function<QString ()> &summaryUpdater)
+{
+ m_summaryUpdater = summaryUpdater;
+}
+
void BuildStep::setEnabled(bool b)
{
if (m_enabled == b)
@@ -275,6 +286,11 @@ void BuildStep::setEnabled(bool b)
emit enabledChanged();
}
+BuildStepList *BuildStep::stepList() const
+{
+ return qobject_cast<BuildStepList *>(parent());
+}
+
bool BuildStep::enabled() const
{
return m_enabled;
@@ -412,6 +428,10 @@ BuildStepConfigWidget::BuildStepConfigWidget(BuildStep *step)
m_summaryText = "<b>" + m_displayName + "</b>";
connect(m_step, &ProjectConfiguration::displayNameChanged,
this, &BuildStepConfigWidget::updateSummary);
+ for (auto aspect : step->aspects()) {
+ connect(aspect, &ProjectConfigurationAspect::changed,
+ this, &BuildStepConfigWidget::recreateSummary);
+ }
}
QString BuildStepConfigWidget::summaryText() const
@@ -437,4 +457,16 @@ void BuildStepConfigWidget::setSummaryText(const QString &summaryText)
}
}
+void BuildStepConfigWidget::setSummaryUpdater(const std::function<QString()> &summaryUpdater)
+{
+ m_summaryUpdater = summaryUpdater;
+ recreateSummary();
+}
+
+void BuildStepConfigWidget::recreateSummary()
+{
+ if (m_summaryUpdater)
+ setSummaryText(m_summaryUpdater());
+}
+
} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h
index 0abf7d5b78..f9fb6fbec6 100644
--- a/src/plugins/projectexplorer/buildstep.h
+++ b/src/plugins/projectexplorer/buildstep.h
@@ -69,11 +69,11 @@ public:
bool enabled() const;
void setEnabled(bool b);
+ BuildStepList *stepList() const;
+
BuildConfiguration *buildConfiguration() const;
DeployConfiguration *deployConfiguration() const;
ProjectConfiguration *projectConfiguration() const;
- Target *target() const;
- Project *project() const override;
enum class OutputFormat {
Stdout, Stderr, // These are for forwarded output from external tools
@@ -97,6 +97,10 @@ public:
void setImmutable(bool immutable) { m_immutable = immutable; }
virtual QVariant data(Core::Id id) const;
+ void setSummaryUpdater(const std::function<QString ()> &summaryUpdater);
+
+ void addMacroExpander();
+
signals:
/// Adds a \p task to the Issues pane.
/// Do note that for linking compile output with tasks, you should first emit the task
@@ -120,6 +124,8 @@ protected:
bool isCanceled() const;
private:
+ using ProjectConfiguration::parent;
+
virtual void doRun() = 0;
virtual void doCancel();
@@ -128,7 +134,9 @@ private:
bool m_immutable = false;
bool m_widgetExpandedByDefault = true;
bool m_runInGuiThread = true;
+ bool m_addMacroExpander = false;
Utils::optional<bool> m_wasExpanded;
+ std::function<QString()> m_summaryUpdater;
};
class PROJECTEXPLORER_EXPORT BuildStepInfo
@@ -209,6 +217,9 @@ public:
void setDisplayName(const QString &displayName);
void setSummaryText(const QString &summaryText);
+ void setSummaryUpdater(const std::function<QString()> &summaryUpdater);
+ void recreateSummary();
+
signals:
void updateSummary();
@@ -216,6 +227,7 @@ private:
BuildStep *m_step = nullptr;
QString m_displayName;
QString m_summaryText;
+ std::function<QString()> m_summaryUpdater;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsteplist.cpp b/src/plugins/projectexplorer/buildsteplist.cpp
index 3b4ce596a4..273835bd99 100644
--- a/src/plugins/projectexplorer/buildsteplist.cpp
+++ b/src/plugins/projectexplorer/buildsteplist.cpp
@@ -34,25 +34,18 @@
#include <utils/algorithm.h>
-using namespace ProjectExplorer;
-
-namespace {
+namespace ProjectExplorer {
const char STEPS_COUNT_KEY[] = "ProjectExplorer.BuildStepList.StepsCount";
const char STEPS_PREFIX[] = "ProjectExplorer.BuildStepList.Step.";
-} // namespace
-
BuildStepList::BuildStepList(QObject *parent, Core::Id id)
- : ProjectConfiguration(parent, id)
+ : QObject(parent), m_id(id)
{
- if (id == Constants::BUILDSTEPS_BUILD) {
- //: Display name of the build build step list. Used as part of the labels in the project window.
- setDefaultDisplayName(tr("Build"));
- } else if (id == Constants::BUILDSTEPS_CLEAN) {
- //: Display name of the clean build step list. Used as part of the labels in the project window.
- setDefaultDisplayName(tr("Clean"));
- }
+ QTC_ASSERT(parent, return);
+ QTC_ASSERT(parent->parent(), return);
+ m_target = qobject_cast<Target *>(parent->parent());
+ QTC_ASSERT(m_target, return);
}
BuildStepList::~BuildStepList()
@@ -68,7 +61,18 @@ void BuildStepList::clear()
QVariantMap BuildStepList::toMap() const
{
- QVariantMap map(ProjectConfiguration::toMap());
+ QVariantMap map;
+
+ {
+ // Only written for compatibility reasons within the 4.11 cycle
+ const char CONFIGURATION_ID_KEY[] = "ProjectExplorer.ProjectConfiguration.Id";
+ const char DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DisplayName";
+ const char DEFAULT_DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DefaultDisplayName";
+ map.insert(QLatin1String(CONFIGURATION_ID_KEY), m_id.toSetting());
+ map.insert(QLatin1String(DISPLAY_NAME_KEY), displayName());
+ map.insert(QLatin1String(DEFAULT_DISPLAY_NAME_KEY), displayName());
+ }
+
// Save build steps
map.insert(QString::fromLatin1(STEPS_COUNT_KEY), m_steps.count());
for (int i = 0; i < m_steps.count(); ++i)
@@ -94,19 +98,28 @@ bool BuildStepList::contains(Core::Id id) const
});
}
-bool BuildStepList::isActive() const
+QString BuildStepList::displayName() const
{
- return qobject_cast<ProjectConfiguration *>(parent())->isActive();
+ if (m_id == Constants::BUILDSTEPS_BUILD) {
+ //: Display name of the build build step list. Used as part of the labels in the project window.
+ return tr("Build");
+ }
+ if (m_id == Constants::BUILDSTEPS_CLEAN) {
+ //: Display name of the clean build step list. Used as part of the labels in the project window.
+ return tr("Clean");
+ }
+ if (m_id == Constants::BUILDSTEPS_DEPLOY) {
+ //: Display name of the deploy build step list. Used as part of the labels in the project window.
+ return tr("Deploy");
+ }
+ QTC_CHECK(false);
+ return {};
}
bool BuildStepList::fromMap(const QVariantMap &map)
{
clear();
- // We need the ID set before trying to restore the steps!
- if (!ProjectConfiguration::fromMap(map))
- return false;
-
const QList<BuildStepFactory *> factories = BuildStepFactory::allBuildStepFactories();
int maxSteps = map.value(QString::fromLatin1(STEPS_COUNT_KEY), 0).toInt();
@@ -140,9 +153,9 @@ QList<BuildStep *> BuildStepList::steps() const
return m_steps;
}
-QList<BuildStep *> BuildStepList::steps(const std::function<bool (const BuildStep *)> &filter) const
+BuildStep *BuildStepList::firstStepWithId(Core::Id id) const
{
- return Utils::filtered(steps(), filter);
+ return Utils::findOrDefault(m_steps, Utils::equal(&BuildStep::id, id));
}
void BuildStepList::insertStep(int position, BuildStep *step)
@@ -162,14 +175,6 @@ void BuildStepList::insertStep(int position, Core::Id stepId)
QTC_ASSERT(false, qDebug() << "No factory for build step" << stepId.toString() << "found.");
}
-void BuildStepList::appendSteps(const QList<StepCreationInfo> &infos)
-{
- for (const StepCreationInfo &info : infos) {
- if (!info.condition || info.condition(target()))
- appendStep(info.stepId);
- }
-}
-
bool BuildStepList::removeStep(int position)
{
BuildStep *bs = at(position);
@@ -198,19 +203,4 @@ BuildStep *BuildStepList::at(int position)
return m_steps.at(position);
}
-Target *BuildStepList::target() const
-{
- Q_ASSERT(parent());
- auto bc = qobject_cast<BuildConfiguration *>(parent());
- if (bc)
- return bc->target();
- auto dc = qobject_cast<DeployConfiguration *>(parent());
- if (dc)
- return dc->target();
- return nullptr;
-}
-
-Project *BuildStepList::project() const
-{
- return target()->project();
-}
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsteplist.h b/src/plugins/projectexplorer/buildsteplist.h
index b9fce034da..52fdd99f89 100644
--- a/src/plugins/projectexplorer/buildsteplist.h
+++ b/src/plugins/projectexplorer/buildsteplist.h
@@ -27,8 +27,9 @@
#include "projectexplorer_export.h"
-#include "projectconfiguration.h"
+#include <coreplugin/id.h>
+#include <QObject>
#include <QVariantMap>
namespace ProjectExplorer {
@@ -36,7 +37,7 @@ namespace ProjectExplorer {
class BuildStep;
class Target;
-class PROJECTEXPLORER_EXPORT BuildStepList : public ProjectConfiguration
+class PROJECTEXPLORER_EXPORT BuildStepList : public QObject
{
Q_OBJECT
@@ -47,7 +48,7 @@ public:
void clear();
QList<BuildStep *> steps() const;
- QList<BuildStep *> steps(const std::function<bool(const BuildStep *)> &filter) const;
+
template <class BS> BS *firstOfType() {
BS *bs = nullptr;
for (int i = 0; i < count(); ++i) {
@@ -57,16 +58,7 @@ public:
}
return nullptr;
}
- template <class BS> QList<BS *>allOfType() {
- QList<BS *> result;
- BS *bs = nullptr;
- for (int i = 0; i < count(); ++i) {
- bs = qobject_cast<BS *>(at(i));
- if (bs)
- result.append(bs);
- }
- return result;
- }
+ BuildStep *firstStepWithId(Core::Id id) const;
int count() const;
bool isEmpty() const;
@@ -81,19 +73,18 @@ public:
Core::Id stepId;
std::function<bool(Target *)> condition; // unset counts as unrestricted
};
- void appendSteps(const QList<StepCreationInfo> &infos);
bool removeStep(int position);
void moveStepUp(int position);
BuildStep *at(int position);
- Target *target() const;
- Project *project() const override;
+ Target *target() { return m_target; }
- QVariantMap toMap() const override;
- bool fromMap(const QVariantMap &map) override;
+ QVariantMap toMap() const;
+ bool fromMap(const QVariantMap &map);
- bool isActive() const override;
+ Core::Id id() const { return m_id; }
+ QString displayName() const;
signals:
void stepInserted(int position);
@@ -102,6 +93,8 @@ signals:
void stepMoved(int from, int to);
private:
+ Target *m_target;
+ Core::Id m_id;
QList<BuildStep *> m_steps;
};
diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp
index 331ccd9f40..de40258b11 100644
--- a/src/plugins/projectexplorer/buildstepspage.cpp
+++ b/src/plugins/projectexplorer/buildstepspage.cpp
@@ -53,7 +53,7 @@ using namespace Utils;
ToolWidget::ToolWidget(QWidget *parent) : FadingPanel(parent)
{
auto layout = new QHBoxLayout;
- layout->setMargin(4);
+ layout->setContentsMargins(4, 4, 4, 4);
layout->setSpacing(4);
setLayout(layout);
m_firstWidget = new FadingWidget(this);
@@ -75,7 +75,7 @@ ToolWidget::ToolWidget(QWidget *parent) : FadingPanel(parent)
m_secondWidget = new FadingWidget(this);
m_secondWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
hbox = new QHBoxLayout();
- hbox->setMargin(0);
+ hbox->setContentsMargins(0, 0, 0, 0);
hbox->setSpacing(4);
m_secondWidget->setLayout(hbox);
@@ -426,20 +426,3 @@ void BuildStepListWidget::updateBuildStepButtonsState()
s->toolWidget->setUpVisible(m_buildStepList->count() != 1);
}
}
-
-BuildStepsPage::BuildStepsPage(BuildConfiguration *bc, Core::Id id) :
- m_id(id),
- m_widget(new BuildStepListWidget(this))
-{
- auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
- layout->setSpacing(0);
- layout->addWidget(m_widget);
-
- m_widget->init(bc->stepList(m_id));
-
- if (m_id == Constants::BUILDSTEPS_BUILD)
- setDisplayName(tr("Build Steps"));
- if (m_id == Constants::BUILDSTEPS_CLEAN)
- setDisplayName(tr("Clean Steps"));
-}
diff --git a/src/plugins/projectexplorer/buildstepspage.h b/src/plugins/projectexplorer/buildstepspage.h
index fd06a71566..2453c9e784 100644
--- a/src/plugins/projectexplorer/buildstepspage.h
+++ b/src/plugins/projectexplorer/buildstepspage.h
@@ -123,19 +123,5 @@ private:
QPushButton *m_addButton = nullptr;
};
-namespace Ui { class BuildStepsPage; }
-
-class BuildStepsPage : public NamedWidget
-{
- Q_OBJECT
-
-public:
- BuildStepsPage(BuildConfiguration *bc, Core::Id id);
-
-private:
- Core::Id m_id;
- BuildStepListWidget *m_widget = nullptr;
-};
-
} // Internal
} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp
new file mode 100644
index 0000000000..84c9b12381
--- /dev/null
+++ b/src/plugins/projectexplorer/buildsystem.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "buildsystem.h"
+
+#include "buildconfiguration.h"
+#include "target.h"
+
+#include <utils/qtcassert.h>
+
+using namespace Utils;
+
+namespace ProjectExplorer {
+
+// --------------------------------------------------------------------
+// BuildSystem:
+// --------------------------------------------------------------------
+
+BuildSystem::BuildSystem(Project *project)
+ : m_project(project)
+{
+ QTC_CHECK(project);
+
+ // Timer:
+ m_delayedParsingTimer.setSingleShot(true);
+
+ connect(&m_delayedParsingTimer, &QTimer::timeout, this, &BuildSystem::triggerParsing);
+}
+
+Project *BuildSystem::project() const
+{
+ return m_project;
+}
+
+bool BuildSystem::isWaitingForParse() const
+{
+ return m_delayedParsingTimer.isActive();
+}
+
+void BuildSystem::requestParse()
+{
+ requestParse(0);
+}
+
+void BuildSystem::requestDelayedParse()
+{
+ requestParse(1000);
+}
+
+void BuildSystem::requestParse(int delay)
+{
+ m_delayedParsingTimer.setInterval(delay);
+ m_delayedParsingTimer.start();
+}
+
+void BuildSystem::triggerParsing()
+{
+ QTC_CHECK(!project()->isParsing());
+
+ Project *p = project();
+ Target *t = p->activeTarget();
+ BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr;
+
+ MacroExpander *e = nullptr;
+ if (bc)
+ e = bc->macroExpander();
+ else if (t)
+ e = t->macroExpander();
+ else
+ e = p->macroExpander();
+
+ Utils::Environment env = p->activeParseEnvironment();
+
+ ParsingContext ctx(p->guardParsingRun(), p, bc, e, env);
+
+ if (validateParsingContext(ctx))
+ parseProject(std::move(ctx));
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildsystem.h b/src/plugins/projectexplorer/buildsystem.h
new file mode 100644
index 0000000000..dd8456074c
--- /dev/null
+++ b/src/plugins/projectexplorer/buildsystem.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "projectexplorer_export.h"
+
+#include "project.h"
+#include "treescanner.h"
+
+#include <QTimer>
+
+namespace ProjectExplorer {
+
+class BuildConfiguration;
+class ExtraCompiler;
+
+// --------------------------------------------------------------------
+// BuildSystem:
+// --------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT BuildSystem : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit BuildSystem(Project *project);
+
+ BuildSystem(const BuildSystem &other) = delete;
+
+ Project *project() const;
+
+ bool isWaitingForParse() const;
+
+ void requestParse();
+ void requestDelayedParse();
+
+protected:
+ class ParsingContext
+ {
+ public:
+ ParsingContext() = default;
+
+ ParsingContext(const ParsingContext &other) = delete;
+ ParsingContext &operator=(const ParsingContext &other) = delete;
+ ParsingContext(ParsingContext &&other) = default;
+ ParsingContext &operator=(ParsingContext &&other) = default;
+
+ Project::ParseGuard guard;
+
+ Project *project = nullptr;
+ BuildConfiguration *buildConfiguration = nullptr;
+ Utils::MacroExpander *expander = nullptr;
+ Utils::Environment environment;
+
+ private:
+ ParsingContext(Project::ParseGuard &&g,
+ Project *p,
+ BuildConfiguration *bc,
+ Utils::MacroExpander *e,
+ Utils::Environment &env)
+ : guard(std::move(g))
+ , project(p)
+ , buildConfiguration(bc)
+ , expander(e)
+ , environment(env)
+ {}
+
+ friend class BuildSystem;
+ };
+
+ virtual bool validateParsingContext(const ParsingContext &ctx)
+ {
+ Q_UNUSED(ctx)
+ return true;
+ }
+
+ virtual void parseProject(ParsingContext &&ctx) = 0; // actual code to parse project
+
+private:
+ void requestParse(int delay); // request a (delayed!) parser run.
+ void triggerParsing();
+
+ QTimer m_delayedParsingTimer;
+
+ Project *m_project;
+};
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.h b/src/plugins/projectexplorer/buildtargettype.h
index ed78b6e802..9e2d162e9d 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.h
+++ b/src/plugins/projectexplorer/buildtargettype.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,27 +25,8 @@
#pragma once
-#include "idevicewidget.h"
-
namespace ProjectExplorer {
-namespace Ui { class DesktopDeviceConfigurationWidget; }
-
-class DesktopDeviceConfigurationWidget : public IDeviceWidget
-{
- Q_OBJECT
-public:
- explicit DesktopDeviceConfigurationWidget(const IDevice::Ptr &device, QWidget *parent = nullptr);
- ~DesktopDeviceConfigurationWidget() override;
-
- void updateDeviceFromUi() override;
-
-private:
- void updateFreePorts();
-
- void initGui();
-private:
- Ui::DesktopDeviceConfigurationWidget *m_ui;
-};
+enum class BuildTargetType { Unknown, Executable, Library };
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp
index 5c25cb83d8..098596d3c1 100644
--- a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp
@@ -40,12 +40,7 @@ CodeStyleSettingsWidget::CodeStyleSettingsWidget(Project *project) : QWidget(),
const EditorConfiguration *config = m_project->editorConfiguration();
- QMap<Core::Id, ICodeStylePreferencesFactory *> factories
- = TextEditorSettings::codeStyleFactories();
- QMapIterator<Core::Id, ICodeStylePreferencesFactory *> it(factories);
- while (it.hasNext()) {
- it.next();
- ICodeStylePreferencesFactory *factory = it.value();
+ for (ICodeStylePreferencesFactory *factory : TextEditorSettings::codeStyleFactories()) {
Core::Id languageId = factory->languageId();
ICodeStylePreferences *codeStylePreferences = config->codeStyle(languageId);
diff --git a/src/plugins/projectexplorer/configtaskhandler.cpp b/src/plugins/projectexplorer/configtaskhandler.cpp
index 5ad2a11a81..e3c5ed58d5 100644
--- a/src/plugins/projectexplorer/configtaskhandler.cpp
+++ b/src/plugins/projectexplorer/configtaskhandler.cpp
@@ -50,7 +50,7 @@ bool ConfigTaskHandler::canHandle(const Task &task) const
void ConfigTaskHandler::handle(const Task &task)
{
- Q_UNUSED(task);
+ Q_UNUSED(task)
Core::ICore::showOptionsDialog(m_targetPage);
}
diff --git a/src/plugins/projectexplorer/currentprojectfilter.cpp b/src/plugins/projectexplorer/currentprojectfilter.cpp
index 0e924eeb2a..c0875fc132 100644
--- a/src/plugins/projectexplorer/currentprojectfilter.cpp
+++ b/src/plugins/projectexplorer/currentprojectfilter.cpp
@@ -56,9 +56,9 @@ void CurrentProjectFilter::prepareSearch(const QString &entry)
{
Q_UNUSED(entry)
if (!fileIterator()) {
- QStringList paths;
+ Utils::FilePathList paths;
if (m_project)
- paths = Utils::transform(m_project->files(Project::AllFiles), &Utils::FilePath::toString);
+ paths = m_project->files(Project::SourceFiles);
setFileIterator(new BaseFileFilter::ListIterator(paths));
}
BaseFileFilter::prepareSearch(entry);
diff --git a/src/plugins/projectexplorer/currentprojectfind.cpp b/src/plugins/projectexplorer/currentprojectfind.cpp
index ca8093f78b..0eb445523a 100644
--- a/src/plugins/projectexplorer/currentprojectfind.cpp
+++ b/src/plugins/projectexplorer/currentprojectfind.cpp
@@ -72,7 +72,7 @@ bool CurrentProjectFind::isEnabled() const
QVariant CurrentProjectFind::additionalParameters() const
{
Project *project = ProjectTree::currentProject();
- if (project && project->document())
+ if (project)
return QVariant::fromValue(project->projectFilePath().toString());
return QVariant();
}
@@ -85,7 +85,7 @@ Utils::FileIterator *CurrentProjectFind::files(const QStringList &nameFilters,
return new Utils::FileListIterator(QStringList(), QList<QTextCodec *>()));
QString projectFile = additionalParameters.toString();
for (Project *project : SessionManager::projects()) {
- if (project->document() && projectFile == project->projectFilePath().toString())
+ if (project && projectFile == project->projectFilePath().toString())
return filesForProjects(nameFilters, exclusionFilters, {project});
}
return new Utils::FileListIterator(QStringList(), QList<QTextCodec *>());
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index 957b742474..2f5e4463b7 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -101,7 +101,7 @@ CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
auto layout = new QFormLayout;
layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
auto detailsContainer = new DetailsWidget(this);
detailsContainer->setState(DetailsWidget::NoSummary);
@@ -255,15 +255,14 @@ Runnable CustomExecutableRunConfiguration::runnable() const
aspect<WorkingDirectoryAspect>()->workingDirectory(macroExpander());
Runnable r;
- r.executable = executable().toString();
- r.commandLineArguments = aspect<ArgumentsAspect>()->arguments(macroExpander());
+ r.setCommandLine(commandLine());
r.environment = aspect<EnvironmentAspect>()->environment();
r.workingDirectory = workingDirectory.toString();
r.device = DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE);
if (!r.executable.isEmpty()) {
- QString expanded = macroExpander()->expand(r.executable);
- r.executable = r.environment.searchInPath(expanded, {workingDirectory}).toString();
+ const QString expanded = macroExpander()->expand(r.executable.toString());
+ r.executable = r.environment.searchInPath(expanded, {workingDirectory});
}
return r;
diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp
index e1175963ea..654337ab2c 100644
--- a/src/plugins/projectexplorer/customtoolchain.cpp
+++ b/src/plugins/projectexplorer/customtoolchain.cpp
@@ -84,11 +84,8 @@ static const char warningExampleKeyC[] = "ProjectExplorer.CustomToolChain.Warnin
CustomToolChain::CustomToolChain() :
ToolChain(Constants::CUSTOM_TOOLCHAIN_TYPEID),
m_outputParserId(GccParser::id())
-{ }
-
-QString CustomToolChain::typeDisplayName() const
{
- return Internal::CustomToolChainFactory::tr("Custom");
+ setTypeDisplayName(Internal::CustomToolChainFactory::tr("Custom"));
}
Abi CustomToolChain::targetAbi() const
@@ -141,7 +138,7 @@ Utils::LanguageExtensions CustomToolChain::languageExtensions(const QStringList
WarningFlags CustomToolChain::warningFlags(const QStringList &cxxflags) const
{
- Q_UNUSED(cxxflags);
+ Q_UNUSED(cxxflags)
return WarningFlags::Default;
}
@@ -158,7 +155,8 @@ void CustomToolChain::setPredefinedMacros(const Macros &macros)
toolChainUpdated();
}
-ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &) const
{
const HeaderPaths builtInHeaderPaths = m_builtInHeaderPaths;
@@ -176,9 +174,10 @@ ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRun
}
HeaderPaths CustomToolChain::builtInHeaderPaths(const QStringList &cxxFlags,
- const FilePath &fileName) const
+ const FilePath &fileName,
+ const Environment &env) const
{
- return createBuiltInHeaderPathsRunner()(cxxFlags, fileName.toString(), "");
+ return createBuiltInHeaderPathsRunner(env)(cxxFlags, fileName.toString(), "");
}
void CustomToolChain::addToEnvironment(Environment &env) const
diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h
index 415cf89abd..d2a5df2926 100644
--- a/src/plugins/projectexplorer/customtoolchain.h
+++ b/src/plugins/projectexplorer/customtoolchain.h
@@ -65,7 +65,6 @@ public:
QString displayName; ///< A translateable name to show in the user interface
};
- QString typeDisplayName() const override;
Abi targetAbi() const override;
void setTargetAbi(const Abi &);
@@ -78,9 +77,11 @@ public:
const Macros &rawPredefinedMacros() const;
void setPredefinedMacros(const Macros &macros);
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &) const override;
HeaderPaths builtInHeaderPaths(const QStringList &cxxFlags,
- const Utils::FilePath &) const override;
+ const Utils::FilePath &,
+ const Utils::Environment &env) const override;
void addToEnvironment(Utils::Environment &env) const override;
QStringList suggestedMkspecList() const override;
IOutputParser *outputParser() const override;
diff --git a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp
index 71c43b01c1..1f8a7c0130 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp
@@ -27,6 +27,7 @@
#include "customwizard.h"
#include "customwizardparameters.h"
+#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h>
#include <utils/temporarydirectory.h>
@@ -107,11 +108,11 @@ static bool
}
process.setWorkingDirectory(workingDirectory);
process.setTimeoutS(30);
+ const Utils::CommandLine cmd(binary, arguments);
if (CustomWizard::verbose())
- qDebug("In %s, running:\n%s\n%s\n", qPrintable(workingDirectory),
- qPrintable(binary),
- qPrintable(arguments.join(QLatin1Char(' '))));
- Utils::SynchronousProcessResponse response = process.run(binary, arguments);
+ qDebug("In %s, running:\n%s\n", qPrintable(workingDirectory),
+ qPrintable(cmd.toUserOutput()));
+ Utils::SynchronousProcessResponse response = process.run(cmd);
if (response.result != Utils::SynchronousProcessResponse::Finished) {
*errorMessage = QString::fromLatin1("Generator script failed: %1")
.arg(response.exitMessage(binary, 30));
diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp
index fcc0c886bf..29c80cb175 100644
--- a/src/plugins/projectexplorer/deployconfiguration.cpp
+++ b/src/plugins/projectexplorer/deployconfiguration.cpp
@@ -44,6 +44,7 @@ DeployConfiguration::DeployConfiguration(Target *target, Core::Id id)
: ProjectConfiguration(target, id),
m_stepList(this, Constants::BUILDSTEPS_DEPLOY)
{
+ QTC_CHECK(target && target == this->target());
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Deploy Settings"));
expander->setAccumulating(true);
@@ -52,8 +53,6 @@ DeployConfiguration::DeployConfiguration(Target *target, Core::Id id)
return bc ? bc->macroExpander() : target->macroExpander();
});
- //: Display name of the deploy build step list. Used as part of the labels in the project window.
- m_stepList.setDefaultDisplayName(tr("Deploy"));
//: Default DeployConfiguration display name
setDefaultDisplayName(tr("Deploy locally"));
}
@@ -68,7 +67,7 @@ const BuildStepList *DeployConfiguration::stepList() const
return &m_stepList;
}
-NamedWidget *DeployConfiguration::createConfigWidget() const
+QWidget *DeployConfiguration::createConfigWidget() const
{
if (!m_configWidgetCreator)
return nullptr;
@@ -99,7 +98,6 @@ bool DeployConfiguration::fromMap(const QVariantMap &map)
m_stepList.clear();
return false;
}
- m_stepList.setDefaultDisplayName(tr("Deploy"));
} else {
qWarning() << "No data for deploy step list found!";
return false;
@@ -108,16 +106,6 @@ bool DeployConfiguration::fromMap(const QVariantMap &map)
return true;
}
-Target *DeployConfiguration::target() const
-{
- return static_cast<Target *>(parent());
-}
-
-Project *DeployConfiguration::project() const
-{
- return target()->project();
-}
-
bool DeployConfiguration::isActive() const
{
return target()->isActive() && target()->activeDeployConfiguration() == this;
@@ -169,14 +157,14 @@ bool DeployConfigurationFactory::canHandle(Target *target) const
return true;
}
-void DeployConfigurationFactory::setConfigWidgetCreator(const std::function<NamedWidget *(Target *)> &configWidgetCreator)
+void DeployConfigurationFactory::setConfigWidgetCreator(const std::function<QWidget *(Target *)> &configWidgetCreator)
{
m_configWidgetCreator = configWidgetCreator;
}
void DeployConfigurationFactory::setUseDeploymentDataView()
{
- m_configWidgetCreator = [](Target *target) { return new DeploymentDataView(target); };
+ m_configWidgetCreator = [](Target *target) { return new Internal::DeploymentDataView(target); };
}
void DeployConfigurationFactory::setConfigBaseId(Core::Id deployConfigBaseId)
@@ -197,7 +185,11 @@ DeployConfiguration *DeployConfigurationFactory::create(Target *parent)
QTC_ASSERT(canHandle(parent), return nullptr);
DeployConfiguration *dc = createDeployConfiguration(parent);
QTC_ASSERT(dc, return nullptr);
- dc->stepList()->appendSteps(m_initialSteps);
+ BuildStepList *stepList = dc->stepList();
+ for (const BuildStepList::StepCreationInfo &info : qAsConst(m_initialSteps)) {
+ if (!info.condition || info.condition(parent))
+ stepList->appendStep(info.stepId);
+ }
return dc;
}
diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h
index 66d387291c..9c82d93466 100644
--- a/src/plugins/projectexplorer/deployconfiguration.h
+++ b/src/plugins/projectexplorer/deployconfiguration.h
@@ -35,7 +35,6 @@ namespace ProjectExplorer {
class BuildStepList;
class Target;
class DeployConfigurationFactory;
-class NamedWidget;
class PROJECTEXPLORER_EXPORT DeployConfiguration final : public ProjectConfiguration
{
@@ -51,19 +50,16 @@ public:
BuildStepList *stepList();
const BuildStepList *stepList() const;
- NamedWidget *createConfigWidget() const;
+ QWidget *createConfigWidget() const;
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
- Target *target() const;
- Project *project() const override;
-
bool isActive() const override;
private:
BuildStepList m_stepList;
- std::function<NamedWidget *(Target *)> m_configWidgetCreator;
+ std::function<QWidget *(Target *)> m_configWidgetCreator;
};
class PROJECTEXPLORER_EXPORT DeployConfigurationFactory
@@ -94,7 +90,7 @@ public:
bool canHandle(ProjectExplorer::Target *target) const;
- void setConfigWidgetCreator(const std::function<NamedWidget *(Target *)> &configWidgetCreator);
+ void setConfigWidgetCreator(const std::function<QWidget *(Target *)> &configWidgetCreator);
void setUseDeploymentDataView();
using PostRestore = std::function<void(DeployConfiguration *dc, const QVariantMap &)>;
@@ -112,7 +108,7 @@ private:
QList<Core::Id> m_supportedTargetDeviceTypes;
QList<BuildStepList::StepCreationInfo> m_initialSteps;
QString m_defaultDisplayName;
- std::function<NamedWidget *(Target *)> m_configWidgetCreator;
+ std::function<QWidget *(Target *)> m_configWidgetCreator;
PostRestore m_postRestore;
};
diff --git a/src/plugins/projectexplorer/deploymentdata.cpp b/src/plugins/projectexplorer/deploymentdata.cpp
index acb8878de6..98d43692b6 100644
--- a/src/plugins/projectexplorer/deploymentdata.cpp
+++ b/src/plugins/projectexplorer/deploymentdata.cpp
@@ -55,11 +55,10 @@ void DeploymentData::addFile(const QString &localFilePath, const QString &remote
addFile(DeployableFile(localFilePath, remoteDirectory, type));
}
-DeployableFile DeploymentData::deployableForLocalFile(const QString &localFilePath) const
+DeployableFile DeploymentData::deployableForLocalFile(const Utils::FilePath &localFilePath) const
{
- return Utils::findOrDefault(m_files, [&localFilePath](const DeployableFile &d) {
- return d.localFilePath().toString() == localFilePath;
- });
+ return Utils::findOrDefault(m_files,
+ Utils::equal(&DeployableFile::localFilePath, localFilePath));
}
bool DeploymentData::operator==(const DeploymentData &other) const
diff --git a/src/plugins/projectexplorer/deploymentdata.h b/src/plugins/projectexplorer/deploymentdata.h
index e45427ebf8..ad4209330e 100644
--- a/src/plugins/projectexplorer/deploymentdata.h
+++ b/src/plugins/projectexplorer/deploymentdata.h
@@ -60,7 +60,7 @@ public:
int fileCount() const { return m_files.count(); }
DeployableFile fileAt(int index) const { return m_files.at(index); }
- DeployableFile deployableForLocalFile(const QString &localFilePath) const;
+ DeployableFile deployableForLocalFile(const Utils::FilePath &localFilePath) const;
bool operator==(const DeploymentData &other) const;
diff --git a/src/plugins/projectexplorer/deploymentdatamodel.cpp b/src/plugins/projectexplorer/deploymentdatamodel.cpp
deleted file mode 100644
index f5d655792f..0000000000
--- a/src/plugins/projectexplorer/deploymentdatamodel.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "deploymentdatamodel.h"
-
-namespace ProjectExplorer {
-
-DeploymentDataModel::DeploymentDataModel(QObject *parent) : QAbstractTableModel(parent)
-{ }
-
-void DeploymentDataModel::setDeploymentData(const DeploymentData &deploymentData)
-{
- beginResetModel();
- m_deploymentData = deploymentData;
- endResetModel();
-}
-
-int DeploymentDataModel::rowCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : m_deploymentData.fileCount();
-}
-
-int DeploymentDataModel::columnCount(const QModelIndex &parent) const
-{
- return parent.isValid() ? 0 : 2;
-}
-
-QVariant DeploymentDataModel::headerData(int section, Qt::Orientation orientation,
- int role) const
-{
- if (orientation == Qt::Vertical || role != Qt::DisplayRole)
- return QVariant();
- return section == 0 ? tr("Local File Path") : tr("Remote Directory");
-}
-
-QVariant DeploymentDataModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount())
- return QVariant();
-
- const DeployableFile &d = m_deploymentData.fileAt(index.row());
- if (index.column() == 0 && role == Qt::DisplayRole)
- return d.localFilePath().toUserOutput();
- if (role == Qt::DisplayRole)
- return d.remoteDirectory();
- return QVariant();
-}
-
-} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/deploymentdataview.cpp b/src/plugins/projectexplorer/deploymentdataview.cpp
index bce3bff0b4..f620cf4a5b 100644
--- a/src/plugins/projectexplorer/deploymentdataview.cpp
+++ b/src/plugins/projectexplorer/deploymentdataview.cpp
@@ -24,56 +24,75 @@
****************************************************************************/
#include "deploymentdataview.h"
-#include "ui_deploymentdataview.h"
-#include "deploymentdatamodel.h"
+#include "deploymentdata.h"
#include "target.h"
+#include <utils/treemodel.h>
+
+#include <QAbstractTableModel>
+#include <QLabel>
+#include <QHeaderView>
+#include <QTreeView>
+#include <QVBoxLayout>
+
+using namespace Utils;
+
namespace ProjectExplorer {
namespace Internal {
-class DeploymentDataViewPrivate
+class DeploymentDataItem : public TreeItem
{
public:
- Ui::DeploymentDataView ui;
- Target *target;
- DeploymentDataModel deploymentDataModel;
-};
+ DeploymentDataItem() = default;
+ DeploymentDataItem(const DeployableFile &file) : file(file) {}
-} // namespace Internal
+ QVariant data(int column, int role) const
+ {
+ if (role == Qt::DisplayRole)
+ return column == 0 ? file.localFilePath().toUserOutput() : file.remoteDirectory();
+ return QVariant();
+ }
+ DeployableFile file;
+};
-using namespace Internal;
-DeploymentDataView::DeploymentDataView(Target *target, QWidget *parent) : NamedWidget(parent),
- d(std::make_unique<DeploymentDataViewPrivate>())
+DeploymentDataView::DeploymentDataView(Target *target)
{
- d->ui.setupUi(this);
- d->ui.deploymentDataView->setTextElideMode(Qt::ElideMiddle);
- d->ui.deploymentDataView->setWordWrap(false);
- d->ui.deploymentDataView->setUniformRowHeights(true);
- d->ui.deploymentDataView->setModel(&d->deploymentDataModel);
+ auto model = new TreeModel<DeploymentDataItem>(this);
+ model->setHeader({tr("Local File Path"), tr("Remote Directory")});
- d->target = target;
+ auto view = new QTreeView(this);
+ view->setMinimumSize(QSize(100, 100));
+ view->setTextElideMode(Qt::ElideMiddle);
+ view->setWordWrap(false);
+ view->setUniformRowHeights(true);
+ view->setModel(model);
- connect(target, &Target::deploymentDataChanged,
- this, &DeploymentDataView::updateDeploymentDataModel);
- updateDeploymentDataModel();
-}
+ auto label = new QLabel(tr("Files to deploy:"), this);
-DeploymentDataView::~DeploymentDataView() = default;
+ auto layout = new QVBoxLayout(this);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(label);
+ layout->addWidget(view);
-void DeploymentDataView::updateDeploymentDataModel()
-{
- d->deploymentDataModel.setDeploymentData(d->target->deploymentData());
- QHeaderView *header = d->ui.deploymentDataView->header();
- header->setSectionResizeMode(0, QHeaderView::Interactive);
- header->setSectionResizeMode(1, QHeaderView::Interactive);
- d->ui.deploymentDataView->resizeColumnToContents(0);
- d->ui.deploymentDataView->resizeColumnToContents(1);
- if (header->sectionSize(0) + header->sectionSize(1)
- < d->ui.deploymentDataView->header()->width()) {
- d->ui.deploymentDataView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
- }
+ auto updatModel = [this, target, model, view] {
+ model->clear();
+ for (const DeployableFile &file : target->deploymentData().allFiles())
+ model->rootItem()->appendChild(new DeploymentDataItem(file));
+
+ QHeaderView *header = view->header();
+ header->setSectionResizeMode(0, QHeaderView::Interactive);
+ header->setSectionResizeMode(1, QHeaderView::Interactive);
+ view->resizeColumnToContents(0);
+ view->resizeColumnToContents(1);
+ if (header->sectionSize(0) + header->sectionSize(1) < header->width())
+ header->setSectionResizeMode(1, QHeaderView::Stretch);
+ };
+
+ connect(target, &Target::deploymentDataChanged, this, updatModel);
+ updatModel();
}
-} // namespace ProjectExplorer
+} // Internal
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/deploymentdataview.h b/src/plugins/projectexplorer/deploymentdataview.h
index 9cc49eaa8f..178a96e3bb 100644
--- a/src/plugins/projectexplorer/deploymentdataview.h
+++ b/src/plugins/projectexplorer/deploymentdataview.h
@@ -25,28 +25,21 @@
#pragma once
-#include "namedwidget.h"
-#include "projectexplorer_export.h"
-
-#include <memory>
+#include <QWidget>
namespace ProjectExplorer {
+
class Target;
-namespace Internal { class DeploymentDataViewPrivate; }
+namespace Internal {
-class PROJECTEXPLORER_EXPORT DeploymentDataView : public NamedWidget
+class DeploymentDataView : public QWidget
{
Q_OBJECT
public:
- explicit DeploymentDataView(Target *target, QWidget *parent = nullptr);
- ~DeploymentDataView() override;
-
-private:
- void updateDeploymentDataModel();
-
- const std::unique_ptr<Internal::DeploymentDataViewPrivate> d;
+ explicit DeploymentDataView(Target *target);
};
-} // namespace ProjectExplorer
+} // Internal
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/deploymentdataview.ui b/src/plugins/projectexplorer/deploymentdataview.ui
deleted file mode 100644
index 325740bd2d..0000000000
--- a/src/plugins/projectexplorer/deploymentdataview.ui
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ProjectExplorer::DeploymentDataView</class>
- <widget class="QWidget" name="ProjectExplorer::DeploymentDataView">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>617</width>
- <height>361</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string/>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Files to deploy:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTreeView" name="deploymentDataView">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>100</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.cpp b/src/plugins/projectexplorer/desktoprunconfiguration.cpp
new file mode 100644
index 0000000000..a3f1f735ac
--- /dev/null
+++ b/src/plugins/projectexplorer/desktoprunconfiguration.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "desktoprunconfiguration.h"
+
+#include "localenvironmentaspect.h"
+#include "project.h"
+#include "runconfigurationaspects.h"
+#include "target.h"
+
+#include <cmakeprojectmanager/cmakeprojectconstants.h>
+#include <qbsprojectmanager/qbsprojectmanagerconstants.h>
+#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
+
+#include <utils/fileutils.h>
+#include <utils/pathchooser.h>
+#include <utils/qtcassert.h>
+#include <utils/stringutils.h>
+
+#include <QFileInfo>
+
+using namespace Utils;
+
+namespace ProjectExplorer {
+namespace Internal {
+
+DesktopRunConfiguration::DesktopRunConfiguration(Target *target, Core::Id id, Kind kind)
+ : RunConfiguration(target, id), m_kind(kind)
+{
+ auto envAspect = addAspect<LocalEnvironmentAspect>(target);
+
+ addAspect<ExecutableAspect>();
+ addAspect<ArgumentsAspect>();
+ addAspect<WorkingDirectoryAspect>();
+ addAspect<TerminalAspect>();
+
+ auto libAspect = addAspect<UseLibraryPathsAspect>();
+ connect(libAspect, &UseLibraryPathsAspect::changed,
+ envAspect, &EnvironmentAspect::environmentChanged);
+
+ if (HostOsInfo::isMacHost()) {
+ auto dyldAspect = addAspect<UseDyldSuffixAspect>();
+ connect(dyldAspect, &UseLibraryPathsAspect::changed,
+ envAspect, &EnvironmentAspect::environmentChanged);
+ envAspect->addModifier([dyldAspect](Environment &env) {
+ if (dyldAspect->value())
+ env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug"));
+ });
+ }
+
+ envAspect->addModifier([this, libAspect](Environment &env) {
+ BuildTargetInfo bti = buildTargetInfo();
+ if (bti.runEnvModifier)
+ bti.runEnvModifier(env, libAspect->value());
+ });
+
+ if (kind == Qbs) {
+
+ connect(project(), &Project::parsingFinished,
+ envAspect, &EnvironmentAspect::environmentChanged);
+
+ connect(target, &Target::deploymentDataChanged,
+ this, &DesktopRunConfiguration::updateTargetInformation);
+ connect(target, &Target::applicationTargetsChanged,
+ this, &DesktopRunConfiguration::updateTargetInformation);
+ // Handles device changes, etc.
+ connect(target, &Target::kitChanged,
+ this, &DesktopRunConfiguration::updateTargetInformation);
+
+ } else if (m_kind == CMake) {
+
+ libAspect->setVisible(false);
+
+ }
+
+ connect(target->project(), &Project::parsingFinished,
+ this, &DesktopRunConfiguration::updateTargetInformation);
+}
+
+void DesktopRunConfiguration::updateTargetInformation()
+{
+ BuildTargetInfo bti = buildTargetInfo();
+
+ auto terminalAspect = aspect<TerminalAspect>();
+ terminalAspect->setUseTerminalHint(bti.usesTerminal);
+
+ if (m_kind == Qmake) {
+
+ FilePath profile = FilePath::fromString(buildKey());
+ if (profile.isEmpty())
+ setDefaultDisplayName(tr("Qt Run Configuration"));
+ else
+ setDefaultDisplayName(profile.toFileInfo().completeBaseName());
+
+ aspect<EnvironmentAspect>()->environmentChanged();
+
+ auto wda = aspect<WorkingDirectoryAspect>();
+ wda->setDefaultWorkingDirectory(bti.workingDirectory);
+ if (wda->pathChooser())
+ wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory());
+
+ aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
+
+ } else if (m_kind == Qbs) {
+
+ setDefaultDisplayName(bti.displayName);
+ const FilePath executable = executableToRun(bti);
+
+ aspect<ExecutableAspect>()->setExecutable(executable);
+
+ if (!executable.isEmpty()) {
+ QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath();
+ if (!defaultWorkingDir.isEmpty()) {
+ auto wdAspect = aspect<WorkingDirectoryAspect>();
+ wdAspect->setDefaultWorkingDirectory(FilePath::fromString(defaultWorkingDir));
+ }
+ }
+
+ emit enabledChanged();
+
+ } else if (m_kind == CMake) {
+
+ aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
+ aspect<WorkingDirectoryAspect>()->setDefaultWorkingDirectory(bti.workingDirectory);
+ aspect<LocalEnvironmentAspect>()->environmentChanged();
+
+ }
+}
+
+bool DesktopRunConfiguration::fromMap(const QVariantMap &map)
+{
+ if (!RunConfiguration::fromMap(map))
+ return false;
+
+ if (m_kind == Qmake || m_kind == Qbs)
+ updateTargetInformation();
+
+ return true;
+}
+
+void DesktopRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info)
+{
+ if (m_kind == Qbs)
+ setDefaultDisplayName(info.displayName);
+
+ updateTargetInformation();
+}
+
+Utils::FilePath DesktopRunConfiguration::executableToRun(const BuildTargetInfo &targetInfo) const
+{
+ const FilePath appInBuildDir = targetInfo.targetFilePath;
+ const DeploymentData deploymentData = target()->deploymentData();
+ if (deploymentData.localInstallRoot().isEmpty())
+ return appInBuildDir;
+
+ const QString deployedAppFilePath = deploymentData
+ .deployableForLocalFile(appInBuildDir).remoteFilePath();
+ if (deployedAppFilePath.isEmpty())
+ return appInBuildDir;
+
+ const FilePath appInLocalInstallDir = deploymentData.localInstallRoot() + deployedAppFilePath;
+ return appInLocalInstallDir.exists() ? appInLocalInstallDir : appInBuildDir;
+}
+
+bool DesktopRunConfiguration::isBuildTargetValid() const
+{
+ return Utils::anyOf(target()->applicationTargets(), [this](const BuildTargetInfo &bti) {
+ return bti.buildKey == buildKey();
+ });
+}
+
+void DesktopRunConfiguration::updateEnabledState()
+{
+ if (m_kind == CMake && !isBuildTargetValid())
+ setEnabled(false);
+ else
+ RunConfiguration::updateEnabledState();
+}
+
+QString DesktopRunConfiguration::disabledReason() const
+{
+ if (m_kind == CMake && !isBuildTargetValid())
+ return tr("The project no longer builds the target associated with this run configuration.");
+ return RunConfiguration::disabledReason();
+}
+
+// Factory
+
+class DesktopQmakeRunConfiguration : public DesktopRunConfiguration
+{
+public:
+ DesktopQmakeRunConfiguration(Target *target, Core::Id id)
+ : DesktopRunConfiguration(target, id, Qmake)
+ {}
+};
+
+class QbsRunConfiguration : public DesktopRunConfiguration
+{
+public:
+ QbsRunConfiguration(Target *target, Core::Id id)
+ : DesktopRunConfiguration(target, id, Qbs)
+ {}
+};
+
+class CMakeRunConfiguration : public DesktopRunConfiguration
+{
+public:
+ CMakeRunConfiguration(Target *target, Core::Id id)
+ : DesktopRunConfiguration(target, id, CMake)
+ {}
+};
+
+const char QMAKE_RUNCONFIG_ID[] = "Qt4ProjectManager.Qt4RunConfiguration:";
+const char QBS_RUNCONFIG_ID[] = "Qbs.RunConfiguration:";
+const char CMAKE_RUNCONFIG_ID[] = "CMakeProjectManager.CMakeRunConfiguration.";
+
+CMakeRunConfigurationFactory::CMakeRunConfigurationFactory()
+{
+ registerRunConfiguration<CMakeRunConfiguration>(CMAKE_RUNCONFIG_ID);
+ addSupportedProjectType(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
+ addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
+}
+
+QbsRunConfigurationFactory::QbsRunConfigurationFactory()
+{
+ registerRunConfiguration<QbsRunConfiguration>(QBS_RUNCONFIG_ID);
+ addSupportedProjectType(QbsProjectManager::Constants::PROJECT_ID);
+ addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
+}
+
+DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory()
+{
+ registerRunConfiguration<DesktopQmakeRunConfiguration>(QMAKE_RUNCONFIG_ID);
+ addSupportedProjectType(QmakeProjectManager::Constants::QMAKEPROJECT_ID);
+ addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.h b/src/plugins/projectexplorer/desktoprunconfiguration.h
new file mode 100644
index 0000000000..4063337ef1
--- /dev/null
+++ b/src/plugins/projectexplorer/desktoprunconfiguration.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "runconfigurationaspects.h"
+#include "runcontrol.h"
+
+namespace ProjectExplorer {
+namespace Internal {
+
+class DesktopRunConfiguration : public RunConfiguration
+{
+ Q_OBJECT
+
+protected:
+ enum Kind { Qmake, Qbs, CMake }; // FIXME: Remove
+
+ DesktopRunConfiguration(Target *target, Core::Id id, Kind kind);
+
+private:
+ void doAdditionalSetup(const RunConfigurationCreationInfo &info) final;
+ bool fromMap(const QVariantMap &map) final;
+ void updateEnabledState() final;
+
+ void updateTargetInformation();
+
+ Utils::FilePath executableToRun(const BuildTargetInfo &targetInfo) const;
+ QString disabledReason() const override;
+
+ bool isBuildTargetValid() const;
+
+ const Kind m_kind;
+};
+
+class DesktopQmakeRunConfigurationFactory : public RunConfigurationFactory
+{
+public:
+ DesktopQmakeRunConfigurationFactory();
+};
+
+class QbsRunConfigurationFactory : public RunConfigurationFactory
+{
+public:
+ QbsRunConfigurationFactory();
+};
+
+class CMakeRunConfigurationFactory : public RunConfigurationFactory
+{
+public:
+ CMakeRunConfigurationFactory();
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
index a725658b9b..1128e35a3b 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
@@ -27,7 +27,6 @@
#include "desktopdeviceprocess.h"
#include "deviceprocesslist.h"
#include "localprocesslist.h"
-#include "desktopdeviceconfigurationwidget.h"
#include "desktopprocesssignaloperation.h"
#include <coreplugin/fileutils.h>
@@ -54,9 +53,14 @@ DesktopDevice::DesktopDevice()
{
setupId(IDevice::AutoDetected, DESKTOP_DEVICE_ID);
setType(DESKTOP_DEVICE_TYPE);
- setDisplayName(QCoreApplication::translate("ProjectExplorer::DesktopDevice", "Local PC"));
+ setDefaultDisplayName(QCoreApplication::translate("ProjectExplorer::DesktopDevice",
+ "Local PC"));
+ setDisplayType(QCoreApplication::translate("ProjectExplorer::DesktopDevice", "Desktop"));
+
setDeviceState(IDevice::DeviceStateUnknown);
setMachineType(IDevice::Hardware);
+ setOsType(HostOsInfo::hostOs());
+
const QString portRange =
QString::fromLatin1("%1-%2").arg(DESKTOP_PORT_START).arg(DESKTOP_PORT_END);
setFreePorts(Utils::PortList::fromString(portRange));
@@ -70,11 +74,6 @@ IDevice::DeviceInfo DesktopDevice::deviceInformation() const
return DeviceInfo();
}
-QString DesktopDevice::displayType() const
-{
- return QCoreApplication::translate("ProjectExplorer::DesktopDevice", "Desktop");
-}
-
IDeviceWidget *DesktopDevice::createWidget()
{
return nullptr;
@@ -140,10 +139,10 @@ class DesktopPortsGatheringMethod : public PortsGatheringMethod
Runnable runnable;
if (HostOsInfo::isWindowsHost() || HostOsInfo::isMacHost()) {
- runnable.executable = "netstat";
+ runnable.executable = FilePath::fromString("netstat");
runnable.commandLineArguments = "-a -n";
} else if (HostOsInfo::isLinuxHost()) {
- runnable.executable = "/bin/sh";
+ runnable.executable = FilePath::fromString("/bin/sh");
runnable.commandLineArguments = "-c 'cat /proc/net/tcp*'";
}
return runnable;
@@ -175,9 +174,4 @@ QUrl DesktopDevice::toolControlChannel(const ControlChannelHint &) const
return url;
}
-Utils::OsType DesktopDevice::osType() const
-{
- return Utils::HostOsInfo::hostOs();
-}
-
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h
index dec063b5e5..2610cc9b12 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h
@@ -40,7 +40,6 @@ class PROJECTEXPLORER_EXPORT DesktopDevice : public IDevice
public:
IDevice::DeviceInfo deviceInformation() const override;
- QString displayType() const override;
IDeviceWidget *createWidget() override;
bool canAutoDetectPorts() const override;
bool canCreateProcessModel() const override;
@@ -51,7 +50,6 @@ public:
DeviceProcessSignalOperation::Ptr signalOperation() const override;
DeviceEnvironmentFetcher::Ptr environmentFetcher() const override;
QUrl toolControlChannel(const ControlChannelHint &) const override;
- Utils::OsType osType() const override;
protected:
DesktopDevice();
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp
deleted file mode 100644
index fdac2ab230..0000000000
--- a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "desktopdeviceconfigurationwidget.h"
-#include "ui_desktopdeviceconfigurationwidget.h"
-#include <projectexplorer/projectexplorerconstants.h>
-
-#include <utils/utilsicons.h>
-#include <utils/portlist.h>
-#include <utils/qtcassert.h>
-
-#include <QRegExpValidator>
-
-using namespace ProjectExplorer::Constants;
-
-namespace ProjectExplorer {
-
-DesktopDeviceConfigurationWidget::DesktopDeviceConfigurationWidget(const IDevice::Ptr &device,
- QWidget *parent) :
- IDeviceWidget(device, parent),
- m_ui(new Ui::DesktopDeviceConfigurationWidget)
-{
- m_ui->setupUi(this);
- connect(m_ui->freePortsLineEdit, &QLineEdit::textChanged,
- this, &DesktopDeviceConfigurationWidget::updateFreePorts);
-
- initGui();
-}
-
-DesktopDeviceConfigurationWidget::~DesktopDeviceConfigurationWidget()
-{
- delete m_ui;
-}
-
-void DesktopDeviceConfigurationWidget::updateDeviceFromUi()
-{
- updateFreePorts();
-}
-
-void DesktopDeviceConfigurationWidget::updateFreePorts()
-{
- device()->setFreePorts(Utils::PortList::fromString(m_ui->freePortsLineEdit->text()));
- m_ui->portsWarningLabel->setVisible(!device()->freePorts().hasMore());
-}
-
-void DesktopDeviceConfigurationWidget::initGui()
-{
- QTC_CHECK(device()->machineType() == IDevice::Hardware);
- m_ui->machineTypeValueLabel->setText(tr("Physical Device"));
- m_ui->freePortsLineEdit->setPlaceholderText(
- QString::fromLatin1("eg: %1-%2").arg(DESKTOP_PORT_START).arg(DESKTOP_PORT_END));
- m_ui->portsWarningLabel->setPixmap(Utils::Icons::WARNING.pixmap());
- m_ui->portsWarningLabel->setToolTip(QLatin1String("<font color=\"red\">")
- + tr("You will need at least one port for QML debugging.")
- + QLatin1String("</font>"));
- QRegExpValidator * const portsValidator
- = new QRegExpValidator(QRegExp(Utils::PortList::regularExpression()), this);
- m_ui->freePortsLineEdit->setValidator(portsValidator);
-
- m_ui->freePortsLineEdit->setText(device()->freePorts().toString());
- updateFreePorts();
-}
-
-} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui b/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui
deleted file mode 100644
index 3fd9fd184e..0000000000
--- a/src/plugins/projectexplorer/devicesupport/desktopdeviceconfigurationwidget.ui
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ProjectExplorer::DesktopDeviceConfigurationWidget</class>
- <widget class="QWidget" name="ProjectExplorer::DesktopDeviceConfigurationWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>437</width>
- <height>265</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string/>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="machineTypeLabel">
- <property name="text">
- <string>Machine type:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="machineTypeValueLabel">
- <property name="text">
- <string>TextLabel</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="freePortsLabel">
- <property name="text">
- <string>Free ports:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLineEdit" name="freePortsLineEdit"/>
- </item>
- <item>
- <widget class="QLabel" name="portsWarningLabel">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp
index bb9f6c8f43..aec61e50f9 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp
+++ b/src/plugins/projectexplorer/devicesupport/desktopdeviceprocess.cpp
@@ -54,7 +54,7 @@ void DesktopDeviceProcess::start(const Runnable &runnable)
QTC_ASSERT(m_process.state() == QProcess::NotRunning, return);
m_process.setProcessEnvironment(runnable.environment.toProcessEnvironment());
m_process.setWorkingDirectory(runnable.workingDirectory);
- m_process.start(runnable.executable,
+ m_process.start(runnable.executable.toString(),
Utils::QtcProcess::splitArgs(runnable.commandLineArguments));
}
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
index cd6e7421aa..ecd0aca473 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
@@ -47,6 +47,8 @@
#include <limits>
#include <memory>
+using namespace Utils;
+
namespace ProjectExplorer {
namespace Internal {
@@ -410,17 +412,17 @@ public:
setupId(AutoDetected, Core::Id::fromString(QUuid::createUuid().toString()));
setType(testTypeId());
setMachineType(Hardware);
+ setOsType(HostOsInfo::hostOs());
+ setDisplayType("blubb");
}
static Core::Id testTypeId() { return "TestType"; }
private:
- QString displayType() const override { return QLatin1String("blubb"); }
IDeviceWidget *createWidget() override { return nullptr; }
DeviceProcessSignalOperation::Ptr signalOperation() const override
{
return DeviceProcessSignalOperation::Ptr();
}
- Utils::OsType osType() const override { return Utils::HostOsInfo::hostOs(); }
};
class TestDeviceFactory : public IDeviceFactory
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp
index 0aa0ac12d6..b5ff411f4f 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp
@@ -154,7 +154,7 @@ void DeviceManagerModel::handleDeviceListChanged()
int DeviceManagerModel::rowCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return d->devices.count();
}
diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp
index 26d3f968e7..06344e68ba 100644
--- a/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicesettingspage.cpp
@@ -35,8 +35,7 @@
namespace ProjectExplorer {
namespace Internal {
-DeviceSettingsPage::DeviceSettingsPage(QObject *parent)
- : Core::IOptionsPage(parent)
+DeviceSettingsPage::DeviceSettingsPage()
{
setId(Constants::DEVICE_SETTINGS_PAGE_ID);
setDisplayName(tr("Devices"));
diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingspage.h b/src/plugins/projectexplorer/devicesupport/devicesettingspage.h
index d652ad3c50..1bb167a19d 100644
--- a/src/plugins/projectexplorer/devicesupport/devicesettingspage.h
+++ b/src/plugins/projectexplorer/devicesupport/devicesettingspage.h
@@ -39,7 +39,7 @@ class DeviceSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- DeviceSettingsPage(QObject *parent = nullptr);
+ DeviceSettingsPage();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp
index af42589622..f33607b5c9 100644
--- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp
@@ -85,9 +85,8 @@ private:
const DeviceManager * const m_deviceManager;
};
-DeviceSettingsWidget::DeviceSettingsWidget(QWidget *parent)
- : QWidget(parent),
- m_ui(new Ui::DeviceSettingsWidget),
+DeviceSettingsWidget::DeviceSettingsWidget()
+ : m_ui(new Ui::DeviceSettingsWidget),
m_deviceManager(DeviceManager::cloneInstance()),
m_deviceManagerModel(new DeviceManagerModel(m_deviceManager, this)),
m_nameValidator(new NameValidator(m_deviceManager, this)),
diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h
index a7961e145d..8c2affa802 100644
--- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h
+++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h
@@ -49,7 +49,7 @@ class DeviceSettingsWidget : public QWidget
{
Q_OBJECT
public:
- DeviceSettingsWidget(QWidget *parent = nullptr);
+ DeviceSettingsWidget();
~DeviceSettingsWidget() override;
void saveSettings();
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
index 0176369ddc..377be1d520 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
@@ -33,6 +33,8 @@
#include <utils/qtcassert.h>
#include <utils/url.h>
+#include <QPointer>
+
using namespace QSsh;
using namespace Utils;
@@ -195,9 +197,13 @@ void PortsGatherer::start()
m_portsGatherer.start(device());
}
-Port PortsGatherer::findPort()
+QUrl PortsGatherer::findEndPoint()
{
- return m_portsGatherer.getNextFreePort(&m_portList);
+ QUrl result;
+ result.setScheme(urlTcpScheme());
+ result.setHost(device()->sshParameters().host());
+ result.setPort(m_portsGatherer.getNextFreePort(&m_portList).number());
+ return result;
}
void PortsGatherer::stop()
@@ -261,16 +267,12 @@ public:
m_portGatherer = qobject_cast<PortsGatherer *>(sharedEndpointGatherer);
if (m_portGatherer) {
- if (auto creator = device()->workerCreator("ChannelForwarder")) {
- m_channelForwarder = qobject_cast<ChannelForwarder *>(creator(runControl));
+ if (auto forwarder = runControl->createWorker("ChannelForwarder")) {
+ m_channelForwarder = qobject_cast<ChannelForwarder *>(forwarder);
if (m_channelForwarder) {
m_channelForwarder->addStartDependency(m_portGatherer);
m_channelForwarder->setFromUrlGetter([this] {
- QUrl url;
- url.setScheme(urlTcpScheme());
- url.setHost(device()->sshParameters().host());
- url.setPort(m_portGatherer->findPort().number());
- return url;
+ return m_portGatherer->findEndPoint();
});
addStartDependency(m_channelForwarder);
}
@@ -285,7 +287,7 @@ public:
if (m_channelForwarder)
m_channel.setPort(m_channelForwarder->recordedData("LocalPort").toUInt());
else if (m_portGatherer)
- m_channel.setPort(m_portGatherer->findPort().number());
+ m_channel.setPort(m_portGatherer->findEndPoint().port());
reportStarted();
}
@@ -336,11 +338,9 @@ ChannelProvider::ChannelProvider(RunControl *runControl, int requiredChannels)
{
setId("ChannelProvider");
- RunWorker *sharedEndpoints = nullptr;
- if (auto sharedEndpointGatherer = device()->workerCreator("SharedEndpointGatherer")) {
+ RunWorker *sharedEndpoints = runControl->createWorker("SharedEndpointGatherer");
+ if (!sharedEndpoints) {
// null is a legit value indicating 'no need to share'.
- sharedEndpoints = sharedEndpointGatherer(runControl);
- } else {
sharedEndpoints = new PortsGatherer(runControl);
}
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
index 4344f059a5..da3f866ae2 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
@@ -74,7 +74,7 @@ public:
explicit PortsGatherer(RunControl *runControl);
~PortsGatherer() override;
- Utils::Port findPort();
+ QUrl findEndPoint();
protected:
void start() override;
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp
index 86d783a6d9..c74c87cc3e 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp
@@ -34,6 +34,7 @@
#include "../runconfiguration.h"
#include <ssh/sshconnection.h>
+#include <utils/displayname.h>
#include <utils/icon.h>
#include <utils/portlist.h>
#include <utils/qtcassert.h>
@@ -123,6 +124,7 @@ const char TimeoutKey[] = "Timeout";
const char HostKeyCheckingKey[] = "HostKeyChecking";
const char DebugServerKey[] = "DebugServerKey";
+const char PeripheralDescriptionFileKey[] = "PeripheralDescriptionFileKey";
const char QmlsceneKey[] = "QmlsceneKey";
using AuthType = QSsh::SshConnectionParameters::AuthenticationType;
@@ -137,17 +139,20 @@ class IDevicePrivate
public:
IDevicePrivate() = default;
- QString displayName;
+ Utils::DisplayName displayName;
+ QString displayType;
Core::Id type;
IDevice::Origin origin = IDevice::AutoDetected;
Core::Id id;
IDevice::DeviceState deviceState = IDevice::DeviceStateUnknown;
IDevice::MachineType machineType = IDevice::Hardware;
+ Utils::OsType osType = Utils::OsTypeOther;
int version = 0; // This is used by devices that have been added by the SDK.
QSsh::SshConnectionParameters sshParameters;
Utils::PortList freePorts;
QString debugServerPath;
+ QString peripheralDescriptionFilePath;
QString qmlsceneCommand;
QList<Utils::Icon> deviceIcons;
@@ -194,14 +199,32 @@ IDevice::~IDevice() = default;
QString IDevice::displayName() const
{
- return d->displayName;
+ return d->displayName.value();
}
void IDevice::setDisplayName(const QString &name)
{
- if (d->displayName == name)
- return;
- d->displayName = name;
+ d->displayName.setValue(name);
+}
+
+void IDevice::setDefaultDisplayName(const QString &name)
+{
+ d->displayName.setDefaultValue(name);
+}
+
+QString IDevice::displayType() const
+{
+ return d->displayType;
+}
+
+void IDevice::setDisplayType(const QString &type)
+{
+ d->displayType = type;
+}
+
+void IDevice::setOsType(Utils::OsType osType)
+{
+ d->osType = osType;
}
IDevice::DeviceInfo IDevice::deviceInformation() const
@@ -280,7 +303,7 @@ PortsGatheringMethod::Ptr IDevice::portsGatheringMethod() const
DeviceProcessList *IDevice::createProcessListModel(QObject *parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
QTC_ASSERT(false, qDebug("This should not have been called..."); return nullptr);
return nullptr;
}
@@ -293,7 +316,7 @@ DeviceTester *IDevice::createDeviceTester() const
Utils::OsType IDevice::osType() const
{
- return Utils::OsTypeOther;
+ return d->osType;
}
DeviceProcess *IDevice::createProcess(QObject * /* parent */) const
@@ -338,7 +361,7 @@ Core::Id IDevice::idFromMap(const QVariantMap &map)
void IDevice::fromMap(const QVariantMap &map)
{
d->type = typeFromMap(map);
- d->displayName = map.value(QLatin1String(DisplayNameKey)).toString();
+ d->displayName.fromMap(map, DisplayNameKey);
d->id = Core::Id::fromSetting(map.value(QLatin1String(IdKey)));
if (!d->id.isValid())
d->id = newId();
@@ -369,6 +392,7 @@ void IDevice::fromMap(const QVariantMap &map)
d->version = map.value(QLatin1String(VersionKey), 0).toInt();
d->debugServerPath = map.value(QLatin1String(DebugServerKey)).toString();
+ d->peripheralDescriptionFilePath = map.value(QLatin1String(PeripheralDescriptionFileKey)).toString();
d->qmlsceneCommand = map.value(QLatin1String(QmlsceneKey)).toString();
d->extraData = map.value(ExtraDataKey).toMap();
}
@@ -382,7 +406,7 @@ void IDevice::fromMap(const QVariantMap &map)
QVariantMap IDevice::toMap() const
{
QVariantMap map;
- map.insert(QLatin1String(DisplayNameKey), d->displayName);
+ d->displayName.toMap(map, DisplayNameKey);
map.insert(QLatin1String(TypeKey), d->type.toString());
map.insert(QLatin1String(IdKey), d->id.toSetting());
map.insert(QLatin1String(OriginKey), d->origin);
@@ -400,6 +424,7 @@ QVariantMap IDevice::toMap() const
map.insert(QLatin1String(VersionKey), d->version);
map.insert(QLatin1String(DebugServerKey), d->debugServerPath);
+ map.insert(QLatin1String(PeripheralDescriptionFileKey), d->peripheralDescriptionFilePath);
map.insert(QLatin1String(QmlsceneKey), d->qmlsceneCommand);
map.insert(ExtraDataKey, d->extraData);
@@ -415,6 +440,10 @@ IDevice::Ptr IDevice::clone() const
device->d->deviceState = d->deviceState;
device->d->deviceActions = d->deviceActions;
device->d->deviceIcons = d->deviceIcons;
+ // Os type is only set in the constructor, always to the same value.
+ // But make sure we notice if that changes in the future (which it shouldn't).
+ QTC_CHECK(device->d->osType == d->osType);
+ device->d->osType = d->osType;
device->fromMap(toMap());
return device;
}
@@ -479,6 +508,17 @@ void IDevice::setDebugServerPath(const QString &path)
d->debugServerPath = path;
}
+
+QString IDevice::peripheralDescriptionFilePath() const
+{
+ return d->peripheralDescriptionFilePath;
+}
+
+void IDevice::setPeripheralDescriptionFilePath(const QString &path)
+{
+ d->peripheralDescriptionFilePath = path;
+}
+
QString IDevice::qmlsceneCommand() const
{
return d->qmlsceneCommand;
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index b263544000..65e739950f 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -60,8 +60,6 @@ class DeviceProcess;
class DeviceProcessList;
class Kit;
class Runnable;
-class RunControl;
-class RunWorker;
namespace Internal { class IDevicePrivate; }
@@ -134,6 +132,7 @@ public:
QString displayName() const;
void setDisplayName(const QString &name);
+ void setDefaultDisplayName(const QString &name);
// Provide some information on the device suitable for formated
// output, e.g. in tool tips. Get a list of name value pairs.
@@ -155,7 +154,9 @@ public:
virtual bool isCompatibleWith(const Kit *k) const;
- virtual QString displayType() const = 0;
+ QString displayType() const;
+ Utils::OsType osType() const;
+
virtual IDeviceWidget *createWidget() = 0;
struct DeviceAction {
@@ -173,15 +174,12 @@ public:
virtual DeviceProcessList *createProcessListModel(QObject *parent = nullptr) const;
virtual bool hasDeviceTester() const { return false; }
virtual DeviceTester *createDeviceTester() const;
- virtual Utils::OsType osType() const;
virtual bool canCreateProcess() const { return false; }
virtual DeviceProcess *createProcess(QObject *parent) const;
virtual DeviceProcessSignalOperation::Ptr signalOperation() const = 0;
virtual DeviceEnvironmentFetcher::Ptr environmentFetcher() const;
- virtual std::function<RunWorker *(RunControl *)> workerCreator(Core::Id) const { return {}; }
-
enum DeviceState { DeviceReadyToUse, DeviceConnected, DeviceDisconnected, DeviceStateUnknown };
DeviceState deviceState() const;
void setDeviceState(const DeviceState state);
@@ -211,6 +209,9 @@ public:
QString debugServerPath() const;
void setDebugServerPath(const QString &path);
+ QString peripheralDescriptionFilePath() const;
+ void setPeripheralDescriptionFilePath(const QString &path);
+
QString qmlsceneCommand() const;
void setQmlsceneCommand(const QString &path);
@@ -227,6 +228,8 @@ protected:
using OpenTerminal = std::function<void(const Utils::Environment &, const QString &)>;
void setOpenTerminal(const OpenTerminal &openTerminal);
+ void setDisplayType(const QString &type);
+ void setOsType(Utils::OsType osType);
private:
IDevice(const IDevice &) = delete;
diff --git a/src/plugins/projectexplorer/devicesupport/idevicewidget.h b/src/plugins/projectexplorer/devicesupport/idevicewidget.h
index f9aad1a892..ef02ef847f 100644
--- a/src/plugins/projectexplorer/devicesupport/idevicewidget.h
+++ b/src/plugins/projectexplorer/devicesupport/idevicewidget.h
@@ -40,7 +40,7 @@ public:
virtual void updateDeviceFromUi() = 0;
protected:
- explicit IDeviceWidget(const IDevice::Ptr &device, QWidget *parent = nullptr) : QWidget(parent),
+ explicit IDeviceWidget(const IDevice::Ptr &device) :
m_device(device)
{ }
diff --git a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
index 832cbd5246..24d692dd28 100644
--- a/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
+++ b/src/plugins/projectexplorer/devicesupport/localprocesslist.cpp
@@ -165,7 +165,7 @@ static QList<DeviceProcessItem> getLocalProcessesUsingPs()
psProcess.start(QLatin1String("ps"), args);
if (psProcess.waitForStarted()) {
QByteArray output;
- if (Utils::SynchronousProcess::readDataFromProcess(psProcess, 30000, &output, 0, false)) {
+ if (Utils::SynchronousProcess::readDataFromProcess(psProcess, 30000, &output, nullptr, false)) {
// Split "457 /Users/foo.app arg1 arg2"
const QStringList lines = QString::fromLocal8Bit(output).split(QLatin1Char('\n'));
const int lineCount = lines.size();
diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp
index 7e8be72c65..56fd1b9503 100644
--- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp
+++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp
@@ -194,15 +194,15 @@ void SshDeviceProcess::handleConnected()
d->process->requestX11Forwarding(display);
if (runInTerminal()) {
d->process->requestTerminal();
- const QStringList cmdLine = d->process->fullLocalCommandLine();
connect(&d->consoleProcess, QOverload<QProcess::ProcessError>::of(&ConsoleProcess::error),
this, &DeviceProcess::error);
connect(&d->consoleProcess, &ConsoleProcess::processStarted,
this, &SshDeviceProcess::handleProcessStarted);
connect(&d->consoleProcess, &ConsoleProcess::stubStopped,
this, [this] { handleProcessFinished(d->consoleProcess.errorString()); });
- d->consoleProcess.start(cmdLine.first(), cmdLine.mid(1).join(' '),
- ConsoleProcess::MetaCharMode::Ignore);
+ d->consoleProcess.setAbortOnMetaChars(false);
+ d->consoleProcess.setCommand(d->process->fullLocalCommandLine());
+ d->consoleProcess.start();
} else {
connect(d->process.get(), &QSsh::SshRemoteProcess::started,
this, &SshDeviceProcess::handleProcessStarted);
@@ -298,7 +298,7 @@ void SshDeviceProcess::handleKillOperationTimeout()
QString SshDeviceProcess::fullCommandLine(const Runnable &runnable) const
{
- QString cmdLine = runnable.executable;
+ QString cmdLine = runnable.executable.toString();
if (!runnable.commandLineArguments.isEmpty())
cmdLine.append(QLatin1Char(' ')).append(runnable.commandLineArguments);
return cmdLine;
@@ -320,12 +320,12 @@ void SshDeviceProcess::SshDeviceProcessPrivate::doSignal(Signal signal)
case SshDeviceProcessPrivate::Connected:
case SshDeviceProcessPrivate::ProcessRunning:
DeviceProcessSignalOperation::Ptr signalOperation = q->device()->signalOperation();
- quint64 processId = q->processId();
+ const qint64 processId = q->processId();
if (signal == Signal::Interrupt) {
if (processId != 0)
signalOperation->interruptProcess(processId);
else
- signalOperation->interruptProcess(runnable.executable);
+ signalOperation->interruptProcess(runnable.executable.toString());
} else {
if (killOperation) // We are already in the process of killing the app.
return;
@@ -336,7 +336,7 @@ void SshDeviceProcess::SshDeviceProcessPrivate::doSignal(Signal signal)
if (processId != 0)
signalOperation->killProcess(processId);
else
- signalOperation->killProcess(runnable.executable);
+ signalOperation->killProcess(runnable.executable.toString());
}
break;
}
diff --git a/src/plugins/projectexplorer/devicesupport/sshsettingspage.cpp b/src/plugins/projectexplorer/devicesupport/sshsettingspage.cpp
index 152467c93e..289820d437 100644
--- a/src/plugins/projectexplorer/devicesupport/sshsettingspage.cpp
+++ b/src/plugins/projectexplorer/devicesupport/sshsettingspage.cpp
@@ -74,7 +74,7 @@ private:
bool m_keygenPathChanged = false;
};
-SshSettingsPage::SshSettingsPage(QObject *parent) : Core::IOptionsPage(parent)
+SshSettingsPage::SshSettingsPage()
{
setId(Constants::SSH_SETTINGS_PAGE_ID);
setDisplayName(tr("SSH"));
diff --git a/src/plugins/projectexplorer/devicesupport/sshsettingspage.h b/src/plugins/projectexplorer/devicesupport/sshsettingspage.h
index e43ef93826..14e7f00acb 100644
--- a/src/plugins/projectexplorer/devicesupport/sshsettingspage.h
+++ b/src/plugins/projectexplorer/devicesupport/sshsettingspage.h
@@ -39,7 +39,7 @@ class SshSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- SshSettingsPage(QObject *parent = 0);
+ SshSettingsPage();
private:
QWidget *widget() override;
diff --git a/src/plugins/projectexplorer/editorconfiguration.cpp b/src/plugins/projectexplorer/editorconfiguration.cpp
index 40e08d368e..a78afc440d 100644
--- a/src/plugins/projectexplorer/editorconfiguration.cpp
+++ b/src/plugins/projectexplorer/editorconfiguration.cpp
@@ -86,9 +86,8 @@ struct EditorConfigurationPrivate
EditorConfiguration::EditorConfiguration() : d(std::make_unique<EditorConfigurationPrivate>())
{
const QMap<Core::Id, ICodeStylePreferences *> languageCodeStylePreferences = TextEditorSettings::codeStyles();
- QMapIterator<Core::Id, ICodeStylePreferences *> itCodeStyle(languageCodeStylePreferences);
- while (itCodeStyle.hasNext()) {
- itCodeStyle.next();
+ for (auto itCodeStyle = languageCodeStylePreferences.cbegin(), end = languageCodeStylePreferences.cend();
+ itCodeStyle != end; ++itCodeStyle) {
Core::Id languageId = itCodeStyle.key();
// global prefs for language
ICodeStylePreferences *originalPreferences = itCodeStyle.value();
@@ -189,10 +188,11 @@ QVariantMap EditorConfiguration::toMap() const
map.insert(kCodec, d->m_textCodec->name());
map.insert(kCodeStyleCount, d->m_languageCodeStylePreferences.count());
- QMapIterator<Core::Id, ICodeStylePreferences *> itCodeStyle(d->m_languageCodeStylePreferences);
+
int i = 0;
- while (itCodeStyle.hasNext()) {
- itCodeStyle.next();
+ for (auto itCodeStyle = d->m_languageCodeStylePreferences.cbegin(),
+ end = d->m_languageCodeStylePreferences.cend();
+ itCodeStyle != end; ++itCodeStyle) {
QVariantMap settingsIdMap;
settingsIdMap.insert(QLatin1String("language"), itCodeStyle.key().toSetting());
QVariantMap value;
diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp
index 0b0eff1e37..68eff43620 100644
--- a/src/plugins/projectexplorer/environmentaspect.cpp
+++ b/src/plugins/projectexplorer/environmentaspect.cpp
@@ -62,7 +62,7 @@ void EnvironmentAspect::setBaseEnvironmentBase(int base)
}
}
-void EnvironmentAspect::setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff)
+void EnvironmentAspect::setUserEnvironmentChanges(const Utils::EnvironmentItems &diff)
{
if (m_userChanges != diff) {
m_userChanges = diff;
diff --git a/src/plugins/projectexplorer/environmentaspect.h b/src/plugins/projectexplorer/environmentaspect.h
index 6657d1dfe8..ef5ed2907e 100644
--- a/src/plugins/projectexplorer/environmentaspect.h
+++ b/src/plugins/projectexplorer/environmentaspect.h
@@ -49,8 +49,8 @@ public:
int baseEnvironmentBase() const;
void setBaseEnvironmentBase(int base);
- QList<Utils::EnvironmentItem> userEnvironmentChanges() const { return m_userChanges; }
- void setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff);
+ Utils::EnvironmentItems userEnvironmentChanges() const { return m_userChanges; }
+ void setUserEnvironmentChanges(const Utils::EnvironmentItems &diff);
void addSupportedBaseEnvironment(const QString &displayName,
const std::function<Utils::Environment()> &getter);
@@ -70,7 +70,7 @@ public:
signals:
void baseEnvironmentChanged();
- void userEnvironmentChangesChanged(const QList<Utils::EnvironmentItem> &diff);
+ void userEnvironmentChangesChanged(const Utils::EnvironmentItems &diff);
void environmentChanged();
protected:
@@ -88,7 +88,7 @@ private:
QString displayName;
};
- QList<Utils::EnvironmentItem> m_userChanges;
+ Utils::EnvironmentItems m_userChanges;
QList<EnvironmentModifier> m_modifiers;
QList<BaseEnvironment> m_baseEnvironments;
int m_base = -1;
diff --git a/src/plugins/projectexplorer/environmentaspectwidget.cpp b/src/plugins/projectexplorer/environmentaspectwidget.cpp
index 0898a3f1b6..b50c861972 100644
--- a/src/plugins/projectexplorer/environmentaspectwidget.cpp
+++ b/src/plugins/projectexplorer/environmentaspectwidget.cpp
@@ -49,11 +49,11 @@ EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWid
setContentsMargins(0, 0, 0, 0);
auto topLayout = new QVBoxLayout(this);
- topLayout->setMargin(0);
+ topLayout->setContentsMargins(0, 0, 0, 0);
auto baseEnvironmentWidget = new QWidget;
auto baseLayout = new QHBoxLayout(baseEnvironmentWidget);
- baseLayout->setMargin(0);
+ baseLayout->setContentsMargins(0, 0, 0, 0);
auto label = new QLabel(tr("Base environment for this run configuration:"), this);
baseLayout->addWidget(label);
@@ -132,7 +132,7 @@ void EnvironmentAspectWidget::userChangesEdited()
m_ignoreChange = false;
}
-void EnvironmentAspectWidget::changeUserChanges(QList<Utils::EnvironmentItem> changes)
+void EnvironmentAspectWidget::changeUserChanges(Utils::EnvironmentItems changes)
{
if (m_ignoreChange)
return;
diff --git a/src/plugins/projectexplorer/environmentaspectwidget.h b/src/plugins/projectexplorer/environmentaspectwidget.h
index 6ca8164f05..44acee2f61 100644
--- a/src/plugins/projectexplorer/environmentaspectwidget.h
+++ b/src/plugins/projectexplorer/environmentaspectwidget.h
@@ -61,7 +61,7 @@ private:
void baseEnvironmentSelected(int idx);
void changeBaseEnvironment();
void userChangesEdited();
- void changeUserChanges(QList<Utils::EnvironmentItem> changes);
+ void changeUserChanges(Utils::EnvironmentItems changes);
void environmentChanged();
EnvironmentAspect *m_aspect;
diff --git a/src/plugins/projectexplorer/environmentwidget.cpp b/src/plugins/projectexplorer/environmentwidget.cpp
index 1a6e424960..04d68dd42d 100644
--- a/src/plugins/projectexplorer/environmentwidget.cpp
+++ b/src/plugins/projectexplorer/environmentwidget.cpp
@@ -30,11 +30,12 @@
#include <utils/detailswidget.h>
#include <utils/environment.h>
-#include <utils/environmentmodel.h>
#include <utils/environmentdialog.h>
+#include <utils/environmentmodel.h>
#include <utils/headerviewstretcher.h>
#include <utils/hostosinfo.h>
#include <utils/itemviews.h>
+#include <utils/namevaluevalidator.h>
#include <utils/tooltip/tooltip.h>
#include <QDir>
@@ -51,48 +52,6 @@
namespace ProjectExplorer {
-class EnvironmentValidator : public QValidator
-{
- Q_OBJECT
-public:
- EnvironmentValidator(QWidget *parent, Utils::EnvironmentModel *model, QTreeView *view,
- const QModelIndex &index) :
- QValidator(parent), m_model(model), m_view(view), m_index(index)
- {
- m_hideTipTimer.setInterval(2000);
- m_hideTipTimer.setSingleShot(true);
- connect(&m_hideTipTimer, &QTimer::timeout,
- this, [](){Utils::ToolTip::hide();});
- }
-
- QValidator::State validate(QString &in, int &pos) const override
- {
- Q_UNUSED(pos)
- QModelIndex idx = m_model->variableToIndex(in);
- if (idx.isValid() && idx != m_index)
- return QValidator::Intermediate;
- Utils::ToolTip::hide();
- m_hideTipTimer.stop();
- return QValidator::Acceptable;
- }
-
- void fixup(QString &input) const override
- {
- Q_UNUSED(input)
-
- QPoint pos = m_view->mapToGlobal(m_view->visualRect(m_index).topLeft());
- pos -= Utils::ToolTip::offsetFromPosition();
- Utils::ToolTip::show(pos, tr("Variable already exists."));
- m_hideTipTimer.start();
- // do nothing
- }
-private:
- Utils::EnvironmentModel *m_model;
- QTreeView *m_view;
- QModelIndex m_index;
- mutable QTimer m_hideTipTimer;
-};
-
class EnvironmentDelegate : public QStyledItemDelegate
{
public:
@@ -108,7 +67,8 @@ public:
return w;
if (auto edit = qobject_cast<QLineEdit *>(w))
- edit->setValidator(new EnvironmentValidator(edit, m_model, m_view, index));
+ edit->setValidator(new Utils::NameValueValidator(
+ edit, m_model, m_view, index, EnvironmentWidget::tr("Variable already exists.")));
return w;
}
private:
@@ -134,6 +94,7 @@ public:
QPushButton *m_addButton;
QPushButton *m_resetButton;
QPushButton *m_unsetButton;
+ QPushButton *m_toggleButton;
QPushButton *m_batchEditButton;
QPushButton *m_appendPathButton = nullptr;
QPushButton *m_prependPathButton = nullptr;
@@ -162,13 +123,13 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
details->setVisible(false);
auto vbox2 = new QVBoxLayout(details);
- vbox2->setMargin(0);
+ vbox2->setContentsMargins(0, 0, 0, 0);
if (additionalDetailsWidget)
vbox2->addWidget(additionalDetailsWidget);
auto horizontalLayout = new QHBoxLayout();
- horizontalLayout->setMargin(0);
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
auto tree = new Utils::TreeView(this);
connect(tree, &QAbstractItemView::activated,
tree, [tree](const QModelIndex &idx) { tree->edit(idx); });
@@ -206,6 +167,13 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, Type type, QWidget *additi
d->m_unsetButton->setText(tr("&Unset"));
buttonLayout->addWidget(d->m_unsetButton);
+ d->m_toggleButton = new QPushButton(tr("Disable"), this);
+ buttonLayout->addWidget(d->m_toggleButton);
+ connect(d->m_toggleButton, &QPushButton::clicked, this, [this] {
+ d->m_model->toggleVariable(d->m_environmentView->currentIndex());
+ updateButtons();
+ });
+
if (type == TypeLocal) {
d->m_appendPathButton = new QPushButton(this);
d->m_appendPathButton->setEnabled(false);
@@ -301,12 +269,12 @@ void EnvironmentWidget::setBaseEnvironmentText(const QString &text)
updateSummaryText();
}
-QList<Utils::EnvironmentItem> EnvironmentWidget::userChanges() const
+Utils::EnvironmentItems EnvironmentWidget::userChanges() const
{
return d->m_model->userChanges();
}
-void EnvironmentWidget::setUserChanges(const QList<Utils::EnvironmentItem> &list)
+void EnvironmentWidget::setUserChanges(const Utils::EnvironmentItems &list)
{
d->m_model->setUserChanges(list);
updateSummaryText();
@@ -320,17 +288,26 @@ void EnvironmentWidget::setOpenTerminalFunc(const EnvironmentWidget::OpenTermina
void EnvironmentWidget::updateSummaryText()
{
- QList<Utils::EnvironmentItem> list = d->m_model->userChanges();
+ Utils::EnvironmentItems list = d->m_model->userChanges();
Utils::EnvironmentItem::sort(&list);
QString text;
foreach (const Utils::EnvironmentItem &item, list) {
if (item.name != Utils::EnvironmentModel::tr("<VARIABLE>")) {
text.append(QLatin1String("<br>"));
- if (item.operation == Utils::EnvironmentItem::Unset)
+ switch (item.operation) {
+ case Utils::EnvironmentItem::Unset:
text.append(tr("Unset <a href=\"%1\"><b>%1</b></a>").arg(item.name.toHtmlEscaped()));
- else
+ break;
+ case Utils::EnvironmentItem::SetEnabled:
+ case Utils::EnvironmentItem::Append:
+ case Utils::EnvironmentItem::Prepend:
text.append(tr("Set <a href=\"%1\"><b>%1</b></a> to <b>%2</b>").arg(item.name.toHtmlEscaped(), item.value.toHtmlEscaped()));
+ break;
+ case Utils::EnvironmentItem::SetDisabled:
+ text.append(tr("Set <a href=\"%1\"><b>%1</b></a> to <b>%2</b> [disabled]").arg(item.name.toHtmlEscaped(), item.value.toHtmlEscaped()));
+ break;
+ }
}
}
@@ -455,14 +432,12 @@ void EnvironmentWidget::prependPathButtonClicked()
void EnvironmentWidget::batchEditEnvironmentButtonClicked()
{
- const QList<Utils::EnvironmentItem> changes = d->m_model->userChanges();
+ const Utils::EnvironmentItems changes = d->m_model->userChanges();
- bool ok;
- const QList<Utils::EnvironmentItem> newChanges = Utils::EnvironmentDialog::getEnvironmentItems(&ok, this, changes);
- if (!ok)
- return;
+ const auto newChanges = Utils::EnvironmentDialog::getEnvironmentItems(this, changes);
- d->m_model->setUserChanges(newChanges);
+ if (newChanges)
+ d->m_model->setUserChanges(*newChanges);
}
void EnvironmentWidget::environmentCurrentIndexChanged(const QModelIndex &current)
@@ -471,13 +446,17 @@ void EnvironmentWidget::environmentCurrentIndexChanged(const QModelIndex &curren
d->m_editButton->setEnabled(true);
const QString &name = d->m_model->indexToVariable(current);
bool modified = d->m_model->canReset(name) && d->m_model->changes(name);
- bool unset = d->m_model->canUnset(name);
+ bool unset = d->m_model->isUnset(name);
d->m_resetButton->setEnabled(modified || unset);
d->m_unsetButton->setEnabled(!unset);
+ d->m_toggleButton->setEnabled(!unset);
+ d->m_toggleButton->setText(d->m_model->isEnabled(name) ? tr("Disable") : tr("Enable"));
} else {
d->m_editButton->setEnabled(false);
d->m_resetButton->setEnabled(false);
d->m_unsetButton->setEnabled(false);
+ d->m_toggleButton->setEnabled(false);
+ d->m_toggleButton->setText(tr("Disable"));
}
if (d->m_appendPathButton) {
d->m_appendPathButton->setEnabled(currentEntryIsPathList(current));
@@ -491,5 +470,3 @@ void EnvironmentWidget::invalidateCurrentIndex()
}
} // namespace ProjectExplorer
-
-#include "environmentwidget.moc"
diff --git a/src/plugins/projectexplorer/environmentwidget.h b/src/plugins/projectexplorer/environmentwidget.h
index 927dc9b0c1..2a7e84c024 100644
--- a/src/plugins/projectexplorer/environmentwidget.h
+++ b/src/plugins/projectexplorer/environmentwidget.h
@@ -27,6 +27,8 @@
#include "projectexplorer_export.h"
+#include <utils/environmentfwd.h>
+
#include <QWidget>
#include <functional>
@@ -34,11 +36,6 @@
QT_FORWARD_DECLARE_CLASS(QModelIndex)
-namespace Utils {
-class Environment;
-class EnvironmentItem;
-} // namespace Utils
-
namespace ProjectExplorer {
class EnvironmentWidgetPrivate;
@@ -56,8 +53,8 @@ public:
void setBaseEnvironmentText(const QString &text);
void setBaseEnvironment(const Utils::Environment &env);
- QList<Utils::EnvironmentItem> userChanges() const;
- void setUserChanges(const QList<Utils::EnvironmentItem> &list);
+ Utils::EnvironmentItems userChanges() const;
+ void setUserChanges(const Utils::EnvironmentItems &list);
using OpenTerminalFunc = std::function<void(const Utils::Environment &env)>;
void setOpenTerminalFunc(const OpenTerminalFunc &func);
diff --git a/src/plugins/projectexplorer/extracompiler.cpp b/src/plugins/projectexplorer/extracompiler.cpp
index adcc8f180e..7123ff38e2 100644
--- a/src/plugins/projectexplorer/extracompiler.cpp
+++ b/src/plugins/projectexplorer/extracompiler.cpp
@@ -254,7 +254,7 @@ Utils::Environment ExtraCompiler::buildEnvironment() const
if (BuildConfiguration *bc = target->activeBuildConfiguration()) {
return bc->environment();
} else {
- QList<Utils::EnvironmentItem> changes =
+ Utils::EnvironmentItems changes =
EnvironmentKitAspect::environmentChanges(target->kit());
Utils::Environment env = Utils::Environment::systemEnvironment();
env.modify(changes);
@@ -376,13 +376,13 @@ QStringList ProcessExtraCompiler::arguments() const
bool ProcessExtraCompiler::prepareToRun(const QByteArray &sourceContents)
{
- Q_UNUSED(sourceContents);
+ Q_UNUSED(sourceContents)
return true;
}
Tasks ProcessExtraCompiler::parseIssues(const QByteArray &stdErr)
{
- Q_UNUSED(stdErr);
+ Q_UNUSED(stdErr)
return {};
}
diff --git a/src/plugins/projectexplorer/extracompiler.h b/src/plugins/projectexplorer/extracompiler.h
index ba9c6774f7..e6eae13f5c 100644
--- a/src/plugins/projectexplorer/extracompiler.h
+++ b/src/plugins/projectexplorer/extracompiler.h
@@ -118,9 +118,9 @@ protected:
virtual bool prepareToRun(const QByteArray &sourceContents);
- virtual void handleProcessError(QProcess *process) { Q_UNUSED(process); }
+ virtual void handleProcessError(QProcess *process) { Q_UNUSED(process) }
virtual void handleProcessStarted(QProcess *process, const QByteArray &sourceContents)
- { Q_UNUSED(process); Q_UNUSED(sourceContents); }
+ { Q_UNUSED(process); Q_UNUSED(sourceContents) }
virtual FileNameToContentsHash handleProcessFinished(QProcess *process) = 0;
virtual Tasks parseIssues(const QByteArray &stdErr);
diff --git a/src/plugins/projectexplorer/fileinsessionfinder.cpp b/src/plugins/projectexplorer/fileinsessionfinder.cpp
index e4c62e405f..8d42c409ad 100644
--- a/src/plugins/projectexplorer/fileinsessionfinder.cpp
+++ b/src/plugins/projectexplorer/fileinsessionfinder.cpp
@@ -72,7 +72,7 @@ FilePathList FileInSessionFinder::doFindFile(const FilePath &filePath)
: FilePath());
FilePathList allFiles;
for (const Project * const p : SessionManager::projects())
- allFiles << p->files(Project::AllFiles);
+ allFiles << p->files(Project::SourceFiles);
m_finder.setProjectFiles(allFiles);
m_finderIsUpToDate = true;
}
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp
index 6ff9c9719a..5072a54708 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.cpp
+++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp
@@ -513,7 +513,7 @@ void FolderNavigationWidget::addNewItem()
if (!current.isValid())
return;
const auto filePath = Utils::FilePath::fromString(m_fileSystemModel->filePath(current));
- const Utils::FilePath path = filePath.toFileInfo().isDir() ? filePath : filePath.parentDir();
+ const Utils::FilePath path = filePath.isDir() ? filePath : filePath.parentDir();
Core::ICore::showNewItemDialog(ProjectExplorerPlugin::tr("New File", "Title of dialog"),
Utils::filtered(Core::IWizardFactory::allWizardFactories(),
Utils::equal(&Core::IWizardFactory::kind,
@@ -554,10 +554,9 @@ void FolderNavigationWidget::removeCurrentItem()
const QVector<FolderNode *> folderNodes = removableFolderNodes(
Utils::FilePath::fromString(filePath));
const QVector<FolderNode *> failedNodes = Utils::filtered(folderNodes,
- [filePath](FolderNode *folder) {
- return !folder->removeFiles(
- {filePath});
- });
+ [filePath](FolderNode *folder) {
+ return folder->removeFiles({filePath}) != RemovedFilesFromProject::Ok;
+ });
Core::FileChangeBlocker changeGuard(filePath);
Core::FileUtils::removeFile(filePath, true /*delete from disk*/);
if (!failedNodes.isEmpty()) {
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index d6521cde99..ef88b51403 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -25,6 +25,7 @@
#include "gccparser.h"
#include "ldparser.h"
+#include "lldparser.h"
#include "task.h"
#include "projectexplorerconstants.h"
#include "buildmanager.h"
@@ -34,6 +35,7 @@
#include <utils/qtcassert.h>
using namespace ProjectExplorer;
+using namespace Utils;
// opt. drive letter + filename: (2 brackets)
static const char FILE_PATTERN[] = "(<command[ -]line>|([A-Za-z]:)?[^:]+):";
@@ -58,6 +60,7 @@ GccParser::GccParser()
m_regExpGccNames.setPattern(QLatin1String(COMMAND_PATTERN));
QTC_CHECK(m_regExpGccNames.isValid());
+ appendOutputParser(new Internal::LldParser);
appendOutputParser(new LdParser);
}
@@ -875,6 +878,130 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
)
<< QString();
+ const auto task = [categoryCompile](Task::TaskType type, const QString &msg,
+ const QString &file = {}, int line = -1) {
+ return Task(type, msg, FilePath::fromString(file), line, categoryCompile);
+ };
+ const auto errorTask = [&task](const QString &msg, const QString &file = {}, int line = -1) {
+ return task(Task::Error, msg, file, line);
+ };
+ const auto unknownTask = [&task](const QString &msg, const QString &file = {}, int line = -1) {
+ return task(Task::Unknown, msg, file, line);
+ };
+ QTest::newRow("lld: undefined reference with debug info")
+ << "ld.lld: error: undefined symbol: func()\n"
+ ">>> referenced by test.cpp:5\n"
+ ">>> /tmp/ccg8pzRr.o:(main)\n"
+ "collect2: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("ld.lld: error: undefined symbol: func()"),
+ unknownTask("referenced by test.cpp:5", "test.cpp", 5),
+ unknownTask("/tmp/ccg8pzRr.o:(main)", "/tmp/ccg8pzRr.o"),
+ errorTask("collect2: error: ld returned 1 exit status")}
+ << QString();
+ QTest::newRow("lld: undefined reference with debug info (more verbose format)")
+ << "ld.lld: error: undefined symbol: someFunc()\n"
+ ">>> referenced by main.cpp:10 (/tmp/untitled4/main.cpp:10)\n"
+ ">>> /tmp/Debug4/untitled4.5abe06ac/3a52ce780950d4d9/main.cpp.o:(main)\n"
+ "clang-8: error: linker command failed with exit code 1 (use -v to see invocation)"
+ << OutputParserTester::STDERR << QString()
+ << QString("clang-8: error: linker command failed with exit code 1 (use -v to see invocation)\n")
+ << Tasks{
+ errorTask("ld.lld: error: undefined symbol: someFunc()"),
+ unknownTask("referenced by main.cpp:10 (/tmp/untitled4/main.cpp:10)",
+ "/tmp/untitled4/main.cpp", 10),
+ unknownTask("/tmp/Debug4/untitled4.5abe06ac/3a52ce780950d4d9/main.cpp.o:(main)",
+ "/tmp/Debug4/untitled4.5abe06ac/3a52ce780950d4d9/main.cpp.o")}
+ << QString();
+ QTest::newRow("lld: undefined reference without debug info")
+ << "ld.lld: error: undefined symbol: func()\n"
+ ">>> referenced by test.cpp\n"
+ ">>> /tmp/ccvjyJph.o:(main)\n"
+ "collect2: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("ld.lld: error: undefined symbol: func()"),
+ unknownTask("referenced by test.cpp", "test.cpp"),
+ unknownTask("/tmp/ccvjyJph.o:(main)", "/tmp/ccvjyJph.o"),
+ errorTask("collect2: error: ld returned 1 exit status")}
+ << QString();
+ if (HostOsInfo::isWindowsHost()) {
+ QTest::newRow("lld: undefined reference with mingw")
+ << "lld-link: error: undefined symbol: __Z4funcv\n"
+ ">>> referenced by C:\\Users\\orgads\\AppData\\Local\\Temp\\cccApKoz.o:(.text)\n"
+ "collect2.exe: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("lld-link: error: undefined symbol: __Z4funcv"),
+ unknownTask("referenced by C:\\Users\\orgads\\AppData\\Local\\Temp\\cccApKoz.o:(.text)",
+ "C:/Users/orgads/AppData/Local/Temp/cccApKoz.o"),
+ errorTask("collect2.exe: error: ld returned 1 exit status")}
+ << QString();
+ }
+ QTest::newRow("lld: multiple definitions with debug info")
+ << "ld.lld: error: duplicate symbol: func()\n"
+ ">>> defined at test1.cpp:1\n"
+ ">>> test1.o:(func())\n"
+ ">>> defined at test1.cpp:1\n"
+ ">>> test1.o:(.text+0x0)\n"
+ "collect2: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("ld.lld: error: duplicate symbol: func()"),
+ unknownTask("defined at test1.cpp:1", "test1.cpp", 1),
+ unknownTask("test1.o:(func())", "test1.o"),
+ unknownTask("defined at test1.cpp:1", "test1.cpp", 1),
+ unknownTask("test1.o:(.text+0x0)", "test1.o"),
+ errorTask("collect2: error: ld returned 1 exit status")}
+ << QString();
+ QTest::newRow("lld: multiple definitions with debug info (more verbose format)")
+ << "ld.lld: error: duplicate symbol: theFunc()\n"
+ ">>> defined at file.cpp:1 (/tmp/untitled3/file.cpp:1)\n"
+ ">>> /tmp/Debug/untitled3.dade828b/3a52ce780950d4d9/file.cpp.o:(theFunc())\n"
+ ">>> defined at main.cpp:5 (/tmp/untitled3/main.cpp:5)\n"
+ ">>> /tmp/Debug/untitled3.dade828b/3a52ce780950d4d9/main.cpp.o:(.text+0x0)\n"
+ "collect2: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("ld.lld: error: duplicate symbol: theFunc()"),
+ unknownTask("defined at file.cpp:1 (/tmp/untitled3/file.cpp:1)",
+ "/tmp/untitled3/file.cpp", 1),
+ unknownTask("/tmp/Debug/untitled3.dade828b/3a52ce780950d4d9/file.cpp.o:(theFunc())",
+ "/tmp/Debug/untitled3.dade828b/3a52ce780950d4d9/file.cpp.o"),
+ unknownTask("defined at main.cpp:5 (/tmp/untitled3/main.cpp:5)",
+ "/tmp/untitled3/main.cpp", 5),
+ unknownTask("/tmp/Debug/untitled3.dade828b/3a52ce780950d4d9/main.cpp.o:(.text+0x0)",
+ "/tmp/Debug/untitled3.dade828b/3a52ce780950d4d9/main.cpp.o"),
+ errorTask("collect2: error: ld returned 1 exit status")}
+ << QString();
+ QTest::newRow("lld: multiple definitions without debug info")
+ << "ld.lld: error: duplicate symbol: func()\n"
+ ">>> defined at test1.cpp\n"
+ ">>> test1.o:(func())\n"
+ ">>> defined at test1.cpp\n"
+ ">>> test1.o:(.text+0x0)\n"
+ "collect2: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("ld.lld: error: duplicate symbol: func()"),
+ unknownTask("defined at test1.cpp", "test1.cpp"),
+ unknownTask("test1.o:(func())", "test1.o"),
+ unknownTask("defined at test1.cpp", "test1.cpp"),
+ unknownTask("test1.o:(.text+0x0)", "test1.o"),
+ errorTask("collect2: error: ld returned 1 exit status")}
+ << QString();
+ if (HostOsInfo::isWindowsHost()) {
+ QTest::newRow("lld: multiple definitions with mingw")
+ << "lld-link: error: duplicate symbol: __Z4funcv in test1.o and in test2.o\n"
+ "collect2.exe: error: ld returned 1 exit status"
+ << OutputParserTester::STDERR << QString() << QString()
+ << Tasks{
+ errorTask("lld-link: error: duplicate symbol: __Z4funcv in test1.o and in test2.o"),
+ errorTask("collect2.exe: error: ld returned 1 exit status", {})}
+ << QString();
+ }
+
QTest::newRow("Mac: ranlib warning")
<< QString::fromLatin1("ranlib: file: lib/libtest.a(Test0.cpp.o) has no symbols")
<< OutputParserTester::STDERR
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index b45d65c8b0..df6a1286fe 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -88,7 +88,7 @@ static QByteArray runGcc(const FilePath &gcc, const QStringList &arguments, cons
cpp.setEnvironment(environment);
cpp.setTimeoutS(10);
- SynchronousProcessResponse response = cpp.runBlocking(gcc.toString(), arguments);
+ SynchronousProcessResponse response = cpp.runBlocking(CommandLine(gcc, arguments));
if (response.result != SynchronousProcessResponse::Finished ||
response.exitCode != 0) {
qWarning() << response.exitMessage(gcc.toString(), 10);
@@ -232,13 +232,11 @@ static QString gccVersion(const FilePath &path, const QStringList &env)
// GccToolChain
// --------------------------------------------------------------------------
-GccToolChain::GccToolChain() :
- GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID)
-{ }
-
GccToolChain::GccToolChain(Core::Id typeId) :
ToolChain(typeId)
-{ }
+{
+ setTypeDisplayName(GccToolChainFactory::tr("GCC"));
+}
void GccToolChain::setCompilerCommand(const FilePath &path)
{
@@ -289,11 +287,6 @@ LanguageExtensions GccToolChain::defaultLanguageExtensions() const
return LanguageExtension::Gnu;
}
-QString GccToolChain::typeDisplayName() const
-{
- return GccToolChainFactory::tr("GCC");
-}
-
Abi GccToolChain::targetAbi() const
{
return m_targetAbi;
@@ -389,7 +382,7 @@ ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() con
if (++iArg < allFlags.length() && !arguments.contains(a))
arguments << a << allFlags.at(iArg);
} else if (a == "--sysroot" || a == "-isysroot" || a == "-D" || a == "-U"
- || a == "-gcc-toolchain" || a == "-target") {
+ || a == "-gcc-toolchain" || a == "-target" || a == "-mllvm") {
if (++iArg < allFlags.length())
arguments << a << allFlags.at(iArg);
} else if (a.startsWith("-m") || a == "-Os" || a == "-O0" || a == "-O1" || a == "-O2"
@@ -583,7 +576,7 @@ HeaderPaths GccToolChain::builtInHeaderPaths(const Utils::Environment &env,
if (!originalTargetTriple.isEmpty())
arguments << "-target" << originalTargetTriple;
- const Utils::optional<HeaderPaths> cachedPaths = headerCache->check(arguments);
+ const Utils::optional<HeaderPaths> cachedPaths = headerCache->check(qMakePair(env, arguments));
if (cachedPaths)
return cachedPaths.value();
@@ -591,7 +584,7 @@ HeaderPaths GccToolChain::builtInHeaderPaths(const Utils::Environment &env,
arguments,
env.toStringList());
extraHeaderPathsFunction(paths);
- headerCache->insert(arguments, paths);
+ headerCache->insert(qMakePair(env, arguments), paths);
qCDebug(gccLog) << "Reporting header paths to code model:";
for (const HeaderPath &hp : paths) {
@@ -603,15 +596,16 @@ HeaderPaths GccToolChain::builtInHeaderPaths(const Utils::Environment &env,
return paths;
}
-ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &env) const
{
// Using a clean environment breaks ccache/distcc/etc.
- Environment env = Environment::systemEnvironment();
- addToEnvironment(env);
+ Environment fullEnv = env;
+ addToEnvironment(fullEnv);
// This runner must be thread-safe!
return [this,
- env,
+ fullEnv,
compilerCommand = m_compilerCommand,
platformCodeGenFlags = m_platformCodeGenFlags,
reinterpretOptions = m_optionsReinterpreter,
@@ -620,7 +614,7 @@ ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner
extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags,
const QString &sysRoot,
const QString &) {
- return builtInHeaderPaths(env,
+ return builtInHeaderPaths(fullEnv,
compilerCommand,
platformCodeGenFlags,
reinterpretOptions,
@@ -634,12 +628,13 @@ ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner
}
HeaderPaths GccToolChain::builtInHeaderPaths(const QStringList &flags,
- const FilePath &sysRootPath) const
+ const FilePath &sysRootPath,
+ const Environment &env) const
{
- return createBuiltInHeaderPathsRunner()(flags,
- sysRootPath.isEmpty() ? sysRoot()
- : sysRootPath.toString(),
- originalTargetTriple());
+ return createBuiltInHeaderPathsRunner(env)(flags,
+ sysRootPath.isEmpty() ? sysRoot()
+ : sysRootPath.toString(),
+ originalTargetTriple());
}
void GccToolChain::addCommandPathToEnvironment(const FilePath &command, Environment &env)
@@ -800,12 +795,8 @@ bool GccToolChain::fromMap(const QVariantMap &data)
m_originalTargetTriple = data.value(originalTargetTripleKeyC).toString();
const QStringList abiList = data.value(supportedAbisKeyC).toStringList();
m_supportedAbis.clear();
- for (const QString &a : abiList) {
- Abi abi = Abi::fromString(a);
- if (!abi.isValid())
- continue;
- m_supportedAbis.append(abi);
- }
+ for (const QString &a : abiList)
+ m_supportedAbis.append(Abi::fromString(a));
if (targetAbiString.isEmpty())
resetToolChain(m_compilerCommand);
@@ -865,17 +856,130 @@ QString GccToolChain::detectVersion() const
// GccToolChainFactory
// --------------------------------------------------------------------------
+static Utils::FilePathList gnuSearchPathsFromRegistry()
+{
+ if (!HostOsInfo::isWindowsHost())
+ return {};
+
+ // Registry token for the "GNU Tools for ARM Embedded Processors".
+ static const char kRegistryToken[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \
+ "Windows\\CurrentVersion\\Uninstall\\";
+
+ Utils::FilePathList searchPaths;
+
+ QSettings registry(kRegistryToken, QSettings::NativeFormat);
+ const auto productGroups = registry.childGroups();
+ for (const QString &productKey : productGroups) {
+ if (!productKey.startsWith("GNU Tools for ARM Embedded Processors"))
+ continue;
+ registry.beginGroup(productKey);
+ QString uninstallFilePath = registry.value("UninstallString").toString();
+ if (uninstallFilePath.startsWith(QLatin1Char('"')))
+ uninstallFilePath.remove(0, 1);
+ if (uninstallFilePath.endsWith(QLatin1Char('"')))
+ uninstallFilePath.remove(uninstallFilePath.size() - 1, 1);
+ registry.endGroup();
+
+ const QString toolkitRootPath = QFileInfo(uninstallFilePath).path();
+ const QString toolchainPath = toolkitRootPath + QLatin1String("/bin");
+ searchPaths.push_back(FilePath::fromString(toolchainPath));
+ }
+
+ return searchPaths;
+}
+
+static Utils::FilePathList atmelSearchPathsFromRegistry()
+{
+ if (!HostOsInfo::isWindowsHost())
+ return {};
+
+ // Registry token for the "Atmel" toolchains, e.g. provided by installed
+ // "Atmel Studio" IDE.
+ static const char kRegistryToken[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Atmel\\";
+
+ Utils::FilePathList searchPaths;
+ QSettings registry(kRegistryToken, QSettings::NativeFormat);
+
+ // This code enumerate the installed toolchains provided
+ // by the Atmel Studio v6.x.
+ const auto toolchainGroups = registry.childGroups();
+ for (const QString &toolchainKey : toolchainGroups) {
+ if (!toolchainKey.endsWith("GCC"))
+ continue;
+ registry.beginGroup(toolchainKey);
+ const auto entries = registry.childGroups();
+ for (const auto &entryKey : entries) {
+ registry.beginGroup(entryKey);
+ const QString installDir = registry.value("Native/InstallDir").toString();
+ const QString version = registry.value("Native/Version").toString();
+ registry.endGroup();
+
+ QString toolchainPath = installDir
+ + QLatin1String("/Atmel Toolchain/")
+ + toolchainKey + QLatin1String("/Native/")
+ + version;
+ if (toolchainKey.startsWith("ARM"))
+ toolchainPath += QLatin1String("/arm-gnu-toolchain");
+ else if (toolchainKey.startsWith("AVR32"))
+ toolchainPath += QLatin1String("/avr32-gnu-toolchain");
+ else if (toolchainKey.startsWith("AVR8"))
+ toolchainPath += QLatin1String("/avr8-gnu-toolchain");
+ else
+ break;
+
+ toolchainPath += QLatin1String("/bin");
+
+ const FilePath path = FilePath::fromString(toolchainPath);
+ if (path.exists()) {
+ searchPaths.push_back(FilePath::fromString(toolchainPath));
+ break;
+ }
+ }
+ registry.endGroup();
+ }
+
+ // This code enumerate the installed toolchains provided
+ // by the Atmel Studio v7.
+ registry.beginGroup("AtmelStudio");
+ const auto productVersions = registry.childGroups();
+ for (const auto &productVersionKey : productVersions) {
+ registry.beginGroup(productVersionKey);
+ const QString installDir = registry.value("InstallDir").toString();
+ registry.endGroup();
+
+ const QStringList knownToolchainSubdirs = {
+ "/toolchain/arm/arm-gnu-toolchain/bin/",
+ "/toolchain/avr8/avr8-gnu-toolchain/bin/",
+ "/toolchain/avr32/avr32-gnu-toolchain/bin/",
+ };
+
+ for (const auto &subdir : knownToolchainSubdirs) {
+ const QString toolchainPath = installDir + subdir;
+ const FilePath path = FilePath::fromString(toolchainPath);
+ if (!path.exists())
+ continue;
+ searchPaths.push_back(path);
+ }
+ }
+ registry.endGroup();
+
+ return searchPaths;
+}
+
GccToolChainFactory::GccToolChainFactory()
{
setDisplayName(tr("GCC"));
setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID});
- setToolchainConstructor([] { return new GccToolChain; });
+ setToolchainConstructor([] { return new GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID); });
setUserCreatable(true);
}
QList<ToolChain *> GccToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
{
+ // GCC is almost never what you want on macOS, but it is by default found in /usr/bin
+ if (HostOsInfo::isMacHost())
+ return {};
QList<ToolChain *> tcs;
QList<ToolChain *> known = alreadyKnown;
static const auto tcChecker = [](const ToolChain *tc) {
@@ -890,14 +994,14 @@ QList<ToolChain *> GccToolChainFactory::autoDetect(const QList<ToolChain *> &alr
return tcs;
}
-QList<ToolChain *> GccToolChainFactory::autoDetect(const FilePath &compilerPath, const Core::Id &language)
+QList<ToolChain *> GccToolChainFactory::detectForImport(const ToolChainDescription &tcd)
{
- const QString fileName = compilerPath.fileName();
- if ((language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
+ const QString fileName = tcd.compilerPath.toString();
+ if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
|| fileName.endsWith("gcc")))
- || (language == Constants::CXX_LANGUAGE_ID && (fileName.startsWith("g++")
+ || (tcd.language == Constants::CXX_LANGUAGE_ID && (fileName.startsWith("g++")
|| fileName.endsWith("g++"))))
- return autoDetectToolChain(compilerPath, language, [](const ToolChain *tc) {
+ return autoDetectToolChain(tcd, [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor;
});
return QList<ToolChain *>();
@@ -914,7 +1018,9 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(
if (fi.isFile())
compilerPaths << FilePath::fromString(compilerName);
} else {
- const FilePathList searchPaths = Environment::systemEnvironment().path();
+ FilePathList searchPaths = Environment::systemEnvironment().path();
+ searchPaths << gnuSearchPathsFromRegistry();
+ searchPaths << atmelSearchPathsFromRegistry();
for (const FilePath &dir : searchPaths) {
static const QRegularExpression regexp(binaryRegexp);
QDir binDir(dir.toString());
@@ -922,6 +1028,8 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(
if (detectVariants == DetectVariants::Yes) {
nameFilters
<< compilerName + "-[1-9]*" // "clang-8", "gcc-5"
+ << ("*-" + compilerName) // "avr-gcc", "avr32-gcc"
+ << ("*-" + compilerName + "-[1-9]*")// "avr-gcc-4.8.1", "avr32-gcc-4.4.7"
<< ("*-*-*-" + compilerName) // "arm-none-eabi-gcc"
<< ("*-*-*-" + compilerName + "-[1-9]*") // "arm-none-eabi-gcc-9.1.0"
<< ("*-*-*-*-" + compilerName) // "x86_64-pc-linux-gnu-gcc"
@@ -983,7 +1091,7 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(
}
}
if (!alreadyExists) {
- const QList<ToolChain *> newToolchains = autoDetectToolChain(compilerPath, language,
+ const QList<ToolChain *> newToolchains = autoDetectToolChain({compilerPath, language},
checker);
result << newToolchains;
existingCandidates << newToolchains;
@@ -993,17 +1101,16 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolchains(
return result;
}
-QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const FilePath &compilerPath,
- const Core::Id language,
+QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const ToolChainDescription &tcd,
const ToolchainChecker &checker)
{
QList<ToolChain *> result;
Environment systemEnvironment = Environment::systemEnvironment();
- GccToolChain::addCommandPathToEnvironment(compilerPath, systemEnvironment);
- const FilePath localCompilerPath = findLocalCompiler(compilerPath, systemEnvironment);
+ GccToolChain::addCommandPathToEnvironment(tcd.compilerPath, systemEnvironment);
+ const FilePath localCompilerPath = findLocalCompiler(tcd.compilerPath, systemEnvironment);
Macros macros
- = gccPredefinedMacros(localCompilerPath, gccPredefinedMacrosOptions(language),
+ = gccPredefinedMacros(localCompilerPath, gccPredefinedMacrosOptions(tcd.language),
systemEnvironment.toStringList());
const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath,
systemEnvironment.toStringList(),
@@ -1013,13 +1120,13 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const FilePath &comp
if (!tc)
return result;
- tc->setLanguage(language);
+ tc->setLanguage(tcd.language);
tc->setDetection(ToolChain::AutoDetection);
tc->predefinedMacrosCache()
->insert(QStringList(),
ToolChain::MacroInspectionReport{macros,
- ToolChain::languageVersion(language, macros)});
- tc->setCompilerCommand(compilerPath);
+ ToolChain::languageVersion(tcd.language, macros)});
+ tc->setCompilerCommand(tcd.compilerPath);
tc->setSupportedAbis(detectedAbis.supportedAbis);
tc->setTargetAbi(abi);
tc->setOriginalTargetTriple(detectedAbis.originalTargetTriple);
@@ -1268,14 +1375,14 @@ void ClangToolChain::syncAutodetectedWithParentToolchains()
}
ClangToolChain::ClangToolChain() :
- GccToolChain(Constants::CLANG_TOOLCHAIN_TYPEID)
+ ClangToolChain(Constants::CLANG_TOOLCHAIN_TYPEID)
{
- syncAutodetectedWithParentToolchains();
}
ClangToolChain::ClangToolChain(Core::Id typeId) :
GccToolChain(typeId)
{
+ setTypeDisplayName(ClangToolChainFactory::tr("Clang"));
syncAutodetectedWithParentToolchains();
}
@@ -1285,11 +1392,6 @@ ClangToolChain::~ClangToolChain()
QObject::disconnect(m_mingwToolchainAddedConnection);
}
-QString ClangToolChain::typeDisplayName() const
-{
- return ClangToolChainFactory::tr("Clang");
-}
-
FilePath ClangToolChain::makeCommand(const Environment &environment) const
{
const QStringList makes
@@ -1339,6 +1441,8 @@ QStringList ClangToolChain::suggestedMkspecList() const
return {"linux-clang", "unsupported/linux-clang"};
if (abi.os() == Abi::WindowsOS)
return {"win32-clang-g++"};
+ if (abi.architecture() == Abi::AsmJsArchitecture && abi.binaryFormat() == Abi::EmscriptenFormat)
+ return {"wasm-emscripten"};
return {}; // Note: Not supported by Qt yet, so default to the mkspec the Qt was build with
}
@@ -1376,15 +1480,16 @@ QString ClangToolChain::sysRoot() const
return mingwCompiler.parentDir().parentDir().toString();
}
-ToolChain::BuiltInHeaderPathsRunner ClangToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner ClangToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &env) const
{
// Using a clean environment breaks ccache/distcc/etc.
- Environment env = Environment::systemEnvironment();
- addToEnvironment(env);
+ Environment fullEnv = env;
+ addToEnvironment(fullEnv);
// This runner must be thread-safe!
return [this,
- env,
+ fullEnv,
compilerCommand = m_compilerCommand,
platformCodeGenFlags = m_platformCodeGenFlags,
reinterpretOptions = m_optionsReinterpreter,
@@ -1393,7 +1498,7 @@ ToolChain::BuiltInHeaderPathsRunner ClangToolChain::createBuiltInHeaderPathsRunn
extraHeaderPathsFunction = m_extraHeaderPathsFunction](const QStringList &flags,
const QString &sysRoot,
const QString &target) {
- return builtInHeaderPaths(env,
+ return builtInHeaderPaths(fullEnv,
compilerCommand,
platformCodeGenFlags,
reinterpretOptions,
@@ -1473,13 +1578,13 @@ QList<ToolChain *> ClangToolChainFactory::autoDetect(const QList<ToolChain *> &a
return tcs;
}
-QList<ToolChain *> ClangToolChainFactory::autoDetect(const FilePath &compilerPath, const Core::Id &language)
+QList<ToolChain *> ClangToolChainFactory::detectForImport(const ToolChainDescription &tcd)
{
- const QString fileName = compilerPath.fileName();
- if ((language == Constants::C_LANGUAGE_ID && fileName.startsWith("clang") && !fileName.startsWith("clang++"))
- || (language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("clang++")))
- return autoDetectToolChain(compilerPath, language);
- return QList<ToolChain *>();
+ const QString fileName = tcd.compilerPath.toString();
+ if ((tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("clang") && !fileName.startsWith("clang++"))
+ || (tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("clang++")))
+ return autoDetectToolChain(tcd);
+ return {};
}
ClangToolChainConfigWidget::ClangToolChainConfigWidget(ClangToolChain *tc) :
@@ -1602,11 +1707,8 @@ void ClangToolChainConfigWidget::makeReadOnlyImpl()
MingwToolChain::MingwToolChain() :
GccToolChain(Constants::MINGW_TOOLCHAIN_TYPEID)
-{ }
-
-QString MingwToolChain::typeDisplayName() const
{
- return MingwToolChainFactory::tr("MinGW");
+ setTypeDisplayName(MingwToolChainFactory::tr("MinGW"));
}
QStringList MingwToolChain::suggestedMkspecList() const
@@ -1649,8 +1751,6 @@ MingwToolChainFactory::MingwToolChainFactory()
QList<ToolChain *> MingwToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
{
- Abi ha = Abi::hostAbi();
- ha = Abi(ha.architecture(), Abi::WindowsOS, Abi::WindowsMSysFlavor, Abi::PEFormat, ha.wordWidth());
static const auto tcChecker = [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor;
};
@@ -1662,17 +1762,18 @@ QList<ToolChain *> MingwToolChainFactory::autoDetect(const QList<ToolChain *> &a
return result;
}
-QList<ToolChain *> MingwToolChainFactory::autoDetect(const FilePath &compilerPath, const Core::Id &language)
+QList<ToolChain *> MingwToolChainFactory::detectForImport(const ToolChainDescription &tcd)
{
- const QString fileName = compilerPath.fileName();
- if ((language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
- || fileName.endsWith("gcc")))
- || (language == Constants::CXX_LANGUAGE_ID && (fileName.startsWith("g++")
- || fileName.endsWith("g++"))))
- return autoDetectToolChain(compilerPath, language, [](const ToolChain *tc) {
+ const QString fileName = tcd.compilerPath.toString();
+ if ((tcd.language == Constants::C_LANGUAGE_ID && (fileName.startsWith("gcc")
+ || fileName.endsWith("gcc")))
+ || (tcd.language == Constants::CXX_LANGUAGE_ID && (fileName.startsWith("g++")
+ || fileName.endsWith("g++"))))
+ return autoDetectToolChain(tcd, [](const ToolChain *tc) {
return tc->targetAbi().osFlavor() == Abi::WindowsMSysFlavor;
});
- return QList<ToolChain *>();
+
+ return {};
}
// --------------------------------------------------------------------------
@@ -1681,11 +1782,8 @@ QList<ToolChain *> MingwToolChainFactory::autoDetect(const FilePath &compilerPat
LinuxIccToolChain::LinuxIccToolChain() :
GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID)
-{ }
-
-QString LinuxIccToolChain::typeDisplayName() const
{
- return LinuxIccToolChainFactory::tr("Linux ICC");
+ setTypeDisplayName(LinuxIccToolChainFactory::tr("Linux ICC"));
}
/**
@@ -1742,12 +1840,12 @@ QList<ToolChain *> LinuxIccToolChainFactory::autoDetect(const QList<ToolChain *>
return result;
}
-QList<ToolChain *> LinuxIccToolChainFactory::autoDetect(const FilePath &compilerPath, const Core::Id &language)
+QList<ToolChain *> LinuxIccToolChainFactory::detectForImport(const ToolChainDescription &tcd)
{
- const QString fileName = compilerPath.fileName();
- if ((language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||
- (language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc")))
- return autoDetectToolChain(compilerPath, language);
+ const QString fileName = tcd.compilerPath.toString();
+ if ((tcd.language == Constants::CXX_LANGUAGE_ID && fileName.startsWith("icpc")) ||
+ (tcd.language == Constants::C_LANGUAGE_ID && fileName.startsWith("icc")))
+ return autoDetectToolChain(tcd);
return {};
}
@@ -1817,11 +1915,11 @@ void ProjectExplorerPlugin::testGccAbiGuessing_data()
QTest::newRow("broken input -- 64bit")
<< QString::fromLatin1("arm-none-foo-gnueabi")
<< QByteArray("#define __SIZEOF_SIZE_T__ 8\n#define __Something\n")
- << QStringList({"arm-unknown-unknown-elf-64bit"});
+ << QStringList({"arm-baremetal-generic-elf-64bit"});
QTest::newRow("broken input -- 32bit")
<< QString::fromLatin1("arm-none-foo-gnueabi")
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n#define __Something\n")
- << QStringList({"arm-unknown-unknown-elf-32bit"});
+ << QStringList({"arm-baremetal-generic-elf-32bit"});
QTest::newRow("totally broken input -- 32bit")
<< QString::fromLatin1("foo-bar-foo")
<< QByteArray("#define __SIZEOF_SIZE_T__ 4\n#define __Something\n")
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index 240ae34247..5d46f949f9 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -68,7 +68,7 @@ class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
{
public:
GccToolChain(Core::Id typeId);
- QString typeDisplayName() const override;
+
Abi targetAbi() const override;
QString originalTargetTriple() const override;
QString version() const;
@@ -83,9 +83,10 @@ public:
MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) const override;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(const Utils::Environment &env) const override;
HeaderPaths builtInHeaderPaths(const QStringList &flags,
- const Utils::FilePath &sysRootPath) const override;
+ const Utils::FilePath &sysRootPath,
+ const Utils::Environment &env) const override;
void addToEnvironment(Utils::Environment &env) const override;
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
@@ -174,8 +175,6 @@ protected:
};
private:
- explicit GccToolChain();
-
void updateSupportedAbis() const;
static QStringList gccPrepareArguments(const QStringList &flags,
const QString &sysRoot,
@@ -214,7 +213,6 @@ public:
explicit ClangToolChain(Core::Id typeId);
~ClangToolChain() override;
- QString typeDisplayName() const override;
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
@@ -228,7 +226,8 @@ public:
QString originalTargetTriple() const override;
QString sysRoot() const override;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &env) const override;
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
@@ -256,7 +255,6 @@ private:
class PROJECTEXPLORER_EXPORT MingwToolChain : public GccToolChain
{
public:
- QString typeDisplayName() const override;
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
QStringList suggestedMkspecList() const override;
@@ -275,8 +273,6 @@ private:
class PROJECTEXPLORER_EXPORT LinuxIccToolChain : public GccToolChain
{
public:
- QString typeDisplayName() const override;
-
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
IOutputParser *outputParser() const override;
diff --git a/src/plugins/projectexplorer/gcctoolchainfactories.h b/src/plugins/projectexplorer/gcctoolchainfactories.h
index e33ebcaa03..c714a5ce16 100644
--- a/src/plugins/projectexplorer/gcctoolchainfactories.h
+++ b/src/plugins/projectexplorer/gcctoolchainfactories.h
@@ -55,7 +55,7 @@ public:
GccToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown) override;
- QList<ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language) override;
+ QList<ToolChain *> detectForImport(const ProjectExplorer::ToolChainDescription &tcd) override;
protected:
enum class DetectVariants { Yes, No };
@@ -65,7 +65,7 @@ protected:
const Core::Id requiredTypeId, const QList<ToolChain *> &alreadyKnown,
const ToolchainChecker &checker = {});
QList<ToolChain *> autoDetectToolChain(
- const Utils::FilePath &compilerPath, const Core::Id language,
+ const ToolChainDescription &tcd,
const ToolchainChecker &checker = {});
};
@@ -138,7 +138,7 @@ public:
ClangToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown) override;
- QList<ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language) final;
+ QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) final;
};
// --------------------------------------------------------------------------
@@ -153,7 +153,7 @@ public:
MingwToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown) override;
- QList<ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language) final;
+ QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) final;
};
// --------------------------------------------------------------------------
@@ -168,7 +168,7 @@ public:
LinuxIccToolChainFactory();
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown) override;
- QList<ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language) final;
+ QList<ToolChain *> detectForImport(const ToolChainDescription &tcd) final;
};
} // namespace Internal
diff --git a/src/plugins/cpptools/images/settingscategory_cpp.png b/src/plugins/projectexplorer/images/settingscategory_cpp.png
index fe39d2663c..fe39d2663c 100644
--- a/src/plugins/cpptools/images/settingscategory_cpp.png
+++ b/src/plugins/projectexplorer/images/settingscategory_cpp.png
Binary files differ
diff --git a/src/plugins/cpptools/images/settingscategory_cpp@2x.png b/src/plugins/projectexplorer/images/settingscategory_cpp@2x.png
index 92078c4281..92078c4281 100644
--- a/src/plugins/cpptools/images/settingscategory_cpp@2x.png
+++ b/src/plugins/projectexplorer/images/settingscategory_cpp@2x.png
Binary files differ
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
index 835f3a0429..749c660e01 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp
@@ -383,8 +383,8 @@ bool LabelField::parseData(const QVariant &data, QString *errorMessage)
QWidget *LabelField::createWidget(const QString &displayName, JsonFieldPage *page)
{
- Q_UNUSED(displayName);
- Q_UNUSED(page);
+ Q_UNUSED(displayName)
+ Q_UNUSED(page)
auto w = new QLabel;
w->setWordWrap(m_wordWrap);
w->setText(m_text);
@@ -426,8 +426,8 @@ bool SpacerField::parseData(const QVariant &data, QString *errorMessage)
QWidget *SpacerField::createWidget(const QString &displayName, JsonFieldPage *page)
{
- Q_UNUSED(displayName);
- Q_UNUSED(page);
+ Q_UNUSED(displayName)
+ Q_UNUSED(page)
int size = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing) * m_factor;
auto w = new QWidget();
@@ -481,7 +481,7 @@ bool LineEditField::parseData(const QVariant &data, QString *errorMessage)
QWidget *LineEditField::createWidget(const QString &displayName, JsonFieldPage *page)
{
- Q_UNUSED(displayName);
+ Q_UNUSED(displayName)
auto w = new FancyLineEdit;
if (m_validatorRegExp.isValid()) {
@@ -581,8 +581,8 @@ bool TextEditField::parseData(const QVariant &data, QString *errorMessage)
QWidget *TextEditField::createWidget(const QString &displayName, JsonFieldPage *page)
{
// TODO: Set up modification monitoring...
- Q_UNUSED(displayName);
- Q_UNUSED(page);
+ Q_UNUSED(displayName)
+ Q_UNUSED(page)
auto w = new QTextEdit;
w->setAcceptRichText(m_acceptRichText);
return w;
@@ -673,8 +673,8 @@ bool PathChooserField::parseData(const QVariant &data, QString *errorMessage)
QWidget *PathChooserField::createWidget(const QString &displayName, JsonFieldPage *page)
{
- Q_UNUSED(displayName);
- Q_UNUSED(page);
+ Q_UNUSED(displayName)
+ Q_UNUSED(page)
auto w = new PathChooser;
if (!m_historyId.isEmpty())
w->setHistoryCompleter(m_historyId);
@@ -754,7 +754,7 @@ bool CheckBoxField::parseData(const QVariant &data, QString *errorMessage)
QWidget *CheckBoxField::createWidget(const QString &displayName, JsonFieldPage *page)
{
- Q_UNUSED(page);
+ Q_UNUSED(page)
return new QCheckBox(displayName);
}
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h
index 487dbd1a64..16da75c4ad 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h
+++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h
@@ -74,7 +74,7 @@ public:
virtual bool validate(Utils::MacroExpander *expander, QString *message);
void initialize(Utils::MacroExpander *expander);
- virtual void cleanup(Utils::MacroExpander *expander) { Q_UNUSED(expander); }
+ virtual void cleanup(Utils::MacroExpander *expander) { Q_UNUSED(expander) }
virtual bool suppressName() const { return false; }
@@ -89,10 +89,10 @@ public:
protected:
QWidget *widget() const;
virtual bool parseData(const QVariant &data, QString *errorMessage) = 0;
- virtual void initializeData(Utils::MacroExpander *expander) { Q_UNUSED(expander); }
+ virtual void initializeData(Utils::MacroExpander *expander) { Q_UNUSED(expander) }
virtual QWidget *createWidget(const QString &displayName, JsonFieldPage *page) = 0;
virtual void setup(JsonFieldPage *page, const QString &name)
- { Q_UNUSED(page); Q_UNUSED(name); }
+ { Q_UNUSED(page); Q_UNUSED(name) }
QString type();
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp
index 7501521be7..c74f3a2f51 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp
@@ -65,7 +65,7 @@ void JsonKitsPage::initializePage()
setPreferredKitPredicate([platform, preferred](const Kit *k) {
return k->supportedPlatforms().contains(platform) && k->hasFeatures(preferred);
});
- setProjectPath(wiz->expander()->expand(unexpandedProjectPath()));
+ setProjectPath(wiz->expander()->expand(Utils::FilePath::fromString(unexpandedProjectPath())));
TargetSetupPage::initializePage();
}
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp
index 9f9844c01e..e750dd59ea 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp
@@ -206,6 +206,10 @@ void JsonSummaryPage::addToProject(const JsonWizard::GeneratorFiles &files)
nativeFilePaths.join(QLatin1String(", "))));
return;
}
+ const QStringList dependencies = m_wizard->stringValue("Dependencies")
+ .split(':', QString::SkipEmptyParts);
+ if (!dependencies.isEmpty())
+ folder->addDependencies(dependencies);
}
return;
}
@@ -250,6 +254,23 @@ void JsonSummaryPage::updateProjectData(FolderNode *node)
m_wizard->setValue(QLatin1String(KEY_SELECTED_PROJECT), QVariant::fromValue(project));
m_wizard->setValue(QLatin1String(KEY_SELECTED_NODE), QVariant::fromValue(node));
m_wizard->setValue(QLatin1String(KEY_IS_SUBPROJECT), node ? true : false);
+ bool qtKeyWordsEnabled = true;
+ if (ProjectTree::hasNode(node)) {
+ const ProjectNode *projectNode = node->asProjectNode();
+ if (!projectNode)
+ projectNode = node->parentProjectNode();
+ while (projectNode) {
+ const QVariant keywordsEnabled = projectNode->data(Constants::QT_KEYWORDS_ENABLED);
+ if (keywordsEnabled.isValid()) {
+ qtKeyWordsEnabled = keywordsEnabled.toBool();
+ break;
+ }
+ if (projectNode->isProduct())
+ break;
+ projectNode = projectNode->parentProjectNode();
+ }
+ }
+ m_wizard->setValue("QtKeywordsEnabled", qtKeyWordsEnabled);
updateFileList();
}
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp
index c8ae9aa013..d510e187fa 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp
@@ -227,7 +227,7 @@ Core::GeneratedFiles JsonWizardFileGenerator::fileList(Utils::MacroExpander *exp
bool JsonWizardFileGenerator::writeFile(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage)
{
- Q_UNUSED(wizard);
+ Q_UNUSED(wizard)
if (!(file->attributes() & Core::GeneratedFile::KeepExistingFileAttribute)) {
if (!file->write(errorMessage))
return false;
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp
index ae3e6aaa52..4f4f8882f7 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp
@@ -80,7 +80,7 @@ static ICodeStylePreferences *codeStylePreferences(Project *project, Id language
bool JsonWizardGenerator::formatFile(const JsonWizard *wizard, GeneratedFile *file, QString *errorMessage)
{
- Q_UNUSED(errorMessage);
+ Q_UNUSED(errorMessage)
if (file->isBinary() || file->contents().isEmpty())
return true; // nothing to do
@@ -124,33 +124,33 @@ bool JsonWizardGenerator::formatFile(const JsonWizard *wizard, GeneratedFile *fi
bool JsonWizardGenerator::writeFile(const JsonWizard *wizard, GeneratedFile *file, QString *errorMessage)
{
- Q_UNUSED(wizard);
- Q_UNUSED(file);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(wizard)
+ Q_UNUSED(file)
+ Q_UNUSED(errorMessage)
return true;
}
bool JsonWizardGenerator::postWrite(const JsonWizard *wizard, GeneratedFile *file, QString *errorMessage)
{
- Q_UNUSED(wizard);
- Q_UNUSED(file);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(wizard)
+ Q_UNUSED(file)
+ Q_UNUSED(errorMessage)
return true;
}
bool JsonWizardGenerator::polish(const JsonWizard *wizard, GeneratedFile *file, QString *errorMessage)
{
- Q_UNUSED(wizard);
- Q_UNUSED(file);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(wizard)
+ Q_UNUSED(file)
+ Q_UNUSED(errorMessage)
return true;
}
bool JsonWizardGenerator::allDone(const JsonWizard *wizard, GeneratedFile *file, QString *errorMessage)
{
- Q_UNUSED(wizard);
- Q_UNUSED(file);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(wizard)
+ Q_UNUSED(file)
+ Q_UNUSED(errorMessage)
return true;
}
@@ -309,9 +309,9 @@ JsonWizardGenerator *FileGeneratorFactory::create(Id typeId, const QVariant &dat
const QString &path, Id platform,
const QVariantMap &variables)
{
- Q_UNUSED(path);
- Q_UNUSED(platform);
- Q_UNUSED(variables);
+ Q_UNUSED(path)
+ Q_UNUSED(platform)
+ Q_UNUSED(variables)
QTC_ASSERT(canCreate(typeId), return nullptr);
@@ -349,9 +349,9 @@ JsonWizardGenerator *ScannerGeneratorFactory::create(Id typeId, const QVariant &
const QString &path, Id platform,
const QVariantMap &variables)
{
- Q_UNUSED(path);
- Q_UNUSED(platform);
- Q_UNUSED(variables);
+ Q_UNUSED(path)
+ Q_UNUSED(platform)
+ Q_UNUSED(variables)
QTC_ASSERT(canCreate(typeId), return nullptr);
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardpagefactory_p.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardpagefactory_p.cpp
index 2e7c93b514..774b63376e 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardpagefactory_p.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardpagefactory_p.cpp
@@ -62,7 +62,7 @@ FieldPageFactory::FieldPageFactory()
Utils::WizardPage *FieldPageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
{
- Q_UNUSED(wizard);
+ Q_UNUSED(wizard)
QTC_ASSERT(canCreate(typeId), return nullptr);
@@ -109,8 +109,8 @@ FilePageFactory::FilePageFactory()
Utils::WizardPage *FilePageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
{
- Q_UNUSED(wizard);
- Q_UNUSED(data);
+ Q_UNUSED(wizard)
+ Q_UNUSED(data)
QTC_ASSERT(canCreate(typeId), return nullptr);
return new JsonFilePage;
@@ -143,7 +143,7 @@ KitsPageFactory::KitsPageFactory()
Utils::WizardPage *KitsPageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
{
- Q_UNUSED(wizard);
+ Q_UNUSED(wizard)
QTC_ASSERT(canCreate(typeId), return nullptr);
auto page = new JsonKitsPage;
@@ -203,8 +203,8 @@ ProjectPageFactory::ProjectPageFactory()
Utils::WizardPage *ProjectPageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
{
- Q_UNUSED(wizard);
- Q_UNUSED(data);
+ Q_UNUSED(wizard)
+ Q_UNUSED(data)
QTC_ASSERT(canCreate(typeId), return nullptr);
auto page = new JsonProjectPage;
@@ -226,7 +226,7 @@ Utils::WizardPage *ProjectPageFactory::create(JsonWizard *wizard, Core::Id typeI
bool ProjectPageFactory::validateData(Core::Id typeId, const QVariant &data, QString *errorMessage)
{
- Q_UNUSED(errorMessage);
+ Q_UNUSED(errorMessage)
QTC_ASSERT(canCreate(typeId), return false);
if (!data.isNull() && data.type() != QVariant::Map) {
@@ -263,8 +263,8 @@ SummaryPageFactory::SummaryPageFactory()
Utils::WizardPage *SummaryPageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
{
- Q_UNUSED(wizard);
- Q_UNUSED(data);
+ Q_UNUSED(wizard)
+ Q_UNUSED(data)
QTC_ASSERT(canCreate(typeId), return nullptr);
auto page = new JsonSummaryPage;
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardscannergenerator.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardscannergenerator.cpp
index 9f24f00718..ff0fcde7d4 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardscannergenerator.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardscannergenerator.cpp
@@ -80,7 +80,7 @@ Core::GeneratedFiles JsonWizardScannerGenerator::fileList(Utils::MacroExpander *
const QString &projectDir,
QString *errorMessage)
{
- Q_UNUSED(wizardDir);
+ Q_UNUSED(wizardDir)
errorMessage->clear();
QDir project(projectDir);
diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp
index bb44b6bec8..b5a2289c34 100644
--- a/src/plugins/projectexplorer/kit.cpp
+++ b/src/plugins/projectexplorer/kit.cpp
@@ -33,6 +33,7 @@
#include "projectexplorerconstants.h"
#include <utils/algorithm.h>
+#include <utils/displayname.h>
#include <utils/fileutils.h>
#include <utils/icon.h>
#include <utils/macroexpander.h>
@@ -85,7 +86,8 @@ public:
if (!id.isValid())
m_id = Id::fromString(QUuid::createUuid().toString());
- m_unexpandedDisplayName = QCoreApplication::translate("ProjectExplorer::Kit", "Unnamed");
+ m_unexpandedDisplayName.setDefaultValue(QCoreApplication::translate("ProjectExplorer::Kit",
+ "Unnamed"));
m_macroExpander.setDisplayName(tr("Kit"));
m_macroExpander.setAccumulating(true);
@@ -112,7 +114,7 @@ public:
false);
}
- QString m_unexpandedDisplayName;
+ DisplayName m_unexpandedDisplayName;
QString m_fileSystemFriendlyName;
QString m_autoDetectionSource;
Id m_id;
@@ -160,8 +162,7 @@ Kit::Kit(const QVariantMap &data) :
else
d->m_sdkProvided = d->m_autodetected;
- d->m_unexpandedDisplayName = data.value(QLatin1String(DISPLAYNAME_KEY),
- d->m_unexpandedDisplayName).toString();
+ d->m_unexpandedDisplayName.fromMap(data, DISPLAYNAME_KEY);
d->m_fileSystemFriendlyName = data.value(QLatin1String(FILESYSTEMFRIENDLYNAME_KEY)).toString();
d->m_iconPath = FilePath::fromString(data.value(QLatin1String(ICON_KEY),
d->m_iconPath.toString()).toString());
@@ -210,6 +211,7 @@ void Kit::copyKitCommon(Kit *target, const Kit *source)
target->d->m_sticky = source->d->m_sticky;
target->d->m_mutable = source->d->m_mutable;
target->d->m_irrelevantAspects = source->d->m_irrelevantAspects;
+ target->d->m_hasValidityInfo = false;
}
Kit *Kit::clone(bool keepName) const
@@ -219,7 +221,7 @@ Kit *Kit::clone(bool keepName) const
if (keepName)
k->d->m_unexpandedDisplayName = d->m_unexpandedDisplayName;
else
- k->d->m_unexpandedDisplayName = newKitName(KitManager::kits());
+ k->d->m_unexpandedDisplayName.setValue(newKitName(KitManager::kits()));
k->d->m_autodetected = false;
// Do not clone m_fileSystemFriendlyName, needs to be unique
k->d->m_hasError = d->m_hasError; // TODO: Is this intentionally not done for copyFrom()?
@@ -294,21 +296,18 @@ void Kit::upgrade()
QString Kit::unexpandedDisplayName() const
{
- return d->m_unexpandedDisplayName;
+ return d->m_unexpandedDisplayName.value();
}
QString Kit::displayName() const
{
- return d->m_macroExpander.expand(d->m_unexpandedDisplayName);
+ return d->m_macroExpander.expand(unexpandedDisplayName());
}
void Kit::setUnexpandedDisplayName(const QString &name)
{
- if (d->m_unexpandedDisplayName == name)
- return;
-
- d->m_unexpandedDisplayName = name;
- kitUpdated();
+ if (d->m_unexpandedDisplayName.setValue(name))
+ kitUpdated();
}
void Kit::setCustomFileSystemFriendlyName(const QString &fileSystemFriendlyName)
@@ -514,8 +513,8 @@ QVariantMap Kit::toMap() const
using IdVariantConstIt = QHash<Id, QVariant>::ConstIterator;
QVariantMap data;
+ d->m_unexpandedDisplayName.toMap(data, DISPLAYNAME_KEY);
data.insert(QLatin1String(ID_KEY), QString::fromLatin1(d->m_id.name()));
- data.insert(QLatin1String(DISPLAYNAME_KEY), d->m_unexpandedDisplayName);
data.insert(QLatin1String(AUTODETECTED_KEY), d->m_autodetected);
if (!d->m_fileSystemFriendlyName.isEmpty())
data.insert(QLatin1String(FILESYSTEMFRIENDLYNAME_KEY), d->m_fileSystemFriendlyName);
diff --git a/src/plugins/projectexplorer/kit.h b/src/plugins/projectexplorer/kit.h
index 8e45911d17..f8a9dbfcba 100644
--- a/src/plugins/projectexplorer/kit.h
+++ b/src/plugins/projectexplorer/kit.h
@@ -146,11 +146,9 @@ private:
static void copyKitCommon(Kit *target, const Kit *source);
void setSdkProvided(bool sdkProvided);
- // Unimplemented.
- Kit(const Kit &other);
- void operator=(const Kit &other);
+ Kit(const Kit &other) = delete;
+ void operator=(const Kit &other) = delete;
- void kitDisplayNameChanged();
void kitUpdated();
QVariantMap toMap() const;
diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp
index 5a95c54ec4..d3c14a0250 100644
--- a/src/plugins/projectexplorer/kitinformation.cpp
+++ b/src/plugins/projectexplorer/kitinformation.cpp
@@ -733,13 +733,15 @@ void ToolChainKitAspect::kitsWereLoaded()
void ToolChainKitAspect::toolChainUpdated(ToolChain *tc)
{
- for (Kit *k : KitManager::kits([tc](const Kit *k) { return toolChain(k, tc->language()) == tc; }))
- notifyAboutUpdate(k);
+ for (Kit *k : KitManager::kits()) {
+ if (toolChain(k, tc->language()) == tc)
+ notifyAboutUpdate(k);
+ }
}
void ToolChainKitAspect::toolChainRemoved(ToolChain *tc)
{
- Q_UNUSED(tc);
+ Q_UNUSED(tc)
foreach (Kit *k, KitManager::kits())
fix(k);
}
@@ -811,7 +813,7 @@ void DeviceTypeKitAspect::setup(Kit *k)
Tasks DeviceTypeKitAspect::validate(const Kit *k) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
return {};
}
@@ -1150,7 +1152,7 @@ private:
void refresh() override
{
- const QList<Utils::EnvironmentItem> changes = currentEnvironment();
+ const Utils::EnvironmentItems changes = currentEnvironment();
QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join(QLatin1String("; "));
QFontMetrics fm(m_summaryLabel->font());
shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, m_summaryLabel->width());
@@ -1159,32 +1161,29 @@ private:
void editEnvironmentChanges()
{
- bool ok;
Utils::MacroExpander *expander = m_kit->macroExpander();
Utils::EnvironmentDialog::Polisher polisher = [expander](QWidget *w) {
Core::VariableChooser::addSupportForChildWidgets(w, expander);
};
- QList<Utils::EnvironmentItem>
- changes = Utils::EnvironmentDialog::getEnvironmentItems(&ok,
- m_summaryLabel,
- currentEnvironment(),
- QString(),
- polisher);
- if (!ok)
+ auto changes = Utils::EnvironmentDialog::getEnvironmentItems(m_summaryLabel,
+ currentEnvironment(),
+ QString(),
+ polisher);
+ if (!changes)
return;
if (Utils::HostOsInfo::isWindowsHost()) {
const Utils::EnvironmentItem forceMSVCEnglishItem("VSLANG", "1033");
- if (m_vslangCheckbox->isChecked() && changes.indexOf(forceMSVCEnglishItem) < 0)
- changes.append(forceMSVCEnglishItem);
+ if (m_vslangCheckbox->isChecked() && changes->indexOf(forceMSVCEnglishItem) < 0)
+ changes->append(forceMSVCEnglishItem);
}
- EnvironmentKitAspect::setEnvironmentChanges(m_kit, changes);
+ EnvironmentKitAspect::setEnvironmentChanges(m_kit, *changes);
}
- QList<Utils::EnvironmentItem> currentEnvironment() const
+ Utils::EnvironmentItems currentEnvironment() const
{
- QList<Utils::EnvironmentItem> changes = EnvironmentKitAspect::environmentChanges(m_kit);
+ Utils::EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(m_kit);
if (Utils::HostOsInfo::isWindowsHost()) {
const Utils::EnvironmentItem forceMSVCEnglishItem("VSLANG", "1033");
@@ -1207,8 +1206,7 @@ private:
"just forces UTF-8 output (may vary depending on the used MSVC "
"compiler)."));
connect(m_vslangCheckbox, &QCheckBox::toggled, this, [this](bool checked) {
- QList<Utils::EnvironmentItem> changes
- = EnvironmentKitAspect::environmentChanges(m_kit);
+ Utils::EnvironmentItems changes = EnvironmentKitAspect::environmentChanges(m_kit);
const Utils::EnvironmentItem forceMSVCEnglishItem("VSLANG", "1033");
if (!checked && changes.indexOf(forceMSVCEnglishItem) >= 0)
changes.removeAll(forceMSVCEnglishItem);
@@ -1254,7 +1252,7 @@ void EnvironmentKitAspect::fix(Kit *k)
const QVariant variant = k->value(EnvironmentKitAspect::id());
if (!variant.isNull() && !variant.canConvert(QVariant::List)) {
qWarning("Kit \"%s\" has a wrong environment value set.", qPrintable(k->displayName()));
- setEnvironmentChanges(k, QList<Utils::EnvironmentItem>());
+ setEnvironmentChanges(k, Utils::EnvironmentItems());
}
}
@@ -1283,14 +1281,14 @@ Core::Id EnvironmentKitAspect::id()
return "PE.Profile.Environment";
}
-QList<Utils::EnvironmentItem> EnvironmentKitAspect::environmentChanges(const Kit *k)
+Utils::EnvironmentItems EnvironmentKitAspect::environmentChanges(const Kit *k)
{
if (k)
return Utils::EnvironmentItem::fromStringList(k->value(EnvironmentKitAspect::id()).toStringList());
- return QList<Utils::EnvironmentItem>();
+ return Utils::EnvironmentItems();
}
-void EnvironmentKitAspect::setEnvironmentChanges(Kit *k, const QList<Utils::EnvironmentItem> &changes)
+void EnvironmentKitAspect::setEnvironmentChanges(Kit *k, const Utils::EnvironmentItems &changes)
{
if (k)
k->setValue(EnvironmentKitAspect::id(), Utils::EnvironmentItem::toStringList(changes));
diff --git a/src/plugins/projectexplorer/kitinformation.h b/src/plugins/projectexplorer/kitinformation.h
index 037b4b9394..57660db588 100644
--- a/src/plugins/projectexplorer/kitinformation.h
+++ b/src/plugins/projectexplorer/kitinformation.h
@@ -186,8 +186,8 @@ public:
ItemList toUserOutput(const Kit *k) const override;
static Core::Id id();
- static QList<Utils::EnvironmentItem> environmentChanges(const Kit *k);
- static void setEnvironmentChanges(Kit *k, const QList<Utils::EnvironmentItem> &changes);
+ static Utils::EnvironmentItems environmentChanges(const Kit *k);
+ static void setEnvironmentChanges(Kit *k, const Utils::EnvironmentItems &changes);
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp
index 91d04b6f5d..c9597844af 100644
--- a/src/plugins/projectexplorer/kitmanager.cpp
+++ b/src/plugins/projectexplorer/kitmanager.cpp
@@ -359,25 +359,6 @@ void KitManager::deregisterKitAspect(KitAspect *ki)
d->removeKitAspect(ki);
}
-QSet<Id> KitManager::supportedPlatforms()
-{
- QSet<Id> platforms;
- foreach (const Kit *k, kits())
- platforms.unite(k->supportedPlatforms());
- return platforms;
-}
-
-QSet<Id> KitManager::availableFeatures(Core::Id platformId)
-{
- QSet<Id> features;
- foreach (const Kit *k, kits()) {
- if (!k->supportedPlatforms().contains(platformId))
- continue;
- features.unite(k->availableFeatures());
- }
- return features;
-}
-
QList<Kit *> KitManager::sortKits(const QList<Kit *> &kits)
{
// This method was added to delay the sorting of kits as long as possible.
@@ -449,13 +430,10 @@ static KitList restoreKitsHelper(const FilePath &fileName)
return result;
}
-QList<Kit *> KitManager::kits(const Kit::Predicate &predicate)
+const QList<Kit *> KitManager::kits()
{
- const QList<Kit *> result = Utils::toRawPointer<QList>(d->m_kitList);
- if (predicate)
- return Utils::filtered(result, predicate);
- return result;
- }
+ return Utils::toRawPointer<QList>(d->m_kitList);
+}
Kit *KitManager::kit(Id id)
{
@@ -580,38 +558,38 @@ int KitAspect::weight(const Kit *k) const
void KitAspect::addToEnvironment(const Kit *k, Environment &env) const
{
- Q_UNUSED(k);
- Q_UNUSED(env);
+ Q_UNUSED(k)
+ Q_UNUSED(env)
}
IOutputParser *KitAspect::createOutputParser(const Kit *k) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
return nullptr;
}
QString KitAspect::displayNamePostfix(const Kit *k) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
return QString();
}
QSet<Id> KitAspect::supportedPlatforms(const Kit *k) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
return QSet<Id>();
}
QSet<Id> KitAspect::availableFeatures(const Kit *k) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
return QSet<Id>();
}
void KitAspect::addToMacroExpander(Kit *k, MacroExpander *expander) const
{
- Q_UNUSED(k);
- Q_UNUSED(expander);
+ Q_UNUSED(k)
+ Q_UNUSED(expander)
}
void KitAspect::notifyAboutUpdate(Kit *k)
@@ -658,12 +636,20 @@ void KitAspectWidget::setStyle(QStyle *s)
QSet<Id> KitFeatureProvider::availableFeatures(Id id) const
{
- return KitManager::availableFeatures(id);
+ QSet<Id> features;
+ for (const Kit *k : KitManager::kits()) {
+ if (k->supportedPlatforms().contains(id))
+ features.unite(k->availableFeatures());
+ }
+ return features;
}
QSet<Id> KitFeatureProvider::availablePlatforms() const
{
- return KitManager::supportedPlatforms();
+ QSet<Id> platforms;
+ for (const Kit *k : KitManager::kits())
+ platforms.unite(k->supportedPlatforms());
+ return platforms;
}
QString KitFeatureProvider::displayNameForPlatform(Id id) const
diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h
index b318544647..c33c176e5c 100644
--- a/src/plugins/projectexplorer/kitmanager.h
+++ b/src/plugins/projectexplorer/kitmanager.h
@@ -167,7 +167,7 @@ public:
static KitManager *instance();
~KitManager() override;
- static QList<Kit *> kits(const Kit::Predicate &predicate = Kit::Predicate());
+ static const QList<Kit *> kits();
static Kit *kit(const Kit::Predicate &predicate);
static Kit *kit(Core::Id id);
static Kit *defaultKit();
@@ -180,9 +180,6 @@ public:
static void deregisterKit(Kit *k);
static void setDefaultKit(Kit *k);
- static QSet<Core::Id> supportedPlatforms();
- static QSet<Core::Id> availableFeatures(Core::Id platformId);
-
static QList<Kit *> sortKits(const QList<Kit *> &kits); // Avoid sorting whenever possible!
static void saveKits();
diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
index 10a0fa5a5d..fd7584ea21 100644
--- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
+++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
@@ -95,7 +95,7 @@ KitManagerConfigWidget::KitManagerConfigWidget(Kit *k) :
inner->setLayout(m_layout);
auto mainLayout = new QGridLayout(this);
- mainLayout->setMargin(1);
+ mainLayout->setContentsMargins(1, 1, 1, 1);
mainLayout->addWidget(inner, 0, 0);
label = createLabel(tr("Name:"), tr("Kit name and icon."));
@@ -414,7 +414,7 @@ void KitManagerConfigWidget::kitWasUpdated(Kit *k)
void KitManagerConfigWidget::showEvent(QShowEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
foreach (KitAspectWidget *widget, m_widgets)
widget->refresh();
}
diff --git a/src/plugins/projectexplorer/ldparser.cpp b/src/plugins/projectexplorer/ldparser.cpp
index 9ce56bf7dd..919c9db30b 100644
--- a/src/plugins/projectexplorer/ldparser.cpp
+++ b/src/plugins/projectexplorer/ldparser.cpp
@@ -65,7 +65,7 @@ void LdParser::stdError(const QString &line)
return;
}
- if (lne.startsWith(QLatin1String("collect2:"))) {
+ if (lne.startsWith("collect2:") || lne.startsWith("collect2.exe:")) {
Task task = Task(Task::Error,
lne /* description */,
Utils::FilePath() /* filename */,
diff --git a/src/plugins/projectexplorer/linuxiccparser.cpp b/src/plugins/projectexplorer/linuxiccparser.cpp
index 6572f47d66..a333d00ca5 100644
--- a/src/plugins/projectexplorer/linuxiccparser.cpp
+++ b/src/plugins/projectexplorer/linuxiccparser.cpp
@@ -25,6 +25,7 @@
#include "linuxiccparser.h"
#include "ldparser.h"
+#include "lldparser.h"
#include "projectexplorerconstants.h"
#include <utils/qtcassert.h>
@@ -62,6 +63,7 @@ LinuxIccParser::LinuxIccParser() :
m_pchInfoLine.setMinimal(true);
QTC_CHECK(m_pchInfoLine.isValid());
+ appendOutputParser(new Internal::LldParser);
appendOutputParser(new LdParser);
}
diff --git a/src/plugins/projectexplorer/lldparser.cpp b/src/plugins/projectexplorer/lldparser.cpp
new file mode 100644
index 0000000000..0f8ffe7476
--- /dev/null
+++ b/src/plugins/projectexplorer/lldparser.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "lldparser.h"
+
+#include "projectexplorerconstants.h"
+#include "task.h"
+
+#include <utils/fileutils.h>
+
+#include <QStringList>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+void LldParser::stdError(const QString &line)
+{
+ const QString trimmedLine = rightTrimmed(line);
+ if (trimmedLine.contains("error:") && trimmedLine.contains("lld")) {
+ emit addTask({Task::Error, trimmedLine, Utils::FilePath(), -1,
+ Constants::TASK_CATEGORY_COMPILE});
+ return;
+ }
+ static const QStringList prefixes{">>> referenced by ", ">>> defined at ", ">>> "};
+ for (const QString &prefix : prefixes) {
+ if (!trimmedLine.startsWith(prefix))
+ continue;
+ int lineNo = -1;
+ const int locOffset = trimmedLine.lastIndexOf(':');
+ if (locOffset != -1) {
+ const int endLocOffset = trimmedLine.indexOf(')', locOffset);
+ const int numberWidth = endLocOffset == -1 ? -1 : endLocOffset - locOffset - 1;
+ bool isNumber = true;
+ lineNo = trimmedLine.mid(locOffset + 1, numberWidth).toInt(&isNumber);
+ if (!isNumber)
+ lineNo = -1;
+ }
+ int filePathOffset = trimmedLine.lastIndexOf('(', locOffset);
+ if (filePathOffset != -1)
+ ++filePathOffset;
+ else
+ filePathOffset = prefix.length();
+ const int filePathLen = locOffset == -1 ? -1 : locOffset - filePathOffset;
+ const auto file = Utils::FilePath::fromUserInput(
+ trimmedLine.mid(filePathOffset, filePathLen).trimmed());
+ emit addTask({Task::Unknown, trimmedLine.mid(4).trimmed(), file, lineNo,
+ Constants::TASK_CATEGORY_COMPILE});
+ return;
+ }
+ IOutputParser::stdError(line);
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/cpptools/cppkitinfo.h b/src/plugins/projectexplorer/lldparser.h
index d2f9a871bd..c459880f8e 100644
--- a/src/plugins/cpptools/cppkitinfo.h
+++ b/src/plugins/projectexplorer/lldparser.h
@@ -25,32 +25,15 @@
#pragma once
-#include "projectpart.h"
-
-#include "cpptools_global.h"
+#include "ioutputparser.h"
namespace ProjectExplorer {
-class Kit;
-class Project;
-class ToolChain;
-} // namespace ProjectExplorer
+namespace Internal {
-namespace CppTools {
-
-class CPPTOOLS_EXPORT KitInfo
+class LldParser : public IOutputParser
{
-public:
- explicit KitInfo(ProjectExplorer::Project *project);
-
- bool isValid() const;
-
- ProjectExplorer::Kit *kit = nullptr;
- ProjectExplorer::ToolChain *cToolChain = nullptr;
- ProjectExplorer::ToolChain *cxxToolChain = nullptr;
-
- ProjectPart::QtVersion projectPartQtVersion = ProjectPart::NoQt;
-
- QString sysRootPath;
+ void stdError(const QString &line) override;
};
-} // namespace CppTools
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/localenvironmentaspect.cpp b/src/plugins/projectexplorer/localenvironmentaspect.cpp
index 366b938ed4..48eac49492 100644
--- a/src/plugins/projectexplorer/localenvironmentaspect.cpp
+++ b/src/plugins/projectexplorer/localenvironmentaspect.cpp
@@ -30,8 +30,6 @@
#include "kit.h"
#include "target.h"
-#include <utils/qtcassert.h>
-
using namespace Utils;
namespace ProjectExplorer {
@@ -56,15 +54,10 @@ LocalEnvironmentAspect::LocalEnvironmentAspect(Target *target)
return env;
});
- target->subscribeSignal(&BuildConfiguration::environmentChanged,
- this, &LocalEnvironmentAspect::buildEnvironmentHasChanged);
connect(target, &Target::activeBuildConfigurationChanged,
- this, &LocalEnvironmentAspect::buildEnvironmentHasChanged);
-}
-
-void LocalEnvironmentAspect::buildEnvironmentHasChanged()
-{
- emit environmentChanged();
+ this, &EnvironmentAspect::environmentChanged);
+ connect(target, &Target::buildEnvironmentChanged,
+ this, &EnvironmentAspect::environmentChanged);
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/localenvironmentaspect.h b/src/plugins/projectexplorer/localenvironmentaspect.h
index 05653899b2..b1e4d5fd55 100644
--- a/src/plugins/projectexplorer/localenvironmentaspect.h
+++ b/src/plugins/projectexplorer/localenvironmentaspect.h
@@ -35,8 +35,6 @@ class PROJECTEXPLORER_EXPORT LocalEnvironmentAspect : public EnvironmentAspect
public:
explicit LocalEnvironmentAspect(Target *parent);
-
- void buildEnvironmentHasChanged();
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp
index fecaacc89c..8961cd718d 100644
--- a/src/plugins/projectexplorer/makestep.cpp
+++ b/src/plugins/projectexplorer/makestep.cpp
@@ -60,30 +60,36 @@ const char MAKEFLAGS[] = "MAKEFLAGS";
namespace ProjectExplorer {
-MakeStep::MakeStep(BuildStepList *parent,
- Core::Id id,
- const QString &buildTarget,
- const QStringList &availableTargets)
+MakeStep::MakeStep(BuildStepList *parent, Core::Id id)
: AbstractProcessStep(parent, id),
- m_availableTargets(availableTargets),
m_userJobCount(defaultJobCount())
{
setDefaultDisplayName(defaultDisplayName());
+ setLowPriority();
+}
+
+void MakeStep::setBuildTarget(const QString &buildTarget)
+{
if (!buildTarget.isEmpty())
setBuildTarget(buildTarget, true);
}
+void MakeStep::setAvailableBuildTargets(const QStringList &buildTargets)
+{
+ m_availableTargets = buildTargets;
+}
+
bool MakeStep::init()
{
BuildConfiguration *bc = buildConfiguration();
if (!bc)
emit addTask(Task::buildConfigurationMissingTask());
- const FilePath make = effectiveMakeCommand();
- if (make.isEmpty())
+ const CommandLine make = effectiveMakeCommand();
+ if (make.executable().isEmpty())
emit addTask(makeCommandMissingTask());
- if (!bc || make.isEmpty()) {
+ if (!bc || make.executable().isEmpty()) {
emitFaultyConfigurationMessage();
return false;
}
@@ -92,8 +98,7 @@ bool MakeStep::init()
pp->setMacroExpander(bc->macroExpander());
pp->setWorkingDirectory(bc->buildDirectory());
pp->setEnvironment(environment(bc));
- pp->setCommand(make);
- pp->setArguments(allArguments());
+ pp->setCommandLine(make);
pp->resolveAll();
// If we are cleaning, then make can fail with an error code, but that doesn't mean
@@ -227,7 +232,7 @@ bool MakeStep::makeflagsJobCountMismatch() const
const Utils::Environment env = environment(buildConfiguration());
if (!env.hasKey(MAKEFLAGS))
return false;
- Utils::optional<int> makeFlagsJobCount = argsJobCount(env.value(MAKEFLAGS));
+ Utils::optional<int> makeFlagsJobCount = argsJobCount(env.expandedValueForKey(MAKEFLAGS));
return makeFlagsJobCount.has_value() && *makeFlagsJobCount != m_userJobCount;
}
@@ -236,7 +241,7 @@ bool MakeStep::makeflagsContainsJobCount() const
const Utils::Environment env = environment(buildConfiguration());
if (!env.hasKey(MAKEFLAGS))
return false;
- return argsJobCount(env.value(MAKEFLAGS)).has_value();
+ return argsJobCount(env.expandedValueForKey(MAKEFLAGS)).has_value();
}
bool MakeStep::userArgsContainsJobCount() const
@@ -254,7 +259,7 @@ Utils::Environment MakeStep::environment(BuildConfiguration *bc) const
const ToolChain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst();
if (tc && tc->targetAbi().os() == Abi::WindowsOS
&& tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
- env.set(MAKEFLAGS, 'L' + env.value(MAKEFLAGS));
+ env.set(MAKEFLAGS, 'L' + env.expandedValueForKey(MAKEFLAGS));
}
}
return env;
@@ -308,13 +313,6 @@ QStringList MakeStep::jobArguments() const
return {"-j" + QString::number(m_userJobCount)};
}
-QString MakeStep::allArguments() const
-{
- QString args = m_makeArguments;
- Utils::QtcProcess::addArgs(&args, jobArguments() + m_buildTargets);
- return args;
-}
-
QString MakeStep::userArguments() const
{
return m_makeArguments;
@@ -330,11 +328,15 @@ FilePath MakeStep::makeCommand() const
return m_makeCommand;
}
-FilePath MakeStep::effectiveMakeCommand() const
+CommandLine MakeStep::effectiveMakeCommand() const
{
- if (!m_makeCommand.isEmpty())
- return m_makeCommand;
- return defaultMakeCommand();
+ CommandLine cmd(m_makeCommand.isEmpty() ? defaultMakeCommand() : m_makeCommand);
+
+ cmd.addArgs(m_makeArguments, CommandLine::Raw);
+ cmd.addArgs(jobArguments());
+ cmd.addArgs(m_buildTargets);
+
+ return cmd;
}
BuildStepConfigWidget *MakeStep::createConfigWidget()
@@ -416,23 +418,10 @@ MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep)
connect(m_makeStep->target(), &Target::kitChanged,
this, &MakeStepConfigWidget::updateDetails);
- const auto pro = m_makeStep->target()->project();
- pro->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
- if (static_cast<BuildConfiguration *>(sender())->isActive()) {
- updateDetails();
- }
- });
- pro->subscribeSignal(&BuildConfiguration::buildDirectoryChanged, this, [this]() {
- if (static_cast<BuildConfiguration *>(sender())->isActive()) {
- updateDetails();
- }
- });
- connect(pro, &Project::activeProjectConfigurationChanged,
- this, [this](ProjectConfiguration *pc) {
- if (pc && pc->isActive()) {
- updateDetails();
- }
- });
+ connect(m_makeStep->buildConfiguration(), &BuildConfiguration::environmentChanged,
+ this, &MakeStepConfigWidget::updateDetails);
+ connect(m_makeStep->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
+ this, &MakeStepConfigWidget::updateDetails);
Core::VariableChooser::addSupportForChildWidgets(this, m_makeStep->macroExpander());
}
@@ -466,7 +455,8 @@ void MakeStepConfigWidget::updateDetails()
else
m_ui->makeLabel->setText(tr("Override %1:").arg(QDir::toNativeSeparators(defaultMake)));
- if (m_makeStep->effectiveMakeCommand().isEmpty()) {
+ const CommandLine make = m_makeStep->effectiveMakeCommand();
+ if (make.executable().isEmpty()) {
setSummaryText(tr("<b>Make:</b> %1").arg(MakeStep::msgNoMakeCommand()));
return;
}
@@ -486,13 +476,12 @@ void MakeStepConfigWidget::updateDetails()
ProcessParameters param;
param.setMacroExpander(bc->macroExpander());
param.setWorkingDirectory(bc->buildDirectory());
- param.setCommand(m_makeStep->effectiveMakeCommand());
- param.setArguments(m_makeStep->allArguments());
+ param.setCommandLine(make);
param.setEnvironment(m_makeStep->environment(bc));
if (param.commandMissing())
setSummaryText(tr("<b>Make:</b> %1 not found in the environment.")
- .arg(param.command().toString())); // Override display text
+ .arg(param.command().executable().toUserOutput())); // Override display text
else
setSummaryText(param.summaryInWorkdir(displayName()));
}
diff --git a/src/plugins/projectexplorer/makestep.h b/src/plugins/projectexplorer/makestep.h
index fffcb7e0d1..f8584047d7 100644
--- a/src/plugins/projectexplorer/makestep.h
+++ b/src/plugins/projectexplorer/makestep.h
@@ -45,22 +45,21 @@ class PROJECTEXPLORER_EXPORT MakeStep : public ProjectExplorer::AbstractProcessS
Q_OBJECT
public:
- explicit MakeStep(ProjectExplorer::BuildStepList *parent,
- Core::Id id,
- const QString &buildTarget = QString(),
- const QStringList &availableTargets = {});
+ explicit MakeStep(ProjectExplorer::BuildStepList *parent, Core::Id id);
+
+ void setBuildTarget(const QString &buildTarget);
+ void setAvailableBuildTargets(const QStringList &buildTargets);
bool init() override;
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
bool buildsTarget(const QString &target) const;
void setBuildTarget(const QString &target, bool on);
QStringList availableTargets() const;
- QString allArguments() const;
QString userArguments() const;
void setUserArguments(const QString &args);
Utils::FilePath makeCommand() const;
void setMakeCommand(const Utils::FilePath &command);
- Utils::FilePath effectiveMakeCommand() const;
+ Utils::CommandLine effectiveMakeCommand() const;
void setClean(bool clean);
bool isClean() const;
diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp
index aa01c0f9b6..372712f8bc 100644
--- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp
+++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp
@@ -97,6 +97,27 @@ static bool projectLesserThan(Project *p1, Project *p2)
return p1 < p2;
}
+static QString displayNameFor(QObject *object)
+{
+ if (auto t = qobject_cast<Target *>(object))
+ return t->displayName();
+ if (auto pc = qobject_cast<ProjectConfiguration *>(object))
+ return pc->displayName();
+ QTC_CHECK(false);
+ return {};
+}
+
+static QString toolTipFor(QObject *object)
+{
+ if (auto t = qobject_cast<Target *>(object))
+ return t->toolTip();
+ if (auto pc = qobject_cast<ProjectConfiguration *>(object))
+ return pc->toolTip();
+ QTC_CHECK(false);
+ return {};
+}
+
+
////////
// TargetSelectorDelegate
////////
@@ -407,22 +428,27 @@ GenericListWidget::GenericListWidget(QWidget *parent)
this, &GenericListWidget::rowChanged);
}
-void GenericListWidget::setProjectConfigurations(const QList<ProjectConfiguration *> &list, ProjectConfiguration *active)
+void GenericListWidget::setProjectConfigurations(const QList<QObject *> &list, QObject *active)
{
m_ignoreIndexChange = true;
clear();
for (int i = 0; i < count(); ++i) {
- auto *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
- disconnect(p, &ProjectConfiguration::displayNameChanged,
+ auto obj = objectAt(i);
+ if (auto t = qobject_cast<Target *>(obj)) {
+ disconnect(t, &Target::kitChanged,
this, &GenericListWidget::displayNameChanged);
+ } else if (auto pc = qobject_cast<ProjectConfiguration *>(obj)) {
+ disconnect(pc, &ProjectConfiguration::displayNameChanged,
+ this, &GenericListWidget::displayNameChanged);
+ }
}
QFontMetrics fn(font());
int width = 0;
- foreach (ProjectConfiguration *pc, list) {
+ for (QObject *pc : list) {
addProjectConfiguration(pc);
- width = qMax(width, fn.horizontalAdvance(pc->displayName()) + padding());
+ width = qMax(width, fn.horizontalAdvance(displayNameFor(pc)) + padding());
}
setOptimalWidth(width);
setActiveProjectConfiguration(active);
@@ -430,57 +456,77 @@ void GenericListWidget::setProjectConfigurations(const QList<ProjectConfiguratio
m_ignoreIndexChange = false;
}
-void GenericListWidget::setActiveProjectConfiguration(ProjectConfiguration *active)
+QObject *GenericListWidget::objectAt(int row) const
+{
+ return item(row)->data(Qt::UserRole).value<QObject *>();
+}
+
+void GenericListWidget::setActiveProjectConfiguration(QObject *active)
{
QListWidgetItem *item = itemForProjectConfiguration(active);
setCurrentItem(item);
}
-void GenericListWidget::addProjectConfiguration(ProjectConfiguration *pc)
+void GenericListWidget::addProjectConfiguration(QObject *obj)
{
+ const QString displayName = displayNameFor(obj);
+ const QString toolTip = toolTipFor(obj);
+
m_ignoreIndexChange = true;
auto lwi = new QListWidgetItem();
- lwi->setText(pc->displayName());
- lwi->setData(Qt::ToolTipRole, pc->toolTip());
- lwi->setData(Qt::UserRole + 1, pc->toolTip());
- lwi->setData(Qt::UserRole, QVariant::fromValue(pc));
+ lwi->setText(displayName);
+ lwi->setData(Qt::ToolTipRole, toolTip);
+ lwi->setData(Qt::UserRole + 1, toolTip);
+ lwi->setData(Qt::UserRole, QVariant::fromValue(obj));
// Figure out pos
int pos = count();
for (int i = 0; i < count(); ++i) {
- auto *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
- if (caseFriendlyCompare(pc->displayName(), p->displayName()) < 0) {
+ QObject *p = objectAt(i);
+ if (caseFriendlyCompare(displayName, displayNameFor(p)) < 0) {
pos = i;
break;
}
}
insertItem(pos, lwi);
- connect(pc, &ProjectConfiguration::displayNameChanged,
- this, &GenericListWidget::displayNameChanged);
- connect(pc, &ProjectConfiguration::toolTipChanged, this, &GenericListWidget::toolTipChanged);
+ if (auto t = qobject_cast<Target *>(obj)) {
+ connect(t, &Target::kitChanged, this,
+ &GenericListWidget::displayNameChanged);
+ connect(t, &Target::kitChanged, this,
+ &GenericListWidget::toolTipChanged);
+ } else if (auto pc = qobject_cast<ProjectConfiguration *>(obj)) {
+ connect(pc, &ProjectConfiguration::displayNameChanged,
+ this, &GenericListWidget::displayNameChanged);
+ connect(pc, &ProjectConfiguration::toolTipChanged,
+ this, &GenericListWidget::toolTipChanged);
+ }
QFontMetrics fn(font());
- int width = fn.horizontalAdvance(pc->displayName()) + padding();
+ int width = fn.horizontalAdvance(displayName) + padding();
if (width > optimalWidth())
setOptimalWidth(width);
m_ignoreIndexChange = false;
}
-void GenericListWidget::removeProjectConfiguration(ProjectConfiguration *pc)
+void GenericListWidget::removeProjectConfiguration(QObject *obj)
{
m_ignoreIndexChange = true;
- disconnect(pc, &ProjectConfiguration::displayNameChanged,
- this, &GenericListWidget::displayNameChanged);
- delete itemForProjectConfiguration(pc);
+ if (auto t = qobject_cast<Target *>(obj)) {
+ disconnect(t, &Target::kitChanged,
+ this, &GenericListWidget::displayNameChanged);
+ } else if (auto pc = qobject_cast<ProjectConfiguration *>(obj)) {
+ disconnect(pc, &ProjectConfiguration::displayNameChanged,
+ this, &GenericListWidget::displayNameChanged);
+ }
+ delete itemForProjectConfiguration(obj);
QFontMetrics fn(font());
int width = 0;
- for (int i = 0; i < count(); ++i) {
- auto *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
- width = qMax(width, fn.horizontalAdvance(p->displayName()) + padding());
- }
+ for (int i = 0; i < count(); ++i)
+ width = qMax(width, fn.horizontalAdvance(displayNameFor(objectAt(i))) + padding());
+
setOptimalWidth(width);
m_ignoreIndexChange = false;
@@ -492,48 +538,48 @@ void GenericListWidget::rowChanged(int index)
return;
if (index < 0)
return;
- emit changeActiveProjectConfiguration(item(index)->data(Qt::UserRole).value<ProjectConfiguration *>());
+ emit changeActiveProjectConfiguration(objectAt(index));
}
void GenericListWidget::displayNameChanged()
{
m_ignoreIndexChange = true;
- ProjectConfiguration *activeProjectConfiguration = nullptr;
+ QObject *activeObject = nullptr;
if (currentItem())
- activeProjectConfiguration = currentItem()->data(Qt::UserRole).value<ProjectConfiguration *>();
+ activeObject = currentItem()->data(Qt::UserRole).value<QObject *>();
- auto *pc = qobject_cast<ProjectConfiguration *>(sender());
+ QObject *obj = sender();
int index = -1;
int i = 0;
for (; i < count(); ++i) {
QListWidgetItem *lwi = item(i);
- if (lwi->data(Qt::UserRole).value<ProjectConfiguration *>() == pc) {
+ if (lwi->data(Qt::UserRole).value<QObject *>() == obj) {
index = i;
break;
}
}
if (index == -1)
return;
+
+ const QString displayName = displayNameFor(obj);
QListWidgetItem *lwi = takeItem(i);
- lwi->setText(pc->displayName());
+ lwi->setText(displayName);
int pos = count();
for (int i = 0; i < count(); ++i) {
- auto *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
- if (caseFriendlyCompare(pc->displayName(), p->displayName()) < 0) {
+ if (caseFriendlyCompare(displayName, displayNameFor(objectAt(i))) < 0) {
pos = i;
break;
}
}
insertItem(pos, lwi);
- if (activeProjectConfiguration)
- setCurrentItem(itemForProjectConfiguration(activeProjectConfiguration));
+ if (activeObject)
+ setCurrentItem(itemForProjectConfiguration(activeObject));
QFontMetrics fn(font());
int width = 0;
- for (int i = 0; i < count(); ++i) {
- auto *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
- width = qMax(width, fn.horizontalAdvance(p->displayName()) + padding());
- }
+ for (int i = 0; i < count(); ++i)
+ width = qMax(width, fn.horizontalAdvance(displayNameFor(objectAt(i))) + padding());
+
setOptimalWidth(width);
m_ignoreIndexChange = false;
@@ -541,18 +587,19 @@ void GenericListWidget::displayNameChanged()
void GenericListWidget::toolTipChanged()
{
- auto *pc = qobject_cast<ProjectConfiguration *>(sender());
- if (QListWidgetItem *lwi = itemForProjectConfiguration(pc)) {
- lwi->setData(Qt::ToolTipRole, pc->toolTip());
- lwi->setData(Qt::UserRole + 1, pc->toolTip());
+ QObject *obj = sender();
+ if (QListWidgetItem *lwi = itemForProjectConfiguration(obj)) {
+ const QString toolTip = toolTipFor(obj);
+ lwi->setData(Qt::ToolTipRole, toolTip);
+ lwi->setData(Qt::UserRole + 1, toolTip);
}
}
-QListWidgetItem *GenericListWidget::itemForProjectConfiguration(ProjectConfiguration *pc)
+QListWidgetItem *GenericListWidget::itemForProjectConfiguration(QObject *pc)
{
for (int i = 0; i < count(); ++i) {
QListWidgetItem *lwi = item(i);
- if (lwi->data(Qt::UserRole).value<ProjectConfiguration *>() == pc)
+ if (lwi->data(Qt::UserRole).value<QObject *>() == pc)
return lwi;
}
return nullptr;
@@ -565,7 +612,7 @@ QListWidgetItem *GenericListWidget::itemForProjectConfiguration(ProjectConfigura
KitAreaWidget::KitAreaWidget(QWidget *parent) : QWidget(parent),
m_layout(new QGridLayout(this))
{
- m_layout->setMargin(3);
+ m_layout->setContentsMargins(3, 3, 3, 3);
setAutoFillBackground(true);
connect(KitManager::instance(), &KitManager::kitUpdated, this, &KitAreaWidget::updateKit);
}
@@ -725,21 +772,21 @@ MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorActi
this, &MiniProjectTargetSelector::kitChanged);
connect(m_listWidgets[TARGET], &GenericListWidget::changeActiveProjectConfiguration,
- this, [this](ProjectConfiguration *pc) {
+ this, [this](QObject *pc) {
SessionManager::setActiveTarget(m_project, static_cast<Target *>(pc), SetActive::Cascade);
});
connect(m_listWidgets[BUILD], &GenericListWidget::changeActiveProjectConfiguration,
- this, [this](ProjectConfiguration *pc) {
+ this, [this](QObject *pc) {
SessionManager::setActiveBuildConfiguration(m_project->activeTarget(),
static_cast<BuildConfiguration *>(pc), SetActive::Cascade);
});
connect(m_listWidgets[DEPLOY], &GenericListWidget::changeActiveProjectConfiguration,
- this, [this](ProjectConfiguration *pc) {
+ this, [this](QObject *pc) {
SessionManager::setActiveDeployConfiguration(m_project->activeTarget(),
static_cast<DeployConfiguration *>(pc), SetActive::Cascade);
});
connect(m_listWidgets[RUN], &GenericListWidget::changeActiveProjectConfiguration,
- this, [this](ProjectConfiguration *pc) {
+ this, [this](QObject *pc) {
m_project->activeTarget()->setActiveRunConfiguration(static_cast<RunConfiguration *>(pc));
});
}
@@ -979,9 +1026,13 @@ void MiniProjectTargetSelector::projectAdded(Project *project)
{
connect(project, &Project::addedProjectConfiguration,
this, &MiniProjectTargetSelector::handleNewProjectConfiguration);
+ connect(project, &Project::addedTarget,
+ this, &MiniProjectTargetSelector::handleNewTarget);
connect(project, &Project::removedProjectConfiguration,
this, &MiniProjectTargetSelector::handleRemovalOfProjectConfiguration);
+ connect(project, &Project::removedTarget,
+ this, &MiniProjectTargetSelector::handleRemovalOfTarget);
foreach (Target *t, project->targets())
addedTarget(t);
@@ -997,9 +1048,13 @@ void MiniProjectTargetSelector::projectRemoved(Project *project)
{
disconnect(project, &Project::addedProjectConfiguration,
this, &MiniProjectTargetSelector::handleNewProjectConfiguration);
+ disconnect(project, &Project::addedTarget,
+ this, &MiniProjectTargetSelector::handleNewTarget);
disconnect(project, &Project::removedProjectConfiguration,
this, &MiniProjectTargetSelector::handleRemovalOfProjectConfiguration);
+ disconnect(project, &Project::removedTarget,
+ this, &MiniProjectTargetSelector::handleRemovalOfTarget);
foreach (Target *t, project->targets())
removedTarget(t);
@@ -1011,16 +1066,17 @@ void MiniProjectTargetSelector::projectRemoved(Project *project)
updateRunListVisible();
}
+void MiniProjectTargetSelector::handleNewTarget(Target *target)
+{
+ addedTarget(target);
+ updateTargetListVisible();
+ updateBuildListVisible();
+ updateDeployListVisible();
+ updateRunListVisible();
+}
+
void MiniProjectTargetSelector::handleNewProjectConfiguration(ProjectConfiguration *pc)
{
- if (auto t = qobject_cast<Target *>(pc)) {
- addedTarget(t);
- updateTargetListVisible();
- updateBuildListVisible();
- updateDeployListVisible();
- updateRunListVisible();
- return;
- }
if (auto bc = qobject_cast<BuildConfiguration *>(pc)) {
if (addedBuildConfiguration(bc))
updateBuildListVisible();
@@ -1038,17 +1094,18 @@ void MiniProjectTargetSelector::handleNewProjectConfiguration(ProjectConfigurati
}
}
-void MiniProjectTargetSelector::handleRemovalOfProjectConfiguration(ProjectConfiguration *pc)
+void MiniProjectTargetSelector::handleRemovalOfTarget(Target *target)
{
- if (auto t = qobject_cast<Target *>(pc)) {
- removedTarget(t);
+ removedTarget(target);
- updateTargetListVisible();
- updateBuildListVisible();
- updateDeployListVisible();
- updateRunListVisible();
- return;
- }
+ updateTargetListVisible();
+ updateBuildListVisible();
+ updateDeployListVisible();
+ updateRunListVisible();
+}
+
+void MiniProjectTargetSelector::handleRemovalOfProjectConfiguration(ProjectConfiguration *pc)
+{
if (auto bc = qobject_cast<BuildConfiguration *>(pc)) {
if (removedBuildConfiguration(bc))
updateBuildListVisible();
@@ -1232,12 +1289,12 @@ void MiniProjectTargetSelector::changeStartupProject(Project *project)
}
if (project) {
- QList<ProjectConfiguration *> list;
+ QList<QObject *> list;
foreach (Target *t, project->targets())
list.append(t);
m_listWidgets[TARGET]->setProjectConfigurations(list, project->activeTarget());
} else {
- m_listWidgets[TARGET]->setProjectConfigurations(QList<ProjectConfiguration *>(), nullptr);
+ m_listWidgets[TARGET]->setProjectConfigurations(QList<QObject *>(), nullptr);
}
updateActionAndSummary();
@@ -1246,9 +1303,7 @@ void MiniProjectTargetSelector::changeStartupProject(Project *project)
void MiniProjectTargetSelector::activeTargetChanged(Target *target)
{
if (m_target) {
- disconnect(m_target, &ProjectConfiguration::displayNameChanged,
- this, &MiniProjectTargetSelector::updateActionAndSummary);
- disconnect(m_target, &Target::toolTipChanged,
+ disconnect(m_target, &Target::kitChanged,
this, &MiniProjectTargetSelector::updateActionAndSummary);
disconnect(m_target, &Target::iconChanged,
this, &MiniProjectTargetSelector::updateActionAndSummary);
@@ -1278,17 +1333,17 @@ void MiniProjectTargetSelector::activeTargetChanged(Target *target)
this, &MiniProjectTargetSelector::updateActionAndSummary);
if (m_target) {
- QList<ProjectConfiguration *> bl;
+ QList<QObject *> bl;
foreach (BuildConfiguration *bc, target->buildConfigurations())
bl.append(bc);
m_listWidgets[BUILD]->setProjectConfigurations(bl, target->activeBuildConfiguration());
- QList<ProjectConfiguration *> dl;
+ QList<QObject *> dl;
foreach (DeployConfiguration *dc, target->deployConfigurations())
dl.append(dc);
m_listWidgets[DEPLOY]->setProjectConfigurations(dl, target->activeDeployConfiguration());
- QList<ProjectConfiguration *> rl;
+ QList<QObject *> rl;
foreach (RunConfiguration *rc, target->runConfigurations())
rl.append(rc);
m_listWidgets[RUN]->setProjectConfigurations(rl, target->activeRunConfiguration());
@@ -1306,9 +1361,7 @@ void MiniProjectTargetSelector::activeTargetChanged(Target *target)
connect(m_runConfiguration, &ProjectConfiguration::displayNameChanged,
this, &MiniProjectTargetSelector::updateActionAndSummary);
- connect(m_target, &ProjectConfiguration::displayNameChanged,
- this, &MiniProjectTargetSelector::updateActionAndSummary);
- connect(m_target, &Target::toolTipChanged,
+ connect(m_target, &Target::kitChanged,
this, &MiniProjectTargetSelector::updateActionAndSummary);
connect(m_target, &Target::iconChanged,
this, &MiniProjectTargetSelector::updateActionAndSummary);
@@ -1319,9 +1372,9 @@ void MiniProjectTargetSelector::activeTargetChanged(Target *target)
connect(m_target, &Target::activeRunConfigurationChanged,
this, &MiniProjectTargetSelector::activeRunConfigurationChanged);
} else {
- m_listWidgets[BUILD]->setProjectConfigurations(QList<ProjectConfiguration *>(), nullptr);
- m_listWidgets[DEPLOY]->setProjectConfigurations(QList<ProjectConfiguration *>(), nullptr);
- m_listWidgets[RUN]->setProjectConfigurations(QList<ProjectConfiguration *>(), nullptr);
+ m_listWidgets[BUILD]->setProjectConfigurations(QList<QObject *>(), nullptr);
+ m_listWidgets[DEPLOY]->setProjectConfigurations(QList<QObject *>(), nullptr);
+ m_listWidgets[RUN]->setProjectConfigurations(QList<QObject *>(), nullptr);
m_buildConfiguration = nullptr;
m_deployConfiguration = nullptr;
m_runConfiguration = nullptr;
diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.h b/src/plugins/projectexplorer/miniprojecttargetselector.h
index 032f69f7eb..7992d21305 100644
--- a/src/plugins/projectexplorer/miniprojecttargetselector.h
+++ b/src/plugins/projectexplorer/miniprojecttargetselector.h
@@ -113,19 +113,21 @@ public:
explicit GenericListWidget(QWidget *parent = nullptr);
signals:
- void changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration *dc);
+ void changeActiveProjectConfiguration(QObject *dc);
public:
- void setProjectConfigurations(const QList<ProjectConfiguration *> &list, ProjectConfiguration *active);
- void setActiveProjectConfiguration(ProjectConfiguration *active);
- void addProjectConfiguration(ProjectConfiguration *pc);
- void removeProjectConfiguration(ProjectConfiguration *pc);
+ void setProjectConfigurations(const QList<QObject *> &list, QObject *active);
+ void setActiveProjectConfiguration(QObject *active);
+ void addProjectConfiguration(QObject *pc);
+ void removeProjectConfiguration(QObject *pc);
private:
+ QObject *objectAt(int row) const;
+
void rowChanged(int index);
void displayNameChanged();
void toolTipChanged();
- QListWidgetItem *itemForProjectConfiguration(ProjectConfiguration *pc);
+ QListWidgetItem *itemForProjectConfiguration(QObject *pc);
bool m_ignoreIndexChange;
};
@@ -148,8 +150,10 @@ public:
private:
void projectAdded(ProjectExplorer::Project *project);
void projectRemoved(ProjectExplorer::Project *project);
- void handleNewProjectConfiguration(ProjectConfiguration *pc);
- void handleRemovalOfProjectConfiguration(ProjectConfiguration *pc);
+ void handleNewProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+ void handleNewTarget(Target *target);
+ void handleRemovalOfProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
+ void handleRemovalOfTarget(Target *pc);
void changeStartupProject(ProjectExplorer::Project *project);
void activeTargetChanged(ProjectExplorer::Target *target);
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 24b528154d..c90799a5e0 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -239,9 +239,9 @@ static QVector<VisualStudioInstallation> detectVisualStudioFromVsWhere(const QSt
Utils::SynchronousProcess vsWhereProcess;
const int timeoutS = 5;
vsWhereProcess.setTimeoutS(timeoutS);
- const QStringList
- arguments{"-products", "*", "-prerelease", "-legacy", "-format", "json", "-utf8"};
- Utils::SynchronousProcessResponse response = vsWhereProcess.runBlocking(vswhere, arguments);
+ const CommandLine cmd(vswhere,
+ {"-products", "*", "-prerelease", "-legacy", "-format", "json", "-utf8"});
+ Utils::SynchronousProcessResponse response = vsWhereProcess.runBlocking(cmd);
switch (response.result) {
case Utils::SynchronousProcessResponse::Finished:
break;
@@ -622,7 +622,7 @@ Macros MsvcToolChain::msvcPredefinedMacros(const QStringList &cxxflags,
if (language() == ProjectExplorer::Constants::C_LANGUAGE_ID)
arguments << QLatin1String("/TC");
arguments << toProcess << QLatin1String("/EP") << QDir::toNativeSeparators(saver.fileName());
- Utils::SynchronousProcessResponse response = cpp.runBlocking(binary.toString(), arguments);
+ SynchronousProcessResponse response = cpp.runBlocking({binary, arguments});
if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0)
return predefinedMacros;
@@ -700,7 +700,7 @@ static QString winExpandDelayedEnvReferences(QString in, const Utils::Environmen
if (nextPos == -1)
break;
const QString var = in.mid(pos + 1, nextPos - pos - 1);
- const QString replacement = env.value(var.toUpper());
+ const QString replacement = env.expandedValueForKey(var.toUpper());
in.replace(pos, nextPos + 1 - pos, replacement);
pos += replacement.size();
}
@@ -715,7 +715,7 @@ void MsvcToolChain::environmentModifications(
const Utils::Environment inEnv = Utils::Environment::systemEnvironment();
Utils::Environment outEnv;
QMap<QString, QString> envPairs;
- QList<Utils::EnvironmentItem> diff;
+ Utils::EnvironmentItems diff;
Utils::optional<QString> error = generateEnvironmentSettings(inEnv,
vcvarsBat,
varsBatArg,
@@ -764,7 +764,7 @@ void MsvcToolChain::initEnvModWatcher(const QFuture<GenerateEnvResult> &future)
m_envModWatcher.setFuture(future);
}
-void MsvcToolChain::updateEnvironmentModifications(QList<Utils::EnvironmentItem> modifications)
+void MsvcToolChain::updateEnvironmentModifications(Utils::EnvironmentItems modifications)
{
Utils::EnvironmentItem::sort(&modifications);
if (modifications != m_environmentModifications) {
@@ -834,13 +834,6 @@ Utils::Environment MsvcToolChain::readEnvironmentSetting(const Utils::Environmen
// MsvcToolChain
// --------------------------------------------------------------------------
-MsvcToolChain::MsvcToolChain(const QString &name,
- const Abi &abi,
- const QString &varsBat,
- const QString &varsBatArg)
- : MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID, name, abi, varsBat, varsBatArg)
-{}
-
static void addToAvailableMsvcToolchains(const MsvcToolChain *toolchain)
{
if (toolchain->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID)
@@ -850,35 +843,13 @@ static void addToAvailableMsvcToolchains(const MsvcToolChain *toolchain)
g_availableMsvcToolchains.push_back(toolchain);
}
-MsvcToolChain::MsvcToolChain(Core::Id typeId,
- const QString &name,
- const Abi &abi,
- const QString &varsBat,
- const QString &varsBatArg)
+MsvcToolChain::MsvcToolChain(Core::Id typeId)
: ToolChain(typeId)
- , m_headerPathsMutex(new QMutex)
- , m_lastEnvironment(Utils::Environment::systemEnvironment())
- , m_abi(abi)
- , m_vcvarsBat(varsBat)
- , m_varsBatArg(varsBatArg)
{
- detectInstalledAbis();
- addToAvailableMsvcToolchains(this);
-
- initEnvModWatcher(Utils::runAsync(envModThreadPool(),
- &MsvcToolChain::environmentModifications,
- varsBat,
- varsBatArg));
-
- Q_ASSERT(!name.isEmpty());
-
- setDisplayName(name);
+ setDisplayName("Microsoft Visual C++ Compiler");
+ setTypeDisplayName(MsvcToolChainFactory::tr("MSVC"));
}
-MsvcToolChain::MsvcToolChain(Core::Id typeId)
- : ToolChain(typeId)
-{}
-
void MsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags &flags)
{
// reset all except unrelated flag
@@ -898,14 +869,9 @@ void MsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags &flags)
flags |= WarningFlags::UnusedParams;
}
-MsvcToolChain::MsvcToolChain()
- : MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID)
-{}
-
MsvcToolChain::~MsvcToolChain()
{
g_availableMsvcToolchains.removeOne(this);
- delete m_headerPathsMutex;
}
Abi MsvcToolChain::targetAbi() const
@@ -920,9 +886,6 @@ Abis MsvcToolChain::supportedAbis() const
void MsvcToolChain::setTargetAbi(const Abi &abi)
{
- if (m_abi == abi)
- return;
-
m_abi = abi;
}
@@ -940,63 +903,57 @@ QString MsvcToolChain::originalTargetTriple() const
: QLatin1String("i686-pc-windows-msvc");
}
-QString MsvcToolChain::typeDisplayName() const
-{
- return MsvcToolChainFactory::tr("MSVC");
-}
-
QStringList MsvcToolChain::suggestedMkspecList() const
{
- QStringList result = {"win32-msvc"}; // Common MSVC mkspec introduced in 5.8.1
+ // "win32-msvc" is the common MSVC mkspec introduced in Qt 5.8.1
switch (m_abi.osFlavor()) {
case Abi::WindowsMsvc2005Flavor:
- result << "win32-msvc2005";
- break;
+ return {"win32-msvc",
+ "win32-msvc2005"};
case Abi::WindowsMsvc2008Flavor:
- result << "win32-msvc2008";
- break;
+ return {"win32-msvc",
+ "win32-msvc2008"};
case Abi::WindowsMsvc2010Flavor:
- result << "win32-msvc2010";
- break;
+ return {"win32-msvc",
+ "win32-msvc2010"};
case Abi::WindowsMsvc2012Flavor:
- result << "win32-msvc2012"
- << "win32-msvc2010";
- break;
+ return {"win32-msvc",
+ "win32-msvc2012",
+ "win32-msvc2010"};
case Abi::WindowsMsvc2013Flavor:
- result << "win32-msvc2013"
- << "winphone-arm-msvc2013"
- << "winphone-x86-msvc2013"
- << "winrt-arm-msvc2013"
- << "winrt-x86-msvc2013"
- << "winrt-x64-msvc2013"
- << "win32-msvc2012"
- << "win32-msvc2010";
- break;
+ return {"win32-msvc",
+ "win32-msvc2013",
+ "winphone-arm-msvc2013",
+ "winphone-x86-msvc2013",
+ "winrt-arm-msvc2013",
+ "winrt-x86-msvc2013",
+ "winrt-x64-msvc2013",
+ "win32-msvc2012",
+ "win32-msvc2010"};
case Abi::WindowsMsvc2015Flavor:
- result << "win32-msvc2015"
- << "winphone-arm-msvc2015"
- << "winphone-x86-msvc2015"
- << "winrt-arm-msvc2015"
- << "winrt-x86-msvc2015"
- << "winrt-x64-msvc2015";
- break;
+ return {"win32-msvc",
+ "win32-msvc2015",
+ "winphone-arm-msvc2015",
+ "winphone-x86-msvc2015",
+ "winrt-arm-msvc2015",
+ "winrt-x86-msvc2015",
+ "winrt-x64-msvc2015"};
case Abi::WindowsMsvc2017Flavor:
- result << "win32-msvc2017"
- << "winrt-arm-msvc2017"
- << "winrt-x86-msvc2017"
- << "winrt-x64-msvc2017";
- break;
+ return {"win32-msvc",
+ "win32-msvc2017",
+ "winrt-arm-msvc2017",
+ "winrt-x86-msvc2017",
+ "winrt-x64-msvc2017"};
case Abi::WindowsMsvc2019Flavor:
- result << "win32-msvc2019"
- << "winrt-arm-msvc2019"
- << "winrt-x86-msvc2019"
- << "winrt-x64-msvc2019";
- break;
+ return {"win32-msvc",
+ "win32-msvc2019",
+ "winrt-arm-msvc2019",
+ "winrt-x86-msvc2019",
+ "winrt-x64-msvc2019"};
default:
- result.clear();
break;
}
- return result;
+ return {};
}
QVariantMap MsvcToolChain::toMap() const
@@ -1162,27 +1119,29 @@ WarningFlags MsvcToolChain::warningFlags(const QStringList &cflags) const
return flags;
}
-ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunner() const
+ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &env) const
{
- Utils::Environment env(m_lastEnvironment);
- addToEnvironment(env);
+ Utils::Environment fullEnv = env;
+ addToEnvironment(fullEnv);
- return [this, env](const QStringList &, const QString &, const QString &) {
- QMutexLocker locker(m_headerPathsMutex);
+ return [this, fullEnv](const QStringList &, const QString &, const QString &) {
+ QMutexLocker locker(&m_headerPathsMutex);
if (m_headerPaths.isEmpty()) {
- foreach (const QString &path,
- env.value(QLatin1String("INCLUDE")).split(QLatin1Char(';'))) {
- m_headerPaths.append({path, HeaderPathType::BuiltIn});
- }
+ m_headerPaths = transform<QVector>(fullEnv.pathListValue("INCLUDE"),
+ [](const FilePath &p) {
+ return HeaderPath(p.toString(), HeaderPathType::BuiltIn);
+ });
}
return m_headerPaths;
};
}
HeaderPaths MsvcToolChain::builtInHeaderPaths(const QStringList &cxxflags,
- const Utils::FilePath &sysRoot) const
+ const Utils::FilePath &sysRoot,
+ const Environment &env) const
{
- return createBuiltInHeaderPathsRunner()(cxxflags, sysRoot.toString(), "");
+ return createBuiltInHeaderPathsRunner(env)(cxxflags, sysRoot.toString(), "");
}
void MsvcToolChain::addToEnvironment(Utils::Environment &env) const
@@ -1268,20 +1227,30 @@ IOutputParser *MsvcToolChain::outputParser() const
return new MsvcParser;
}
-void MsvcToolChain::changeVcVarsCall(const QString &varsBat, const QString &varsBatArg)
+void MsvcToolChain::setupVarsBat(const Abi &abi, const QString &varsBat, const QString &varsBatArg)
{
+ m_lastEnvironment = Utils::Environment::systemEnvironment();
+ m_abi = abi;
m_vcvarsBat = varsBat;
m_varsBatArg = varsBatArg;
if (!varsBat.isEmpty()) {
detectInstalledAbis();
initEnvModWatcher(Utils::runAsync(envModThreadPool(),
- &ClangClToolChain::environmentModifications,
- m_vcvarsBat,
- m_varsBatArg));
+ &MsvcToolChain::environmentModifications,
+ varsBat,
+ varsBatArg));
}
}
+void MsvcToolChain::resetVarsBat()
+{
+ m_lastEnvironment = Utils::Environment::systemEnvironment();
+ m_abi = Abi();
+ m_vcvarsBat.clear();
+ m_varsBatArg.clear();
+}
+
// --------------------------------------------------------------------------
// MsvcBasedToolChainConfigWidget: Creates a simple GUI without error label
// to display name and varsBat. Derived classes should add the error label and
@@ -1379,9 +1348,8 @@ void MsvcToolChainConfigWidget::applyImpl()
{
auto *tc = static_cast<MsvcToolChain *>(toolChain());
QTC_ASSERT(tc, return );
- tc->setTargetAbi(m_abiWidget->currentAbi());
const QString vcVars = QDir::fromNativeSeparators(m_varsBatPathCombo->currentText());
- tc->changeVcVarsCall(vcVars, vcVarsArguments());
+ tc->setupVarsBat(m_abiWidget->currentAbi(), vcVars, vcVarsArguments());
setFromMsvcToolChain();
}
@@ -1542,10 +1510,10 @@ static const MsvcToolChain *findMsvcToolChain(const QString &displayedVarsBat)
static QVersionNumber clangClVersion(const QString &clangClPath)
{
- Utils::SynchronousProcess clangClProcess;
- const Utils::SynchronousProcessResponse response
- = clangClProcess.runBlocking(clangClPath, {QStringLiteral("--version")});
- if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0)
+ SynchronousProcess clangClProcess;
+ const SynchronousProcessResponse response
+ = clangClProcess.runBlocking({clangClPath, {"--version"}});
+ if (response.result != SynchronousProcessResponse::Finished || response.exitCode != 0)
return {};
const QRegularExpressionMatch match = QRegularExpression(
QStringLiteral("clang version (\\d+(\\.\\d+)+)"))
@@ -1611,13 +1579,17 @@ static QList<ToolChain *> detectClangClToolChainInPath(const QString &clangClPat
return systemEnvironment.isSameExecutable(tc->compilerCommand().toString(),
clangClPath);
}));
- if (!tc) {
- tc = new ClangClToolChain(name, clangClPath);
- tc->setDetection(ToolChain::AutoDetection);
- tc->setLanguage(language);
- tc->resetMsvcToolChain(toolChain);
+ if (tc) {
+ res << tc;
+ } else {
+ auto cltc = new ClangClToolChain;
+ cltc->setClangPath(clangClPath);
+ cltc->setDisplayName(name);
+ cltc->setDetection(ToolChain::AutoDetection);
+ cltc->setLanguage(language);
+ cltc->setupVarsBat(toolChain->targetAbi(), toolChain->varsBat(), toolChain->varsBatArg());
+ res << cltc;
}
- res << tc;
}
return res;
}
@@ -1634,7 +1606,7 @@ void ClangClToolChainConfigWidget::applyImpl()
clangClToolChain->setClangPath(clangClPath.toString());
if (clangClPath.fileName() != "clang-cl.exe") {
- clangClToolChain->resetMsvcToolChain();
+ clangClToolChain->resetVarsBat();
setFromClangClToolChain();
return;
}
@@ -1645,11 +1617,12 @@ void ClangClToolChainConfigWidget::applyImpl()
displayedVarsBat);
if (results.isEmpty()) {
- clangClToolChain->resetMsvcToolChain();
+ clangClToolChain->resetVarsBat();
} else {
for (const ToolChain *toolchain : results) {
if (toolchain->language() == clangClToolChain->language()) {
- clangClToolChain->resetMsvcToolChain(static_cast<const MsvcToolChain *>(toolchain));
+ auto mstc = static_cast<const MsvcToolChain *>(toolchain);
+ clangClToolChain->setupVarsBat(mstc->targetAbi(), mstc->varsBat(), mstc->varsBatArg());
break;
}
}
@@ -1674,15 +1647,12 @@ void ClangClToolChainConfigWidget::makeReadOnlyImpl()
// clang-cl.exe as a [to some extent] compatible drop-in replacement for cl.
// --------------------------------------------------------------------------
-ClangClToolChain::ClangClToolChain(const QString &name,
- const QString &clangPath)
- : MsvcToolChain(Constants::CLANG_CL_TOOLCHAIN_TYPEID, name, Abi(), "", "")
- , m_clangPath(clangPath)
-{}
-
ClangClToolChain::ClangClToolChain()
: MsvcToolChain(Constants::CLANG_CL_TOOLCHAIN_TYPEID)
-{}
+{
+ setDisplayName("clang-cl");
+ setTypeDisplayName(QCoreApplication::translate("ProjectExplorer::ClangToolChainFactory", "Clang"));
+}
bool ClangClToolChain::isValid() const
{
@@ -1702,11 +1672,6 @@ Utils::FilePath ClangClToolChain::compilerCommand() const
return Utils::FilePath::fromString(m_clangPath);
}
-QString ClangClToolChain::typeDisplayName() const
-{
- return QCoreApplication::translate("ProjectExplorer::ClangToolChainFactory", "Clang");
-}
-
QStringList ClangClToolChain::suggestedMkspecList() const
{
const QString mkspec = "win32-clang-" + Abi::toString(targetAbi().osFlavor());
@@ -1747,18 +1712,6 @@ std::unique_ptr<ToolChainConfigWidget> ClangClToolChain::createConfigurationWidg
return std::make_unique<ClangClToolChainConfigWidget>(this);
}
-void ClangClToolChain::resetMsvcToolChain(const MsvcToolChain *base)
-{
- if (!base) {
- m_abi = Abi();
- changeVcVarsCall("");
- return;
- }
-
- m_abi = base->targetAbi();
- changeVcVarsCall(base->varsBat(), base->varsBatArg());
-}
-
bool ClangClToolChain::operator==(const ToolChain &other) const
{
if (!MsvcToolChain::operator==(other))
@@ -1781,8 +1734,7 @@ Macros ClangClToolChain::msvcPredefinedMacros(const QStringList &cxxflags,
QStringList arguments = cxxflags;
arguments.append(gccPredefinedMacrosOptions(language()));
arguments.append("-");
- Utils::SynchronousProcessResponse response = cpp.runBlocking(compilerCommand().toString(),
- arguments);
+ Utils::SynchronousProcessResponse response = cpp.runBlocking({compilerCommand(), arguments});
if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0) {
// Show the warning but still parse the output.
QTC_CHECK(false && "clang-cl exited with non-zero code.");
@@ -1800,14 +1752,15 @@ Utils::LanguageVersion ClangClToolChain::msvcLanguageVersion(const QStringList &
return MsvcToolChain::msvcLanguageVersion(cxxflags, language, macros);
}
-ClangClToolChain::BuiltInHeaderPathsRunner ClangClToolChain::createBuiltInHeaderPathsRunner() const
+ClangClToolChain::BuiltInHeaderPathsRunner ClangClToolChain::createBuiltInHeaderPathsRunner(
+ const Environment &env) const
{
{
- QMutexLocker locker(m_headerPathsMutex);
+ QMutexLocker locker(&m_headerPathsMutex);
m_headerPaths.clear();
}
- return MsvcToolChain::createBuiltInHeaderPathsRunner();
+ return MsvcToolChain::createBuiltInHeaderPathsRunner(env);
}
// --------------------------------------------------------------------------
@@ -1819,7 +1772,7 @@ MsvcToolChainFactory::MsvcToolChainFactory()
setDisplayName(tr("MSVC"));
setSupportedToolChainType(Constants::MSVC_TOOLCHAIN_TYPEID);
setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID});
- setToolchainConstructor([] { return new MsvcToolChain; });
+ setToolchainConstructor([] { return new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID); });
}
QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath,
@@ -1856,11 +1809,15 @@ static QList<ToolChain *> findOrCreateToolChain(const QList<ToolChain *> &alread
auto mtc = static_cast<MsvcToolChain *>(tc);
return mtc->varsBat() == varsBat && mtc->varsBatArg() == varsBatArg;
});
- if (!tc) {
- tc = new MsvcToolChain(name, abi, varsBat, varsBatArg);
- tc->setLanguage(language);
+ if (tc) {
+ res << tc;
+ } else {
+ auto mstc = new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID);
+ mstc->setupVarsBat(abi, varsBat, varsBatArg);
+ mstc->setDisplayName(name);
+ mstc->setLanguage(language);
+ res << mstc;
}
- res << tc;
}
return res;
}
@@ -1882,9 +1839,8 @@ static void detectCppBuildTools2015(QList<ToolChain *> *list)
{" (x86_arm)", "x86_arm", Abi::ArmArchitecture, Abi::PEFormat, 32},
{" (x64_arm)", "amd64_arm", Abi::ArmArchitecture, Abi::PEFormat, 64}};
- const QString name = QStringLiteral("Microsoft Visual C++ Build Tools");
- const QString vcVarsBat = windowsProgramFilesDir() + QLatin1Char('/') + name
- + QStringLiteral("/vcbuildtools.bat");
+ const QString name = "Microsoft Visual C++ Build Tools";
+ const QString vcVarsBat = windowsProgramFilesDir() + '/' + name + "/vcbuildtools.bat";
if (!QFileInfo(vcVarsBat).isFile())
return;
for (const Entry &e : entries) {
@@ -1894,10 +1850,9 @@ static void detectCppBuildTools2015(QList<ToolChain *> *list)
e.format,
e.wordSize);
for (auto language : {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) {
- auto tc = new MsvcToolChain(name + QLatin1String(e.postFix),
- abi,
- vcVarsBat,
- QLatin1String(e.varsBatArg));
+ auto tc = new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID);
+ tc->setupVarsBat(abi, vcVarsBat, QLatin1String(e.varsBatArg));
+ tc->setDisplayName(name + QLatin1String(e.postFix));
tc->setDetection(ToolChain::AutoDetection);
tc->setLanguage(language);
list->append(tc);
@@ -2048,11 +2003,6 @@ QList<ToolChain *> ClangClToolChainFactory::autoDetect(const QList<ToolChain *>
return results;
}
-ToolChain *ClangClToolChainFactory::create()
-{
- return new ClangClToolChain("clang-cl", "");
-}
-
bool MsvcToolChain::operator==(const ToolChain &other) const
{
if (!ToolChain::operator==(other))
@@ -2111,13 +2061,12 @@ Utils::optional<QString> MsvcToolChain::generateEnvironmentSettings(const Utils:
if (cmdPath.isEmpty())
cmdPath = env.searchInPath(QLatin1String("cmd.exe"));
// Windows SDK setup scripts require command line switches for environment expansion.
- QStringList cmdArguments({QLatin1String("/E:ON"), QLatin1String("/V:ON"), QLatin1String("/c")});
- cmdArguments << QDir::toNativeSeparators(saver.fileName());
+ CommandLine cmd(cmdPath, {"/E:ON", "/V:ON", "/c", QDir::toNativeSeparators(saver.fileName())});
if (debug)
- qDebug() << "readEnvironmentSetting: " << call << cmdPath << cmdArguments.join(' ')
+ qDebug() << "readEnvironmentSetting: " << call << cmd.toUserOutput()
<< " Env: " << runEnv.size();
run.setCodec(QTextCodec::codecForName("UTF-8"));
- Utils::SynchronousProcessResponse response = run.runBlocking(cmdPath.toString(), cmdArguments);
+ Utils::SynchronousProcessResponse response = run.runBlocking(cmd);
if (response.result != Utils::SynchronousProcessResponse::Finished) {
const QString message = !response.stdErr().isEmpty()
@@ -2169,12 +2118,6 @@ bool MsvcToolChainFactory::canCreate() const
return !g_availableMsvcToolchains.isEmpty();
}
-ToolChain *MsvcToolChainFactory::create()
-{
- return new MsvcToolChain("Microsoft Visual C++ Compiler",
- Abi::hostAbi(), g_availableMsvcToolchains.first()->varsBat(), "");
-}
-
MsvcToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, WarningFlags &flags)
: m_flags(flags)
{
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index bc0adb00ba..80d8db723c 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -28,6 +28,7 @@
#include "abi.h"
#include "abiwidget.h"
#include "toolchain.h"
+#include "toolchaincache.h"
#include "toolchainconfigwidget.h"
#include <QFutureWatcher>
@@ -56,11 +57,7 @@ public:
enum Type { WindowsSDK, VS };
enum Platform { x86, amd64, x86_amd64, ia64, x86_ia64, arm, x86_arm, amd64_arm, amd64_x86 };
- explicit MsvcToolChain(const QString &name,
- const Abi &abi,
- const QString &varsBat,
- const QString &varsBatArg);
- MsvcToolChain();
+ explicit MsvcToolChain(Core::Id typeId);
~MsvcToolChain() override;
Abi targetAbi() const override;
@@ -73,8 +70,6 @@ public:
QStringList suggestedMkspecList() const override;
- QString typeDisplayName() const override;
-
QVariantMap toMap() const override;
bool fromMap(const QVariantMap &data) override;
@@ -84,9 +79,11 @@ public:
Macros predefinedMacros(const QStringList &cxxflags) const override;
Utils::LanguageExtensions languageExtensions(const QStringList &cxxflags) const override;
WarningFlags warningFlags(const QStringList &cflags) const override;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &env) const override;
HeaderPaths builtInHeaderPaths(const QStringList &cxxflags,
- const Utils::FilePath &sysRoot) const override;
+ const Utils::FilePath &sysRoot,
+ const Utils::Environment &env) const override;
void addToEnvironment(Utils::Environment &env) const override;
Utils::FilePath makeCommand(const Utils::Environment &environment) const override;
@@ -95,8 +92,8 @@ public:
QString varsBatArg() const { return m_varsBatArg; }
QString varsBat() const { return m_vcvarsBat; }
- void setVarsBatArg(const QString &varsBA) { m_varsBatArg = varsBA; }
- void changeVcVarsCall(const QString &varsBat, const QString &varsBatArgs = QString());
+ void setupVarsBat(const Abi &abi, const QString &varsBat, const QString &varsBatArg);
+ void resetVarsBat();
bool operator==(const ToolChain &) const override;
@@ -122,13 +119,6 @@ protected:
bool triggered() const;
};
- explicit MsvcToolChain(Core::Id typeId,
- const QString &name,
- const Abi &abi,
- const QString &varsBat,
- const QString &varsBatArg);
- explicit MsvcToolChain(Core::Id typeId);
-
static void inferWarningsForLevel(int warningLevel, WarningFlags &flags);
Utils::Environment readEnvironmentSetting(const Utils::Environment &env) const;
@@ -142,7 +132,7 @@ protected:
struct GenerateEnvResult
{
Utils::optional<QString> error;
- QList<Utils::EnvironmentItem> environmentItems;
+ Utils::EnvironmentItems environmentItems;
};
static void environmentModifications(QFutureInterface<GenerateEnvResult> &future,
QString vcvarsBat,
@@ -150,15 +140,15 @@ protected:
void initEnvModWatcher(const QFuture<GenerateEnvResult> &future);
protected:
- mutable QMutex *m_headerPathsMutex = nullptr;
+ mutable QMutex m_headerPathsMutex;
mutable HeaderPaths m_headerPaths;
private:
- void updateEnvironmentModifications(QList<Utils::EnvironmentItem> modifications);
+ void updateEnvironmentModifications(Utils::EnvironmentItems modifications);
void rescanForCompiler();
void detectInstalledAbis();
- mutable QList<Utils::EnvironmentItem> m_environmentModifications;
+ mutable Utils::EnvironmentItems m_environmentModifications;
mutable QFutureWatcher<GenerateEnvResult> m_envModWatcher;
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
@@ -177,11 +167,9 @@ protected:
class PROJECTEXPLORER_EXPORT ClangClToolChain : public MsvcToolChain
{
public:
- ClangClToolChain(const QString &name, const QString &llvmDir);
ClangClToolChain();
bool isValid() const override;
- QString typeDisplayName() const override;
QStringList suggestedMkspecList() const override;
void addToEnvironment(Utils::Environment &env) const override;
Utils::FilePath compilerCommand() const override;
@@ -189,13 +177,13 @@ public:
QVariantMap toMap() const override;
bool fromMap(const QVariantMap &data) override;
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(
+ const Utils::Environment &env) const override;
const QList<MsvcToolChain *> &msvcToolchains() const;
QString clangPath() const { return m_clangPath; }
void setClangPath(const QString &path) { m_clangPath = path; }
- void resetMsvcToolChain(const MsvcToolChain *base = nullptr);
Macros msvcPredefinedMacros(const QStringList &cxxflags,
const Utils::Environment &env) const override;
Utils::LanguageVersion msvcLanguageVersion(const QStringList &cxxflags,
@@ -222,7 +210,6 @@ public:
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown) override;
bool canCreate() const override;
- ToolChain *create() override;
static QString vcVarsBatFor(const QString &basePath,
MsvcToolChain::Platform platform,
@@ -239,7 +226,6 @@ public:
QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown) override;
bool canCreate() const override;
- ToolChain *create() override;
};
// --------------------------------------------------------------------------
diff --git a/src/plugins/projectexplorer/outputparser_test.cpp b/src/plugins/projectexplorer/outputparser_test.cpp
index 765a087650..17834ff5c8 100644
--- a/src/plugins/projectexplorer/outputparser_test.cpp
+++ b/src/plugins/projectexplorer/outputparser_test.cpp
@@ -137,7 +137,7 @@ void OutputParserTester::appendOutputParser(IOutputParser *parser)
void OutputParserTester::outputAdded(const QString &line, BuildStep::OutputFormat format)
{
- Q_UNUSED(format);
+ Q_UNUSED(format)
if (!m_receivedOutput.isEmpty())
m_receivedOutput.append('\n');
m_receivedOutput.append(line);
@@ -145,8 +145,8 @@ void OutputParserTester::outputAdded(const QString &line, BuildStep::OutputForma
void OutputParserTester::taskAdded(const Task &task, int linkedLines, int skipLines)
{
- Q_UNUSED(linkedLines);
- Q_UNUSED(skipLines);
+ Q_UNUSED(linkedLines)
+ Q_UNUSED(skipLines)
m_receivedTasks.append(task);
}
diff --git a/src/plugins/projectexplorer/panelswidget.cpp b/src/plugins/projectexplorer/panelswidget.cpp
index 882f4d0f44..6e2b50bfcd 100644
--- a/src/plugins/projectexplorer/panelswidget.cpp
+++ b/src/plugins/projectexplorer/panelswidget.cpp
@@ -64,7 +64,7 @@ public:
}
void paintEvent(QPaintEvent *e) override
{
- Q_UNUSED(e);
+ Q_UNUSED(e)
QPainter p(this);
QColor fillColor = creatorTheme()->color(Theme::PanelsWidgetSeparatorLineColor);
p.fillRect(contentsRect(), fillColor);
@@ -128,7 +128,7 @@ PanelsWidget::PanelsWidget(QWidget *parent) :
// The layout holding the individual panels:
auto topLayout = new QVBoxLayout(m_root);
- topLayout->setMargin(0);
+ topLayout->setContentsMargins(0, 0, 0, 0);
topLayout->setSpacing(0);
m_layout = new QGridLayout;
@@ -186,9 +186,9 @@ void PanelsWidget::addPropertiesPanel(const QString &displayName, const QIcon &i
QPalette palette = nameLabel->palette();
for (int i = QPalette::Active; i < QPalette::NColorGroups; ++i ) {
// FIXME: theming
- QColor foregroundColor = palette.color(QPalette::ColorGroup(i), QPalette::Foreground);
+ QColor foregroundColor = palette.color(QPalette::ColorGroup(i), QPalette::WindowText);
foregroundColor.setAlpha(110);
- palette.setBrush(QPalette::ColorGroup(i), QPalette::Foreground, foregroundColor);
+ palette.setBrush(QPalette::ColorGroup(i), QPalette::WindowText, foregroundColor);
}
nameLabel->setPalette(palette);
nameLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
diff --git a/src/plugins/projectexplorer/processparameters.cpp b/src/plugins/projectexplorer/processparameters.cpp
index f535cc120e..d8b91e49b9 100644
--- a/src/plugins/projectexplorer/processparameters.cpp
+++ b/src/plugins/projectexplorer/processparameters.cpp
@@ -54,34 +54,18 @@ ProcessParameters::ProcessParameters() :
{
}
-void ProcessParameters::setCommandLine(const CommandLine &cmdLine)
-{
- m_command = cmdLine.executable();
- m_arguments = cmdLine.arguments();
- m_effectiveCommand.clear();
- m_effectiveArguments.clear();
-}
-
/*!
- Sets the executable to run.
+ Sets the command to run.
*/
-
-void ProcessParameters::setCommand(const Utils::FilePath &cmd)
+void ProcessParameters::setCommandLine(const CommandLine &cmdLine)
{
- m_command = cmd;
+ m_command = cmdLine;
m_effectiveCommand.clear();
-}
-
-/*!
- Sets the command line arguments used by the process.
-*/
-
-void ProcessParameters::setArguments(const QString &arguments)
-{
- m_arguments = arguments;
m_effectiveArguments.clear();
+ resolveAll();
}
+
/*!
Sets the \a workingDirectory for the process for a build configuration.
@@ -132,7 +116,7 @@ FilePath ProcessParameters::effectiveWorkingDirectory() const
FilePath ProcessParameters::effectiveCommand() const
{
if (m_effectiveCommand.isEmpty()) {
- FilePath cmd = m_command;
+ FilePath cmd = m_command.executable();
if (m_macroExpander)
cmd = m_macroExpander->expand(cmd);
m_effectiveCommand =
@@ -158,7 +142,7 @@ bool ProcessParameters::commandMissing() const
QString ProcessParameters::effectiveArguments() const
{
if (m_effectiveArguments.isEmpty()) {
- m_effectiveArguments = m_arguments;
+ m_effectiveArguments = m_command.arguments();
if (m_macroExpander)
m_effectiveArguments = m_macroExpander->expand(m_effectiveArguments);
}
@@ -167,7 +151,7 @@ QString ProcessParameters::effectiveArguments() const
QString ProcessParameters::prettyCommand() const
{
- QString cmd = m_command.toString();
+ QString cmd = m_command.executable().toString();
if (m_macroExpander)
cmd = m_macroExpander->expand(cmd);
return Utils::FilePath::fromString(cmd).fileName();
diff --git a/src/plugins/projectexplorer/processparameters.h b/src/plugins/projectexplorer/processparameters.h
index c87ede7d5b..3742387d81 100644
--- a/src/plugins/projectexplorer/processparameters.h
+++ b/src/plugins/projectexplorer/processparameters.h
@@ -31,7 +31,6 @@
#include <utils/fileutils.h>
namespace Utils {
-class CommandLine;
class MacroExpander;
} // Utils
@@ -44,12 +43,7 @@ public:
ProcessParameters();
void setCommandLine(const Utils::CommandLine &cmdLine);
-
- void setCommand(const Utils::FilePath &cmd);
- Utils::FilePath command() const { return m_command; }
-
- void setArguments(const QString &arguments);
- QString arguments() const { return m_arguments; }
+ Utils::CommandLine command() const { return m_command; }
void setWorkingDirectory(const Utils::FilePath &workingDirectory);
Utils::FilePath workingDirectory() const { return m_workingDirectory; }
@@ -78,8 +72,7 @@ public:
void resolveAll();
private:
Utils::FilePath m_workingDirectory;
- Utils::FilePath m_command;
- QString m_arguments;
+ Utils::CommandLine m_command;
Utils::Environment m_environment;
Utils::MacroExpander *m_macroExpander;
diff --git a/src/plugins/projectexplorer/processstep.cpp b/src/plugins/projectexplorer/processstep.cpp
index 231cb831bb..89062879d3 100644
--- a/src/plugins/projectexplorer/processstep.cpp
+++ b/src/plugins/projectexplorer/processstep.cpp
@@ -33,19 +33,21 @@
#include <coreplugin/variablechooser.h>
+#include <utils/fileutils.h>
#include <utils/macroexpander.h>
#include <QFormLayout>
+using namespace Utils;
+
namespace ProjectExplorer {
-const char PROCESS_STEP_ID[] = "ProjectExplorer.ProcessStep";
const char PROCESS_COMMAND_KEY[] = "ProjectExplorer.ProcessStep.Command";
const char PROCESS_WORKINGDIRECTORY_KEY[] = "ProjectExplorer.ProcessStep.WorkingDirectory";
const char PROCESS_ARGUMENTS_KEY[] = "ProjectExplorer.ProcessStep.Arguments";
ProcessStep::ProcessStep(BuildStepList *bsl)
- : AbstractProcessStep(bsl, PROCESS_STEP_ID)
+ : AbstractProcessStep(bsl, Constants::PROCESS_STEP_ID)
{
//: Default ProcessStep display name
setDefaultDisplayName(tr("Custom Process Step"));
@@ -68,6 +70,17 @@ ProcessStep::ProcessStep(BuildStepList *bsl)
m_workingDirectory->setDisplayStyle(BaseStringAspect::PathChooserDisplay);
m_workingDirectory->setLabelText(tr("Working directory:"));
m_workingDirectory->setExpectedKind(Utils::PathChooser::Directory);
+
+ setSummaryUpdater([this] {
+ QString display = displayName();
+ if (display.isEmpty())
+ display = tr("Custom Process Step");
+ ProcessParameters param;
+ setupProcessParameters(&param);
+ return param.summary(display);
+ });
+
+ addMacroExpander();
}
bool ProcessStep::init()
@@ -81,8 +94,6 @@ void ProcessStep::setupProcessParameters(ProcessParameters *pp)
{
BuildConfiguration *bc = buildConfiguration();
- QString command = m_command->value();
- QString arguments = m_arguments->value();
QString workingDirectory = m_workingDirectory->value();
if (workingDirectory.isEmpty()) {
if (bc)
@@ -94,45 +105,17 @@ void ProcessStep::setupProcessParameters(ProcessParameters *pp)
pp->setMacroExpander(bc ? bc->macroExpander() : Utils::globalMacroExpander());
pp->setEnvironment(bc ? bc->environment() : Utils::Environment::systemEnvironment());
pp->setWorkingDirectory(Utils::FilePath::fromString(workingDirectory));
- pp->setCommand(Utils::FilePath::fromString(command));
- pp->setArguments(arguments);
+ pp->setCommandLine({m_command->filePath(), m_arguments->value(), CommandLine::Raw});
pp->resolveAll();
}
-BuildStepConfigWidget *ProcessStep::createConfigWidget()
-{
- auto widget = AbstractProcessStep::createConfigWidget();
-
- Core::VariableChooser::addSupportForChildWidgets(widget, macroExpander());
-
- auto updateDetails = [this, widget] {
- QString display = displayName();
- if (display.isEmpty())
- display = tr("Custom Process Step");
- ProcessParameters param;
- setupProcessParameters(&param);
- widget->setSummaryText(param.summary(display));
- };
-
- updateDetails();
-
- connect(m_command, &ProjectConfigurationAspect::changed,
- widget, updateDetails);
- connect(m_workingDirectory, &ProjectConfigurationAspect::changed,
- widget, updateDetails);
- connect(m_arguments, &ProjectConfigurationAspect::changed,
- widget, updateDetails);
-
- return widget;
-}
-
//*******
// ProcessStepFactory
//*******
ProcessStepFactory::ProcessStepFactory()
{
- registerStep<ProcessStep>(PROCESS_STEP_ID);
+ registerStep<ProcessStep>(Constants::PROCESS_STEP_ID);
setDisplayName(ProcessStep::tr("Custom Process Step", "item in combobox"));
}
diff --git a/src/plugins/projectexplorer/processstep.h b/src/plugins/projectexplorer/processstep.h
index 241d440ad2..4ef741588b 100644
--- a/src/plugins/projectexplorer/processstep.h
+++ b/src/plugins/projectexplorer/processstep.h
@@ -45,8 +45,6 @@ class PROJECTEXPLORER_EXPORT ProcessStep : public AbstractProcessStep
public:
explicit ProcessStep(BuildStepList *bsl);
- BuildStepConfigWidget *createConfigWidget() override;
-
private:
bool init() override;
void setupProcessParameters(ProcessParameters *pp);
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index d909c4b909..1d7cd11d9c 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -25,16 +25,19 @@
#include "project.h"
-#include "buildinfo.h"
#include "buildconfiguration.h"
+#include "buildinfo.h"
+#include "buildsystem.h"
#include "deployconfiguration.h"
#include "editorconfiguration.h"
#include "kit.h"
#include "makestep.h"
#include "projectexplorer.h"
#include "projectnodes.h"
-#include "target.h"
+#include "runconfiguration.h"
+#include "runcontrol.h"
#include "session.h"
+#include "target.h"
#include "userfileaccessor.h"
#include <coreplugin/idocument.h>
@@ -48,8 +51,10 @@
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projecttree.h>
-#include <utils/pointeralgorithm.h>
+#include <utils/algorithm.h>
+#include <utils/environment.h>
#include <utils/macroexpander.h>
+#include <utils/pointeralgorithm.h>
#include <utils/qtcassert.h>
#include <QFileDialog>
@@ -115,34 +120,50 @@ const Project::NodeMatcher Project::GeneratedFiles = [](const Node *node) {
// ProjectDocument:
// --------------------------------------------------------------------
-ProjectDocument::ProjectDocument(const QString &mimeType, const Utils::FilePath &fileName,
- const ProjectDocument::ProjectCallback &callback) :
- m_callback(callback)
+class ProjectDocument : public Core::IDocument
+{
+public:
+ ProjectDocument(const QString &mimeType, const Utils::FilePath &fileName, Project *project);
+
+ Core::IDocument::ReloadBehavior reloadBehavior(Core::IDocument::ChangeTrigger state,
+ Core::IDocument::ChangeType type) const final;
+ bool reload(QString *errorString,
+ Core::IDocument::ReloadFlag flag,
+ Core::IDocument::ChangeType type) final;
+
+private:
+ Project *m_project;
+};
+
+ProjectDocument::ProjectDocument(const QString &mimeType,
+ const Utils::FilePath &fileName,
+ Project *project)
+ : m_project(project)
{
+ QTC_CHECK(project);
+
setFilePath(fileName);
setMimeType(mimeType);
- if (m_callback)
- Core::DocumentManager::addDocument(this);
+ Core::DocumentManager::addDocument(this);
}
Core::IDocument::ReloadBehavior
ProjectDocument::reloadBehavior(Core::IDocument::ChangeTrigger state,
Core::IDocument::ChangeType type) const
{
- Q_UNUSED(state);
- Q_UNUSED(type);
+ Q_UNUSED(state)
+ Q_UNUSED(type)
return BehaviorSilent;
}
bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag flag,
Core::IDocument::ChangeType type)
{
- Q_UNUSED(errorString);
- Q_UNUSED(flag);
- Q_UNUSED(type);
+ Q_UNUSED(errorString)
+ Q_UNUSED(flag)
+ Q_UNUSED(type)
- if (m_callback)
- m_callback();
+ emit m_project->projectFileIsDirty(filePath());
return true;
}
@@ -152,19 +173,19 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f
class ProjectPrivate
{
public:
- ProjectPrivate(const QString &mimeType, const Utils::FilePath &fileName,
- const ProjectDocument::ProjectCallback &callback)
- {
- m_document = std::make_unique<ProjectDocument>(mimeType, fileName, callback);
- }
-
~ProjectPrivate();
Core::Id m_id;
bool m_isParsing = false;
bool m_hasParsingData = false;
bool m_needsInitialExpansion = false;
+ bool m_canBuildProducts = false;
+ bool m_knowsAllBuildExecutables = true;
+ bool m_hasMakeInstallEquivalent = false;
+ bool m_needsBuildConfigurations = true;
+ std::unique_ptr<BuildSystem> m_buildSystem;
std::unique_ptr<Core::IDocument> m_document;
+ std::vector<std::unique_ptr<Core::IDocument>> m_extraProjectDocuments;
std::unique_ptr<ProjectNode> m_rootProjectNode;
std::unique_ptr<ContainerNode> m_containerNode;
std::vector<std::unique_ptr<Target>> m_targets;
@@ -190,10 +211,12 @@ ProjectPrivate::~ProjectPrivate()
std::unique_ptr<ProjectNode> oldNode = std::move(m_rootProjectNode);
}
-Project::Project(const QString &mimeType, const Utils::FilePath &fileName,
- const ProjectDocument::ProjectCallback &callback) :
- d(new ProjectPrivate(mimeType, fileName, callback))
+Project::Project(const QString &mimeType,
+ const Utils::FilePath &fileName)
+ : d(new ProjectPrivate)
{
+ d->m_document = std::make_unique<ProjectDocument>(mimeType, fileName, this);
+
d->m_macroExpander.setDisplayName(tr("Project"));
d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"),
[this] { return displayName(); });
@@ -224,24 +247,23 @@ Core::Id Project::id() const
QString Project::mimeType() const
{
- return document()->mimeType();
+ return d->m_document->mimeType();
}
-Core::IDocument *Project::document() const
+bool Project::canBuildProducts() const
{
- QTC_CHECK(d->m_document);
- return d->m_document.get();
+ return d->m_canBuildProducts;
}
-Utils::FilePath Project::projectFilePath() const
+BuildSystem *Project::buildSystem() const
{
- QTC_ASSERT(document(), return Utils::FilePath());
- return document()->filePath();
+ return d->m_buildSystem.get();
}
-bool Project::hasActiveBuildSettings() const
+Utils::FilePath Project::projectFilePath() const
{
- return activeTarget() && BuildConfigurationFactory::find(activeTarget());
+ QTC_ASSERT(d->m_document, return Utils::FilePath());
+ return d->m_document->filePath();
}
void Project::addTarget(std::unique_ptr<Target> &&t)
@@ -251,15 +273,8 @@ void Project::addTarget(std::unique_ptr<Target> &&t)
QTC_ASSERT(!target(t->kit()), return);
Q_ASSERT(t->project() == this);
- t->setDefaultDisplayName(t->displayName());
-
// add it
d->m_targets.emplace_back(std::move(t));
- connect(pointer, &Target::addedProjectConfiguration, this, &Project::addedProjectConfiguration);
- connect(pointer, &Target::aboutToRemoveProjectConfiguration, this, &Project::aboutToRemoveProjectConfiguration);
- connect(pointer, &Target::removedProjectConfiguration, this, &Project::removedProjectConfiguration);
- connect(pointer, &Target::activeProjectConfigurationChanged, this, &Project::activeProjectConfigurationChanged);
- emit addedProjectConfiguration(pointer);
emit addedTarget(pointer);
// check activeTarget:
@@ -267,6 +282,27 @@ void Project::addTarget(std::unique_ptr<Target> &&t)
SessionManager::setActiveTarget(this, pointer, SetActive::Cascade);
}
+Target *Project::addTargetForDefaultKit()
+{
+ return addTargetForKit(KitManager::defaultKit());
+}
+
+Target *Project::addTargetForKit(Kit *kit)
+{
+ if (!kit || target(kit))
+ return nullptr;
+
+ auto t = std::make_unique<Target>(this, kit, Target::_constructor_tag{});
+ Target *pointer = t.get();
+
+ if (!setupTarget(pointer))
+ return {};
+
+ addTarget(std::move(t));
+
+ return pointer;
+}
+
bool Project::removeTarget(Target *target)
{
QTC_ASSERT(target && Utils::contains(d->m_targets, target), return false);
@@ -274,7 +310,6 @@ bool Project::removeTarget(Target *target)
if (BuildManager::isBuilding(target))
return false;
- emit aboutToRemoveProjectConfiguration(target);
emit aboutToRemoveTarget(target);
auto keep = Utils::take(d->m_targets, target);
if (target == d->m_activeTarget) {
@@ -282,7 +317,6 @@ bool Project::removeTarget(Target *target)
SessionManager::setActiveTarget(this, newActiveTarget, SetActive::Cascade);
}
emit removedTarget(target);
- emit removedProjectConfiguration(target);
return true;
}
@@ -306,8 +340,9 @@ void Project::setActiveTarget(Target *target)
if ((!target && d->m_targets.size() == 0) ||
(target && Utils::contains(d->m_targets, target))) {
d->m_activeTarget = target;
- emit activeProjectConfigurationChanged(d->m_activeTarget);
emit activeTargetChanged(d->m_activeTarget);
+ emit activeBuildConfigurationChanged(
+ d->m_activeTarget ? d->m_activeTarget->activeBuildConfiguration() : nullptr);
}
}
@@ -321,6 +356,26 @@ void Project::setNeedsInitialExpansion(bool needsExpansion)
d->m_needsInitialExpansion = needsExpansion;
}
+void Project::setExtraProjectFiles(const QVector<Utils::FilePath> &projectDocumentPaths)
+{
+ QSet<Utils::FilePath> uniqueNewFiles = Utils::toSet(projectDocumentPaths);
+ uniqueNewFiles.remove(projectFilePath()); // Make sure to never add the main project file!
+
+ QSet<Utils::FilePath> existingWatches = Utils::transform<QSet>(d->m_extraProjectDocuments,
+ &Core::IDocument::filePath);
+
+ QSet<Utils::FilePath> toAdd = uniqueNewFiles.subtract(existingWatches);
+ QSet<Utils::FilePath> toRemove = existingWatches.subtract(uniqueNewFiles);
+
+ Utils::erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<Core::IDocument> &d) {
+ return toRemove.contains(d->filePath());
+ });
+ for (const Utils::FilePath &p : toAdd) {
+ d->m_extraProjectDocuments.emplace_back(
+ std::make_unique<ProjectDocument>(d->m_document->mimeType(), p, this));
+ }
+}
+
Target *Project::target(Core::Id id) const
{
return Utils::findOrDefault(d->m_targets, Utils::equal(&Target::id, id));
@@ -339,17 +394,6 @@ Tasks Project::projectIssues(const Kit *k) const
return {};
}
-std::unique_ptr<Target> Project::createTarget(Kit *k)
-{
- if (!k || target(k))
- return nullptr;
-
- auto t = std::make_unique<Target>(this, k, Target::_constructor_tag{});
- if (!setupTarget(t.get()))
- return {};
- return t;
-}
-
bool Project::copySteps(Target *sourceTarget, Target *newTarget)
{
QTC_ASSERT(newTarget, return false);
@@ -539,28 +583,6 @@ void Project::handleSubTreeChanged(FolderNode *node)
emit fileListChanged();
}
-std::unique_ptr<Target> Project::restoreTarget(const QVariantMap &data)
-{
- Core::Id id = idFromMap(data);
- if (target(id)) {
- qWarning("Warning: Duplicated target id found, not restoring second target with id '%s'. Continuing.",
- qPrintable(id.toString()));
- return nullptr;
- }
-
- Kit *k = KitManager::kit(id);
- if (!k) {
- qWarning("Warning: No kit '%s' found. Continuing.", qPrintable(id.toString()));
- return nullptr;
- }
-
- auto t = std::make_unique<Target>(this, k, Target::_constructor_tag{});
- if (!t->fromMap(data))
- return {};
-
- return t;
-}
-
void Project::saveSettings()
{
emit aboutToSaveSettings();
@@ -572,12 +594,20 @@ void Project::saveSettings()
Project::RestoreResult Project::restoreSettings(QString *errorMessage)
{
+ BuildConfiguration *oldBc = activeTarget() ? activeTarget()->activeBuildConfiguration()
+ : nullptr;
+
if (!d->m_accessor)
d->m_accessor = std::make_unique<Internal::UserFileAccessor>(this);
QVariantMap map(d->m_accessor->restoreSettings(Core::ICore::mainWindow()));
RestoreResult result = fromMap(map, errorMessage);
if (result == RestoreResult::Ok)
emit settingsLoaded();
+
+ BuildConfiguration *bc = activeTarget() ? activeTarget()->activeBuildConfiguration() : nullptr;
+ if (bc != oldBc)
+ emit activeBuildConfigurationChanged(bc);
+
return result;
}
@@ -586,13 +616,15 @@ Project::RestoreResult Project::restoreSettings(QString *errorMessage)
*/
Utils::FilePathList Project::files(const Project::NodeMatcher &filter) const
{
+ QTC_ASSERT(filter, return {});
+
Utils::FilePathList result;
if (d->m_sortedNodeList.empty() && filter(containerNode()))
result.append(projectFilePath());
Utils::FilePath lastAdded;
for (const Node *n : qAsConst(d->m_sortedNodeList)) {
- if (filter && !filter(n))
+ if (!filter(n))
continue;
// Remove duplicates:
@@ -602,7 +634,7 @@ Utils::FilePathList Project::files(const Project::NodeMatcher &filter) const
lastAdded = path;
result.append(path);
- };
+ }
return result;
}
@@ -695,7 +727,7 @@ ContainerNode *Project::containerNode() const
Project::RestoreResult Project::fromMap(const QVariantMap &map, QString *errorMessage)
{
- Q_UNUSED(errorMessage);
+ Q_UNUSED(errorMessage)
if (map.contains(QLatin1String(EDITOR_SETTINGS_KEY))) {
QVariantMap values(map.value(QLatin1String(EDITOR_SETTINGS_KEY)).toMap());
d->m_editorConfiguration.fromMap(values);
@@ -733,10 +765,27 @@ void Project::createTargetFromMap(const QVariantMap &map, int index)
const QString key = QString::fromLatin1(TARGET_KEY_PREFIX) + QString::number(index);
if (!map.contains(key))
return;
- QVariantMap targetMap = map.value(key).toMap();
- std::unique_ptr<Target> t = restoreTarget(targetMap);
- if (!t || (t->runConfigurations().isEmpty() && t->buildConfigurations().isEmpty()))
+ const QVariantMap targetMap = map.value(key).toMap();
+
+ Core::Id id = idFromMap(targetMap);
+ if (target(id)) {
+ qWarning("Warning: Duplicated target id found, not restoring second target with id '%s'. Continuing.",
+ qPrintable(id.toString()));
+ return;
+ }
+
+ Kit *k = KitManager::kit(id);
+ if (!k) {
+ qWarning("Warning: No kit '%s' found. Continuing.", qPrintable(id.toString()));
+ return;
+ }
+
+ auto t = std::make_unique<Target>(this, k, Target::_constructor_tag{});
+ if (!t->fromMap(targetMap))
+ return;
+
+ if (t->runConfigurations().isEmpty() && t->buildConfigurations().isEmpty())
return;
addTarget(std::move(t));
@@ -749,7 +798,7 @@ EditorConfiguration *Project::editorConfiguration() const
QStringList Project::filesGeneratedFrom(const QString &file) const
{
- Q_UNUSED(file);
+ Q_UNUSED(file)
return QStringList();
}
@@ -796,15 +845,53 @@ void Project::setProjectLanguage(Core::Id id, bool enabled)
removeProjectLanguage(id);
}
+void Project::setHasMakeInstallEquivalent(bool enabled)
+{
+ d->m_hasMakeInstallEquivalent = enabled;
+}
+
void Project::projectLoaded()
{
}
+void Project::setKnowsAllBuildExecutables(bool value)
+{
+ d->m_knowsAllBuildExecutables = value;
+}
+
+void Project::setNeedsBuildConfigurations(bool value)
+{
+ d->m_needsBuildConfigurations = value;
+}
+
Task Project::createProjectTask(Task::TaskType type, const QString &description)
{
return Task(type, description, Utils::FilePath(), -1, Core::Id());
}
+Utils::Environment Project::activeParseEnvironment() const
+{
+ const Target *const t = activeTarget();
+ const BuildConfiguration *const bc = t ? t->activeBuildConfiguration() : nullptr;
+ if (bc)
+ return bc->environment();
+
+ const RunConfiguration *const rc = t ? t->activeRunConfiguration() : nullptr;
+ if (rc)
+ return rc->runnable().environment;
+
+ Utils::Environment result = Utils::Environment::systemEnvironment();
+ if (t)
+ t->kit()->addToEnvironment(result);
+ return result;
+}
+
+void Project::setBuildSystem(std::unique_ptr<BuildSystem> &&bs)
+{
+ QTC_ASSERT(!bs->parent(), bs->setParent(nullptr));
+ d->m_buildSystem = std::move(bs);
+}
+
Core::Context Project::projectContext() const
{
return Core::Context(d->m_id);
@@ -835,17 +922,21 @@ bool Project::needsConfiguration() const
bool Project::needsBuildConfigurations() const
{
- return true;
+ return d->m_needsBuildConfigurations;
}
-void Project::configureAsExampleProject(const QSet<Core::Id> &platforms)
+void Project::configureAsExampleProject()
{
- Q_UNUSED(platforms);
}
bool Project::knowsAllBuildExecutables() const
{
- return true;
+ return d->m_knowsAllBuildExecutables;
+}
+
+bool Project::hasMakeInstallEquivalent() const
+{
+ return d->m_hasMakeInstallEquivalent;
}
MakeInstallCommand Project::makeInstallCommand(const Target *target, const QString &installRoot)
@@ -855,7 +946,7 @@ MakeInstallCommand Project::makeInstallCommand(const Target *target, const QStri
if (const BuildConfiguration * const bc = target->activeBuildConfiguration()) {
if (const auto makeStep = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD)
->firstOfType<MakeStep>()) {
- cmd.command = makeStep->effectiveMakeCommand();
+ cmd.command = makeStep->effectiveMakeCommand().executable();
}
}
cmd.arguments << "install" << ("INSTALL_ROOT=" + QDir::toNativeSeparators(installRoot));
@@ -898,8 +989,8 @@ Utils::MacroExpander *Project::macroExpander() const
QVariant Project::additionalData(Core::Id id, const Target *target) const
{
- Q_UNUSED(id);
- Q_UNUSED(target);
+ Q_UNUSED(id)
+ Q_UNUSED(target)
return QVariant();
}
@@ -938,6 +1029,11 @@ void Project::setRequiredKitPredicate(const Kit::Predicate &predicate)
d->m_requiredKitPredicate = predicate;
}
+void Project::setCanBuildProducts()
+{
+ d->m_canBuildProducts = true;
+}
+
Kit::Predicate Project::preferredKitPredicate() const
{
return d->m_preferredKitPredicate;
@@ -984,15 +1080,6 @@ public:
setDisplayName(TEST_PROJECT_DISPLAYNAME);
}
- void testStartParsing()
- {
- emitParsingStarted();
- }
-
- void testParsingFinished(bool success) {
- emitParsingFinished(success);
- }
-
bool needsConfiguration() const final { return false; }
};
@@ -1007,10 +1094,6 @@ void ProjectExplorerPlugin::testProject_setup()
QVERIFY(project.macroExpander());
- QVERIFY(project.document());
- QCOMPARE(project.document()->filePath(), TEST_PROJECT_PATH);
- QCOMPARE(project.document()->mimeType(), TEST_PROJECT_MIMETYPE);
-
QCOMPARE(project.mimeType(), TEST_PROJECT_MIMETYPE);
QCOMPARE(project.projectFilePath(), TEST_PROJECT_PATH);
QCOMPARE(project.projectDirectory(), TEST_PROJECT_PATH.parentDir());
@@ -1051,14 +1134,17 @@ void ProjectExplorerPlugin::testProject_parsingSuccess()
QSignalSpy startSpy(&project, &Project::parsingStarted);
QSignalSpy stopSpy(&project, &Project::parsingFinished);
- project.testStartParsing();
- QCOMPARE(startSpy.count(), 1);
- QCOMPARE(stopSpy.count(), 0);
+ {
+ Project::ParseGuard guard = project.guardParsingRun();
+ QCOMPARE(startSpy.count(), 1);
+ QCOMPARE(stopSpy.count(), 0);
- QVERIFY(project.isParsing());
- QVERIFY(!project.hasParsingData());
+ QVERIFY(project.isParsing());
+ QVERIFY(!project.hasParsingData());
+
+ guard.markAsSuccess();
+ }
- project.testParsingFinished(true);
QCOMPARE(startSpy.count(), 1);
QCOMPARE(stopSpy.count(), 1);
QCOMPARE(stopSpy.at(0), {QVariant(true)});
@@ -1074,14 +1160,15 @@ void ProjectExplorerPlugin::testProject_parsingFail()
QSignalSpy startSpy(&project, &Project::parsingStarted);
QSignalSpy stopSpy(&project, &Project::parsingFinished);
- project.testStartParsing();
- QCOMPARE(startSpy.count(), 1);
- QCOMPARE(stopSpy.count(), 0);
+ {
+ Project::ParseGuard guard = project.guardParsingRun();
+ QCOMPARE(startSpy.count(), 1);
+ QCOMPARE(stopSpy.count(), 0);
- QVERIFY(project.isParsing());
- QVERIFY(!project.hasParsingData());
+ QVERIFY(project.isParsing());
+ QVERIFY(!project.hasParsingData());
+ }
- project.testParsingFinished(false);
QCOMPARE(startSpy.count(), 1);
QCOMPARE(stopSpy.count(), 1);
QCOMPARE(stopSpy.at(0), {QVariant(false)});
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index e66e049c0c..9c4f38fecb 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -42,11 +42,15 @@
#include <functional>
namespace Core { class Context; }
-namespace Utils { class MacroExpander; }
+namespace Utils {
+class Environment;
+class MacroExpander;
+}
namespace ProjectExplorer {
class BuildInfo;
+class BuildSystem;
class ContainerNode;
class EditorConfiguration;
class FolderNode;
@@ -58,24 +62,6 @@ class ProjectNode;
class ProjectPrivate;
class Target;
-// Auto-registers with the DocumentManager if a callback is set!
-class PROJECTEXPLORER_EXPORT ProjectDocument : public Core::IDocument
-{
-public:
- using ProjectCallback = std::function<void()>;
-
- ProjectDocument(const QString &mimeType, const Utils::FilePath &fileName,
- const ProjectCallback &callback = {});
-
- Core::IDocument::ReloadBehavior reloadBehavior(Core::IDocument::ChangeTrigger state,
- Core::IDocument::ChangeType type) const final;
- bool reload(QString *errorString, Core::IDocument::ReloadFlag flag,
- Core::IDocument::ChangeType type) final;
-
-private:
- ProjectCallback m_callback;
-};
-
// Documentation inside.
class PROJECTEXPLORER_EXPORT Project : public QObject
{
@@ -91,16 +77,17 @@ public:
isParsingRole
};
- Project(const QString &mimeType, const Utils::FilePath &fileName,
- const ProjectDocument::ProjectCallback &callback = {});
+ Project(const QString &mimeType, const Utils::FilePath &fileName);
~Project() override;
QString displayName() const;
Core::Id id() const;
QString mimeType() const;
+ bool canBuildProducts() const;
+
+ BuildSystem *buildSystem() const;
- Core::IDocument *document() const;
Utils::FilePath projectFilePath() const;
Utils::FilePath projectDirectory() const;
static Utils::FilePath projectDirectory(const Utils::FilePath &top);
@@ -112,13 +99,12 @@ public:
virtual ProjectNode *rootProjectNode() const;
ContainerNode *containerNode() const;
- bool hasActiveBuildSettings() const;
-
// EditorConfiguration:
EditorConfiguration *editorConfiguration() const;
// Target:
- void addTarget(std::unique_ptr<Target> &&target);
+ Target *addTargetForDefaultKit();
+ Target *addTargetForKit(Kit *kit);
bool removeTarget(Target *target);
QList<Target *> targets() const;
@@ -128,9 +114,7 @@ public:
Target *target(Kit *k) const;
virtual Tasks projectIssues(const Kit *k) const;
- std::unique_ptr<Target> createTarget(Kit *k);
static bool copySteps(Target *sourceTarget, Target *newTarget);
- std::unique_ptr<Target> restoreTarget(const QVariantMap &data);
void saveSettings();
enum class RestoreResult { Ok, Error, UserAbort };
@@ -154,8 +138,8 @@ public:
void setNamedSettings(const QString &name, const QVariant &value);
virtual bool needsConfiguration() const;
- virtual bool needsBuildConfigurations() const;
- virtual void configureAsExampleProject(const QSet<Core::Id> &platforms);
+ bool needsBuildConfigurations() const;
+ virtual void configureAsExampleProject();
virtual ProjectImporter *projectImporter() const;
@@ -164,10 +148,10 @@ public:
// The build system is able to report all executables that can be built, independent
// of configuration.
- virtual bool knowsAllBuildExecutables() const;
+ bool knowsAllBuildExecutables() const;
virtual DeploymentKnowledge deploymentKnowledge() const { return DeploymentKnowledge::Bad; }
- virtual bool hasMakeInstallEquivalent() const { return false; }
+ bool hasMakeInstallEquivalent() const;
virtual MakeInstallCommand makeInstallCommand(const Target *target, const QString &installRoot);
void setup(const QList<BuildInfo> &infoList);
@@ -201,21 +185,77 @@ public:
bool needsInitialExpansion() const;
void setNeedsInitialExpansion(bool needsInitialExpansion);
+ class ParseGuard
+ {
+ public:
+ ParseGuard()
+ : ParseGuard(nullptr)
+ {}
+
+ ~ParseGuard()
+ {
+ if (m_project)
+ m_project->emitParsingFinished(m_success);
+ }
+
+ void markAsSuccess() const { m_success = true; }
+ bool isSuccess() const { return m_success; }
+ bool isNull() const { return !m_project; }
+
+ ParseGuard(const ParseGuard &other) = delete;
+ ParseGuard &operator=(const ParseGuard &other) = delete;
+ ParseGuard(ParseGuard &&other)
+ {
+ std::swap(m_project, other.m_project);
+ std::swap(m_success, other.m_success);
+ }
+ ParseGuard &operator=(ParseGuard &&other)
+ {
+ std::swap(m_project, other.m_project);
+ std::swap(m_success, other.m_success);
+ return *this;
+ }
+
+ private:
+ ParseGuard(Project *p)
+ : m_project(p)
+ {
+ if (m_project)
+ m_project->emitParsingStarted();
+ }
+
+ Project *m_project = nullptr;
+ mutable bool m_success = false;
+
+ friend class Project;
+ };
+
+ // FIXME: Make this private and the BuildSystem a friend
+ ParseGuard guardParsingRun() { return ParseGuard(this); }
+ void setRootProjectNode(std::unique_ptr<ProjectNode> &&root);
+
+ // Set project files that will be watched and trigger the same callback
+ // as the main project file.
+ void setExtraProjectFiles(const QVector<Utils::FilePath> &projectDocumentPaths);
+
+ Utils::Environment activeParseEnvironment() const;
+
signals:
+ void projectFileIsDirty(const Utils::FilePath &path);
+
void displayNameChanged();
void fileListChanged();
// Note: activeTarget can be 0 (if no targets are defined).
void activeTargetChanged(ProjectExplorer::Target *target);
- void aboutToRemoveProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
void addedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
- // *ANY* active project configuration changed somewhere in the tree. This might not be
+ // *ANY* active build configuration changed somewhere in the tree. This might not be
// the one that would get started right now, since some part of the tree in between might
// not be active.
- void activeProjectConfigurationChanged(ProjectExplorer::ProjectConfiguration *pc);
+ void activeBuildConfigurationChanged(ProjectExplorer::ProjectConfiguration *bc);
void aboutToRemoveTarget(ProjectExplorer::Target *target);
void removedTarget(ProjectExplorer::Target *target);
@@ -236,12 +276,6 @@ protected:
void createTargetFromMap(const QVariantMap &map, int index);
virtual bool setupTarget(Target *t);
- // Helper methods to manage parsing state and signalling
- // Call in GUI thread before the actual parsing starts
- void emitParsingStarted();
- // Call in GUI thread right after the actual parsing is done
- void emitParsingFinished(bool success);
-
void setDisplayName(const QString &name);
// Used to pre-check kits in the TargetSetupPage. RequiredKitPredicate
// is used to select kits available in the TargetSetupPage
@@ -249,20 +283,36 @@ protected:
// The predicate used to select kits available in TargetSetupPage.
void setRequiredKitPredicate(const Kit::Predicate &predicate);
+ void setCanBuildProducts();
+
void setId(Core::Id id);
- void setRootProjectNode(std::unique_ptr<ProjectNode> &&root); // takes ownership!
void setProjectLanguages(Core::Context language);
void addProjectLanguage(Core::Id id);
void removeProjectLanguage(Core::Id id);
void setProjectLanguage(Core::Id id, bool enabled);
+ void setHasMakeInstallEquivalent(bool enabled);
virtual void projectLoaded(); // Called when the project is fully loaded.
+ void setKnowsAllBuildExecutables(bool value);
+ void setNeedsBuildConfigurations(bool value);
+
static ProjectExplorer::Task createProjectTask(ProjectExplorer::Task::TaskType type,
const QString &description);
+ void setBuildSystem(std::unique_ptr<BuildSystem> &&bs); // takes ownership!
+
private:
+ // Helper methods to manage parsing state and signalling
+ // Call in GUI thread before the actual parsing starts
+ void emitParsingStarted();
+ // Call in GUI thread right after the actual parsing is done
+ void emitParsingFinished(bool success);
+
+ void addTarget(std::unique_ptr<Target> &&target);
+
void handleSubTreeChanged(FolderNode *node);
void setActiveTarget(Target *target);
+
ProjectPrivate *d;
friend class ContainerNode;
diff --git a/src/plugins/projectexplorer/projectconfiguration.cpp b/src/plugins/projectexplorer/projectconfiguration.cpp
index 3d05c9ff87..5ad0299034 100644
--- a/src/plugins/projectexplorer/projectconfiguration.cpp
+++ b/src/plugins/projectexplorer/projectconfiguration.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "projectconfiguration.h"
+#include "target.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -32,7 +33,6 @@ using namespace ProjectExplorer;
const char CONFIGURATION_ID_KEY[] = "ProjectExplorer.ProjectConfiguration.Id";
const char DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DisplayName";
-const char DEFAULT_DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DefaultDisplayName";
// ProjectConfigurationAspect
@@ -82,14 +82,28 @@ void ProjectConfigurationAspects::toMap(QVariantMap &map) const
// ProjectConfiguration
ProjectConfiguration::ProjectConfiguration(QObject *parent, Core::Id id)
- : QObject(parent), m_id(id)
+ : QObject(parent)
+ , m_id(id)
{
+ QTC_CHECK(parent);
QTC_CHECK(id.isValid());
setObjectName(id.toString());
+
+ for (QObject *obj = this; obj; obj = obj->parent()) {
+ m_target = qobject_cast<Target *>(obj);
+ if (m_target)
+ break;
+ }
+ QTC_CHECK(m_target);
}
ProjectConfiguration::~ProjectConfiguration() = default;
+Project *ProjectConfiguration::project() const
+{
+ return m_target->project();
+}
+
Core::Id ProjectConfiguration::id() const
{
return m_id;
@@ -100,31 +114,15 @@ QString ProjectConfiguration::settingsIdKey()
return QString(CONFIGURATION_ID_KEY);
}
-QString ProjectConfiguration::displayName() const
-{
- if (!m_displayName.isEmpty())
- return m_displayName;
- return m_defaultDisplayName;
-}
-
void ProjectConfiguration::setDisplayName(const QString &name)
{
- if (displayName() == name)
- return;
- if (name == m_defaultDisplayName)
- m_displayName.clear();
- else
- m_displayName = name;
- emit displayNameChanged();
+ if (m_displayName.setValue(name))
+ emit displayNameChanged();
}
void ProjectConfiguration::setDefaultDisplayName(const QString &name)
{
- if (m_defaultDisplayName == name)
- return;
- const QString originalName = displayName();
- m_defaultDisplayName = name;
- if (originalName != displayName())
+ if (m_displayName.setDefaultValue(name))
emit displayNameChanged();
}
@@ -141,24 +139,21 @@ QString ProjectConfiguration::toolTip() const
return m_toolTip;
}
-bool ProjectConfiguration::usesDefaultDisplayName() const
-{
- return m_displayName.isEmpty();
-}
-
QVariantMap ProjectConfiguration::toMap() const
{
QTC_CHECK(m_id.isValid());
QVariantMap map;
map.insert(QLatin1String(CONFIGURATION_ID_KEY), m_id.toSetting());
- map.insert(QLatin1String(DISPLAY_NAME_KEY), m_displayName);
- map.insert(QLatin1String(DEFAULT_DISPLAY_NAME_KEY), m_defaultDisplayName);
-
+ m_displayName.toMap(map, DISPLAY_NAME_KEY);
m_aspects.toMap(map);
-
return map;
}
+Target *ProjectConfiguration::target() const
+{
+ return m_target;
+}
+
bool ProjectConfiguration::fromMap(const QVariantMap &map)
{
Core::Id id = Core::Id::fromSetting(map.value(QLatin1String(CONFIGURATION_ID_KEY)));
@@ -166,13 +161,8 @@ bool ProjectConfiguration::fromMap(const QVariantMap &map)
// mangle in their build keys.
QTC_ASSERT(id.toString().startsWith(m_id.toString()), return false);
- m_displayName = map.value(QLatin1String(DISPLAY_NAME_KEY), QString()).toString();
- m_defaultDisplayName = map.value(QLatin1String(DEFAULT_DISPLAY_NAME_KEY),
- m_defaultDisplayName.isEmpty() ?
- m_displayName : m_defaultDisplayName).toString();
-
+ m_displayName.fromMap(map, DISPLAY_NAME_KEY);
m_aspects.fromMap(map);
-
return true;
}
diff --git a/src/plugins/projectexplorer/projectconfiguration.h b/src/plugins/projectexplorer/projectconfiguration.h
index 2d5be2299d..4f7a219455 100644
--- a/src/plugins/projectexplorer/projectconfiguration.h
+++ b/src/plugins/projectexplorer/projectconfiguration.h
@@ -28,6 +28,7 @@
#include "projectexplorer_export.h"
#include <coreplugin/id.h>
+#include <utils/displayname.h>
#include <utils/macroexpander.h>
#include <QObject>
@@ -42,6 +43,7 @@ namespace ProjectExplorer {
class Project;
class ProjectConfigurationAspects;
+class Target;
class PROJECTEXPLORER_EXPORT ProjectConfigurationAspect : public QObject
{
@@ -135,9 +137,8 @@ public:
Core::Id id() const;
- QString displayName() const;
-
- bool usesDefaultDisplayName() const;
+ QString displayName() const { return m_displayName.value(); }
+ bool usesDefaultDisplayName() const { return m_displayName.usesDefaultValue(); }
void setDisplayName(const QString &name);
void setDefaultDisplayName(const QString &name);
@@ -153,7 +154,8 @@ public:
Utils::MacroExpander *macroExpander() { return &m_macroExpander; }
const Utils::MacroExpander *macroExpander() const { return &m_macroExpander; }
- virtual Project *project() const = 0;
+ Target *target() const;
+ Project *project() const;
virtual bool isActive() const = 0;
@@ -180,9 +182,9 @@ protected:
ProjectConfigurationAspects m_aspects;
private:
+ Target *m_target = nullptr;
const Core::Id m_id;
- QString m_displayName;
- QString m_defaultDisplayName;
+ Utils::DisplayName m_displayName;
QString m_toolTip;
Utils::MacroExpander m_macroExpander;
};
diff --git a/src/plugins/projectexplorer/projectconfigurationaspects.cpp b/src/plugins/projectexplorer/projectconfigurationaspects.cpp
index a4cec91d28..692c5d77b9 100644
--- a/src/plugins/projectexplorer/projectconfigurationaspects.cpp
+++ b/src/plugins/projectexplorer/projectconfigurationaspects.cpp
@@ -44,6 +44,8 @@
#include <QSpinBox>
#include <QToolButton>
#include <QTextEdit>
+#include <QRadioButton>
+#include <QButtonGroup>
using namespace Utils;
@@ -60,6 +62,17 @@ public:
QPointer<QCheckBox> m_checkBox; // Owned by configuration widget
};
+class BaseSelectionAspectPrivate
+{
+public:
+ int m_value = 0;
+ int m_defaultValue = 0;
+ struct Option { QString displayName; QString tooltip; };
+ QVector<Option> m_options;
+ QList<QPointer<QRadioButton>> m_buttons; // Owned by configuration widget
+ QPointer<QButtonGroup> m_buttonGroup;
+};
+
class BaseStringAspectPrivate
{
public:
@@ -80,6 +93,8 @@ public:
QPointer<QTextEdit> m_textEditDisplay;
QPixmap m_labelPixmap;
Utils::FilePath m_baseFileName;
+ bool m_readOnly = false;
+ bool m_showToolTipOnLabel = false;
};
class BaseIntegerAspectPrivate
@@ -138,12 +153,12 @@ void BaseStringAspect::toMap(QVariantMap &map) const
d->m_checker->toMap(map);
}
-FilePath BaseStringAspect::fileName() const
+FilePath BaseStringAspect::filePath() const
{
return FilePath::fromString(d->m_value);
}
-void BaseStringAspect::setFileName(const FilePath &val)
+void BaseStringAspect::setFilePath(const FilePath &val)
{
setValue(val.toString());
}
@@ -162,6 +177,12 @@ void BaseStringAspect::setLabelPixmap(const QPixmap &labelPixmap)
d->m_label->setPixmap(labelPixmap);
}
+void BaseStringAspect::setShowToolTipOnLabel(bool show)
+{
+ d->m_showToolTipOnLabel = show;
+ update();
+}
+
QString BaseStringAspect::labelText() const
{
return d->m_labelText;
@@ -221,6 +242,17 @@ void BaseStringAspect::setBaseFileName(const FilePath &baseFileName)
d->m_pathChooserDisplay->setBaseFileName(baseFileName);
}
+void BaseStringAspect::setReadOnly(bool readOnly)
+{
+ d->m_readOnly = readOnly;
+ if (d->m_pathChooserDisplay)
+ d->m_pathChooserDisplay->setReadOnly(readOnly);
+ if (d->m_lineEditDisplay)
+ d->m_lineEditDisplay->setReadOnly(readOnly);
+ if (d->m_textEditDisplay)
+ d->m_textEditDisplay->setReadOnly(readOnly);
+}
+
void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
{
QTC_CHECK(!d->m_label);
@@ -240,6 +272,7 @@ void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
d->m_pathChooserDisplay->setHistoryCompleter(d->m_historyCompleterKey);
d->m_pathChooserDisplay->setEnvironment(d->m_environment);
d->m_pathChooserDisplay->setBaseFileName(d->m_baseFileName);
+ d->m_pathChooserDisplay->setReadOnly(d->m_readOnly);
connect(d->m_pathChooserDisplay, &PathChooser::pathChanged,
this, &BaseStringAspect::setValue);
hbox->addWidget(d->m_pathChooserDisplay);
@@ -249,6 +282,7 @@ void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
d->m_lineEditDisplay->setPlaceholderText(d->m_placeHolderText);
if (!d->m_historyCompleterKey.isEmpty())
d->m_lineEditDisplay->setHistoryCompleter(d->m_historyCompleterKey);
+ d->m_lineEditDisplay->setReadOnly(d->m_readOnly);
connect(d->m_lineEditDisplay, &FancyLineEdit::textEdited,
this, &BaseStringAspect::setValue);
hbox->addWidget(d->m_lineEditDisplay);
@@ -256,6 +290,7 @@ void BaseStringAspect::addToConfigurationLayout(QFormLayout *layout)
case TextEditDisplay:
d->m_textEditDisplay = new QTextEdit(parent);
d->m_textEditDisplay->setPlaceholderText(d->m_placeHolderText);
+ d->m_textEditDisplay->setReadOnly(d->m_readOnly);
connect(d->m_textEditDisplay, &QTextEdit::textChanged, this, [this] {
const QString value = d->m_textEditDisplay->document()->toPlainText();
if (value != d->m_value) {
@@ -306,8 +341,10 @@ void BaseStringAspect::update()
d->m_textEditDisplay->setEnabled(enabled);
}
- if (d->m_labelDisplay)
+ if (d->m_labelDisplay) {
d->m_labelDisplay->setText(displayedString);
+ d->m_labelDisplay->setToolTip(d->m_showToolTipOnLabel ? displayedString : QString());
+ }
if (d->m_label) {
d->m_label->setText(d->m_labelText);
@@ -398,6 +435,75 @@ void BaseBoolAspect::setToolTip(const QString &tooltip)
}
/*!
+ \class ProjectExplorer::BaseSelectionAspect
+*/
+
+BaseSelectionAspect::BaseSelectionAspect()
+ : d(new Internal::BaseSelectionAspectPrivate)
+{}
+
+BaseSelectionAspect::~BaseSelectionAspect() = default;
+
+void BaseSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
+{
+ QTC_CHECK(d->m_buttonGroup == nullptr);
+ d->m_buttonGroup = new QButtonGroup;
+ d->m_buttonGroup->setExclusive(true);
+
+ QTC_ASSERT(d->m_buttons.isEmpty(), d->m_buttons.clear());
+ for (int i = 0, n = d->m_options.size(); i < n; ++i) {
+ const Internal::BaseSelectionAspectPrivate::Option &option = d->m_options.at(i);
+ auto button = new QRadioButton(option.displayName, layout->parentWidget());
+ button->setChecked(i == d->m_value);
+ button->setToolTip(option.tooltip);
+ layout->addRow(QString(), button);
+ d->m_buttons.append(button);
+ d->m_buttonGroup->addButton(button);
+ connect(button, &QAbstractButton::clicked, this, [this, i] {
+ d->m_value = i;
+ emit changed();
+ });
+ }
+}
+
+void BaseSelectionAspect::fromMap(const QVariantMap &map)
+{
+ d->m_value = map.value(settingsKey(), d->m_defaultValue).toInt();
+}
+
+void BaseSelectionAspect::toMap(QVariantMap &data) const
+{
+ data.insert(settingsKey(), d->m_value);
+}
+
+int BaseSelectionAspect::defaultValue() const
+{
+ return d->m_defaultValue;
+}
+
+void BaseSelectionAspect::setDefaultValue(int defaultValue)
+{
+ d->m_defaultValue = defaultValue;
+}
+
+int BaseSelectionAspect::value() const
+{
+ return d->m_value;
+}
+
+void BaseSelectionAspect::setValue(int value)
+{
+ d->m_value = value;
+ if (d->m_buttonGroup && 0 <= value && value < d->m_buttons.size())
+ d->m_buttons.at(value)->setChecked(true);
+}
+
+void BaseSelectionAspect::addOption(const QString &displayName, const QString &toolTip)
+{
+ d->m_options.append({displayName, toolTip});
+}
+
+/*!
\class ProjectExplorer::BaseIntegerAspect
*/
diff --git a/src/plugins/projectexplorer/projectconfigurationaspects.h b/src/plugins/projectexplorer/projectconfigurationaspects.h
index 250482b44e..3195ad63fc 100644
--- a/src/plugins/projectexplorer/projectconfigurationaspects.h
+++ b/src/plugins/projectexplorer/projectconfigurationaspects.h
@@ -39,6 +39,7 @@ namespace Internal {
class BaseBoolAspectPrivate;
class BaseStringAspectPrivate;
class BaseIntegerAspectPrivate;
+class BaseSelectionAspectPrivate;
} // Internal
class PROJECTEXPLORER_EXPORT BaseBoolAspect : public ProjectConfigurationAspect
@@ -67,6 +68,31 @@ private:
std::unique_ptr<Internal::BaseBoolAspectPrivate> d;
};
+class PROJECTEXPLORER_EXPORT BaseSelectionAspect : public ProjectConfigurationAspect
+{
+ Q_OBJECT
+
+public:
+ BaseSelectionAspect();
+ ~BaseSelectionAspect() override;
+
+ void addToConfigurationLayout(QFormLayout *layout) override;
+
+ int value() const;
+ void setValue(int val);
+
+ int defaultValue() const;
+ void setDefaultValue(int defaultValue);
+
+ void addOption(const QString &displayName, const QString &toolTip = {});
+
+ void fromMap(const QVariantMap &map) override;
+ void toMap(QVariantMap &map) const override;
+
+private:
+ std::unique_ptr<Internal::BaseSelectionAspectPrivate> d;
+};
+
class PROJECTEXPLORER_EXPORT BaseStringAspect : public ProjectConfigurationAspect
{
Q_OBJECT
@@ -83,6 +109,7 @@ public:
QString labelText() const;
void setLabelText(const QString &labelText);
void setLabelPixmap(const QPixmap &labelPixmap);
+ void setShowToolTipOnLabel(bool show);
void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter);
void setPlaceHolderText(const QString &placeHolderText);
@@ -90,6 +117,7 @@ public:
void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
void setEnvironment(const Utils::Environment &env);
void setBaseFileName(const Utils::FilePath &baseFileName);
+ void setReadOnly(bool readOnly);
bool isChecked() const;
void makeCheckable(const QString &optionalLabel, const QString &optionalBaseKey);
@@ -105,8 +133,8 @@ public:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
- Utils::FilePath fileName() const;
- void setFileName(const Utils::FilePath &val);
+ Utils::FilePath filePath() const;
+ void setFilePath(const Utils::FilePath &val);
private:
void update();
diff --git a/src/plugins/projectexplorer/projectconfigurationmodel.cpp b/src/plugins/projectexplorer/projectconfigurationmodel.cpp
index 111d5a0745..edd87babe0 100644
--- a/src/plugins/projectexplorer/projectconfigurationmodel.cpp
+++ b/src/plugins/projectexplorer/projectconfigurationmodel.cpp
@@ -34,46 +34,24 @@
#include <utils/algorithm.h>
#include <utils/stringutils.h>
-using namespace ProjectExplorer;
-
/*!
- \class ProjectExplorer::BuildConfigurationModel
- \brief The BuildConfigurationModel class is a model to represent the build
- configurations of a target.
+ \class ProjectExplorer::ProjectConfigurationModel
+ \brief The ProjectConfigurationModel class is a model to represent the build,
+ deploy and run configurations of a target.
To be used in the dropdown lists of comboboxes.
- Automatically adjusts itself to added and removed BuildConfigurations.
- Very similar to the Run Configuration Model.
-
- TODO might it possible to share code without making the code a complete mess.
*/
-namespace {
-
-const auto ComparisonOperator =
- [](const ProjectConfiguration *a, const ProjectConfiguration *b) {
- return Utils::caseFriendlyCompare(a->displayName(), b->displayName()) < 0;
- };
-
-} // namespace
+namespace ProjectExplorer {
-ProjectConfigurationModel::ProjectConfigurationModel(Target *target, FilterFunction filter,
- QObject *parent) :
- QAbstractListModel(parent),
- m_target(target),
- m_filter(filter)
+static bool isOrderedBefore(const ProjectConfiguration *a, const ProjectConfiguration *b)
{
- m_projectConfigurations = Utils::filtered(m_target->projectConfigurations(), m_filter);
- Utils::sort(m_projectConfigurations, ComparisonOperator);
-
- connect(target, &Target::addedProjectConfiguration,
- this, &ProjectConfigurationModel::addedProjectConfiguration);
- connect(target, &Target::removedProjectConfiguration,
- this, &ProjectConfigurationModel::removedProjectConfiguration);
+ return Utils::caseFriendlyCompare(a->displayName(), b->displayName()) < 0;
+}
- foreach (ProjectConfiguration *pc, m_projectConfigurations)
- connect(pc, &ProjectConfiguration::displayNameChanged,
- this, &ProjectConfigurationModel::displayNameChanged);
+ProjectConfigurationModel::ProjectConfigurationModel(Target *target) :
+ m_target(target)
+{
}
int ProjectConfigurationModel::rowCount(const QModelIndex &parent) const
@@ -97,10 +75,10 @@ void ProjectConfigurationModel::displayNameChanged()
if (oldPos < 0)
return;
- if (oldPos >= 1 && ComparisonOperator(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(oldPos - 1))) {
+ if (oldPos >= 1 && isOrderedBefore(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(oldPos - 1))) {
// We need to move up
int newPos = oldPos - 1;
- while (newPos >= 0 && ComparisonOperator(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(newPos))) {
+ while (newPos >= 0 && isOrderedBefore(m_projectConfigurations.at(oldPos), m_projectConfigurations.at(newPos))) {
--newPos;
}
++newPos;
@@ -112,11 +90,11 @@ void ProjectConfigurationModel::displayNameChanged()
// Not only did we move, we also changed...
emit dataChanged(index(newPos, 0), index(newPos,0));
} else if (oldPos < m_projectConfigurations.size() - 1
- && ComparisonOperator(m_projectConfigurations.at(oldPos + 1), m_projectConfigurations.at(oldPos))) {
+ && isOrderedBefore(m_projectConfigurations.at(oldPos + 1), m_projectConfigurations.at(oldPos))) {
// We need to move down
int newPos = oldPos + 1;
while (newPos < m_projectConfigurations.size()
- && ComparisonOperator(m_projectConfigurations.at(newPos), m_projectConfigurations.at(oldPos))) {
+ && isOrderedBefore(m_projectConfigurations.at(newPos), m_projectConfigurations.at(oldPos))) {
++newPos;
}
beginMoveRows(QModelIndex(), oldPos, oldPos, QModelIndex(), newPos);
@@ -142,37 +120,24 @@ QVariant ProjectConfigurationModel::data(const QModelIndex &index, int role) con
return QVariant();
}
-ProjectConfiguration *ProjectConfigurationModel::projectConfigurationAt(int i)
+ProjectConfiguration *ProjectConfigurationModel::projectConfigurationAt(int i) const
{
if (i > m_projectConfigurations.size() || i < 0)
return nullptr;
return m_projectConfigurations.at(i);
}
-ProjectConfiguration *ProjectConfigurationModel::projectConfigurationFor(const QModelIndex &idx)
+int ProjectConfigurationModel::indexFor(ProjectConfiguration *pc) const
{
- if (idx.row() > m_projectConfigurations.size() || idx.row() < 0)
- return nullptr;
- return m_projectConfigurations.at(idx.row());
-}
-
-QModelIndex ProjectConfigurationModel::indexFor(ProjectConfiguration *pc)
-{
- int idx = m_projectConfigurations.indexOf(pc);
- if (idx == -1)
- return QModelIndex();
- return index(idx, 0);
+ return m_projectConfigurations.indexOf(pc);
}
-void ProjectConfigurationModel::addedProjectConfiguration(ProjectConfiguration *pc)
+void ProjectConfigurationModel::addProjectConfiguration(ProjectConfiguration *pc)
{
- if (!m_filter(pc))
- return;
-
// Find the right place to insert
int i = 0;
for (; i < m_projectConfigurations.size(); ++i) {
- if (ComparisonOperator(pc, m_projectConfigurations.at(i)))
+ if (isOrderedBefore(pc, m_projectConfigurations.at(i)))
break;
}
@@ -184,7 +149,7 @@ void ProjectConfigurationModel::addedProjectConfiguration(ProjectConfiguration *
this, &ProjectConfigurationModel::displayNameChanged);
}
-void ProjectConfigurationModel::removedProjectConfiguration(ProjectConfiguration *pc)
+void ProjectConfigurationModel::removeProjectConfiguration(ProjectConfiguration *pc)
{
int i = m_projectConfigurations.indexOf(pc);
if (i < 0)
@@ -194,26 +159,4 @@ void ProjectConfigurationModel::removedProjectConfiguration(ProjectConfiguration
endRemoveRows();
}
-BuildConfigurationModel::BuildConfigurationModel(Target *t, QObject *parent) :
- ProjectConfigurationModel(t,
- [](const ProjectConfiguration *pc) {
- return qobject_cast<const BuildConfiguration *>(pc) != nullptr;
- },
- parent)
-{ }
-
-DeployConfigurationModel::DeployConfigurationModel(Target *t, QObject *parent) :
- ProjectConfigurationModel(t,
- [](const ProjectConfiguration *pc) {
- return qobject_cast<const DeployConfiguration *>(pc) != nullptr;
- },
- parent)
-{ }
-
-RunConfigurationModel::RunConfigurationModel(Target *t, QObject *parent) :
- ProjectConfigurationModel(t,
- [](const ProjectConfiguration *pc) {
- return qobject_cast<const RunConfiguration *>(pc) != nullptr;
- },
- parent)
-{ }
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectconfigurationmodel.h b/src/plugins/projectexplorer/projectconfigurationmodel.h
index adc1a00402..d3d68b3bfb 100644
--- a/src/plugins/projectexplorer/projectconfigurationmodel.h
+++ b/src/plugins/projectexplorer/projectconfigurationmodel.h
@@ -37,46 +37,25 @@ class ProjectConfiguration;
class ProjectConfigurationModel : public QAbstractListModel
{
Q_OBJECT
-public:
- using FilterFunction = std::function<bool(const ProjectConfiguration *)>;
- explicit ProjectConfigurationModel(Target *target, FilterFunction filter,
- QObject *parent = nullptr);
+public:
+ explicit ProjectConfigurationModel(Target *target);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- ProjectConfiguration *projectConfigurationAt(int i);
- ProjectConfiguration *projectConfigurationFor(const QModelIndex &idx);
- QModelIndex indexFor(ProjectConfiguration *pc);
+ ProjectConfiguration *projectConfigurationAt(int i) const;
+ int indexFor(ProjectConfiguration *pc) const;
+
+ void addProjectConfiguration(ProjectConfiguration *pc);
+ void removeProjectConfiguration(ProjectConfiguration *pc);
private:
- void addedProjectConfiguration(ProjectConfiguration *pc);
- void removedProjectConfiguration(ProjectConfiguration *pc);
void displayNameChanged();
Target *m_target;
- FilterFunction m_filter;
QList<ProjectConfiguration *> m_projectConfigurations;
};
-class BuildConfigurationModel : public ProjectConfigurationModel
-{
-public:
- explicit BuildConfigurationModel(Target *t, QObject *parent = nullptr);
-};
-
-class DeployConfigurationModel : public ProjectConfigurationModel
-{
-public:
- explicit DeployConfigurationModel(Target *t, QObject *parent = nullptr);
-};
-
-class RunConfigurationModel : public ProjectConfigurationModel
-{
-public:
- explicit RunConfigurationModel(Target *t, QObject *parent = nullptr);
-};
-
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index d4b35e356b..b88ce71af4 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -33,6 +33,7 @@
#include "customwizard/customwizard.h"
#include "deployablefile.h"
#include "deployconfiguration.h"
+#include "desktoprunconfiguration.h"
#include "extraabi.h"
#include "gcctoolchainfactories.h"
#ifdef WITH_JOURNALD
@@ -148,6 +149,7 @@
#include <QApplication>
#include <QDir>
#include <QFileDialog>
+#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
#include <QThreadPool>
@@ -252,6 +254,8 @@ const char TERMINAL_MODE_SETTINGS_KEY[] = "ProjectExplorer/Settings/TerminalMode
const char CLOSE_FILES_WITH_PROJECT_SETTINGS_KEY[]
= "ProjectExplorer/Settings/CloseFilesWithProject";
const char CLEAR_ISSUES_ON_REBUILD_SETTINGS_KEY[] = "ProjectExplorer/Settings/ClearIssuesOnRebuild";
+const char ABORT_BUILD_ALL_ON_ERROR_SETTINGS_KEY[]
+ = "ProjectExplorer/Settings/AbortBuildAllOnError";
} // namespace Constants
@@ -354,7 +358,6 @@ public:
void buildQueueFinished(bool success);
- void buildStateChanged(ProjectExplorer::Project * pro);
void loadAction();
void handleUnloadProject();
void unloadProjectContextMenu();
@@ -430,6 +433,7 @@ public:
QAction *m_closeAllProjects;
QAction *m_buildProjectOnlyAction;
Utils::ParameterAction *m_buildAction;
+ Utils::ParameterAction *m_buildForRunConfigAction;
Utils::ProxyAction *m_modeBarBuildAction;
QAction *m_buildActionContextMenu;
QAction *m_buildDependenciesActionContextMenu;
@@ -562,8 +566,11 @@ public:
CurrentProjectFind m_curretProjectFind;
CustomExecutableRunConfigurationFactory m_customExecutableRunConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, CustomExecutableRunConfiguration>
- m_customExecutableRunWorkerFactory;
+ RunWorkerFactory m_customExecutableRunWorkerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {Constants::NORMAL_RUN_MODE},
+ {m_customExecutableRunConfigFactory.id()}
+ };
ProjectFileWizardExtension m_projectFileWizardExtension;
@@ -585,6 +592,17 @@ public:
ToolChainKitAspect toolChainKitAspect;
SysRootKitAspect sysRootKitAspect;
EnvironmentKitAspect environmentKitAspect;
+
+ DesktopQmakeRunConfigurationFactory qmakeRunConfigFactory;
+ QbsRunConfigurationFactory qbsRunConfigFactory;
+ CMakeRunConfigurationFactory cmakeRunConfigFactory;
+
+ RunWorkerFactory desktopRunWorkerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {qmakeRunConfigFactory.id(), qbsRunConfigFactory.id(), cmakeRunConfigFactory.id()}
+ };
+
};
static ProjectExplorerPlugin *m_instance = nullptr;
@@ -607,8 +625,6 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin()
delete dd;
dd = nullptr;
m_instance = nullptr;
-
- RunWorkerFactory::destroyRemainingRunWorkerFactories();
}
ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
@@ -618,7 +634,7 @@ ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
{
- Q_UNUSED(error);
+ Q_UNUSED(error)
dd = new ProjectExplorerPluginPrivate;
@@ -758,12 +774,12 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
ActionContainer *folderOpenLocationCtxMenu =
ActionManager::createMenu(Constants::FOLDER_OPEN_LOCATIONS_CONTEXT_MENU);
folderOpenLocationCtxMenu->menu()->setTitle(tr("Open..."));
- folderOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Show);
+ folderOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Hide);
ActionContainer *projectOpenLocationCtxMenu =
ActionManager::createMenu(Constants::PROJECT_OPEN_LOCATIONS_CONTEXT_MENU);
projectOpenLocationCtxMenu->menu()->setTitle(tr("Open..."));
- projectOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Show);
+ projectOpenLocationCtxMenu->setOnAllDisabledBehavior(ActionContainer::Hide);
// build menu
ActionContainer *mbuild =
@@ -800,10 +816,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
msessionContextMenu->appendGroup(Constants::G_PROJECT_TREE);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
- mprojectContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_REBUILD);
+ mprojectContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_LAST);
mprojectContextMenu->appendGroup(Constants::G_PROJECT_TREE);
@@ -813,13 +829,14 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd, &ProjectExplorerPluginPrivate::updateLocationSubMenus);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
- msubProjectContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
+ msubProjectContextMenu->appendGroup(Constants::G_FOLDER_LOCATIONS);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_LAST);
msubProjectContextMenu->appendGroup(Constants::G_PROJECT_TREE);
+ msubProjectContextMenu->addMenu(projectOpenLocationCtxMenu, Constants::G_FOLDER_LOCATIONS);
connect(msubProjectContextMenu->menu(), &QMenu::aboutToShow,
dd, &ProjectExplorerPluginPrivate::updateLocationSubMenus);
@@ -1044,6 +1061,17 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_modeBarBuildAction->setAction(cmd->action());
ModeManager::addAction(dd->m_modeBarBuildAction, Constants::P_ACTION_BUILDPROJECT);
+ // build for run config
+ dd->m_buildForRunConfigAction = new Utils::ParameterAction(
+ tr("Build for Run Configuration"), tr("Build for Run Configuration \"%1\""),
+ Utils::ParameterAction::EnabledWithParameter, this);
+ dd->m_buildForRunConfigAction->setIcon(buildIcon);
+ cmd = ActionManager::registerAction(dd->m_buildForRunConfigAction,
+ "ProjectExplorer.BuildForRunConfig");
+ cmd->setAttribute(Command::CA_UpdateText);
+ cmd->setDescription(dd->m_buildForRunConfigAction->text());
+ mbuild->addAction(cmd, Constants::G_BUILD_BUILD);
+
// deploy action
dd->m_deployAction = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
Utils::ParameterAction::AlwaysEnabled, this);
@@ -1222,7 +1250,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
// duplicate file action
- dd->m_duplicateFileAction = new QAction(tr("Duplicate File"), this);
+ dd->m_duplicateFileAction = new QAction(tr("Duplicate File..."), this);
cmd = ActionManager::registerAction(dd->m_duplicateFileAction, Constants::DUPLICATEFILE,
projecTreeContext);
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
@@ -1365,6 +1393,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
= s->value(Constants::CLOSE_FILES_WITH_PROJECT_SETTINGS_KEY, true).toBool();
dd->m_projectExplorerSettings.clearIssuesOnRebuild
= s->value(Constants::CLEAR_ISSUES_ON_REBUILD_SETTINGS_KEY, true).toBool();
+ dd->m_projectExplorerSettings.abortBuildAllOnError
+ = s->value(Constants::ABORT_BUILD_ALL_ON_ERROR_SETTINGS_KEY, true).toBool();
dd->m_projectExplorerSettings.buildDirectoryTemplate
= s->value(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY).toString();
if (dd->m_projectExplorerSettings.buildDirectoryTemplate.isEmpty())
@@ -1372,7 +1402,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
auto buildManager = new BuildManager(this, dd->m_cancelBuildAction);
connect(buildManager, &BuildManager::buildStateChanged,
- dd, &ProjectExplorerPluginPrivate::buildStateChanged);
+ dd, &ProjectExplorerPluginPrivate::updateActions);
connect(buildManager, &BuildManager::buildQueueFinished,
dd, &ProjectExplorerPluginPrivate::buildQueueFinished, Qt::QueuedConnection);
@@ -1392,6 +1422,21 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
connect(dd->m_buildActionContextMenu, &QAction::triggered, dd, [] {
dd->queue({ ProjectTree::currentProject() }, { Id(Constants::BUILDSTEPS_BUILD) });
});
+ connect(dd->m_buildForRunConfigAction, &QAction::triggered, dd, [] {
+ const Project * const project = SessionManager::startupProject();
+ QTC_ASSERT(project, return);
+ const Target * const target = project->activeTarget();
+ QTC_ASSERT(target, return);
+ const RunConfiguration * const runConfig = target->activeRunConfiguration();
+ QTC_ASSERT(runConfig, return);
+ const auto buildKeyMatcher = [runConfig](const ProjectNode *candidate) {
+ return candidate->buildKey() == runConfig->buildKey();
+ };
+ ProjectNode * const productNode
+ = project->rootProjectNode()->findProjectNode(buildKeyMatcher);
+ QTC_ASSERT(productNode->isProduct(), return);
+ productNode->build();
+ });
connect(dd->m_buildDependenciesActionContextMenu, &QAction::triggered, dd, [] {
dd->queue(SessionManager::projectOrder(ProjectTree::currentProject()),
{ Id(Constants::BUILDSTEPS_BUILD) });
@@ -1623,7 +1668,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
[]() -> QString {
if (Target *target = activeTarget()) {
if (RunConfiguration *rc = target->activeRunConfiguration())
- return rc->executable().toString();
+ return rc->commandLine().executable().toString();
}
return QString();
});
@@ -1641,7 +1686,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
BuildConfiguration::tr("Variables in the current build environment"),
[](const QString &var) {
if (BuildConfiguration *bc = activeBuildConfiguration())
- return bc->environment().value(var);
+ return bc->environment().expandedValueForKey(var);
return QString();
});
@@ -1728,18 +1773,10 @@ void ProjectExplorerPlugin::unloadProject(Project *project)
BuildManager::cancel();
}
- IDocument *document = project->document();
-
- if (!document || document->filePath().isEmpty()) //nothing to save?
- return;
-
- if (!DocumentManager::saveModifiedDocumentSilently(document))
- return;
-
if (projectExplorerSettings().closeSourceFilesWithProject && !dd->closeAllFilesInProject(project))
return;
- dd->addToRecentProjects(document->filePath().toString(), project->displayName());
+ dd->addToRecentProjects(project->projectFilePath().toString(), project->displayName());
SessionManager::removeProject(project);
dd->updateActions();
@@ -1866,6 +1903,11 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
return AsynchronousShutdown;
}
+void ProjectExplorerPlugin::showSessionManager()
+{
+ dd->showSessionManager();
+}
+
void ProjectExplorerPlugin::openNewProjectDialog()
{
if (!ICore::isNewItemDialogRunning()) {
@@ -1958,6 +2000,8 @@ void ProjectExplorerPluginPrivate::savePersistentSettings()
dd->m_projectExplorerSettings.closeSourceFilesWithProject);
s->setValue(Constants::CLEAR_ISSUES_ON_REBUILD_SETTINGS_KEY,
dd->m_projectExplorerSettings.clearIssuesOnRebuild);
+ s->setValue(Constants::ABORT_BUILD_ALL_ON_ERROR_SETTINGS_KEY,
+ dd->m_projectExplorerSettings.abortBuildAllOnError);
s->setValue(QLatin1String("ProjectExplorer/Settings/AutomaticallyCreateRunConfigurations"),
dd->m_projectExplorerSettings.automaticallyCreateRunConfigurations);
s->setValue(QLatin1String("ProjectExplorer/Settings/EnvironmentId"), dd->m_projectExplorerSettings.environmentId.toByteArray());
@@ -2147,11 +2191,6 @@ QStringList ProjectExplorerPlugin::projectFileGlobs()
return result;
}
-void ProjectExplorerPlugin::updateContextMenuActions()
-{
- dd->updateContextMenuActions();
-}
-
QThreadPool *ProjectExplorerPlugin::sharedThreadPool()
{
return &(dd->m_threadPool);
@@ -2219,12 +2258,6 @@ void ProjectExplorerPluginPrivate::restoreSession()
updateActions();
}
-void ProjectExplorerPluginPrivate::buildStateChanged(Project * pro)
-{
- Q_UNUSED(pro)
- updateActions();
-}
-
void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, Core::Id runMode)
{
if (!runConfiguration->isConfigured()) {
@@ -2275,9 +2308,12 @@ void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl)
m_outputPane.flash(); // one flash for starting
m_outputPane.showTabFor(runControl);
Core::Id runMode = runControl->runMode();
- bool popup = (runMode == Constants::NORMAL_RUN_MODE && m_outputPane.settings().popUpForRunOutput)
- || (runMode == Constants::DEBUG_RUN_MODE && m_outputPane.settings().popUpForDebugOutput);
- m_outputPane.setBehaviorOnOutput(runControl, popup ? AppOutputPane::Popup : AppOutputPane::Flash);
+ const auto popupMode = runMode == Constants::NORMAL_RUN_MODE
+ ? m_outputPane.settings().runOutputMode
+ : runMode == Constants::DEBUG_RUN_MODE
+ ? m_outputPane.settings().debugOutputMode
+ : AppOutputPaneMode::FlashOnOutput;
+ m_outputPane.setBehaviorOnOutput(runControl, popupMode);
connect(runControl, &QObject::destroyed, this, &ProjectExplorerPluginPrivate::checkForShutdown,
Qt::QueuedConnection);
++m_activeRunControlCount;
@@ -2333,6 +2369,7 @@ void ProjectExplorerPluginPrivate::buildQueueFinished(bool success)
m_delayedRunConfiguration = nullptr;
m_shouldHaveRunConfiguration = false;
m_runMode = Constants::NO_RUN_MODE;
+ emit m_instance->updateRunActions();
}
void ProjectExplorerPluginPrivate::runConfigurationConfigurationFinished()
@@ -2357,59 +2394,6 @@ QList<QPair<QString, QString> > ProjectExplorerPluginPrivate::recentProjects() c
});
}
-static QString pathOrDirectoryFor(const Node *node, bool dir)
-{
- Utils::FilePath path = node->filePath();
- QString location;
- const FolderNode *folder = node->asFolderNode();
- if (node->isVirtualFolderType() && folder) {
- // Virtual Folder case
- // If there are files directly below or no subfolders, take the folder path
- if (!folder->fileNodes().isEmpty() || folder->folderNodes().isEmpty()) {
- location = path.toString();
- } else {
- // Otherwise we figure out a commonPath from the subfolders
- QStringList list;
- foreach (FolderNode *f, folder->folderNodes())
- list << f->filePath().toString() + QLatin1Char('/');
- location = Utils::commonPath(list);
- }
-
- QFileInfo fi(location);
- while ((!fi.exists() || !fi.isDir()) && !fi.isRoot())
- fi.setFile(fi.absolutePath());
- location = fi.absoluteFilePath();
- } else if (!path.isEmpty()) {
- QFileInfo fi = path.toFileInfo();
- // remove any /suffixes, which e.g. ResourceNode uses
- // Note this should be removed again by making node->path() a true path again
- // That requires changes in both the VirtualFolderNode and ResourceNode
- while (!fi.exists() && !fi.isRoot())
- fi.setFile(fi.absolutePath());
-
- if (dir)
- location = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
- else
- location = fi.absoluteFilePath();
- }
- return location;
-}
-
-static QString pathFor(const Node *node)
-{
- return pathOrDirectoryFor(node, false);
-}
-
-static QString directoryFor(const Node *node)
-{
- return pathOrDirectoryFor(node, true);
-}
-
-QString ProjectExplorerPlugin::directoryFor(Node *node)
-{
- return ProjectExplorer::directoryFor(node);
-}
-
void ProjectExplorerPluginPrivate::updateActions()
{
const Project *const project = SessionManager::startupProject();
@@ -2437,8 +2421,13 @@ void ProjectExplorerPluginPrivate::updateActions()
? Icons::CANCELBUILD_FLAT.icon()
: buildAction->icon());
+ const RunConfiguration * const runConfig = project && project->activeTarget()
+ ? project->activeTarget()->activeRunConfiguration() : nullptr;
+
// Normal actions
m_buildAction->setParameter(projectName);
+ if (runConfig)
+ m_buildForRunConfigAction->setParameter(runConfig->displayName());
m_rebuildAction->setParameter(projectName);
m_cleanAction->setParameter(projectName);
@@ -2446,6 +2435,11 @@ void ProjectExplorerPluginPrivate::updateActions()
m_rebuildAction->setEnabled(buildActionState.first);
m_cleanAction->setEnabled(buildActionState.first);
+ // The last condition is there to prevent offering this action for custom run configurations.
+ m_buildForRunConfigAction->setEnabled(buildActionState.first
+ && runConfig && project->canBuildProducts()
+ && !runConfig->buildTargetInfo().projectFilePath.isEmpty());
+
m_buildAction->setToolTip(buildActionState.second);
m_rebuildAction->setToolTip(buildActionState.second);
m_cleanAction->setToolTip(buildActionState.second);
@@ -2596,7 +2590,7 @@ int ProjectExplorerPluginPrivate::queue(QList<Project *> projects, QList<Id> ste
BuildConfiguration *bc = t ? t->activeBuildConfiguration() : nullptr;
if (!bc)
return false;
- if (!Utils::FilePath::fromString(rc->runnable().executable).isChildOf(bc->buildDirectory()))
+ if (!rc->runnable().executable.isChildOf(bc->buildDirectory()))
return false;
IDevice::ConstPtr device = rc->runnable().device;
if (device.isNull())
@@ -2812,9 +2806,10 @@ void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc,
QList<Id> stepIds;
if (!forceSkipDeploy && dd->m_projectExplorerSettings.deployBeforeRun) {
- if (dd->m_projectExplorerSettings.buildBeforeDeploy)
+ if (!BuildManager::isBuilding() && dd->m_projectExplorerSettings.buildBeforeDeploy)
stepIds << Id(Constants::BUILDSTEPS_BUILD);
- stepIds << Id(Constants::BUILDSTEPS_DEPLOY);
+ if (!BuildManager::isDeploying())
+ stepIds << Id(Constants::BUILDSTEPS_DEPLOY);
}
Project *pro = rc->target()->project();
@@ -2823,7 +2818,9 @@ void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc,
if (queueCount < 0) // something went wrong
return;
- if (queueCount > 0) {
+ if (queueCount > 0 || BuildManager::isBuilding(rc->project())) {
+ QTC_ASSERT(dd->m_runMode == Constants::NO_RUN_MODE, return);
+
// delay running till after our queued steps were processed
dd->m_runMode = runMode;
dd->m_delayedRunConfiguration = rc;
@@ -2846,26 +2843,13 @@ QList<QPair<Runnable, Utils::ProcessHandle>> ProjectExplorerPlugin::runningRunCo
void ProjectExplorerPluginPrivate::projectAdded(Project *pro)
{
+ Q_UNUSED(pro)
m_projectsMode.setEnabled(true);
-
- // more specific action en and disabling ?
- pro->subscribeSignal(&BuildConfiguration::enabledChanged, this, [this]() {
- auto bc = qobject_cast<BuildConfiguration *>(sender());
- if (bc && bc->isActive() && bc->project() == SessionManager::startupProject()) {
- updateActions();
- emit m_instance->updateRunActions();
- }
- });
- pro->subscribeSignal(&RunConfiguration::requestRunActionsUpdate, this, [this]() {
- auto rc = qobject_cast<RunConfiguration *>(sender());
- if (rc && rc->isActive() && rc->project() == SessionManager::startupProject())
- emit m_instance->updateRunActions();
- });
}
void ProjectExplorerPluginPrivate::projectRemoved(Project *pro)
{
- Q_UNUSED(pro);
+ Q_UNUSED(pro)
m_projectsMode.setEnabled(SessionManager::hasProjects());
}
@@ -2936,6 +2920,7 @@ void ProjectExplorerPluginPrivate::activeRunConfigurationChanged()
rc = startupProject->activeTarget()->activeRunConfiguration();
if (rc == previousRunConfiguration)
return;
+ updateActions();
emit m_instance->updateRunActions();
}
@@ -3037,9 +3022,9 @@ bool ProjectExplorerPlugin::canRunStartupProject(Core::Id runMode, QString *whyN
return false;
}
-
if (dd->m_projectExplorerSettings.buildBeforeDeploy
&& dd->m_projectExplorerSettings.deployBeforeRun
+ && !BuildManager::isBuilding(project)
&& hasBuildSettings(project)) {
QPair<bool, QString> buildState = dd->buildSettingsEnabled(project);
if (!buildState.first) {
@@ -3047,18 +3032,26 @@ bool ProjectExplorerPlugin::canRunStartupProject(Core::Id runMode, QString *whyN
*whyNot = buildState.second;
return false;
}
+
+ if (BuildManager::isBuilding()) {
+ if (whyNot)
+ *whyNot = tr("A build is still in progress.");
+ return false;
+ }
}
// shouldn't actually be shown to the user...
- if (!RunControl::canRun(activeRC, runMode)) {
+ if (!RunControl::canRun(runMode,
+ DeviceTypeKitAspect::deviceTypeId(target->kit()),
+ activeRC->id())) {
if (whyNot)
*whyNot = tr("Cannot run \"%1\".").arg(activeRC->displayName());
return false;
}
- if (BuildManager::isBuilding()) {
+ if (dd->m_delayedRunConfiguration && dd->m_delayedRunConfiguration->project() == project) {
if (whyNot)
- *whyNot = tr("A build is still in progress.");
+ *whyNot = tr("A run action is already scheduled for the active project.");
return false;
}
@@ -3284,8 +3277,10 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_diffFileAction->setEnabled(DiffService::instance()
&& currentNodeIsTextFile && TextEditor::TextDocument::currentTextDocument());
- m_duplicateFileAction->setVisible(supports(DuplicateFile));
- m_duplicateFileAction->setEnabled(supports(DuplicateFile));
+ const bool canDuplicate = supports(AddNewFile)
+ && currentNode->asFileNode()->fileType() != FileType::Project;
+ m_duplicateFileAction->setVisible(canDuplicate);
+ m_duplicateFileAction->setEnabled(canDuplicate);
EditorManager::populateOpenWithMenu(m_openWithMenu,
currentNode->filePath().toString());
@@ -3331,8 +3326,8 @@ void ProjectExplorerPluginPrivate::updateLocationSubMenus()
const FolderNode *const fn
= ProjectTree::currentNode() ? ProjectTree::currentNode()->asFolderNode() : nullptr;
- const QList<FolderNode::LocationInfo> locations
- = fn ? fn->locationInfo() : QList<FolderNode::LocationInfo>();
+ const QVector<FolderNode::LocationInfo> locations = fn ? fn->locationInfo()
+ : QVector<FolderNode::LocationInfo>();
const bool isVisible = !locations.isEmpty();
projectMenu->menuAction()->setVisible(isVisible);
@@ -3341,10 +3336,19 @@ void ProjectExplorerPluginPrivate::updateLocationSubMenus()
if (!isVisible)
return;
+ unsigned int lastPriority = 0;
for (const FolderNode::LocationInfo &li : locations) {
+ if (li.priority != lastPriority) {
+ projectMenu->addSeparator();
+ folderMenu->addSeparator();
+ lastPriority = li.priority;
+ }
const int line = li.line;
const Utils::FilePath path = li.path;
- auto *action = new QAction(li.displayName, nullptr);
+ QString displayName = fn->filePath() == li.path
+ ? li.displayName
+ : tr("%1 in %2").arg(li.displayName).arg(li.path.toUserOutput());
+ auto *action = new QAction(displayName, nullptr);
connect(action, &QAction::triggered, this, [line, path]() {
Core::EditorManager::openEditorAt(path.toString(), line);
});
@@ -3360,7 +3364,7 @@ void ProjectExplorerPluginPrivate::addNewFile()
{
Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode, return);
- QString location = directoryFor(currentNode);
+ QString location = currentNode->directory();
QVariantMap map;
// store void pointer to avoid QVariant to use qobject_cast, which might core-dump when trying
@@ -3386,7 +3390,7 @@ void ProjectExplorerPluginPrivate::addNewSubproject()
{
Node* currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode, return);
- QString location = directoryFor(currentNode);
+ QString location = currentNode->directory();
if (currentNode->isProjectNodeType()
&& currentNode->supportsAction(AddSubProject, currentNode)) {
@@ -3421,7 +3425,7 @@ void ProjectExplorerPluginPrivate::addExistingProjects()
if (!projectNode && currentNode->asContainerNode())
projectNode = currentNode->asContainerNode()->rootProjectNode();
QTC_ASSERT(projectNode, return);
- const QString dir = directoryFor(currentNode);
+ const QString dir = currentNode->directory();
QStringList subProjectFilePaths = QFileDialog::getOpenFileNames(
ICore::mainWindow(), tr("Choose Project File"), dir,
projectNode->subProjectFileNamePatterns().join(";;"));
@@ -3461,7 +3465,7 @@ void ProjectExplorerPluginPrivate::handleAddExistingFiles()
QTC_ASSERT(folderNode, return);
QStringList fileNames = QFileDialog::getOpenFileNames(ICore::mainWindow(),
- tr("Add Existing Files"), directoryFor(node));
+ tr("Add Existing Files"), node->directory());
if (fileNames.isEmpty())
return;
@@ -3475,7 +3479,7 @@ void ProjectExplorerPluginPrivate::addExistingDirectory()
QTC_ASSERT(folderNode, return);
- SelectableFilesDialogAddDirectory dialog(Utils::FilePath::fromString(directoryFor(node)),
+ SelectableFilesDialogAddDirectory dialog(Utils::FilePath::fromString(node->directory()),
Utils::FilePathList(), ICore::mainWindow());
dialog.setAddFileFilter({});
@@ -3489,7 +3493,7 @@ void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStri
if (!folderNode || !ProjectTree::hasNode(folderNode))
return;
- const QString dir = directoryFor(folderNode);
+ const QString dir = folderNode->directory();
QStringList fileNames = filePaths;
QStringList notAdded;
folderNode->addFiles(fileNames, &notAdded);
@@ -3533,14 +3537,14 @@ void ProjectExplorerPluginPrivate::searchOnFileSystem()
{
const Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode, return);
- TextEditor::FindInFiles::findOnFileSystem(pathFor(currentNode));
+ TextEditor::FindInFiles::findOnFileSystem(currentNode->path());
}
void ProjectExplorerPluginPrivate::showInGraphicalShell()
{
Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode, return);
- FileUtils::showInGraphicalShell(ICore::mainWindow(), pathFor(currentNode));
+ FileUtils::showInGraphicalShell(ICore::mainWindow(), currentNode->path());
}
void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env)
@@ -3552,7 +3556,7 @@ void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env
if (!environment)
return;
- FileUtils::openTerminal(directoryFor(currentNode), environment.value());
+ FileUtils::openTerminal(currentNode->directory(), environment.value());
}
void ProjectExplorerPluginPrivate::openTerminalHereWithRunEnv()
@@ -3573,7 +3577,7 @@ void ProjectExplorerPluginPrivate::openTerminalHereWithRunEnv()
device = DeviceKitAspect::device(target->kit());
QTC_ASSERT(device && device->canOpenTerminal(), return);
const QString workingDir = device->type() == Constants::DESKTOP_DEVICE_TYPE
- ? directoryFor(currentNode) : runnable.workingDirectory;
+ ? currentNode->directory() : runnable.workingDirectory;
device->openTerminal(runnable.environment, workingDir);
}
@@ -3601,7 +3605,12 @@ void ProjectExplorerPluginPrivate::removeFile()
FolderNode *folderNode = currentNode->asFileNode()->parentFolderNode();
QTC_ASSERT(folderNode, return);
- if (!folderNode->removeFiles(QStringList(filePath.toString()))) {
+ const RemovedFilesFromProject status
+ = folderNode->removeFiles(QStringList(filePath.toString()));
+ const bool success = status == RemovedFilesFromProject::Ok
+ || (status == RemovedFilesFromProject::Wildcard
+ && removeFileDialog.isDeleteFileChecked());
+ if (!success) {
QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
tr("Could not remove file %1 from project %2.")
.arg(filePath.toUserOutput())
@@ -3625,24 +3634,33 @@ void ProjectExplorerPluginPrivate::duplicateFile()
QFileInfo sourceFileInfo(filePath);
QString baseName = sourceFileInfo.baseName();
- QString newFilePath = filePath;
- int copyTokenIndex = filePath.lastIndexOf(baseName)+baseName.length();
- newFilePath.insert(copyTokenIndex, tr("_copy"));
+ QString newFileName = sourceFileInfo.fileName();
+ int copyTokenIndex = newFileName.lastIndexOf(baseName)+baseName.length();
+ newFileName.insert(copyTokenIndex, tr("_copy"));
- // Build a new file name till a non-existing file is not found.
- uint counter = 0;
- while (QFileInfo::exists(newFilePath)) {
- newFilePath = filePath;
- newFilePath.insert(copyTokenIndex, tr("_copy%1").arg(++counter));
- }
+ bool okPressed;
+ newFileName = QInputDialog::getText(ICore::mainWindow(), tr("Choose File Name"),
+ tr("New file name:"), QLineEdit::Normal, newFileName, &okPressed);
+ if (!okPressed)
+ return;
+ if (!ProjectTree::hasNode(currentNode))
+ return;
- // Create a copy and add the file to the parent folder node.
+ const QString newFilePath = sourceFileInfo.path() + '/' + newFileName;
FolderNode *folderNode = fileNode->parentFolderNode();
QTC_ASSERT(folderNode, return);
- if (!(QFile::copy(filePath, newFilePath) && folderNode->addFiles(QStringList(newFilePath)))) {
- QMessageBox::warning(ICore::mainWindow(), tr("Duplicating File Failed"),
- tr("Could not duplicate the file %1.")
- .arg(QDir::toNativeSeparators(filePath)));
+ QFile sourceFile(filePath);
+ if (!sourceFile.copy(newFilePath)) {
+ QMessageBox::critical(ICore::mainWindow(), tr("Duplicating File Failed"),
+ tr("Failed to copy file \"%1\" to \"%2\": %3.")
+ .arg(QDir::toNativeSeparators(filePath),
+ QDir::toNativeSeparators(newFilePath), sourceFile.errorString()));
+ return;
+ }
+ if (!folderNode->addFiles(QStringList(newFilePath))) {
+ QMessageBox::critical(ICore::mainWindow(), tr("Duplicating File Failed"),
+ tr("Failed to add new file \"%1\" to the project.")
+ .arg(QDir::toNativeSeparators(newFilePath)));
}
}
@@ -3859,6 +3877,11 @@ QString ProjectExplorerPlugin::defaultBuildDirectoryTemplate()
return QString(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE);
}
+void ProjectExplorerPlugin::updateActions()
+{
+ dd->updateActions();
+}
+
QList<QPair<QString, QString> > ProjectExplorerPlugin::recentProjects()
{
return dd->recentProjects();
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 23c2098216..32531e094b 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -159,19 +159,19 @@ public:
static QString displayNameForStepId(Core::Id stepId);
- static QString directoryFor(Node *node);
static QStringList projectFileGlobs();
- static void updateContextMenuActions();
-
static QThreadPool *sharedThreadPool();
+ static void showSessionManager();
static void openNewProjectDialog();
static void openOpenProjectDialog();
static QString buildDirectoryTemplate();
static QString defaultBuildDirectoryTemplate();
+ static void updateActions();
+
signals:
void finishedInitialization();
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 097fcb6da5..a63af418d9 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -13,8 +13,11 @@ HEADERS += projectexplorer.h \
addrunconfigdialog.h \
ansifilterparser.h \
buildinfo.h \
+ buildsystem.h \
+ buildtargettype.h \
clangparser.h \
configtaskhandler.h \
+ desktoprunconfiguration.h \
environmentaspect.h \
environmentaspectwidget.h \
extraabi.h \
@@ -102,6 +105,7 @@ HEADERS += projectexplorer.h \
miniprojecttargetselector.h \
buildenvironmentwidget.h \
ldparser.h \
+ lldparser.h \
linuxiccparser.h \
runconfigurationaspects.h \
processparameters.h \
@@ -133,10 +137,8 @@ HEADERS += projectexplorer.h \
devicesupport/sshdeviceprocess.h \
devicesupport/sshdeviceprocesslist.h \
devicesupport/sshsettingspage.h \
- devicesupport/desktopdeviceconfigurationwidget.h \
devicesupport/desktopprocesssignaloperation.h \
deploymentdata.h \
- deploymentdatamodel.h \
deploymentdataview.h \
buildtargetinfo.h \
customtoolchain.h \
@@ -162,7 +164,8 @@ HEADERS += projectexplorer.h \
makestep.h \
parseissuesdialog.h \
projectconfigurationaspects.h \
- treescanner.h
+ treescanner.h \
+ rawprojectpart.h
SOURCES += projectexplorer.cpp \
abi.cpp \
@@ -170,8 +173,10 @@ SOURCES += projectexplorer.cpp \
addrunconfigdialog.cpp \
ansifilterparser.cpp \
buildinfo.cpp \
+ buildsystem.cpp \
clangparser.cpp \
configtaskhandler.cpp \
+ desktoprunconfiguration.cpp \
environmentaspect.cpp \
environmentaspectwidget.cpp \
extraabi.cpp \
@@ -253,6 +258,7 @@ SOURCES += projectexplorer.cpp \
miniprojecttargetselector.cpp \
buildenvironmentwidget.cpp \
ldparser.cpp \
+ lldparser.cpp \
linuxiccparser.cpp \
runconfigurationaspects.cpp \
taskhub.cpp \
@@ -279,11 +285,9 @@ SOURCES += projectexplorer.cpp \
devicesupport/sshdeviceprocess.cpp \
devicesupport/sshdeviceprocesslist.cpp \
devicesupport/sshsettingspage.cpp \
- devicesupport/desktopdeviceconfigurationwidget.cpp \
devicesupport/desktopprocesssignaloperation.cpp \
deployablefile.cpp \
deploymentdata.cpp \
- deploymentdatamodel.cpp \
deploymentdataview.cpp \
customtoolchain.cpp \
projectmacroexpander.cpp \
@@ -306,19 +310,18 @@ SOURCES += projectexplorer.cpp \
makestep.cpp \
parseissuesdialog.cpp \
projectconfigurationaspects.cpp \
- treescanner.cpp
+ treescanner.cpp \
+ rawprojectpart.cpp
FORMS += \
editorsettingspropertiespage.ui \
sessiondialog.ui \
projectwizardpage.ui \
projectexplorersettingspage.ui \
- deploymentdataview.ui \
codestylesettingspropertiespage.ui \
devicesupport/devicefactoryselectiondialog.ui \
devicesupport/devicesettingswidget.ui \
devicesupport/devicetestdialog.ui \
- devicesupport/desktopdeviceconfigurationwidget.ui \
customparserconfigdialog.ui \
makestep.ui
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 395c1cced9..9fabfcb98f 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -40,7 +40,9 @@ Project {
"buildstep.cpp", "buildstep.h",
"buildsteplist.cpp", "buildsteplist.h",
"buildstepspage.cpp", "buildstepspage.h",
+ "buildsystem.cpp", "buildsystem.h",
"buildtargetinfo.h",
+ "buildtargettype.h",
"clangparser.cpp", "clangparser.h",
"codestylesettingspropertiespage.cpp", "codestylesettingspropertiespage.h", "codestylesettingspropertiespage.ui",
"compileoutputwindow.cpp", "compileoutputwindow.h",
@@ -59,9 +61,7 @@ Project {
"deploymentdata.h",
"deploymentdataview.cpp",
"deploymentdataview.h",
- "deploymentdataview.ui",
- "deploymentdatamodel.cpp",
- "deploymentdatamodel.h",
+ "desktoprunconfiguration.cpp", "desktoprunconfiguration.h",
"editorconfiguration.cpp", "editorconfiguration.h",
"editorsettingspropertiespage.cpp", "editorsettingspropertiespage.h", "editorsettingspropertiespage.ui",
"environmentaspect.cpp", "environmentaspect.h",
@@ -91,6 +91,7 @@ Project {
"kitmodel.cpp", "kitmodel.h",
"kitoptionspage.cpp", "kitoptionspage.h",
"ldparser.cpp", "ldparser.h",
+ "lldparser.cpp", "lldparser.h",
"linuxiccparser.cpp", "linuxiccparser.h",
"localenvironmentaspect.cpp", "localenvironmentaspect.h",
"makestep.cpp", "makestep.h", "makestep.ui",
@@ -127,6 +128,7 @@ Project {
"projecttreewidget.cpp", "projecttreewidget.h",
"projectwindow.cpp", "projectwindow.h",
"projectwizardpage.cpp", "projectwizardpage.h", "projectwizardpage.ui",
+ "rawprojectpart.cpp", "rawprojectpart.h",
"removetaskhandler.cpp", "removetaskhandler.h",
"runconfiguration.cpp", "runconfiguration.h",
"runcontrol.cpp", "runcontrol.h",
@@ -225,8 +227,7 @@ Project {
"sshdeviceprocess.cpp", "sshdeviceprocess.h",
"sshdeviceprocesslist.cpp", "sshdeviceprocesslist.h",
"sshsettingspage.cpp", "sshsettingspage.h",
- "desktopprocesssignaloperation.cpp", "desktopprocesssignaloperation.h",
- "desktopdeviceconfigurationwidget.cpp", "desktopdeviceconfigurationwidget.h", "desktopdeviceconfigurationwidget.ui"
+ "desktopprocesssignaloperation.cpp", "desktopprocesssignaloperation.h"
]
}
diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc
index 29bda00509..df61a97b26 100644
--- a/src/plugins/projectexplorer/projectexplorer.qrc
+++ b/src/plugins/projectexplorer/projectexplorer.qrc
@@ -85,5 +85,7 @@
<file>images/settingscategory_devices@2x.png</file>
<file>images/settingscategory_kits.png</file>
<file>images/settingscategory_kits@2x.png</file>
+ <file>images/settingscategory_cpp.png</file>
+ <file>images/settingscategory_cpp@2x.png</file>
</qresource>
</RCC>
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index ad2d9e049e..c76f1acda1 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -144,12 +144,15 @@ const char PREFERRED_PROJECT_NODE[] = "ProjectExplorer.PreferredProjectNode";
const char PREFERRED_PROJECT_NODE_PATH[] = "ProjectExplorer.PreferredProjectPath";
const char PROJECT_POINTER[] = "ProjectExplorer.Project";
const char PROJECT_KIT_IDS[] = "ProjectExplorer.Profile.Ids";
+const char QT_KEYWORDS_ENABLED[] = "ProjectExplorer.QtKeywordsEnabled";
// Build step lists ids:
const char BUILDSTEPS_CLEAN[] = "ProjectExplorer.BuildSteps.Clean";
const char BUILDSTEPS_BUILD[] = "ProjectExplorer.BuildSteps.Build";
const char BUILDSTEPS_DEPLOY[] = "ProjectExplorer.BuildSteps.Deploy";
+const char PROCESS_STEP_ID[] = "ProjectExplorer.ProcessStep";
+
// Language
// Keep these short: These constants are exposed to the MacroExplorer!
@@ -195,10 +198,13 @@ const char GENERATOR_ID_PREFIX[] = "PE.Wizard.Generator.";
// RunMode
const char NO_RUN_MODE[]="RunConfiguration.NoRunMode";
const char NORMAL_RUN_MODE[]="RunConfiguration.NormalRunMode";
-const char QML_PROFILER_RUN_MODE[]="RunConfiguration.QmlProfilerRunMode";
-const char PERFPROFILER_RUN_MODE[]="PerfProfiler.RunMode";
const char DEBUG_RUN_MODE[]="RunConfiguration.DebugRunMode";
+const char QML_PROFILER_RUN_MODE[]="RunConfiguration.QmlProfilerRunMode";
+const char QML_PROFILER_RUNNER[]="RunConfiguration.QmlProfilerRunner";
const char QML_PREVIEW_RUN_MODE[]="RunConfiguration.QmlPreviewRunMode";
+const char QML_PREVIEW_RUNNER[]="RunConfiguration.QmlPreviewRunner";
+const char PERFPROFILER_RUN_MODE[]="PerfProfiler.RunMode";
+const char PERFPROFILER_RUNNER[]="PerfProfiler.Runner";
// Navigation Widget
const char PROJECTTREE_ID[] = "Projects";
diff --git a/src/plugins/projectexplorer/projectexplorersettings.h b/src/plugins/projectexplorer/projectexplorersettings.h
index 85e9a77abe..6472725db6 100644
--- a/src/plugins/projectexplorer/projectexplorersettings.h
+++ b/src/plugins/projectexplorer/projectexplorersettings.h
@@ -34,6 +34,7 @@ namespace ProjectExplorer {
namespace Internal {
enum class TerminalMode { On, Off, Smart };
+enum class AppOutputPaneMode { FlashOnOutput, PopupOnOutput, PopupOnFirstOutput };
class ProjectExplorerSettings
{
@@ -50,6 +51,7 @@ public:
bool addLibraryPathsToRunEnv = true;
bool closeSourceFilesWithProject = true;
bool clearIssuesOnRebuild = true;
+ bool abortBuildAllOnError = true;
StopBeforeBuild stopBeforeBuild = StopBeforeBuild::StopNone;
TerminalMode terminalMode = TerminalMode::Smart;
QString buildDirectoryTemplate;
@@ -75,14 +77,15 @@ inline bool operator==(const ProjectExplorerSettings &p1, const ProjectExplorerS
&& p1.terminalMode == p2.terminalMode
&& p1.closeSourceFilesWithProject == p2.closeSourceFilesWithProject
&& p1.clearIssuesOnRebuild == p2.clearIssuesOnRebuild
+ && p1.abortBuildAllOnError == p2.abortBuildAllOnError
&& p1.buildDirectoryTemplate == p2.buildDirectoryTemplate;
}
class AppOutputSettings
{
public:
- bool popUpForRunOutput = true;
- bool popUpForDebugOutput = false;
+ AppOutputPaneMode runOutputMode = AppOutputPaneMode::PopupOnFirstOutput;
+ AppOutputPaneMode debugOutputMode = AppOutputPaneMode::FlashOnOutput;
bool cleanOldOutput = false;
bool mergeChannels = false;
bool wrapOutput = false;
diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp
index 73f622aedf..78727aa08b 100644
--- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp
+++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp
@@ -108,6 +108,7 @@ ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const
m_settings.terminalMode = static_cast<TerminalMode>(m_ui.terminalModeComboBox->currentIndex());
m_settings.closeSourceFilesWithProject = m_ui.closeSourceFilesCheckBox->isChecked();
m_settings.clearIssuesOnRebuild = m_ui.clearIssuesCheckBox->isChecked();
+ m_settings.abortBuildAllOnError = m_ui.abortBuildAllOnErrorCheckBox->isChecked();
m_settings.buildDirectoryTemplate = buildDirectoryTemplate();
return m_settings;
}
@@ -126,6 +127,7 @@ void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &
m_ui.terminalModeComboBox->setCurrentIndex(static_cast<int>(m_settings.terminalMode));
m_ui.closeSourceFilesCheckBox->setChecked(m_settings.closeSourceFilesWithProject);
m_ui.clearIssuesCheckBox->setChecked(m_settings.clearIssuesOnRebuild);
+ m_ui.abortBuildAllOnErrorCheckBox->setChecked(m_settings.abortBuildAllOnError);
setBuildDirectoryTemplate(pes.buildDirectoryTemplate);
}
diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui
index 448ad3655b..dc82660112 100644
--- a/src/plugins/projectexplorer/projectexplorersettingspage.ui
+++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui
@@ -142,6 +142,13 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="abortBuildAllOnErrorCheckBox">
+ <property name="text">
+ <string>Abort on error when building all projects</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelStopBeforeBuild">
@@ -302,6 +309,7 @@
<zorder>promptToStopRunControlCheckBox</zorder>
<zorder>addLibraryPathsToRunEnvCheckBox</zorder>
<zorder>clearIssuesCheckBox</zorder>
+ <zorder>abortBuildAllOnErrorCheckBox</zorder>
</widget>
</item>
<item>
diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp
index 4d32dba9d6..1a2dbbfcad 100644
--- a/src/plugins/projectexplorer/projectimporter.cpp
+++ b/src/plugins/projectexplorer/projectimporter.cpp
@@ -366,13 +366,12 @@ bool ProjectImporter::hasKitWithTemporaryData(Core::Id id, const QVariant &data)
});
}
-static ProjectImporter::ToolChainData
-createToolChains(const Utils::FilePath &toolChainPath, const Core::Id &language)
+static ProjectImporter::ToolChainData createToolChains(const ToolChainDescription &tcd)
{
ProjectImporter::ToolChainData data;
for (ToolChainFactory *factory : ToolChainFactory::allToolChainFactories()) {
- data.tcs = factory->autoDetect(toolChainPath, language);
+ data.tcs = factory->detectForImport(tcd);
if (data.tcs.isEmpty())
continue;
@@ -387,12 +386,11 @@ createToolChains(const Utils::FilePath &toolChainPath, const Core::Id &language)
}
ProjectImporter::ToolChainData
-ProjectImporter::findOrCreateToolChains(const Utils::FilePath &toolChainPath,
- const Core::Id &language) const
+ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const
{
ToolChainData result;
- result.tcs = ToolChainManager::toolChains([toolChainPath, language](const ToolChain *tc) {
- return tc->language() == language && tc->compilerCommand() == toolChainPath;
+ result.tcs = ToolChainManager::toolChains([&tcd](const ToolChain *tc) {
+ return tc->language() == tcd.language && tc->compilerCommand() == tcd.compilerPath;
});
for (const ToolChain *tc : result.tcs) {
const QByteArray tcId = tc->id();
@@ -403,7 +401,7 @@ ProjectImporter::findOrCreateToolChains(const Utils::FilePath &toolChainPath,
// Create a new toolchain:
UpdateGuard guard(*this);
- return createToolChains(toolChainPath, language);
+ return createToolChains(tcd);
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectimporter.h b/src/plugins/projectexplorer/projectimporter.h
index f1cf482607..20a2700683 100644
--- a/src/plugins/projectexplorer/projectimporter.h
+++ b/src/plugins/projectexplorer/projectimporter.h
@@ -27,12 +27,10 @@
#include "projectexplorer_export.h"
-#include <coreplugin/id.h>
+#include "toolchain.h"
#include <utils/fileutils.h>
-#include <QVariant>
-
namespace ProjectExplorer {
class BuildInfo;
@@ -110,7 +108,7 @@ protected:
// Does *any* kit feature the requested data yet?
bool hasKitWithTemporaryData(Core::Id id, const QVariant &data) const;
- ToolChainData findOrCreateToolChains(const Utils::FilePath &toolChainPath, const Core::Id &language) const;
+ ToolChainData findOrCreateToolChains(const ToolChainDescription &tcd) const;
private:
void markKitAsTemporary(Kit *k) const;
diff --git a/src/plugins/projectexplorer/projectmacroexpander.cpp b/src/plugins/projectexplorer/projectmacroexpander.cpp
index 83aaf2d5fb..6fcdb89f94 100644
--- a/src/plugins/projectexplorer/projectmacroexpander.cpp
+++ b/src/plugins/projectexplorer/projectmacroexpander.cpp
@@ -29,13 +29,13 @@
namespace ProjectExplorer {
-ProjectMacroExpander::ProjectMacroExpander(const QString &mainFilePath, const QString &projectName,
+ProjectMacroExpander::ProjectMacroExpander(const Utils::FilePath &mainFilePath, const QString &projectName,
const Kit *kit, const QString &bcName,
BuildConfiguration::BuildType buildType)
{
registerFileVariables(Constants::VAR_CURRENTPROJECT_PREFIX,
QCoreApplication::translate("ProjectExplorer", "Main file of current project"),
- [mainFilePath]() -> QString { return mainFilePath; });
+ [mainFilePath] { return mainFilePath.toString(); });
registerVariable(Constants::VAR_CURRENTPROJECT_NAME,
QCoreApplication::translate("ProjectExplorer", "Name of current project"),
diff --git a/src/plugins/projectexplorer/projectmacroexpander.h b/src/plugins/projectexplorer/projectmacroexpander.h
index 351081c97e..59028ddd9c 100644
--- a/src/plugins/projectexplorer/projectmacroexpander.h
+++ b/src/plugins/projectexplorer/projectmacroexpander.h
@@ -37,8 +37,11 @@ class Kit;
class PROJECTEXPLORER_EXPORT ProjectMacroExpander : public Utils::MacroExpander
{
public:
- ProjectMacroExpander(const QString &mainFilePath, const QString &projectName, const Kit *kit,
- const QString &bcName, BuildConfiguration::BuildType buildType);
+ ProjectMacroExpander(const Utils::FilePath &mainFilePath,
+ const QString &projectName,
+ const Kit *kit,
+ const QString &bcName,
+ BuildConfiguration::BuildType buildType);
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index d78db7b2ae..5fe63fefe9 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -59,6 +59,8 @@
#include <QVBoxLayout>
#include <functional>
+#include <tuple>
+#include <vector>
using namespace Utils;
@@ -173,7 +175,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
result = font;
break;
}
- case Qt::TextColorRole: {
+ case Qt::ForegroundRole: {
result = node->isEnabled() ? m_enabledTextColor : m_disabledTextColor;
break;
}
@@ -221,11 +223,53 @@ bool FlatModel::setData(const QModelIndex &index, const QVariant &value, int rol
Node *node = nodeForIndex(index);
QTC_ASSERT(node, return false);
+ std::vector<std::tuple<Node *, FilePath, FilePath>> toRename;
const Utils::FilePath orgFilePath = node->filePath();
const Utils::FilePath newFilePath = orgFilePath.parentDir().pathAppended(value.toString());
+ const QFileInfo orgFileInfo = orgFilePath.toFileInfo();
+ toRename.emplace_back(std::make_tuple(node, orgFilePath, newFilePath));
+
+ // The base name of the file was changed. Go look for other files with the same base name
+ // and offer to rename them as well.
+ if (orgFilePath != newFilePath && orgFileInfo.suffix() == newFilePath.toFileInfo().suffix()) {
+ ProjectNode *productNode = node->parentProjectNode();
+ while (productNode && !productNode->isProduct())
+ productNode = productNode->parentProjectNode();
+ if (productNode) {
+ const auto filter = [&orgFilePath, &orgFileInfo](const Node *n) {
+ return n->asFileNode()
+ && n->filePath().toFileInfo().dir() == orgFileInfo.dir()
+ && n->filePath().toFileInfo().completeBaseName()
+ == orgFileInfo.completeBaseName()
+ && n->filePath() != orgFilePath;
+ };
+ const QList<Node *> candidateNodes = productNode->findNodes(filter);
+ if (!candidateNodes.isEmpty()) {
+ const QMessageBox::StandardButton reply = QMessageBox::question(
+ Core::ICore::mainWindow(), tr("Rename More Files?"),
+ tr("Would you like to rename these files as well?\n %1")
+ .arg(transform<QStringList>(candidateNodes, [](const Node *n) {
+ return n->filePath().toFileInfo().fileName();
+ }).join("\n ")));
+ if (reply == QMessageBox::Yes) {
+ for (Node * const n : candidateNodes) {
+ QString targetFilePath = orgFileInfo.absolutePath() + '/'
+ + newFilePath.toFileInfo().completeBaseName();
+ const QString suffix = n->filePath().toFileInfo().suffix();
+ if (!suffix.isEmpty())
+ targetFilePath.append('.').append(suffix);
+ toRename.emplace_back(std::make_tuple(n, n->filePath(),
+ FilePath::fromString(targetFilePath)));
+ }
+ }
+ }
+ }
+ }
- ProjectExplorerPlugin::renameFile(node, newFilePath.toString());
- emit renamed(orgFilePath, newFilePath);
+ for (const auto &f : toRename) {
+ ProjectExplorerPlugin::renameFile(std::get<0>(f), std::get<2>(f).toString());
+ emit renamed(std::get<1>(f), std::get<2>(f));
+ }
return true;
}
@@ -533,7 +577,7 @@ private:
bool FlatModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent)
{
- Q_UNUSED(action);
+ Q_UNUSED(action)
const auto * const dropData = dynamic_cast<const DropMimeData *>(data);
QTC_ASSERT(dropData, return false);
@@ -579,7 +623,7 @@ bool FlatModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int r
// Node weirdness: Sometimes the "file path" is a directory, sometimes it's a file...
const auto dirForProjectNode = [](const ProjectNode *pNode) {
const FilePath dir = pNode->filePath();
- if (dir.toFileInfo().isDir())
+ if (dir.isDir())
return dir;
return FilePath::fromString(dir.toFileInfo().path());
};
@@ -687,7 +731,10 @@ bool FlatModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int r
if (vcsAddPossible && !targetVcs.vcs->vcsAdd(targetFile))
failedVcsOp << targetFile;
}
- sourceProjectNode->removeFiles(filesToRemove, &failedRemoveFromProject);
+ const RemovedFilesFromProject result
+ = sourceProjectNode->removeFiles(filesToRemove, &failedRemoveFromProject);
+ if (result == RemovedFilesFromProject::Wildcard)
+ failedRemoveFromProject.clear();
targetProjectNode->addFiles(filesToAdd, &failedAddToProject);
break;
}
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index e6825e98be..c2244ed010 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -41,6 +41,7 @@
#include <utils/mimetypes/mimetype.h>
#include <utils/pointeralgorithm.h>
#include <utils/qtcassert.h>
+#include <utils/stringutils.h>
#include <QFileInfo>
#include <QDir>
@@ -212,6 +213,15 @@ const ProjectNode *Node::managingProject() const
return const_cast<Node *>(this)->managingProject();
}
+Project *Node::getProject() const
+{
+ if (const ContainerNode * const cn = asContainerNode())
+ return cn->project();
+ if (!m_parentFolderNode)
+ return nullptr;
+ return m_parentFolderNode->getProject();
+}
+
/*!
The path of the file or folder in the filesystem the node represents.
*/
@@ -303,6 +313,43 @@ FileType Node::fileTypeForFileName(const Utils::FilePath &file)
Utils::MimeMatchMode::MatchExtension));
}
+QString Node::pathOrDirectory(bool dir) const
+{
+ QString location;
+ const FolderNode *folder = asFolderNode();
+ if (isVirtualFolderType() && folder) {
+ // Virtual Folder case
+ // If there are files directly below or no subfolders, take the folder path
+ if (!folder->fileNodes().isEmpty() || folder->folderNodes().isEmpty()) {
+ location = m_filePath.toString();
+ } else {
+ // Otherwise we figure out a commonPath from the subfolders
+ QStringList list;
+ foreach (FolderNode *f, folder->folderNodes())
+ list << f->filePath().toString() + QLatin1Char('/');
+ location = Utils::commonPath(list);
+ }
+
+ QFileInfo fi(location);
+ while ((!fi.exists() || !fi.isDir()) && !fi.isRoot())
+ fi.setFile(fi.absolutePath());
+ location = fi.absoluteFilePath();
+ } else if (!m_filePath.isEmpty()) {
+ QFileInfo fi = m_filePath.toFileInfo();
+ // remove any /suffixes, which e.g. ResourceNode uses
+ // Note this could be removed again by making path() a true path again
+ // That requires changes in both the VirtualFolderNode and ResourceNode
+ while (!fi.exists() && !fi.isRoot())
+ fi.setFile(fi.absolutePath());
+
+ if (dir)
+ location = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
+ else
+ location = fi.absoluteFilePath();
+ }
+ return location;
+}
+
/*!
\class ProjectExplorer::FileNode
@@ -661,12 +708,13 @@ void FolderNode::setIcon(const QIcon &icon)
m_icon = icon;
}
-void FolderNode::setLocationInfo(const QList<FolderNode::LocationInfo> &info)
+void FolderNode::setLocationInfo(const QVector<FolderNode::LocationInfo> &info)
{
m_locations = info;
+ Utils::sort(m_locations, &LocationInfo::priority);
}
-const QList<FolderNode::LocationInfo> FolderNode::locationInfo() const
+const QVector<FolderNode::LocationInfo> FolderNode::locationInfo() const
{
return m_locations;
}
@@ -696,12 +744,12 @@ bool FolderNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
return false;
}
-bool FolderNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject FolderNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
- ProjectNode *pn = managingProject();
- if (pn)
+ if (ProjectNode * const pn = managingProject())
return pn->removeFiles(filePaths, notRemoved);
- return false;
+ return RemovedFilesFromProject::Error;
}
bool FolderNode::deleteFiles(const QStringList &filePaths)
@@ -728,9 +776,16 @@ bool FolderNode::renameFile(const QString &filePath, const QString &newFilePath)
return false;
}
+bool FolderNode::addDependencies(const QStringList &dependencies)
+{
+ if (ProjectNode * const pn = managingProject())
+ return pn->addDependencies(dependencies);
+ return false;
+}
+
FolderNode::AddNewInformation FolderNode::addNewInformation(const QStringList &files, Node *context) const
{
- Q_UNUSED(files);
+ Q_UNUSED(files)
return AddNewInformation(displayName(), context == this ? 120 : 100);
}
@@ -832,11 +887,12 @@ bool ProjectNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
return false;
}
-bool ProjectNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject ProjectNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
Q_UNUSED(filePaths)
Q_UNUSED(notRemoved)
- return false;
+ return RemovedFilesFromProject::Error;
}
bool ProjectNode::deleteFiles(const QStringList &filePaths)
@@ -847,8 +903,8 @@ bool ProjectNode::deleteFiles(const QStringList &filePaths)
bool ProjectNode::canRenameFile(const QString &filePath, const QString &newFilePath)
{
- Q_UNUSED(filePath);
- Q_UNUSED(newFilePath);
+ Q_UNUSED(filePath)
+ Q_UNUSED(newFilePath)
return true;
}
@@ -859,6 +915,12 @@ bool ProjectNode::renameFile(const QString &filePath, const QString &newFilePath
return false;
}
+bool ProjectNode::addDependencies(const QStringList &dependencies)
+{
+ Q_UNUSED(dependencies)
+ return false;
+}
+
bool ProjectNode::supportsAction(ProjectAction, const Node *) const
{
return false;
@@ -866,7 +928,7 @@ bool ProjectNode::supportsAction(ProjectAction, const Node *) const
bool ProjectNode::deploysFolder(const QString &folder) const
{
- Q_UNUSED(folder);
+ Q_UNUSED(folder)
return false;
}
@@ -882,17 +944,21 @@ ProjectNode *ProjectNode::projectNode(const Utils::FilePath &file) const
QVariant ProjectNode::data(Core::Id role) const
{
- Q_UNUSED(role);
- return QVariant();
+ return m_fallbackData.value(role);
}
bool ProjectNode::setData(Core::Id role, const QVariant &value) const
{
- Q_UNUSED(role);
- Q_UNUSED(value);
+ Q_UNUSED(role)
+ Q_UNUSED(value)
return false;
}
+void ProjectNode::setFallbackData(Core::Id key, const QVariant &value)
+{
+ m_fallbackData.insert(key, value);
+}
+
bool FolderNode::isEmpty() const
{
return m_nodes.size() == 0;
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index ce36882aa9..0bea9c3810 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -78,13 +78,14 @@ enum ProjectAction {
// DeleteFile is a define on windows...
EraseFile,
Rename,
- DuplicateFile,
// hides actions that use the path(): Open containing folder, open terminal here and Find in Directory
HidePathActions,
HideFileActions,
HideFolderActions,
};
+enum class RemovedFilesFromProject { Ok, Wildcard, Error };
+
class FileNode;
class FolderNode;
class ProjectNode;
@@ -121,6 +122,8 @@ public:
// or node->parentProjectNode() for all other cases.
const ProjectNode *managingProject() const; // see above.
+ Project *getProject() const;
+
const Utils::FilePath &filePath() const; // file system path
int line() const;
virtual QString displayName() const;
@@ -156,6 +159,9 @@ public:
static FileType fileTypeForMimeType(const Utils::MimeType &mt);
static FileType fileTypeForFileName(const Utils::FilePath &file);
+ QString path() const { return pathOrDirectory(false); }
+ QString directory() const { return pathOrDirectory(true); }
+
protected:
Node();
Node(const Node &other) = delete;
@@ -164,6 +170,8 @@ protected:
void setFilePath(const Utils::FilePath &filePath);
private:
+ QString pathOrDirectory(bool dir) const;
+
FolderNode *m_parentFolderNode = nullptr;
Utils::FilePath m_filePath;
int m_line = -1;
@@ -243,17 +251,27 @@ public:
void setDisplayName(const QString &name);
void setIcon(const QIcon &icon);
- class LocationInfo {
+ class LocationInfo
+ {
public:
- LocationInfo(const QString &dn, const Utils::FilePath &p, const int l = -1) :
- path(p), line(l), displayName(dn) { }
+ LocationInfo() = default;
+ LocationInfo(const QString &dn,
+ const Utils::FilePath &p,
+ const int l = 0,
+ const unsigned int prio = 0)
+ : path(p)
+ , line(l)
+ , priority(prio)
+ , displayName(dn)
+ {}
Utils::FilePath path;
int line = -1;
+ unsigned int priority = 0;
QString displayName;
};
- void setLocationInfo(const QList<LocationInfo> &info);
- const QList<LocationInfo> locationInfo() const;
+ void setLocationInfo(const QVector<LocationInfo> &info);
+ const QVector<LocationInfo> locationInfo() const;
QString addFileFilter() const;
void setAddFileFilter(const QString &filter) { m_addFileFilter = filter; }
@@ -261,10 +279,12 @@ public:
bool supportsAction(ProjectAction action, const Node *node) const override;
virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr);
- virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr);
+ virtual RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved = nullptr);
virtual bool deleteFiles(const QStringList &filePaths);
virtual bool canRenameFile(const QString &filePath, const QString &newFilePath);
virtual bool renameFile(const QString &filePath, const QString &newFilePath);
+ virtual bool addDependencies(const QStringList &dependencies);
class AddNewInformation
{
@@ -297,7 +317,7 @@ protected:
virtual void handleSubTreeChanged(FolderNode *node);
std::vector<std::unique_ptr<Node>> m_nodes;
- QList<LocationInfo> m_locations;
+ QVector<LocationInfo> m_locations;
private:
std::unique_ptr<Node> takeNode(Node *node);
@@ -336,10 +356,12 @@ public:
bool showInSimpleTree() const override { return true; }
bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override;
+ RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
bool deleteFiles(const QStringList &filePaths) override;
bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
+ bool addDependencies(const QStringList &dependencies) override;
bool supportsAction(ProjectAction action, const Node *node) const override;
// by default returns false
@@ -359,6 +381,15 @@ public:
bool isProduct() const { return m_isProduct; }
+ // TODO: Currently used only for "Build for current run config" functionality, but we should
+ // probably use it to centralize the node-specific "Build" functionality that
+ // currently each project manager plugin adds to the context menu by itself.
+ // The function should then move up to the Node class, so it can also serve the
+ // "build single file" case.
+ virtual void build() {}
+
+ void setFallbackData(Core::Id key, const QVariant &value);
+
protected:
void setIsProduct() { m_isProduct = true; }
@@ -366,6 +397,7 @@ protected:
private:
bool m_isProduct = false;
+ QHash<Core::Id, QVariant> m_fallbackData; // Used in data(), unless overridden.
};
class PROJECTEXPLORER_EXPORT ContainerNode : public FolderNode
diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp
index 5259a0d609..5010b18b87 100644
--- a/src/plugins/projectexplorer/projecttree.cpp
+++ b/src/plugins/projectexplorer/projecttree.cpp
@@ -321,7 +321,7 @@ void ProjectTree::updateExternalFileWarning()
}
infoBar->addInfo(Core::InfoBarEntry(externalFileId,
tr("<b>Warning:</b> This file is outside the project directory."),
- Core::InfoBarEntry::GlobalSuppressionEnabled));
+ Core::InfoBarEntry::GlobalSuppression::Enabled));
}
bool ProjectTree::hasFocus(ProjectTreeWidget *widget)
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 5e4b19f8c9..f18b21a9be 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -335,18 +335,20 @@ int ProjectTreeWidget::expandedCount(Node *node)
void ProjectTreeWidget::rowsInserted(const QModelIndex &parent, int start, int end)
{
+ if (m_delayedRename.isEmpty())
+ return;
Node *node = m_model->nodeForIndex(parent);
QTC_ASSERT(node, return);
- int i = start;
- while (i <= end) {
+ for (int i = start; i <= end && !m_delayedRename.isEmpty(); ++i) {
QModelIndex idx = m_model->index(i, 0, parent);
Node *n = m_model->nodeForIndex(idx);
- if (n && n->filePath() == m_delayedRename) {
+ if (!n)
+ continue;
+ const int renameIdx = m_delayedRename.indexOf(n->filePath());
+ if (renameIdx != -1) {
m_view->setCurrentIndex(idx);
- m_delayedRename.clear();
- break;
+ m_delayedRename.removeAt(renameIdx);
}
- ++i;
}
}
@@ -460,14 +462,14 @@ void ProjectTreeWidget::editCurrentItem()
void ProjectTreeWidget::renamed(const FilePath &oldPath, const FilePath &newPath)
{
update();
- Q_UNUSED(oldPath);
+ Q_UNUSED(oldPath)
if (!currentNode() || currentNode()->filePath() != newPath) {
// try to find the node
Node *node = nodeForFile(newPath);
if (node)
m_view->setCurrentIndex(m_model->indexForNode(node));
else
- m_delayedRename = newPath;
+ m_delayedRename << newPath;
}
}
@@ -503,7 +505,7 @@ void ProjectTreeWidget::setCurrentItem(Node *node)
void ProjectTreeWidget::handleCurrentItemChange(const QModelIndex &current)
{
- Q_UNUSED(current);
+ Q_UNUSED(current)
ProjectTree::nodeChanged(this);
}
diff --git a/src/plugins/projectexplorer/projecttreewidget.h b/src/plugins/projectexplorer/projecttreewidget.h
index c4b729f097..74b301e93b 100644
--- a/src/plugins/projectexplorer/projecttreewidget.h
+++ b/src/plugins/projectexplorer/projecttreewidget.h
@@ -94,7 +94,7 @@ private:
QString m_modelId;
bool m_autoSync = true;
- Utils::FilePath m_delayedRename;
+ QList<Utils::FilePath> m_delayedRename;
static QList<ProjectTreeWidget *> m_projectTreeWidgets;
friend class ProjectTreeWidgetFactory;
diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp
index 7827034c2a..0f2bfb4dc3 100644
--- a/src/plugins/projectexplorer/projectwelcomepage.cpp
+++ b/src/plugins/projectexplorer/projectwelcomepage.cpp
@@ -37,6 +37,7 @@
#include <utils/algorithm.h>
#include <utils/fileutils.h>
+#include <utils/icon.h>
#include <utils/stringutils.h>
#include <utils/theme/theme.h>
@@ -535,13 +536,19 @@ public:
if (!projectWelcomePage->m_projectModel)
projectWelcomePage->m_projectModel = new ProjectModel(this);
+ auto manageSessionsButton = new WelcomePageButton(this);
+ manageSessionsButton->setText(ProjectWelcomePage::tr("Manage"));
+ const Icon icon({{":/utils/images/settings.png", Theme::Welcome_ForegroundSecondaryColor}}, Icon::Tint);
+ manageSessionsButton->setIcon(icon.pixmap());
+ manageSessionsButton->setOnClicked([] { ProjectExplorerPlugin::showSessionManager(); });
+
auto newButton = new WelcomePageButton(this);
- newButton->setText(ProjectWelcomePage::tr("New Project"));
+ newButton->setText(ProjectWelcomePage::tr("New"));
newButton->setIcon(pixmap("new", Theme::Welcome_ForegroundSecondaryColor));
newButton->setOnClicked([] { ProjectExplorerPlugin::openNewProjectDialog(); });
auto openButton = new WelcomePageButton(this);
- openButton->setText(ProjectWelcomePage::tr("Open Project"));
+ openButton->setText(ProjectWelcomePage::tr("Open"));
openButton->setIcon(pixmap("open", Theme::Welcome_ForegroundSecondaryColor));
openButton->setOnClicked([] { ProjectExplorerPlugin::openOpenProjectDialog(); });
@@ -551,7 +558,7 @@ public:
auto recentProjectsLabel = new QLabel(this);
recentProjectsLabel->setFont(sizedFont(16, this));
- recentProjectsLabel->setText(ProjectWelcomePage::tr("Recent Projects"));
+ recentProjectsLabel->setText(ProjectWelcomePage::tr("Projects"));
auto sessionsList = new TreeView(this);
sessionsList->setModel(projectWelcomePage->m_sessionModel);
@@ -567,11 +574,17 @@ public:
auto hbox11 = new QHBoxLayout;
hbox11->setContentsMargins(0, 0, 0, 0);
- hbox11->addWidget(newButton);
+ hbox11->addWidget(sessionsLabel);
+ hbox11->addSpacing(16);
+ hbox11->addWidget(manageSessionsButton);
hbox11->addStretch(1);
auto hbox21 = new QHBoxLayout;
hbox21->setContentsMargins(0, 0, 0, 0);
+ hbox21->addWidget(recentProjectsLabel);
+ hbox21->addSpacing(16);
+ hbox21->addWidget(newButton);
+ hbox21->addSpacing(16);
hbox21->addWidget(openButton);
hbox21->addStretch(1);
@@ -580,16 +593,13 @@ public:
vbox1->addStrut(200);
vbox1->addItem(hbox11);
vbox1->addSpacing(16);
- vbox1->addWidget(sessionsLabel);
- vbox1->addSpacing(21);
vbox1->addWidget(sessionsList);
auto vbox2 = new QVBoxLayout;
vbox2->setContentsMargins(0, 0, 0, 0);
+ vbox1->addStrut(200);
vbox2->addItem(hbox21);
vbox2->addSpacing(16);
- vbox2->addWidget(recentProjectsLabel);
- vbox2->addSpacing(21);
vbox2->addWidget(projectsList);
auto hbox = new QHBoxLayout(this);
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 065de1e715..96cfc251d3 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -552,12 +552,8 @@ public:
BuildConfiguration *lastBc = nullptr;
for (const BuildInfo &info : projectImporter->import(path, false)) {
Target *target = project->target(info.kitId);
- if (!target) {
- std::unique_ptr<Target> newTarget = project->createTarget(KitManager::kit(info.kitId));
- target = newTarget.get();
- if (newTarget)
- project->addTarget(std::move(newTarget));
- }
+ if (!target)
+ target = project->addTargetForKit(KitManager::kit(info.kitId));
if (target) {
projectImporter->makePersistent(target->kit());
BuildConfiguration *bc = info.factory()->create(target, info);
diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp
index 9eaf136d8b..692c40d78d 100644
--- a/src/plugins/projectexplorer/projectwizardpage.cpp
+++ b/src/plugins/projectexplorer/projectwizardpage.cpp
@@ -27,7 +27,6 @@
#include "ui_projectwizardpage.h"
#include "project.h"
-#include "projectexplorer.h"
#include "session.h"
#include <coreplugin/icore.h>
@@ -95,7 +94,7 @@ AddNewTree::AddNewTree(FolderNode *node, QList<AddNewTree *> children, const QSt
m_canAdd(false)
{
if (node)
- m_toolTip = ProjectExplorerPlugin::directoryFor(node);
+ m_toolTip = node->directory();
foreach (AddNewTree *child, children)
appendChild(child);
}
@@ -107,7 +106,7 @@ AddNewTree::AddNewTree(FolderNode *node, QList<AddNewTree *> children,
m_priority(info.priority)
{
if (node)
- m_toolTip = ProjectExplorerPlugin::directoryFor(node);
+ m_toolTip = node->directory();
foreach (AddNewTree *child, children)
appendChild(child);
}
@@ -180,7 +179,7 @@ void BestNodeSelector::inspect(AddNewTree *tree, bool isContextNode)
if (m_deploys)
return;
- const QString projectDirectory = ProjectExplorerPlugin::directoryFor(node);
+ const QString projectDirectory = node->directory();
const int projectDirectorySize = projectDirectory.size();
if (m_commonDirectory != projectDirectory
&& !m_commonDirectory.startsWith(projectDirectory + QLatin1Char('/'))
diff --git a/src/plugins/projectexplorer/rawprojectpart.cpp b/src/plugins/projectexplorer/rawprojectpart.cpp
new file mode 100644
index 0000000000..4f24eaf49e
--- /dev/null
+++ b/src/plugins/projectexplorer/rawprojectpart.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "rawprojectpart.h"
+
+#include "abi.h"
+#include "kitinformation.h"
+#include "project.h"
+#include "projectexplorerconstants.h"
+#include "target.h"
+
+#include <utils/algorithm.h>
+
+namespace ProjectExplorer {
+
+RawProjectPartFlags::RawProjectPartFlags(const ToolChain *toolChain,
+ const QStringList &commandLineFlags)
+{
+ // Keep the following cheap/non-blocking for the ui thread. Expensive
+ // operations are encapsulated in ToolChainInfo as "runners".
+ this->commandLineFlags = commandLineFlags;
+ if (toolChain) {
+ warningFlags = toolChain->warningFlags(commandLineFlags);
+ languageExtensions = toolChain->languageExtensions(commandLineFlags);
+ }
+}
+
+void RawProjectPart::setDisplayName(const QString &displayName)
+{
+ this->displayName = displayName;
+}
+
+void RawProjectPart::setFiles(const QStringList &files,
+ const FileIsActive &fileIsActive,
+ const GetMimeType &getMimeType)
+{
+ this->files = files;
+ this->fileIsActive = fileIsActive;
+ this->getMimeType = getMimeType;
+}
+
+static QString trimTrailingSlashes(const QString &path) {
+ QString p = path;
+ while (p.endsWith('/') && p.count() > 1) {
+ p.chop(1);
+ }
+ return p;
+}
+
+HeaderPath RawProjectPart::frameworkDetectionHeuristic(const HeaderPath &header)
+{
+ QString path = trimTrailingSlashes(header.path);
+
+ if (path.endsWith(".framework")) {
+ path = path.left(path.lastIndexOf(QLatin1Char('/')));
+ return {path, HeaderPathType::Framework};
+ }
+ return header;
+}
+
+void RawProjectPart::setProjectFileLocation(const QString &projectFile, int line, int column)
+{
+ this->projectFile = projectFile;
+ projectFileLine = line;
+ projectFileColumn = column;
+}
+
+void RawProjectPart::setConfigFileName(const QString &configFileName)
+{
+ this->projectConfigFile = configFileName;
+}
+
+void RawProjectPart::setBuildSystemTarget(const QString &target)
+{
+ buildSystemTarget = target;
+}
+
+void RawProjectPart::setCallGroupId(const QString &id)
+{
+ callGroupId = id;
+}
+
+void RawProjectPart::setQtVersion(Utils::QtVersion qtVersion)
+{
+ this->qtVersion = qtVersion;
+}
+
+void RawProjectPart::setMacros(const Macros &macros)
+{
+ this->projectMacros = macros;
+}
+
+void RawProjectPart::setHeaderPaths(const HeaderPaths &headerPaths)
+{
+ this->headerPaths = headerPaths;
+}
+
+void RawProjectPart::setIncludePaths(const QStringList &includePaths)
+{
+ this->headerPaths = Utils::transform<QVector>(includePaths, [](const QString &path) {
+ HeaderPath hp(path, HeaderPathType::User);
+ return RawProjectPart::frameworkDetectionHeuristic(hp);
+ });
+}
+
+void RawProjectPart::setPreCompiledHeaders(const QStringList &preCompiledHeaders)
+{
+ this->precompiledHeaders = preCompiledHeaders;
+}
+
+void RawProjectPart::setSelectedForBuilding(bool yesno)
+{
+ this->selectedForBuilding = yesno;
+}
+
+void RawProjectPart::setFlagsForC(const RawProjectPartFlags &flags)
+{
+ flagsForC = flags;
+}
+
+void RawProjectPart::setFlagsForCxx(const RawProjectPartFlags &flags)
+{
+ flagsForCxx = flags;
+}
+
+void RawProjectPart::setBuildTargetType(BuildTargetType type)
+{
+ buildTargetType = type;
+}
+
+KitInfo::KitInfo(Project *project)
+{
+ // Kit
+ if (Target *target = project->activeTarget())
+ kit = target->kit();
+ else
+ kit = KitManager::defaultKit();
+
+ // Toolchains
+ if (kit) {
+ cToolChain = ToolChainKitAspect::toolChain(kit, Constants::C_LANGUAGE_ID);
+ cxxToolChain = ToolChainKitAspect::toolChain(kit, Constants::CXX_LANGUAGE_ID);
+ }
+
+ // Sysroot
+ sysRootPath = SysRootKitAspect::sysRoot(kit).toString();
+}
+
+bool KitInfo::isValid() const
+{
+ return kit;
+}
+
+ToolChainInfo::ToolChainInfo(const ToolChain *toolChain,
+ const QString &sysRootPath,
+ const Utils::Environment &env)
+{
+ if (toolChain) {
+ // Keep the following cheap/non-blocking for the ui thread...
+ type = toolChain->typeId();
+ isMsvc2015ToolChain = toolChain->targetAbi().osFlavor() == Abi::WindowsMsvc2015Flavor;
+ wordWidth = toolChain->targetAbi().wordWidth();
+ targetTriple = toolChain->originalTargetTriple();
+ extraCodeModelFlags = toolChain->extraCodeModelFlags();
+
+ // ...and save the potentially expensive operations for later so that
+ // they can be run from a worker thread.
+ this->sysRootPath = sysRootPath;
+ headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner(env);
+ macroInspectionRunner = toolChain->createMacroInspectionRunner();
+ }
+}
+
+ProjectUpdateInfo::ProjectUpdateInfo(Project *project,
+ const KitInfo &kitInfo,
+ const Utils::Environment &env,
+ const RawProjectParts &rawProjectParts)
+ : project(project)
+ , rawProjectParts(rawProjectParts)
+ , cToolChain(kitInfo.cToolChain)
+ , cxxToolChain(kitInfo.cxxToolChain)
+ , cToolChainInfo(ToolChainInfo(cToolChain, kitInfo.sysRootPath, env))
+ , cxxToolChainInfo(ToolChainInfo(cxxToolChain, kitInfo.sysRootPath, env))
+{}
+
+bool ProjectUpdateInfo::isValid() const
+{
+ return project && !rawProjectParts.isEmpty();
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/rawprojectpart.h b/src/plugins/projectexplorer/rawprojectpart.h
new file mode 100644
index 0000000000..eda3ce5ad7
--- /dev/null
+++ b/src/plugins/projectexplorer/rawprojectpart.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "buildtargettype.h"
+#include "headerpath.h"
+#include "projectexplorer_export.h"
+#include "projectexplorer_global.h"
+#include "projectmacro.h"
+
+// this include style is forced for the cpp unit test mocks
+#include <projectexplorer/toolchain.h>
+
+#include <utils/cpplanguage_details.h>
+#include <utils/environment.h>
+
+#include <QPointer>
+
+#include <functional>
+
+namespace ProjectExplorer {
+
+class Kit;
+class Project;
+
+class PROJECTEXPLORER_EXPORT RawProjectPartFlags
+{
+public:
+ RawProjectPartFlags() = default;
+ RawProjectPartFlags(const ToolChain *toolChain, const QStringList &commandLineFlags);
+
+public:
+ QStringList commandLineFlags;
+ // The following are deduced from commandLineFlags.
+ WarningFlags warningFlags = WarningFlags::Default;
+ Utils::LanguageExtensions languageExtensions = Utils::LanguageExtension::None;
+};
+
+class PROJECTEXPLORER_EXPORT RawProjectPart
+{
+public:
+ void setDisplayName(const QString &displayName);
+
+ void setProjectFileLocation(const QString &projectFile, int line = -1, int column = -1);
+ void setConfigFileName(const QString &configFileName);
+ void setCallGroupId(const QString &id);
+
+ // FileIsActive and GetMimeType must be thread-safe.
+ using FileIsActive = std::function<bool(const QString &filePath)>;
+ using GetMimeType = std::function<QString(const QString &filePath)>;
+ void setFiles(const QStringList &files,
+ const FileIsActive &fileIsActive = {},
+ const GetMimeType &getMimeType = {});
+ static HeaderPath frameworkDetectionHeuristic(const HeaderPath &header);
+ void setHeaderPaths(const HeaderPaths &headerPaths);
+ void setIncludePaths(const QStringList &includePaths);
+ void setPreCompiledHeaders(const QStringList &preCompiledHeaders);
+
+ void setBuildSystemTarget(const QString &target);
+ void setBuildTargetType(BuildTargetType type);
+ void setSelectedForBuilding(bool yesno);
+
+ void setFlagsForC(const RawProjectPartFlags &flags);
+ void setFlagsForCxx(const RawProjectPartFlags &flags);
+
+ void setMacros(const Macros &macros);
+ void setQtVersion(Utils::QtVersion qtVersion);
+
+public:
+ QString displayName;
+
+ QString projectFile;
+ int projectFileLine = -1;
+ int projectFileColumn = -1;
+ QString callGroupId;
+
+ // Files
+ QStringList files;
+ FileIsActive fileIsActive;
+ GetMimeType getMimeType;
+ QStringList precompiledHeaders;
+ HeaderPaths headerPaths;
+ QString projectConfigFile; // Generic Project Manager only
+
+ // Build system
+ QString buildSystemTarget;
+ BuildTargetType buildTargetType = BuildTargetType::Unknown;
+ bool selectedForBuilding = true;
+
+ // Flags
+ RawProjectPartFlags flagsForC;
+ RawProjectPartFlags flagsForCxx;
+
+ // Misc
+ Macros projectMacros;
+ Utils::QtVersion qtVersion = Utils::QtVersion::Unknown;
+};
+
+using RawProjectParts = QVector<RawProjectPart>;
+
+class PROJECTEXPLORER_EXPORT KitInfo
+{
+public:
+ explicit KitInfo(Project *project);
+
+ bool isValid() const;
+
+ Kit *kit = nullptr;
+ ToolChain *cToolChain = nullptr;
+ ToolChain *cxxToolChain = nullptr;
+
+ Utils::QtVersion projectPartQtVersion = Utils::QtVersion::None;
+
+ QString sysRootPath;
+};
+
+class PROJECTEXPLORER_EXPORT ToolChainInfo
+{
+public:
+ ToolChainInfo() = default;
+ ToolChainInfo(const ProjectExplorer::ToolChain *toolChain,
+ const QString &sysRootPath,
+ const Utils::Environment &env);
+
+ bool isValid() const { return type.isValid(); }
+
+public:
+ Core::Id type;
+ bool isMsvc2015ToolChain = false;
+ unsigned wordWidth = 0;
+ QString targetTriple;
+ QStringList extraCodeModelFlags;
+
+ QString sysRootPath; // For headerPathsRunner.
+ ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner;
+ ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner;
+};
+
+class PROJECTEXPLORER_EXPORT ProjectUpdateInfo
+{
+public:
+ ProjectUpdateInfo() = default;
+ ProjectUpdateInfo(Project *project,
+ const KitInfo &kitInfo,
+ const Utils::Environment &env,
+ const RawProjectParts &rawProjectParts);
+ bool isValid() const;
+
+public:
+ QPointer<Project> project;
+ RawProjectParts rawProjectParts;
+
+ const ToolChain *cToolChain = nullptr;
+ const ToolChain *cxxToolChain = nullptr;
+
+ ToolChainInfo cToolChainInfo;
+ ToolChainInfo cxxToolChainInfo;
+};
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index 5c3c6fc0e9..c0a06f099a 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -25,17 +25,18 @@
#include "runconfiguration.h"
-#include "project.h"
-#include "runcontrol.h"
-#include "target.h"
-#include "toolchain.h"
#include "abi.h"
#include "buildconfiguration.h"
#include "environmentaspect.h"
#include "kitinformation.h"
+#include "kitinformation.h"
+#include "project.h"
+#include "projectexplorer.h"
#include "runconfigurationaspects.h"
+#include "runcontrol.h"
#include "session.h"
-#include "kitinformation.h"
+#include "target.h"
+#include "toolchain.h"
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
@@ -61,15 +62,15 @@ using namespace ProjectExplorer::Internal;
namespace ProjectExplorer {
+const char BUILD_KEY[] = "ProjectExplorer.RunConfiguration.BuildKey";
+
///////////////////////////////////////////////////////////////////////
//
// ISettingsAspect
//
///////////////////////////////////////////////////////////////////////
-ISettingsAspect::ISettingsAspect(const ConfigWidgetCreator &creator)
- : m_configWidgetCreator(creator)
-{}
+ISettingsAspect::ISettingsAspect() = default;
QWidget *ISettingsAspect::createConfigWidget() const
{
@@ -77,6 +78,12 @@ QWidget *ISettingsAspect::createConfigWidget() const
return m_configWidgetCreator();
}
+void ISettingsAspect::setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetCreator)
+{
+ m_configWidgetCreator = configWidgetCreator;
+}
+
+
///////////////////////////////////////////////////////////////////////
//
// IRunConfigurationAspect
@@ -145,7 +152,7 @@ void GlobalOrProjectAspect::resetProjectToGlobalSettings()
necessary data as the RunControl may continue to exist after the RunConfiguration
has been destroyed.
- A RunConfiguration disables itself when the project is parsing or has no parsing
+ A RunConfiguration disables itself if the project has no parsing
data available. The disabledReason() method can be used to get a user-facing string
describing why the RunConfiguration considers itself unfit for use.
@@ -160,8 +167,7 @@ static std::vector<RunConfiguration::AspectFactory> theAspectFactories;
RunConfiguration::RunConfiguration(Target *target, Core::Id id)
: ProjectConfiguration(target, id)
{
- connect(target->project(), &Project::parsingStarted,
- this, [this]() { updateEnabledState(); });
+ QTC_CHECK(target && target == this->target());
connect(target->project(), &Project::parsingFinished,
this, [this]() { updateEnabledState(); });
@@ -171,8 +177,10 @@ RunConfiguration::RunConfiguration(Target *target, Core::Id id)
updateEnabledState();
});
- connect(this, &RunConfiguration::enabledChanged,
- this, &RunConfiguration::requestRunActionsUpdate);
+ connect(this, &RunConfiguration::enabledChanged, this, [this] {
+ if (isActive() && project() == SessionManager::startupProject())
+ emit ProjectExplorerPlugin::instance()->updateRunActions();
+ });
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Run Settings"));
@@ -184,7 +192,7 @@ RunConfiguration::RunConfiguration(Target *target, Core::Id id)
expander->registerPrefix("CurrentRun:Env", tr("Variables in the current run environment"),
[this](const QString &var) {
const auto envAspect = aspect<EnvironmentAspect>();
- return envAspect ? envAspect->environment().value(var) : QString();
+ return envAspect ? envAspect->environment().expandedValueForKey(var) : QString();
});
expander->registerVariable(Constants::VAR_CURRENTRUN_WORKINGDIR,
@@ -201,10 +209,14 @@ RunConfiguration::RunConfiguration(Target *target, Core::Id id)
for (const AspectFactory &factory : theAspectFactories)
m_aspects.append(factory(target));
- m_executableGetter = [this] {
+ m_commandLineGetter = [this] {
+ FilePath executable;
if (const auto executableAspect = aspect<ExecutableAspect>())
- return executableAspect->executable();
- return FilePath();
+ executable = executableAspect->executable();
+ QString arguments;
+ if (const auto argumentsAspect = aspect<ArgumentsAspect>())
+ arguments = argumentsAspect->arguments(macroExpander());
+ return CommandLine{executable, arguments, CommandLine::Raw};
};
}
@@ -225,12 +237,11 @@ void RunConfiguration::setEnabled(bool enabled)
QString RunConfiguration::disabledReason() const
{
- if (target()->project()->isParsing())
- return tr("The Project is currently being parsed.");
- if (!target()->project()->hasParsingData()) {
- QString msg = tr("The project could not be fully parsed.");
+ if (!project()->hasParsingData()) {
+ QString msg = project()->isParsing() ? tr("The project is currently being parsed.")
+ : tr("The project could not be fully parsed.");
const FilePath projectFilePath = buildTargetInfo().projectFilePath;
- if (!projectFilePath.exists())
+ if (!projectFilePath.isEmpty() && !projectFilePath.exists())
msg += '\n' + tr("The project file \"%1\" does not exist.").arg(projectFilePath.toString());
return msg;
}
@@ -241,7 +252,7 @@ QWidget *RunConfiguration::createConfigurationWidget()
{
auto widget = new QWidget;
auto formLayout = new QFormLayout(widget);
- formLayout->setMargin(0);
+ formLayout->setContentsMargins(0, 0, 0, 0);
formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
for (ProjectConfigurationAspect *aspect : m_aspects) {
@@ -259,9 +270,7 @@ QWidget *RunConfiguration::createConfigurationWidget()
void RunConfiguration::updateEnabledState()
{
- Project *p = target()->project();
-
- setEnabled(!p->isParsing() && p->hasParsingData());
+ setEnabled(project()->hasParsingData());
}
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
@@ -283,6 +292,14 @@ RunConfiguration *RunConfiguration::startupRunConfiguration()
return nullptr;
}
+QMap<Core::Id, QVariantMap> RunConfiguration::aspectData() const
+{
+ QMap<Core::Id, QVariantMap> data;
+ for (ProjectConfigurationAspect *aspect : m_aspects)
+ aspect->toMap(data[aspect->id()]);
+ return data;
+}
+
bool RunConfiguration::isConfigured() const
{
return true;
@@ -304,20 +321,12 @@ BuildConfiguration *RunConfiguration::activeBuildConfiguration() const
return target()->activeBuildConfiguration();
}
-Target *RunConfiguration::target() const
-{
- return static_cast<Target *>(parent());
-}
-
-Project *RunConfiguration::project() const
-{
- return target()->project();
-}
-
QVariantMap RunConfiguration::toMap() const
{
QVariantMap map = ProjectConfiguration::toMap();
+ map.insert(BUILD_KEY, m_buildKey);
+
// FIXME: Remove this id mangling, e.g. by using a separate entry for the build key.
if (!m_buildKey.isEmpty()) {
const Core::Id mangled = id().withSuffix(m_buildKey);
@@ -327,14 +336,14 @@ QVariantMap RunConfiguration::toMap() const
return map;
}
-void RunConfiguration::setExecutableGetter(const RunConfiguration::ExecutableGetter &exeGetter)
+void RunConfiguration::setCommandLineGetter(const CommandLineGetter &cmdGetter)
{
- m_executableGetter = exeGetter;
+ m_commandLineGetter = cmdGetter;
}
-FilePath RunConfiguration::executable() const
+CommandLine RunConfiguration::commandLine() const
{
- return m_executableGetter();
+ return m_commandLineGetter();
}
BuildTargetInfo RunConfiguration::buildTargetInfo() const
@@ -347,9 +356,13 @@ bool RunConfiguration::fromMap(const QVariantMap &map)
if (!ProjectConfiguration::fromMap(map))
return false;
- // FIXME: Remove this id mangling, e.g. by using a separate entry for the build key.
- const Core::Id mangledId = Core::Id::fromSetting(map.value(settingsIdKey()));
- m_buildKey = mangledId.suffixAfter(id());
+ m_buildKey = map.value(BUILD_KEY).toString();
+
+ if (m_buildKey.isEmpty()) {
+ // FIXME: Remove this id mangling, e.g. by using a separate entry for the build key.
+ const Core::Id mangledId = Core::Id::fromSetting(map.value(settingsIdKey()));
+ m_buildKey = mangledId.suffixAfter(id());
+ }
return true;
}
@@ -392,9 +405,7 @@ bool RunConfiguration::fromMap(const QVariantMap &map)
Runnable RunConfiguration::runnable() const
{
Runnable r;
- r.executable = executable().toString();
- if (auto argumentsAspect = aspect<ArgumentsAspect>())
- r.commandLineArguments = argumentsAspect->arguments(macroExpander());
+ r.setCommandLine(commandLine());
if (auto workingDirectoryAspect = aspect<WorkingDirectoryAspect>())
r.workingDirectory = workingDirectoryAspect->workingDirectory(macroExpander()).toString();
if (auto environmentAspect = aspect<EnvironmentAspect>())
@@ -402,14 +413,6 @@ Runnable RunConfiguration::runnable() const
return r;
}
-OutputFormatter *RunConfiguration::createOutputFormatter() const
-{
- if (m_outputFormatterCreator)
- return m_outputFormatterCreator(project());
- return new OutputFormatter();
-}
-
-
/*!
\class ProjectExplorer::IRunConfigurationFactory
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index 3e5cbc6b15..d78aacaabc 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -33,13 +33,7 @@
#include <utils/environment.h>
#include <utils/port.h>
-#include <utils/processhandle.h>
-#include <utils/qtcassert.h>
-#include <utils/icon.h>
-#include <QHash>
-#include <QPointer>
-#include <QVariant>
#include <QWidget>
#include <functional>
@@ -54,16 +48,8 @@ class Runnable;
class RunConfigurationFactory;
class RunConfiguration;
class RunConfigurationCreationInfo;
-class RunControl;
-class RunWorkerFactory;
class Target;
-namespace Internal {
-class RunControlPrivate;
-class RunWorkerPrivate;
-class SimpleRunControlPrivate;
-} // Internal
-
/**
* An interface for a hunk of global or per-project
* configuration data.
@@ -75,14 +61,15 @@ class PROJECTEXPLORER_EXPORT ISettingsAspect : public QObject
Q_OBJECT
public:
- /// Create a configuration widget for this settings aspect.
- using ConfigWidgetCreator = std::function<QWidget *()>;
+ ISettingsAspect();
- explicit ISettingsAspect(const ConfigWidgetCreator &configWidgetCreator);
+ /// Create a configuration widget for this settings aspect.
QWidget *createConfigWidget() const;
protected:
- ///
+ using ConfigWidgetCreator = std::function<QWidget *()>;
+ void setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetCreator);
+
friend class GlobalOrProjectAspect;
/// Converts current object into map for storage.
virtual void toMap(QVariantMap &map) const = 0;
@@ -152,17 +139,14 @@ public:
// TODO rename function
virtual ConfigurationState ensureConfigured(QString *errorMessage = nullptr);
- Target *target() const;
- Project *project() const override;
-
Utils::OutputFormatter *createOutputFormatter() const;
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
- using ExecutableGetter = std::function<Utils::FilePath()>;
- void setExecutableGetter(const ExecutableGetter &exeGetter);
- Utils::FilePath executable() const;
+ using CommandLineGetter = std::function<Utils::CommandLine()>;
+ void setCommandLineGetter(const CommandLineGetter &cmdGetter);
+ Utils::CommandLine commandLine() const;
virtual Runnable runnable() const;
@@ -187,8 +171,9 @@ public:
addAspectFactory([](Target *target) { return new T(target); });
}
+ QMap<Core::Id, QVariantMap> aspectData() const;
+
signals:
- void requestRunActionsUpdate();
void configurationFinished();
void enabledChanged();
@@ -198,11 +183,6 @@ protected:
/// convenience function to get current build configuration.
BuildConfiguration *activeBuildConfiguration() const;
- template<class T> void setOutputFormatter()
- {
- m_outputFormatterCreator = [](Project *project) { return new T(project); };
- }
-
virtual void updateEnabledState();
virtual void doAdditionalSetup(const RunConfigurationCreationInfo &) {}
@@ -213,8 +193,7 @@ private:
QString m_buildKey;
bool m_isEnabled = false;
- std::function<Utils::OutputFormatter *(Project *)> m_outputFormatterCreator;
- ExecutableGetter m_executableGetter;
+ CommandLineGetter m_commandLineGetter;
};
class RunConfigurationCreationInfo
@@ -245,6 +224,7 @@ public:
static RunConfiguration *clone(Target *parent, RunConfiguration *source);
static const QList<RunConfigurationCreationInfo> creatorsForTarget(Target *parent);
+ Core::Id id() const { return m_runConfigBaseId; }
Core::Id runConfigurationBaseId() const { return m_runConfigBaseId; }
static QString decoratedTargetName(const QString &targetName, Target *kit);
diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp
index fe890b3a29..0358dd54a5 100644
--- a/src/plugins/projectexplorer/runconfigurationaspects.cpp
+++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp
@@ -32,15 +32,17 @@
#include "runconfiguration.h"
#include "target.h"
-#include <utils/utilsicons.h>
+#include <utils/detailsbutton.h>
#include <utils/fancylineedit.h>
#include <utils/pathchooser.h>
#include <utils/qtcprocess.h>
+#include <utils/utilsicons.h>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QFormLayout>
+#include <QPlainTextEdit>
#include <QToolButton>
using namespace Utils;
@@ -264,7 +266,13 @@ ArgumentsAspect::ArgumentsAspect()
QString ArgumentsAspect::arguments(const MacroExpander *expander) const
{
QTC_ASSERT(expander, return m_arguments);
- return expander->expandProcessArgs(m_arguments);
+ if (m_currentlyExpanding)
+ return m_arguments;
+
+ m_currentlyExpanding = true;
+ const QString expanded = expander->expandProcessArgs(m_arguments);
+ m_currentlyExpanding = false;
+ return expanded;
}
QString ArgumentsAspect::unexpandedArguments() const
@@ -280,6 +288,8 @@ void ArgumentsAspect::setArguments(const QString &arguments)
}
if (m_chooser && m_chooser->text() != arguments)
m_chooser->setText(arguments);
+ if (m_multiLineChooser && m_multiLineChooser->toPlainText() != arguments)
+ m_multiLineChooser->setPlainText(arguments);
}
void ArgumentsAspect::fromMap(const QVariantMap &map)
@@ -291,25 +301,77 @@ void ArgumentsAspect::fromMap(const QVariantMap &map)
else
m_arguments = args.toString();
- if (m_chooser)
+ m_multiLine = map.value(settingsKey() + ".multi", false).toBool();
+
+ if (m_multiLineButton)
+ m_multiLineButton->setChecked(m_multiLine);
+ if (!m_multiLine && m_chooser)
m_chooser->setText(m_arguments);
+ if (m_multiLine && m_multiLineChooser)
+ m_multiLineChooser->setPlainText(m_arguments);
}
void ArgumentsAspect::toMap(QVariantMap &map) const
{
map.insert(settingsKey(), m_arguments);
+ map.insert(settingsKey() + ".multi", m_multiLine);
}
-void ArgumentsAspect::addToConfigurationLayout(QFormLayout *layout)
+QWidget *ArgumentsAspect::setupChooser()
{
- QTC_CHECK(!m_chooser);
- m_chooser = new FancyLineEdit(layout->parentWidget());
- m_chooser->setHistoryCompleter(settingsKey());
+ if (m_multiLine) {
+ if (!m_multiLineChooser) {
+ m_multiLineChooser = new QPlainTextEdit;
+ connect(m_multiLineChooser.data(), &QPlainTextEdit::textChanged,
+ this, [this] { setArguments(m_multiLineChooser->toPlainText()); });
+ }
+ m_multiLineChooser->setPlainText(m_arguments);
+ return m_multiLineChooser.data();
+ }
+ if (!m_chooser) {
+ m_chooser = new FancyLineEdit;
+ m_chooser->setHistoryCompleter(settingsKey());
+ connect(m_chooser.data(), &QLineEdit::textChanged, this, &ArgumentsAspect::setArguments);
+ }
m_chooser->setText(m_arguments);
+ return m_chooser.data();
+}
- connect(m_chooser.data(), &QLineEdit::textChanged, this, &ArgumentsAspect::setArguments);
-
- layout->addRow(tr("Command line arguments:"), m_chooser);
+void ArgumentsAspect::addToConfigurationLayout(QFormLayout *layout)
+{
+ QTC_CHECK(!m_chooser && !m_multiLineChooser && !m_multiLineButton);
+
+ const auto container = new QWidget;
+ const auto containerLayout = new QHBoxLayout(container);
+ containerLayout->setContentsMargins(0, 0, 0, 0);
+ containerLayout->addWidget(setupChooser());
+ m_multiLineButton = new ExpandButton;
+ m_multiLineButton->setToolTip(tr("Toggle multi-line mode"));
+ m_multiLineButton->setChecked(m_multiLine);
+ connect(m_multiLineButton, &QCheckBox::clicked, this, [this](bool checked) {
+ if (m_multiLine == checked)
+ return;
+ m_multiLine = checked;
+ setupChooser();
+ QWidget *oldWidget = nullptr;
+ QWidget *newWidget = nullptr;
+ if (m_multiLine) {
+ oldWidget = m_chooser.data();
+ newWidget = m_multiLineChooser.data();
+ } else {
+ oldWidget = m_multiLineChooser.data();
+ newWidget = m_chooser.data();
+ }
+ QTC_ASSERT(!oldWidget == !newWidget, return);
+ if (oldWidget) {
+ QTC_ASSERT(oldWidget->parentWidget()->layout(), return);
+ oldWidget->parentWidget()->layout()->replaceWidget(oldWidget, newWidget);
+ delete oldWidget;
+ }
+ });
+ containerLayout->addWidget(m_multiLineButton);
+ containerLayout->setAlignment(m_multiLineButton, Qt::AlignTop);
+ layout->addRow(tr("Command line arguments:"), container);
}
/*!
@@ -383,9 +445,9 @@ void ExecutableAspect::makeOverridable(const QString &overridingKey, const QStri
FilePath ExecutableAspect::executable() const
{
if (m_alternativeExecutable && m_alternativeExecutable->isChecked())
- return m_alternativeExecutable->fileName();
+ return m_alternativeExecutable->filePath();
- return m_executable.fileName();
+ return m_executable.filePath();
}
void ExecutableAspect::addToConfigurationLayout(QFormLayout *layout)
@@ -408,6 +470,7 @@ void ExecutableAspect::setPlaceHolderText(const QString &placeHolderText)
void ExecutableAspect::setExecutable(const FilePath &executable)
{
m_executable.setValue(executable.toString());
+ m_executable.setShowToolTipOnLabel(true);
}
void ExecutableAspect::setSettingsKey(const QString &key)
diff --git a/src/plugins/projectexplorer/runconfigurationaspects.h b/src/plugins/projectexplorer/runconfigurationaspects.h
index 77973f65f4..2b65737789 100644
--- a/src/plugins/projectexplorer/runconfigurationaspects.h
+++ b/src/plugins/projectexplorer/runconfigurationaspects.h
@@ -29,11 +29,16 @@
#include "applicationlauncher.h"
#include "environmentaspect.h"
+#include <QPointer>
+
QT_BEGIN_NAMESPACE
class QCheckBox;
+class QPlainTextEdit;
class QToolButton;
QT_END_NAMESPACE
+namespace Utils { class ExpandButton; }
+
namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT TerminalAspect : public ProjectConfigurationAspect
@@ -113,8 +118,14 @@ private:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
+ QWidget *setupChooser();
+
QString m_arguments;
QPointer<Utils::FancyLineEdit> m_chooser;
+ QPointer<QPlainTextEdit> m_multiLineChooser;
+ QPointer<Utils::ExpandButton> m_multiLineButton;
+ bool m_multiLine = false;
+ mutable bool m_currentlyExpanding = false;
};
class PROJECTEXPLORER_EXPORT UseLibraryPathsAspect : public BaseBoolAspect
diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp
index f90a8fd48c..4d32362fd0 100644
--- a/src/plugins/projectexplorer/runcontrol.cpp
+++ b/src/plugins/projectexplorer/runcontrol.cpp
@@ -25,6 +25,7 @@
#include "runcontrol.h"
+#include "devicesupport/desktopdevice.h"
#include "project.h"
#include "target.h"
#include "toolchain.h"
@@ -72,9 +73,25 @@ namespace ProjectExplorer {
static QList<RunWorkerFactory *> g_runWorkerFactories;
-RunWorkerFactory::RunWorkerFactory()
+static QSet<Core::Id> g_runModes;
+static QSet<Core::Id> g_runConfigs;
+
+RunWorkerFactory::RunWorkerFactory(const WorkerCreator &producer,
+ const QList<Core::Id> &runModes,
+ const QList<Core::Id> &runConfigs,
+ const QList<Core::Id> &deviceTypes)
+ : m_producer(producer),
+ m_supportedRunModes(runModes),
+ m_supportedRunConfigurations(runConfigs),
+ m_supportedDeviceTypes(deviceTypes)
{
g_runWorkerFactories.append(this);
+
+ // Debugging only.
+ for (Core::Id runMode : runModes)
+ g_runModes.insert(runMode);
+ for (Core::Id runConfig : runConfigs)
+ g_runConfigs.insert(runConfig);
}
RunWorkerFactory::~RunWorkerFactory()
@@ -82,57 +99,54 @@ RunWorkerFactory::~RunWorkerFactory()
g_runWorkerFactories.removeOne(this);
}
-bool RunWorkerFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const
+bool RunWorkerFactory::canRun(Core::Id runMode,
+ Core::Id deviceType,
+ const QString &runConfigId) const
{
if (!m_supportedRunModes.contains(runMode))
return false;
if (!m_supportedRunConfigurations.isEmpty()) {
- if (!m_supportedRunConfigurations.contains(runConfiguration->id()))
- return false;
- }
+ // FIXME: That's to be used after mangled ids are gone.
+ //if (!m_supportedRunConfigurations.contains(runConfigId)
+ // return false;
+ bool ok = false;
+ for (const Core::Id &id : m_supportedRunConfigurations) {
+ if (runConfigId.startsWith(id.toString())) {
+ ok = true;
+ break;
+ }
+ }
- for (const Constraint &constraint : m_constraints) {
- if (!constraint(runConfiguration))
+ if (!ok)
return false;
}
- return true;
-}
-
-void RunWorkerFactory::setProducer(const WorkerCreator &producer)
-{
- m_producer = producer;
-}
+ if (!m_supportedDeviceTypes.isEmpty())
+ return m_supportedDeviceTypes.contains(deviceType);
-void RunWorkerFactory::addConstraint(const Constraint &constraint)
-{
- // Default constructed Constraints are not worth keeping.
- // FIXME: Make it a QTC_ASSERT once there is no code path
- // using this "feature" anymore.
- if (!constraint)
- return;
- m_constraints.append(constraint);
-}
-
-void RunWorkerFactory::addSupportedRunMode(Core::Id runMode)
-{
- m_supportedRunModes.append(runMode);
-}
-
-void RunWorkerFactory::setSupportedRunConfigurations(const QList<Core::Id> &ids)
-{
- m_supportedRunConfigurations = ids;
+ return true;
}
-void RunWorkerFactory::addSupportedRunConfiguration(Core::Id id)
+void RunWorkerFactory::dumpAll()
{
- m_supportedRunConfigurations.append(id);
-}
+ const QList<Core::Id> devices =
+ Utils::transform(IDeviceFactory::allDeviceFactories(), &IDeviceFactory::deviceType);
-void RunWorkerFactory::destroyRemainingRunWorkerFactories()
-{
- qDeleteAll(g_runWorkerFactories);
+ for (Core::Id runMode : qAsConst(g_runModes)) {
+ qDebug() << "";
+ for (Core::Id device : devices) {
+ for (Core::Id runConfig : qAsConst(g_runConfigs)) {
+ const auto check = std::bind(&RunWorkerFactory::canRun,
+ std::placeholders::_1,
+ runMode,
+ device,
+ runConfig.toString());
+ const auto factory = Utils::findOrDefault(g_runWorkerFactories, check);
+ qDebug() << "MODE:" << runMode << device << runConfig << factory;
+ }
+ }
+ }
}
/*!
@@ -310,6 +324,10 @@ public:
Utils::Icon icon;
MacroExpander *macroExpander;
QPointer<RunConfiguration> runConfiguration; // Not owned. Avoid use.
+ QString buildKey;
+ QMap<Core::Id, QVariantMap> settingsData;
+ Core::Id runConfigId;
+ BuildTargetInfo buildTargetInfo;
Kit *kit = nullptr; // Not owned.
QPointer<Target> target; // Not owned.
QPointer<Project> project; // Not owned.
@@ -339,13 +357,13 @@ void RunControl::setRunConfiguration(RunConfiguration *runConfig)
QTC_ASSERT(runConfig, return);
QTC_CHECK(!d->runConfiguration);
d->runConfiguration = runConfig;
+ d->runConfigId = runConfig->id();
d->runnable = runConfig->runnable();
- d->displayName = runConfig->displayName();
- if (auto outputFormatter = runConfig->createOutputFormatter()) {
- delete d->outputFormatter;
- d->outputFormatter = outputFormatter;
- }
+ d->displayName = runConfig->displayName();
d->macroExpander = runConfig->macroExpander();
+ d->buildKey = runConfig->buildKey();
+ d->settingsData = runConfig->aspectData();
+
setTarget(runConfig->target());
}
@@ -354,6 +372,15 @@ void RunControl::setTarget(Target *target)
QTC_ASSERT(target, return);
QTC_CHECK(!d->target);
d->target = target;
+
+ if (!d->buildKey.isEmpty())
+ d->buildTargetInfo = target->buildTarget(d->buildKey);
+
+ delete d->outputFormatter;
+ d->outputFormatter = OutputFormatterFactory::createFormatter(target);
+ if (!d->outputFormatter)
+ d->outputFormatter = new OutputFormatter();
+
setKit(target->kit());
d->project = target->project();
}
@@ -430,38 +457,25 @@ void RunControl::initiateFinish()
QTimer::singleShot(0, d.get(), &RunControlPrivate::initiateFinish);
}
-using WorkerCreators = QHash<Core::Id, RunControl::WorkerCreator>;
-
-static WorkerCreators &theWorkerCreators()
-{
- static WorkerCreators creators;
- return creators;
-}
-
-void RunControl::registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator)
+RunWorker *RunControl::createWorker(Core::Id workerId)
{
- theWorkerCreators().insert(id, workerCreator);
- auto keys = theWorkerCreators().keys();
- Q_UNUSED(keys);
-}
-
-RunWorker *RunControl::createWorker(Core::Id id)
-{
- auto keys = theWorkerCreators().keys();
- Q_UNUSED(keys);
- WorkerCreator creator = theWorkerCreators().value(id);
- if (creator)
- return creator(this);
- creator = device()->workerCreator(id);
- if (creator)
- return creator(this);
- return nullptr;
+ const auto check = std::bind(&RunWorkerFactory::canRun,
+ std::placeholders::_1,
+ workerId,
+ DeviceTypeKitAspect::deviceTypeId(d->kit),
+ QString{});
+ RunWorkerFactory *factory = Utils::findOrDefault(g_runWorkerFactories, check);
+ return factory ? factory->producer()(this) : nullptr;
}
bool RunControl::createMainWorker()
{
- const auto canRun = std::bind(&RunWorkerFactory::canRun, std::placeholders::_1,
- d->runConfiguration, d->runMode);
+ const auto canRun = std::bind(&RunWorkerFactory::canRun,
+ std::placeholders::_1,
+ d->runMode,
+ DeviceTypeKitAspect::deviceTypeId(d->kit),
+ d->runConfigId.toString());
+
const QList<RunWorkerFactory *> candidates = Utils::filtered(g_runWorkerFactories, canRun);
// There might be combinations that cannot run. But that should have been checked
// with canRun below.
@@ -473,9 +487,13 @@ bool RunControl::createMainWorker()
return candidates.front()->producer()(this) != nullptr;
}
-bool RunControl::canRun(RunConfiguration *runConfig, Core::Id runMode)
+bool RunControl::canRun(Core::Id runMode, Core::Id deviceType, Core::Id runConfigId)
{
- const auto check = std::bind(&RunWorkerFactory::canRun, std::placeholders::_1, runConfig, runMode);
+ const auto check = std::bind(&RunWorkerFactory::canRun,
+ std::placeholders::_1,
+ runMode,
+ deviceType,
+ runConfigId.toString());
return Utils::contains(g_runWorkerFactories, check);
}
@@ -879,19 +897,24 @@ ProjectConfigurationAspect *RunControl::aspect(Core::Id id) const
return d->runConfiguration ? d->runConfiguration->aspect(id) : nullptr;
}
-ISettingsAspect *RunControl::settings(Core::Id id) const
+QVariantMap RunControl::settingsData(Core::Id id) const
{
- return d->runConfiguration ? d->runConfiguration->currentSettings(id) : nullptr;
+ return d->settingsData.value(id);
}
QString RunControl::buildKey() const
{
- return d->runConfiguration ? d->runConfiguration->buildKey() : QString();
+ return d->buildKey;
}
-BuildTargetInfo RunControl::buildTargetInfo() const
+FilePath RunControl::targetFilePath() const
{
- return d->runConfiguration->buildTargetInfo();
+ return d->buildTargetInfo.targetFilePath;
+}
+
+FilePath RunControl::projectFilePath() const
+{
+ return d->buildTargetInfo.projectFilePath;
}
/*!
@@ -1086,44 +1109,76 @@ SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
: RunWorker(runControl)
{
setId("SimpleTargetRunner");
- m_runnable = runControl->runnable(); // Default value. Can be overridden using setRunnable.
- m_device = runControl->device(); // Default value. Can be overridden using setDevice.
if (auto terminalAspect = runControl->aspect<TerminalAspect>())
m_useTerminal = terminalAspect->useTerminal();
}
void SimpleTargetRunner::start()
{
+ if (m_starter)
+ m_starter();
+ else
+ doStart(runControl()->runnable(), runControl()->device());
+}
+
+void SimpleTargetRunner::doStart(const Runnable &runnable, const IDevice::ConstPtr &device)
+{
m_stopReported = false;
m_launcher.disconnect(this);
m_launcher.setUseTerminal(m_useTerminal);
- const bool isDesktop = m_device.isNull()
- || m_device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
- const QString rawDisplayName = m_runnable.displayName();
+ const bool isDesktop = device.isNull() || device.dynamicCast<const DesktopDevice>();
+ const QString rawDisplayName = runnable.displayName();
const QString displayName = isDesktop
? QDir::toNativeSeparators(rawDisplayName)
: rawDisplayName;
const QString msg = RunControl::tr("Starting %1 %2...")
- .arg(displayName).arg(m_runnable.commandLineArguments);
+ .arg(displayName).arg(runnable.commandLineArguments);
appendMessage(msg, Utils::NormalMessageFormat);
if (isDesktop) {
connect(&m_launcher, &ApplicationLauncher::appendMessage,
this, &SimpleTargetRunner::appendMessage);
- connect(&m_launcher, &ApplicationLauncher::processStarted,
- this, &SimpleTargetRunner::onProcessStarted);
+
+ connect(&m_launcher, &ApplicationLauncher::processStarted, this, [this] {
+ // Console processes only know their pid after being started
+ ProcessHandle pid = m_launcher.applicationPID();
+ runControl()->setApplicationProcessHandle(pid);
+ pid.activate();
+ reportStarted();
+ });
+
connect(&m_launcher, &ApplicationLauncher::processExited,
- this, &SimpleTargetRunner::onProcessFinished);
+ this, [this, displayName](int exitCode, QProcess::ExitStatus status) {
+ QString msg;
+ if (status == QProcess::CrashExit)
+ msg = tr("%1 crashed.");
+ else
+ msg = tr("%2 exited with code %1").arg(exitCode);
+ appendMessage(msg.arg(displayName), Utils::NormalMessageFormat);
+ if (!m_stopReported) {
+ m_stopReported = true;
+ reportStopped();
+ }
+ });
+
connect(&m_launcher, &ApplicationLauncher::error,
- this, &SimpleTargetRunner::onProcessError);
+ this, [this, runnable](QProcess::ProcessError error) {
+ if (error == QProcess::Timedout)
+ return; // No actual change on the process side.
+ const QString msg = userMessageForProcessError(error, runnable.executable);
+ appendMessage(msg, Utils::NormalMessageFormat);
+ if (!m_stopReported) {
+ m_stopReported = true;
+ reportStopped();
+ }
+ });
- const QString executable = m_runnable.executable;
- if (executable.isEmpty()) {
+ if (runnable.executable.isEmpty()) {
reportFailure(RunControl::tr("No executable specified."));
} else {
- m_launcher.start(m_runnable);
+ m_launcher.start(runnable);
}
} else {
@@ -1171,7 +1226,7 @@ void SimpleTargetRunner::start()
appendMessage(progressString, Utils::NormalMessageFormat);
});
- m_launcher.start(m_runnable, device());
+ m_launcher.start(runnable, device);
}
}
@@ -1180,55 +1235,11 @@ void SimpleTargetRunner::stop()
m_launcher.stop();
}
-void SimpleTargetRunner::onProcessStarted()
+void SimpleTargetRunner::setStarter(const std::function<void ()> &starter)
{
- // Console processes only know their pid after being started
- ProcessHandle pid = m_launcher.applicationPID();
- runControl()->setApplicationProcessHandle(pid);
- pid.activate();
- reportStarted();
+ m_starter = starter;
}
-void SimpleTargetRunner::onProcessFinished(int exitCode, QProcess::ExitStatus status)
-{
- QString msg;
- if (status == QProcess::CrashExit)
- msg = tr("%1 crashed.");
- else
- msg = tr("%2 exited with code %1").arg(exitCode);
- appendMessage(msg.arg(m_runnable.displayName()), Utils::NormalMessageFormat);
- if (!m_stopReported) {
- m_stopReported = true;
- reportStopped();
- }
-}
-
-void SimpleTargetRunner::onProcessError(QProcess::ProcessError error)
-{
- if (error == QProcess::Timedout)
- return; // No actual change on the process side.
- QString msg = userMessageForProcessError(error, m_runnable.displayName());
- appendMessage(msg, Utils::NormalMessageFormat);
- if (!m_stopReported) {
- m_stopReported = true;
- reportStopped();
- }
-}
-
-IDevice::ConstPtr SimpleTargetRunner::device() const
-{
- return m_device;
-}
-
-void SimpleTargetRunner::setRunnable(const Runnable &runnable)
-{
- m_runnable = runnable;
-}
-
-void SimpleTargetRunner::setDevice(const IDevice::ConstPtr &device)
-{
- m_device = device;
-}
// RunWorkerPrivate
@@ -1496,7 +1507,7 @@ bool RunWorker::supportsReRunning() const
return d->supportsReRunning;
}
-QString RunWorker::userMessageForProcessError(QProcess::ProcessError error, const QString &program)
+QString RunWorker::userMessageForProcessError(QProcess::ProcessError error, const FilePath &program)
{
QString failedToStart = tr("The process failed to start.");
QString msg = tr("An unknown error in the process occurred.");
@@ -1504,7 +1515,7 @@ QString RunWorker::userMessageForProcessError(QProcess::ProcessError error, cons
case QProcess::FailedToStart:
msg = failedToStart + ' ' + tr("Either the "
"invoked program \"%1\" is missing, or you may have insufficient "
- "permissions to invoke the program.").arg(program);
+ "permissions to invoke the program.").arg(program.toUserOutput());
break;
case QProcess::Crashed:
msg = tr("The process was ended forcefully.");
@@ -1551,13 +1562,46 @@ void RunWorker::stop()
CommandLine Runnable::commandLine() const
{
- return CommandLine(FilePath::fromString(executable), commandLineArguments);
+ return CommandLine(executable, commandLineArguments, CommandLine::Raw);
}
void Runnable::setCommandLine(const CommandLine &cmdLine)
{
- executable = cmdLine.executable().toString();
+ executable = cmdLine.executable();
commandLineArguments = cmdLine.arguments();
}
+// OutputFormatterFactory
+
+static QList<OutputFormatterFactory *> g_outputFormatterFactories;
+
+OutputFormatterFactory::OutputFormatterFactory()
+{
+ // This is a bit cheating: We know that only two formatters exist right now,
+ // and this here gives the second (python) implicit more priority.
+ // For a final solution, probably all matching formatters should be used
+ // in parallel, so there's no need to invent a fancy priority system here.
+ g_outputFormatterFactories.prepend(this);
+}
+
+OutputFormatterFactory::~OutputFormatterFactory()
+{
+ g_outputFormatterFactories.removeOne(this);
+}
+
+OutputFormatter *OutputFormatterFactory::createFormatter(Target *target)
+{
+ for (auto factory : qAsConst(g_outputFormatterFactories)) {
+ if (auto formatter = factory->m_creator(target))
+ return formatter;
+ }
+ return nullptr;
+}
+
+void OutputFormatterFactory::setFormatterCreator
+ (const std::function<OutputFormatter *(Target *)> &creator)
+{
+ m_creator = creator;
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/runcontrol.h b/src/plugins/projectexplorer/runcontrol.h
index fbb1c151ff..a9f55c1a24 100644
--- a/src/plugins/projectexplorer/runcontrol.h
+++ b/src/plugins/projectexplorer/runcontrol.h
@@ -26,22 +26,18 @@
#pragma once
#include "applicationlauncher.h"
-#include "buildtargetinfo.h"
#include "devicesupport/idevice.h"
#include "projectexplorerconstants.h"
#include "runconfiguration.h"
#include <utils/environment.h>
-#include <utils/port.h>
#include <utils/processhandle.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/icon.h>
#include <QHash>
-#include <QPointer>
#include <QVariant>
-#include <QWidget>
#include <functional>
#include <memory>
@@ -52,14 +48,10 @@ class OutputFormatter;
} // Utils
namespace ProjectExplorer {
-class BuildConfiguration;
class GlobalOrProjectAspect;
class Node;
-class RunConfigurationFactory;
class RunConfiguration;
-class RunConfigurationCreationInfo;
class RunControl;
-class RunWorkerFactory;
class Target;
namespace Internal {
@@ -76,7 +68,7 @@ public:
Utils::CommandLine commandLine() const;
void setCommandLine(const Utils::CommandLine &cmdLine);
- QString executable;
+ Utils::FilePath executable;
QString commandLineArguments;
QString workingDirectory;
Utils::Environment environment;
@@ -84,7 +76,7 @@ public:
QHash<Core::Id, QVariant> extraData;
// FIXME: Not necessarily a display name
- QString displayName() const { return executable; }
+ QString displayName() const { return executable.toString(); }
};
class PROJECTEXPLORER_EXPORT RunWorker : public QObject
@@ -126,7 +118,8 @@ public:
void setSupportsReRunning(bool reRunningSupported);
bool supportsReRunning() const;
- static QString userMessageForProcessError(QProcess::ProcessError, const QString &programName);
+ static QString userMessageForProcessError(QProcess::ProcessError,
+ const Utils::FilePath &programName);
bool isEssential() const;
void setEssential(bool essential);
@@ -146,36 +139,35 @@ private:
const std::unique_ptr<Internal::RunWorkerPrivate> d;
};
-class PROJECTEXPLORER_EXPORT RunWorkerFactory
+class PROJECTEXPLORER_EXPORT RunWorkerFactory final
{
public:
using WorkerCreator = std::function<RunWorker *(RunControl *)>;
- using Constraint = std::function<bool(RunConfiguration *)>;
- RunWorkerFactory();
- virtual ~RunWorkerFactory();
+ RunWorkerFactory(const WorkerCreator &producer,
+ const QList<Core::Id> &runModes,
+ const QList<Core::Id> &runConfigs = {},
+ const QList<Core::Id> &deviceTypes = {});
- bool canRun(RunConfiguration *runConfiguration, Core::Id runMode) const;
+ ~RunWorkerFactory();
- void setProducer(const WorkerCreator &producer);
- void addConstraint(const Constraint &constraint);
- void addSupportedRunMode(Core::Id runMode);
+ bool canRun(Core::Id runMode, Core::Id deviceType, const QString &runConfigId) const;
+ WorkerCreator producer() const { return m_producer; }
- void setSupportedRunConfigurations(const QList<Core::Id> &ids);
- void addSupportedRunConfiguration(Core::Id id);
+ template <typename Worker>
+ static WorkerCreator make()
+ {
+ return [](RunControl *runControl) { return new Worker(runControl); };
+ }
- WorkerCreator producer() const { return m_producer; }
+ // For debugging only.
+ static void dumpAll();
private:
- // FIXME: That's temporary until ownership has been transferred to
- // the individual plugins.
- friend class ProjectExplorerPlugin;
- static void destroyRemainingRunWorkerFactories();
-
+ WorkerCreator m_producer;
QList<Core::Id> m_supportedRunModes;
QList<Core::Id> m_supportedRunConfigurations;
- QList<Constraint> m_constraints;
- WorkerCreator m_producer;
+ QList<Core::Id> m_supportedDeviceTypes;
};
/**
@@ -235,16 +227,12 @@ public:
return runConfiguration() ? runConfiguration()->aspect<T>() : nullptr;
}
- template <typename T>
- auto aspectData() -> decltype(T::runData(nullptr, this)) {
- if (T *asp = aspect<T>())
- return T::runData(asp, this);
- return {};
- }
-
- ISettingsAspect *settings(Core::Id id) const;
QString buildKey() const;
- BuildTargetInfo buildTargetInfo() const;
+
+ QVariantMap settingsData(Core::Id id) const;
+
+ Utils::FilePath targetFilePath() const;
+ Utils::FilePath projectFilePath() const;
Utils::OutputFormatter *outputFormatter() const;
Core::Id runMode() const;
@@ -257,24 +245,10 @@ public:
const QString &cancelButtonText = QString(),
bool *prompt = nullptr);
- RunWorker *createWorker(Core::Id id);
-
- using WorkerCreator = RunWorkerFactory::WorkerCreator;
- using Constraint = RunWorkerFactory::Constraint;
-
- static void registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator);
-
- template <class Worker>
- static void registerWorker(Core::Id runMode, const Constraint &constraint)
- {
- auto factory = new RunWorkerFactory;
- factory->setProducer([](RunControl *rc) { return new Worker(rc); });
- factory->addSupportedRunMode(runMode);
- factory->addConstraint(constraint);
- }
+ RunWorker *createWorker(Core::Id workerId);
bool createMainWorker();
- static bool canRun(RunConfiguration *runConfig, Core::Id runMode);
+ static bool canRun(Core::Id runMode, Core::Id deviceType, Core::Id runConfigId);
signals:
void appendMessage(const QString &msg, Utils::OutputFormat format);
@@ -306,41 +280,38 @@ class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public RunWorker
public:
explicit SimpleTargetRunner(RunControl *runControl);
- void setRunnable(const Runnable &runnable);
-
- void setDevice(const IDevice::ConstPtr &device);
- IDevice::ConstPtr device() const;
-
protected:
- void start() override;
- void stop() override;
+ void setStarter(const std::function<void()> &starter);
+ void doStart(const Runnable &runnable, const IDevice::ConstPtr &device);
private:
- void onProcessStarted();
- void onProcessFinished(int exitCode, QProcess::ExitStatus status);
- void onProcessError(QProcess::ProcessError error);
+ void start() final;
+ void stop() final;
+
+ const Runnable &runnable() const = delete;
ApplicationLauncher m_launcher;
- Runnable m_runnable;
- IDevice::ConstPtr m_device;
+ std::function<void()> m_starter;
+
bool m_stopReported = false;
bool m_useTerminal = false;
};
-template <class RunWorker, class RunConfig>
-class SimpleRunWorkerFactory : public RunWorkerFactory
+class PROJECTEXPLORER_EXPORT OutputFormatterFactory
{
+protected:
+ OutputFormatterFactory();
+
public:
- SimpleRunWorkerFactory(Core::Id runMode = ProjectExplorer::Constants::NORMAL_RUN_MODE)
- {
- addSupportedRunMode(runMode);
- addConstraint([](RunConfiguration *runConfig) {
- return qobject_cast<RunConfig *>(runConfig) != nullptr;
- });
- setProducer([](RunControl *runControl) {
- return new RunWorker(runControl);
- });
- }
+ virtual ~OutputFormatterFactory();
+
+ static Utils::OutputFormatter *createFormatter(Target *target);
+
+protected:
+ void setFormatterCreator(const std::function<Utils::OutputFormatter *(Target *)> &creator);
+
+private:
+ std::function<Utils::OutputFormatter *(Target *)> m_creator;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index 39b2f01af6..8a934874a7 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -26,22 +26,19 @@
#include "runsettingspropertiespage.h"
#include "addrunconfigdialog.h"
+#include "buildmanager.h"
#include "buildstepspage.h"
#include "deployconfiguration.h"
-#include "runconfiguration.h"
-#include "target.h"
#include "projectconfigurationmodel.h"
+#include "runconfiguration.h"
#include "session.h"
+#include "target.h"
-#include <extensionsystem/pluginmanager.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/buildmanager.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <utils/utilsicons.h>
-#include <QVariant>
#include <QAction>
#include <QComboBox>
#include <QGridLayout>
@@ -56,29 +53,10 @@
namespace ProjectExplorer {
namespace Internal {
-struct FactoryAndId
-{
- RunConfigurationFactory *factory;
- Core::Id id;
-};
-
-} // namespace Internal
-} // namespace ProjectExplorer
-
-Q_DECLARE_METATYPE(ProjectExplorer::Internal::FactoryAndId)
-
-using namespace ProjectExplorer;
-using namespace ProjectExplorer::Internal;
-using ExtensionSystem::PluginManager;
-
-///
-/// RunSettingsWidget
-///
+// RunSettingsWidget
RunSettingsWidget::RunSettingsWidget(Target *target) :
- m_target(target),
- m_runConfigurationsModel(new RunConfigurationModel(target, this)),
- m_deployConfigurationModel(new DeployConfigurationModel(target, this))
+ m_target(target)
{
Q_ASSERT(m_target);
@@ -143,10 +121,10 @@ RunSettingsWidget::RunSettingsWidget(Target *target) :
// deploy part
deployWidget->setContentsMargins(0, 10, 0, 25);
m_deployLayout = new QVBoxLayout(deployWidget);
- m_deployLayout->setMargin(0);
+ m_deployLayout->setContentsMargins(0, 0, 0, 0);
m_deployLayout->setSpacing(5);
- m_deployConfigurationCombo->setModel(m_deployConfigurationModel);
+ m_deployConfigurationCombo->setModel(m_target->deployConfigurationModel());
m_addDeployMenu = new QMenu(m_addDeployToolButton);
m_addDeployToolButton->setMenu(m_addDeployMenu);
@@ -175,7 +153,7 @@ RunSettingsWidget::RunSettingsWidget(Target *target) :
// run part
runWidget->setContentsMargins(0, 10, 0, 25);
m_runLayout = new QVBoxLayout(runWidget);
- m_runLayout->setMargin(0);
+ m_runLayout->setContentsMargins(0, 0, 0, 0);
m_runLayout->setSpacing(5);
m_disabledIcon = new QLabel;
@@ -188,10 +166,10 @@ RunSettingsWidget::RunSettingsWidget(Target *target) :
m_runLayout->addLayout(disabledHBox);
+ ProjectConfigurationModel *model = m_target->runConfigurationModel();
RunConfiguration *rc = m_target->activeRunConfiguration();
- m_runConfigurationCombo->setModel(m_runConfigurationsModel);
- m_runConfigurationCombo->setCurrentIndex(
- m_runConfigurationsModel->indexFor(rc).row());
+ m_runConfigurationCombo->setModel(model);
+ m_runConfigurationCombo->setCurrentIndex(model->indexFor(rc));
m_removeRunToolButton->setEnabled(m_target->runConfigurations().size() > 1);
m_renameRunButton->setEnabled(rc);
@@ -284,10 +262,12 @@ void RunSettingsWidget::activeRunConfigurationChanged()
{
if (m_ignoreChange)
return;
- QModelIndex actRc = m_runConfigurationsModel->indexFor(m_target->activeRunConfiguration());
+
+ ProjectConfigurationModel *model = m_target->runConfigurationModel();
+ int index = model->indexFor(m_target->activeRunConfiguration());
m_ignoreChange = true;
- m_runConfigurationCombo->setCurrentIndex(actRc.row());
- setConfigurationWidget(qobject_cast<RunConfiguration *>(m_runConfigurationsModel->projectConfigurationAt(actRc.row())));
+ m_runConfigurationCombo->setCurrentIndex(index);
+ setConfigurationWidget(qobject_cast<RunConfiguration *>(model->projectConfigurationAt(index)));
m_ignoreChange = false;
m_renameRunButton->setEnabled(m_target->activeRunConfiguration());
m_cloneRunButton->setEnabled(m_target->activeRunConfiguration());
@@ -318,7 +298,8 @@ void RunSettingsWidget::currentRunConfigurationChanged(int index)
RunConfiguration *selectedRunConfiguration = nullptr;
if (index >= 0)
- selectedRunConfiguration = qobject_cast<RunConfiguration *>(m_runConfigurationsModel->projectConfigurationAt(index));
+ selectedRunConfiguration = qobject_cast<RunConfiguration *>
+ (m_target->runConfigurationModel()->projectConfigurationAt(index));
if (selectedRunConfiguration == m_runConfiguration)
return;
@@ -339,7 +320,7 @@ void RunSettingsWidget::currentDeployConfigurationChanged(int index)
SessionManager::setActiveDeployConfiguration(m_target, nullptr, SetActive::Cascade);
else
SessionManager::setActiveDeployConfiguration(m_target,
- qobject_cast<DeployConfiguration *>(m_deployConfigurationModel->projectConfigurationAt(index)),
+ qobject_cast<DeployConfiguration *>(m_target->deployConfigurationModel()->projectConfigurationAt(index)),
SetActive::Cascade);
}
@@ -434,9 +415,9 @@ void RunSettingsWidget::updateDeployConfiguration(DeployConfiguration *dc)
if (!dc)
return;
- QModelIndex actDc = m_deployConfigurationModel->indexFor(dc);
+ int index = m_target->deployConfigurationModel()->indexFor(dc);
m_ignoreChange = true;
- m_deployConfigurationCombo->setCurrentIndex(actDc.row());
+ m_deployConfigurationCombo->setCurrentIndex(index);
m_ignoreChange = false;
m_deployConfigurationWidget = dc->createConfigWidget();
@@ -551,3 +532,6 @@ void RunSettingsWidget::updateEnabledState()
m_disabledText->setVisible(!enable && !reason.isEmpty());
m_disabledText->setText(reason);
}
+
+} // Internal
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.h b/src/plugins/projectexplorer/runsettingspropertiespage.h
index bf86fe56ba..12f1403c42 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.h
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.h
@@ -39,10 +39,8 @@ QT_END_NAMESPACE
namespace ProjectExplorer {
class DeployConfiguration;
-class DeployConfigurationModel;
class NamedWidget;
class RunConfiguration;
-class RunConfigurationModel;
class RunConfigWidget;
class Target;
@@ -83,12 +81,10 @@ private:
void updateEnabledState();
Target *m_target;
- RunConfigurationModel *m_runConfigurationsModel;
- DeployConfigurationModel *m_deployConfigurationModel;
QWidget *m_runConfigurationWidget = nullptr;
RunConfiguration *m_runConfiguration = nullptr;
QVBoxLayout *m_runLayout = nullptr;
- NamedWidget *m_deployConfigurationWidget = nullptr;
+ QWidget *m_deployConfigurationWidget = nullptr;
QVBoxLayout *m_deployLayout = nullptr;
BuildStepListWidget *m_deploySteps = nullptr;
QMenu *m_addDeployMenu;
diff --git a/src/plugins/projectexplorer/selectablefilesmodel.cpp b/src/plugins/projectexplorer/selectablefilesmodel.cpp
index 71077cf570..6ef592598e 100644
--- a/src/plugins/projectexplorer/selectablefilesmodel.cpp
+++ b/src/plugins/projectexplorer/selectablefilesmodel.cpp
@@ -298,7 +298,7 @@ void SelectableFilesModel::propagateDown(const QModelIndex &idx)
Qt::ItemFlags SelectableFilesModel::flags(const QModelIndex &index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
}
@@ -550,7 +550,7 @@ SelectableFilesWidget::SelectableFilesWidget(QWidget *parent) :
QLatin1String(HIDE_FILE_FILTER_DEFAULT)).toString();
auto layout = new QGridLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
m_baseDirLabel->setText(tr("Source directory:"));
m_baseDirChooser->setHistoryCompleter(QLatin1String("PE.AddToProjectDir.History"));
diff --git a/src/plugins/projectexplorer/subscription.cpp b/src/plugins/projectexplorer/subscription.cpp
index 3a84235132..a8092ed3ba 100644
--- a/src/plugins/projectexplorer/subscription.cpp
+++ b/src/plugins/projectexplorer/subscription.cpp
@@ -53,21 +53,26 @@ void Subscription::subscribe(ProjectConfiguration *pc)
return;
connectTo(pc);
+}
- if (auto t = qobject_cast<Target *>(pc)) {
- for (ProjectConfiguration *pc : t->projectConfigurations())
- connectTo(pc);
- }
+void Subscription::subscribeTarget(Target *target)
+{
+ if (!m_subscriber)
+ return;
+
+ for (ProjectConfiguration *pc : target->projectConfigurations())
+ connectTo(pc);
}
void Subscription::unsubscribe(ProjectConfiguration *pc)
{
disconnectFrom(pc);
+}
- if (auto t = qobject_cast<Target *>(pc)) {
- for (ProjectConfiguration *pc : t->projectConfigurations())
- disconnectFrom(pc);
- }
+void Subscription::unsubscribeTarget(Target *target)
+{
+ for (ProjectConfiguration *pc : target->projectConfigurations())
+ disconnectFrom(pc);
}
void Subscription::unsubscribeAll()
@@ -113,33 +118,18 @@ ProjectSubscription::ProjectSubscription(const Subscription::Connector &s, const
QTC_ASSERT(m_subscriber, return);
for (Target *t : p->targets())
- subscribe(t);
+ subscribeTarget(t);
// Disconnect on removal of a project, to make it save to remove/add a project:
connect(SessionManager::instance(), &SessionManager::projectRemoved,
this, [this, p](Project *reported) { if (p == reported) { destroy(); } });
connect(p, &Project::addedProjectConfiguration, this, &ProjectSubscription::subscribe);
+ connect(p, &Project::addedTarget, this, &ProjectSubscription::subscribeTarget);
connect(p, &Project::removedProjectConfiguration, this, &ProjectSubscription::unsubscribe);
+ connect(p, &Project::removedTarget, this, &ProjectSubscription::unsubscribeTarget);
}
ProjectSubscription::~ProjectSubscription() = default;
-TargetSubscription::TargetSubscription(const Subscription::Connector &s, const QObject *r,
- Target *t) :
- Subscription(s, r, t)
-{
- QTC_ASSERT(m_subscriber, return);
-
- subscribe(t);
-
- // Disconnect on removal of a target, to make it save to remove/add a target:
- connect(t->project(), &Project::removedTarget, this,
- [t, this](const Target *reportedTarget) { if (t == reportedTarget) { destroy(); } });
- connect(t, &Target::addedProjectConfiguration, this, &TargetSubscription::subscribe);
- connect(t, &Target::removedProjectConfiguration, this, &TargetSubscription::unsubscribe);
-}
-
-TargetSubscription::~TargetSubscription() = default;
-
} // namespace Internal
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/subscription.h b/src/plugins/projectexplorer/subscription.h
index 71aa3596f3..baff689d8e 100644
--- a/src/plugins/projectexplorer/subscription.h
+++ b/src/plugins/projectexplorer/subscription.h
@@ -51,7 +51,9 @@ public:
protected:
void subscribe(ProjectConfiguration *pc);
+ void subscribeTarget(Target *target);
void unsubscribe(ProjectConfiguration *pc);
+ void unsubscribeTarget(Target *target);
void unsubscribeAll();
void connectTo(ProjectConfiguration *pc);
@@ -70,12 +72,5 @@ public:
~ProjectSubscription() final;
};
-class PROJECTEXPLORER_EXPORT TargetSubscription : public Subscription
-{
-public:
- TargetSubscription(const Connector &s, const QObject *receiver, Target *t);
- ~TargetSubscription() final;
-};
-
} // namespace Internal
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index 44be607065..d0e6f56c90 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -23,6 +23,7 @@
**
****************************************************************************/
+#include "projectconfigurationmodel.h"
#include "target.h"
#include "buildconfiguration.h"
@@ -47,6 +48,7 @@
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
+#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
@@ -56,7 +58,10 @@
#include <limits>
-namespace {
+using namespace Utils;
+
+namespace ProjectExplorer {
+
const char ACTIVE_BC_KEY[] = "ProjectExplorer.Target.ActiveBuildConfiguration";
const char BC_KEY_PREFIX[] = "ProjectExplorer.Target.BuildConfiguration.";
const char BC_COUNT_KEY[] = "ProjectExplorer.Target.BuildConfigurationCount";
@@ -79,18 +84,19 @@ static QString formatDeviceInfo(const ProjectExplorer::IDevice::DeviceInfo &inpu
return lines.join(QLatin1String("<br>"));
}
-} // namespace
-
// -------------------------------------------------------------------------
// Target
// -------------------------------------------------------------------------
-namespace ProjectExplorer {
-
class TargetPrivate
{
public:
- TargetPrivate(Kit *k);
+ TargetPrivate(Target *t, Kit *k) :
+ m_kit(k),
+ m_buildConfigurationModel(t),
+ m_deployConfigurationModel(t),
+ m_runConfigurationModel(t)
+ { }
bool m_isEnabled = true;
QIcon m_overlayIcon;
@@ -106,21 +112,26 @@ public:
QVariantMap m_pluginSettings;
Kit *const m_kit;
+ MacroExpander m_macroExpander;
+
+ ProjectConfigurationModel m_buildConfigurationModel;
+ ProjectConfigurationModel m_deployConfigurationModel;
+ ProjectConfigurationModel m_runConfigurationModel;
};
-TargetPrivate::TargetPrivate(Kit *k) :
- m_kit(k)
-{ }
Target::Target(Project *project, Kit *k, _constructor_tag) :
- ProjectConfiguration(project, k->id()),
- d(std::make_unique<TargetPrivate>(k))
+ QObject(project),
+ d(std::make_unique<TargetPrivate>(this, k))
{
QTC_CHECK(d->m_kit);
connect(DeviceManager::instance(), &DeviceManager::updated, this, &Target::updateDeviceState);
-
- setDisplayName(d->m_kit->displayName());
- setToolTip(d->m_kit->toHtml());
+ connect(project, &Project::parsingFinished, this, [this](bool success) {
+ if (success && this->project() == SessionManager::startupProject()
+ && this == this->project()->activeTarget()) {
+ updateDefaultRunConfigurations();
+ }
+ }, Qt::QueuedConnection); // Must wait for run configs to change their enabled state.
KitManager *km = KitManager::instance();
connect(km, &KitManager::kitUpdated, this, &Target::handleKitUpdates);
@@ -140,7 +151,6 @@ Target::Target(Project *project, Kit *k, _constructor_tag) :
QCoreApplication::translate("ProjectExplorer", "Name of current project"),
[project] { return project->displayName(); },
false);
-
}
Target::~Target()
@@ -155,10 +165,8 @@ void Target::handleKitUpdates(Kit *k)
if (k != d->m_kit)
return;
- setDisplayName(k->displayName());
updateDefaultDeployConfigurations();
updateDeviceState(); // in case the device changed...
- setToolTip(k->toHtml());
emit iconChanged();
emit kitChanged();
@@ -186,6 +194,21 @@ Kit *Target::kit() const
return d->m_kit;
}
+Core::Id Target::id() const
+{
+ return d->m_kit->id();
+}
+
+QString Target::displayName() const
+{
+ return d->m_kit->displayName();
+}
+
+QString Target::toolTip() const
+{
+ return d->m_kit->toHtml();
+}
+
void Target::addBuildConfiguration(BuildConfiguration *bc)
{
QTC_ASSERT(bc && !d->m_buildConfigurations.contains(bc), return);
@@ -205,8 +228,9 @@ void Target::addBuildConfiguration(BuildConfiguration *bc)
// add it
d->m_buildConfigurations.push_back(bc);
- emit addedProjectConfiguration(bc);
+ project()->addedProjectConfiguration(bc);
emit addedBuildConfiguration(bc);
+ d->m_buildConfigurationModel.addProjectConfiguration(bc);
if (!activeBuildConfiguration())
setActiveBuildConfiguration(bc);
@@ -222,9 +246,6 @@ bool Target::removeBuildConfiguration(BuildConfiguration *bc)
return false;
d->m_buildConfigurations.removeOne(bc);
- emit aboutToRemoveProjectConfiguration(bc);
- d->m_buildConfigurations.removeOne(bc);
-
if (activeBuildConfiguration() == bc) {
if (d->m_buildConfigurations.isEmpty())
@@ -234,7 +255,8 @@ bool Target::removeBuildConfiguration(BuildConfiguration *bc)
}
emit removedBuildConfiguration(bc);
- emit removedProjectConfiguration(bc);
+ project()->removedProjectConfiguration(bc);
+ d->m_buildConfigurationModel.removeProjectConfiguration(bc);
delete bc;
return true;
@@ -256,7 +278,7 @@ void Target::setActiveBuildConfiguration(BuildConfiguration *bc)
(bc && d->m_buildConfigurations.contains(bc) &&
bc != d->m_activeBuildConfiguration)) {
d->m_activeBuildConfiguration = bc;
- emit activeProjectConfigurationChanged(d->m_activeBuildConfiguration);
+ project()->activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
emit activeBuildConfigurationChanged(d->m_activeBuildConfiguration);
}
}
@@ -275,7 +297,8 @@ void Target::addDeployConfiguration(DeployConfiguration *dc)
// add it
d->m_deployConfigurations.push_back(dc);
- emit addedProjectConfiguration(dc);
+ project()->addedProjectConfiguration(dc);
+ d->m_deployConfigurationModel.addProjectConfiguration(dc);
emit addedDeployConfiguration(dc);
if (!d->m_activeDeployConfiguration)
@@ -292,7 +315,6 @@ bool Target::removeDeployConfiguration(DeployConfiguration *dc)
if (BuildManager::isBuilding(dc))
return false;
- emit aboutToRemoveProjectConfiguration(dc);
d->m_deployConfigurations.removeOne(dc);
if (activeDeployConfiguration() == dc) {
@@ -303,7 +325,8 @@ bool Target::removeDeployConfiguration(DeployConfiguration *dc)
SetActive::Cascade);
}
- emit removedProjectConfiguration(dc);
+ project()->removedProjectConfiguration(dc);
+ d->m_deployConfigurationModel.removeProjectConfiguration(dc);
emit removedDeployConfiguration(dc);
delete dc;
@@ -326,7 +349,6 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
(dc && d->m_deployConfigurations.contains(dc) &&
dc != d->m_activeDeployConfiguration)) {
d->m_activeDeployConfiguration = dc;
- emit activeProjectConfigurationChanged(d->m_activeDeployConfiguration);
emit activeDeployConfigurationChanged(d->m_activeDeployConfiguration);
}
updateDeviceState();
@@ -392,7 +414,8 @@ void Target::addRunConfiguration(RunConfiguration *rc)
d->m_runConfigurations.push_back(rc);
- emit addedProjectConfiguration(rc);
+ project()->addedProjectConfiguration(rc);
+ d->m_runConfigurationModel.addProjectConfiguration(rc);
emit addedRunConfiguration(rc);
if (!activeRunConfiguration())
@@ -403,7 +426,6 @@ void Target::removeRunConfiguration(RunConfiguration *rc)
{
QTC_ASSERT(rc && d->m_runConfigurations.contains(rc), return);
- emit aboutToRemoveProjectConfiguration(rc);
d->m_runConfigurations.removeOne(rc);
if (activeRunConfiguration() == rc) {
@@ -414,7 +436,8 @@ void Target::removeRunConfiguration(RunConfiguration *rc)
}
emit removedRunConfiguration(rc);
- emit removedProjectConfiguration(rc);
+ project()->removedProjectConfiguration(rc);
+ d->m_runConfigurationModel.removeProjectConfiguration(rc);
delete rc;
}
@@ -430,7 +453,6 @@ void Target::setActiveRunConfiguration(RunConfiguration *rc)
(rc && d->m_runConfigurations.contains(rc) &&
rc != d->m_activeRunConfiguration)) {
d->m_activeRunConfiguration = rc;
- emit activeProjectConfigurationChanged(d->m_activeRunConfiguration);
emit activeRunConfigurationChanged(d->m_activeRunConfiguration);
}
updateDeviceState();
@@ -468,7 +490,18 @@ QVariantMap Target::toMap() const
if (!d->m_kit) // Kit was deleted, target is only around to be copied.
return QVariantMap();
- QVariantMap map(ProjectConfiguration::toMap());
+ QVariantMap map;
+
+ {
+ // FIXME: For compatibility within the 4.11 cycle, remove this block later.
+ // This is only read by older versions of Creator, but even there not actively used.
+ const char CONFIGURATION_ID_KEY[] = "ProjectExplorer.ProjectConfiguration.Id";
+ const char DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DisplayName";
+ const char DEFAULT_DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DefaultDisplayName";
+ map.insert(QLatin1String(CONFIGURATION_ID_KEY), id().toSetting());
+ map.insert(QLatin1String(DISPLAY_NAME_KEY), displayName());
+ map.insert(QLatin1String(DEFAULT_DISPLAY_NAME_KEY), displayName());
+ }
const QList<BuildConfiguration *> bcs = buildConfigurations();
map.insert(QLatin1String(ACTIVE_BC_KEY), bcs.indexOf(d->m_activeBuildConfiguration));
@@ -500,7 +533,7 @@ void Target::updateDefaultBuildConfigurations()
qWarning("No build configuration factory found for target id '%s'.", qPrintable(id().toString()));
return;
}
- for (const BuildInfo &info : bcFactory->allAvailableSetups(kit(), project()->projectFilePath().toString())) {
+ for (const BuildInfo &info : bcFactory->allAvailableSetups(kit(), project()->projectFilePath())) {
if (BuildConfiguration *bc = bcFactory->create(this, info))
addBuildConfiguration(bc);
}
@@ -692,6 +725,26 @@ MakeInstallCommand Target::makeInstallCommand(const QString &installRoot) const
return project()->makeInstallCommand(this, installRoot);
}
+MacroExpander *Target::macroExpander() const
+{
+ return &d->m_macroExpander;
+}
+
+ProjectConfigurationModel *Target::buildConfigurationModel() const
+{
+ return &d->m_buildConfigurationModel;
+}
+
+ProjectConfigurationModel *Target::deployConfigurationModel() const
+{
+ return &d->m_deployConfigurationModel;
+}
+
+ProjectConfigurationModel *Target::runConfigurationModel() const
+{
+ return &d->m_runConfigurationModel;
+}
+
void Target::updateDeviceState()
{
IDevice::ConstPtr current = DeviceKitAspect::device(kit());
@@ -737,14 +790,8 @@ void Target::setEnabled(bool enabled)
bool Target::fromMap(const QVariantMap &map)
{
- if (!ProjectConfiguration::fromMap(map))
- return false;
-
QTC_ASSERT(d->m_kit == KitManager::kit(id()), return false);
- setDisplayName(d->m_kit->displayName()); // Overwrite displayname read from file
- setDefaultDisplayName(d->m_kit->displayName());
-
bool ok;
int bcCount = map.value(QLatin1String(BC_COUNT_KEY), 0).toInt(&ok);
if (!ok || bcCount < 0)
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index a630e28468..d7e64beda4 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -42,11 +42,12 @@ class DeploymentData;
class Kit;
class MakeInstallCommand;
class Project;
+class ProjectConfigurationModel;
class RunConfiguration;
class TargetPrivate;
-class PROJECTEXPLORER_EXPORT Target : public ProjectConfiguration
+class PROJECTEXPLORER_EXPORT Target : public QObject
{
friend class SessionManager; // for setActiveBuild and setActiveDeployConfiguration
Q_OBJECT
@@ -57,13 +58,15 @@ public:
Target(Project *parent, Kit *k, _constructor_tag);
~Target() override;
- Project *project() const override;
+ bool isActive() const;
- bool isActive() const final;
-
- // Kit:
+ Project *project() const;
Kit *kit() const;
+ Core::Id id() const;
+ QString displayName() const;
+ QString toolTip() const;
+
// Build configuration
void addBuildConfiguration(BuildConfiguration *bc);
bool removeBuildConfiguration(BuildConfiguration *bc);
@@ -107,7 +110,7 @@ public:
void setOverlayIcon(const QIcon &icon);
QString overlayIconToolTip();
- QVariantMap toMap() const override;
+ QVariantMap toMap() const;
void updateDefaultBuildConfigurations();
void updateDefaultDeployConfigurations();
@@ -119,23 +122,11 @@ public:
QVariant additionalData(Core::Id id) const;
MakeInstallCommand makeInstallCommand(const QString &installRoot) const;
- template<typename S, typename R, typename T>
- void subscribeSignal(void (S::*sig)(), R*recv, T (R::*sl)()) {
- new Internal::TargetSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
- if (S* sender = qobject_cast<S*>(pc))
- return connect(sender, sig, recv, sl);
- return QMetaObject::Connection();
- }, recv, this);
- }
-
- template<typename S, typename R, typename T>
- void subscribeSignal(void (S::*sig)(), R*recv, T sl) {
- new Internal::TargetSubscription([sig, recv, sl, this](ProjectConfiguration *pc) {
- if (S* sender = qobject_cast<S*>(pc))
- return connect(sender, sig, recv, sl);
- return QMetaObject::Connection();
- }, recv, this);
- }
+ Utils::MacroExpander *macroExpander() const;
+
+ ProjectConfigurationModel *buildConfigurationModel() const;
+ ProjectConfigurationModel *deployConfigurationModel() const;
+ ProjectConfigurationModel *runConfigurationModel() const;
signals:
void targetEnabled(bool);
@@ -144,12 +135,6 @@ signals:
void kitChanged();
- void aboutToRemoveProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
- void removedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
- void addedProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc);
-
- void activeProjectConfigurationChanged(ProjectExplorer::ProjectConfiguration *pc);
-
// TODO clean up signal names
// might be better to also have aboutToRemove signals
void removedRunConfiguration(ProjectExplorer::RunConfiguration *rc);
@@ -159,6 +144,7 @@ signals:
void removedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc);
void addedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc);
void activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration *);
+ void buildEnvironmentChanged(ProjectExplorer::BuildConfiguration *bc);
void removedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc);
void addedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc);
@@ -170,7 +156,7 @@ signals:
private:
void setEnabled(bool);
- bool fromMap(const QVariantMap &map) override;
+ bool fromMap(const QVariantMap &map);
void updateDeviceState();
diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp
index c41d5ca1e4..aabb2d33a6 100644
--- a/src/plugins/projectexplorer/targetsettingspanel.cpp
+++ b/src/plugins/projectexplorer/targetsettingspanel.cpp
@@ -151,7 +151,7 @@ TargetSetupPageWrapper::TargetSetupPageWrapper(Project *project)
hbox->addWidget(box);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
m_setupPageContainer = new QVBoxLayout;
layout->addLayout(m_setupPageContainer);
layout->addLayout(hbox);
@@ -200,7 +200,7 @@ void TargetSetupPageWrapper::addTargetSetupPage()
{
m_targetSetupPage = new TargetSetupPage(this);
m_targetSetupPage->setUseScrollArea(false);
- m_targetSetupPage->setProjectPath(m_project->projectFilePath().toString());
+ m_targetSetupPage->setProjectPath(m_project->projectFilePath());
m_targetSetupPage->setRequiredKitPredicate(m_project->requiredKitPredicate());
m_targetSetupPage->setPreferredKitPredicate(m_project->preferredKitPredicate());
m_targetSetupPage->setProjectImporter(m_project->projectImporter());
@@ -268,7 +268,7 @@ void TargetGroupItemPrivate::ensureWidget()
label->setAlignment(Qt::AlignTop);
auto layout = new QVBoxLayout(m_noKitLabel);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(label);
layout->addStretch(10);
@@ -287,7 +287,7 @@ void TargetGroupItemPrivate::ensureWidget()
auto widget = new QWidget;
auto label = new QLabel("This project is already configured.");
auto layout = new QVBoxLayout(widget);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(label);
layout->addStretch(10);
m_configuredPage = new PanelsWidget(tr("Configure Project"),
@@ -350,7 +350,7 @@ public:
return k->icon();
}
- case Qt::TextColorRole: {
+ case Qt::ForegroundRole: {
if (!isEnabled())
return Utils::creatorTheme()->color(Theme::TextColorDisabled);
break;
@@ -407,8 +407,7 @@ public:
QTC_ASSERT(!data.isValid(), return false);
if (!isEnabled()) {
m_currentChild = DefaultPage;
- Kit *k = KitManager::kit(m_kitId);
- m_project->addTarget(m_project->createTarget(k));
+ m_project->addTargetForKit(KitManager::kit(m_kitId));
} else {
// Go to Run page, when on Run previously etc.
TargetItem *previousItem = parent()->currentTargetItem();
@@ -450,7 +449,7 @@ public:
QAction *enableAction = menu->addAction(tr("Enable Kit \"%1\" for Project \"%2\"").arg(kitName, projectName));
enableAction->setEnabled(isSelectable && m_kitId.isValid() && !isEnabled());
QObject::connect(enableAction, &QAction::triggered, [this, kit] {
- m_project->addTarget(m_project->createTarget(kit));
+ m_project->addTargetForKit(kit);
});
QAction *disableAction = menu->addAction(tr("Disable Kit \"%1\" for Project \"%2\"").arg(kitName, projectName));
@@ -805,13 +804,13 @@ TargetItem *TargetGroupItem::targetItem(Target *target) const
void TargetGroupItemPrivate::handleRemovedKit(Kit *kit)
{
- Q_UNUSED(kit);
+ Q_UNUSED(kit)
rebuildContents();
}
void TargetGroupItemPrivate::handleUpdatedKit(Kit *kit)
{
- Q_UNUSED(kit);
+ Q_UNUSED(kit)
rebuildContents();
}
diff --git a/src/plugins/projectexplorer/targetsetuppage.cpp b/src/plugins/projectexplorer/targetsetuppage.cpp
index b5d2bfe3de..7f45cf69b7 100644
--- a/src/plugins/projectexplorer/targetsetuppage.cpp
+++ b/src/plugins/projectexplorer/targetsetuppage.cpp
@@ -52,6 +52,8 @@
#include <QVBoxLayout>
#include <QCheckBox>
+using namespace Utils;
+
namespace ProjectExplorer {
static QList<IPotentialKit *> g_potentialKits;
@@ -67,10 +69,10 @@ IPotentialKit::~IPotentialKit()
}
namespace Internal {
-static Utils::FilePath importDirectory(const QString &projectPath)
+static FilePath importDirectory(const FilePath &projectPath)
{
// Setup import widget:
- auto path = Utils::FilePath::fromString(projectPath);
+ auto path = projectPath;
path = path.parentDir(); // base dir
path = path.parentDir(); // parent dir
@@ -88,7 +90,7 @@ public:
QLabel *noValidKitLabel;
QLabel *optionHintLabel;
QCheckBox *allKitsCheckBox;
- Utils::FancyLineEdit *kitFilterLineEdit;
+ FancyLineEdit *kitFilterLineEdit;
void setupUi(TargetSetupPage *q)
{
@@ -118,7 +120,7 @@ public:
allKitsCheckBox->setTristate(true);
allKitsCheckBox->setText(TargetSetupPage::tr("Select all kits"));
- kitFilterLineEdit = new Utils::FancyLineEdit(setupTargetPage);
+ kitFilterLineEdit = new FancyLineEdit(setupTargetPage);
kitFilterLineEdit->setFiltering(true);
kitFilterLineEdit->setPlaceholderText(TargetSetupPage::tr("Type to filter kits by name..."));
@@ -162,7 +164,7 @@ public:
QObject::connect(allKitsCheckBox, &QAbstractButton::clicked,
q, &TargetSetupPage::changeAllKitsSelections);
- QObject::connect(kitFilterLineEdit, &Utils::FancyLineEdit::filterChanged,
+ QObject::connect(kitFilterLineEdit, &FancyLineEdit::filterChanged,
q, &TargetSetupPage::kitFilterChanged);
}
};
@@ -172,7 +174,7 @@ public:
using namespace Internal;
TargetSetupPage::TargetSetupPage(QWidget *parent) :
- Utils::WizardPage(parent),
+ WizardPage(parent),
m_ui(new TargetSetupPageUi),
m_importWidget(new ImportWidget(this)),
m_spacer(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding))
@@ -193,7 +195,7 @@ TargetSetupPage::TargetSetupPage(QWidget *parent) :
m_ui->scrollArea->setWidget(centralWidget);
centralWidget->setLayout(new QVBoxLayout);
m_ui->centralWidget->setLayout(new QVBoxLayout);
- m_ui->centralWidget->layout()->setMargin(0);
+ m_ui->centralWidget->layout()->setContentsMargins(0, 0, 0, 0);
setTitle(tr("Kit Selection"));
@@ -210,9 +212,9 @@ TargetSetupPage::TargetSetupPage(QWidget *parent) :
connect(km, &KitManager::kitRemoved, this, &TargetSetupPage::handleKitRemoval);
connect(km, &KitManager::kitUpdated, this, &TargetSetupPage::handleKitUpdate);
connect(m_importWidget, &ImportWidget::importFrom,
- this, [this](const Utils::FilePath &dir) { import(dir); });
+ this, [this](const FilePath &dir) { import(dir); });
- setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Kits"));
+ setProperty(SHORT_TITLE_PROPERTY, tr("Kits"));
}
void TargetSetupPage::initializePage()
@@ -253,30 +255,37 @@ TargetSetupPage::~TargetSetupPage()
bool TargetSetupPage::isComplete() const
{
- return Utils::anyOf(m_widgets, [](const TargetSetupWidget *w) {
+ return anyOf(m_widgets, [](const TargetSetupWidget *w) {
return w->isKitSelected();
});
}
void TargetSetupPage::setupWidgets(const QString &filterText)
{
- // Known profiles:
- auto kitList = sortedKitList(m_requiredPredicate);
-
- foreach (Kit *k, kitList) {
- if (filterText.isEmpty() || k->displayName().contains(filterText, Qt::CaseInsensitive))
- addWidget(k);
+ const auto kitList = KitManager::sortKits(KitManager::kits());
+ for (Kit *k : kitList) {
+ if (!filterText.isEmpty() && !k->displayName().contains(filterText, Qt::CaseInsensitive))
+ continue;
+ const auto widget = new TargetSetupWidget(k, m_projectPath);
+ setInitialCheckState(widget);
+ connect(widget, &TargetSetupWidget::selectedToggled,
+ this, &TargetSetupPage::kitSelectionChanged);
+ connect(widget, &TargetSetupWidget::selectedToggled, this, &QWizardPage::completeChanged);
+ updateWidget(widget);
+ m_widgets.push_back(widget);
+ m_baseLayout->addWidget(widget);
}
+ addAdditionalWidgets();
// Setup import widget:
m_importWidget->setCurrentDirectory(Internal::importDirectory(m_projectPath));
updateVisibility();
- selectAtLeastOneKit();
}
void TargetSetupPage::reset()
{
+ removeAdditionalWidgets();
while (m_widgets.size() > 0) {
TargetSetupWidget *w = m_widgets.back();
@@ -290,19 +299,25 @@ void TargetSetupPage::reset()
m_ui->allKitsCheckBox->setChecked(false);
}
+void TargetSetupPage::setInitialCheckState(TargetSetupWidget *widget)
+{
+ widget->setKitSelected(widget->isEnabled() && m_preferredPredicate
+ && m_preferredPredicate(widget->kit()));
+}
+
TargetSetupWidget *TargetSetupPage::widget(const Core::Id kitId,
TargetSetupWidget *fallback) const
{
- return Utils::findOr(m_widgets, fallback, [kitId](const TargetSetupWidget *w) {
+ return findOr(m_widgets, fallback, [kitId](const TargetSetupWidget *w) {
return w->kit() && w->kit()->id() == kitId;
});
}
-void TargetSetupPage::setProjectPath(const QString &path)
+void TargetSetupPage::setProjectPath(const FilePath &path)
{
m_projectPath = path;
if (!m_projectPath.isEmpty()) {
- QFileInfo fileInfo(QDir::cleanPath(path));
+ QFileInfo fileInfo(QDir::cleanPath(path.toString()));
QStringList subDirsList = fileInfo.absolutePath().split('/');
m_ui->headerLabel->setText(tr("The following kits can be used for project <b>%1</b>:",
"%1: Project name").arg(subDirsList.last()));
@@ -350,9 +365,9 @@ void TargetSetupPage::setupImports()
if (!m_importer || m_projectPath.isEmpty())
return;
- QStringList toImport = m_importer->importCandidates();
- foreach (const QString &path, toImport)
- import(Utils::FilePath::fromString(path), true);
+ const QStringList toImport = m_importer->importCandidates();
+ for (const QString &path : toImport)
+ import(FilePath::fromString(path), true);
}
void TargetSetupPage::handleKitAddition(Kit *k)
@@ -386,40 +401,43 @@ void TargetSetupPage::handleKitUpdate(Kit *k)
if (m_importer)
m_importer->makePersistent(k);
- bool acceptable = !m_requiredPredicate || m_requiredPredicate(k);
- const bool wasAcceptable = Utils::contains(m_widgets, [k](const TargetSetupWidget *w) {
- return w->kit() == k;
- });
- if (acceptable == wasAcceptable)
- return;
-
- if (!acceptable)
- removeWidget(k);
- else if (acceptable)
- addWidget(k);
-
+ const auto newWidgetList = sortedWidgetList();
+ if (newWidgetList != m_widgets) { // Sorting has changed.
+ m_widgets = newWidgetList;
+ reLayout();
+ }
+ updateWidget(widget(k));
kitSelectionChanged();
updateVisibility();
}
void TargetSetupPage::selectAtLeastOneKit()
{
- const bool atLeastOneKitSelected = Utils::anyOf(m_widgets, [](TargetSetupWidget *w) {
+ bool atLeastOneKitSelected = anyOf(m_widgets, [](TargetSetupWidget *w) {
return w->isKitSelected();
});
if (!atLeastOneKitSelected) {
- TargetSetupWidget *w = m_firstWidget;
- Kit *defaultKit = KitManager::defaultKit();
- if (defaultKit)
- w = widget(defaultKit->id(), m_firstWidget);
- if (w) {
- w->setKitSelected(true);
- kitSelectionChanged();
+ Kit * const defaultKit = KitManager::defaultKit();
+ if (defaultKit && isUsable(defaultKit)) {
+ if (TargetSetupWidget * const w = widget(defaultKit)) {
+ w->setKitSelected(true);
+ atLeastOneKitSelected = true;
+ }
+ }
+ }
+ if (!atLeastOneKitSelected) {
+ for (TargetSetupWidget * const w : qAsConst(m_widgets)) {
+ if (isUsable(w->kit())) {
+ w->setKitSelected(true);
+ atLeastOneKitSelected = true;
+ }
}
- m_firstWidget = nullptr;
}
- emit completeChanged(); // Is this necessary?
+ if (atLeastOneKitSelected) {
+ kitSelectionChanged();
+ emit completeChanged(); // Is this necessary?
+ }
}
void TargetSetupPage::updateVisibility()
@@ -436,6 +454,36 @@ void TargetSetupPage::updateVisibility()
emit completeChanged();
}
+void TargetSetupPage::reLayout()
+{
+ removeAdditionalWidgets();
+ for (TargetSetupWidget * const w : qAsConst(m_widgets))
+ m_baseLayout->removeWidget(w);
+ for (TargetSetupWidget * const w : qAsConst(m_widgets))
+ m_baseLayout->addWidget(w);
+ addAdditionalWidgets();
+}
+
+bool TargetSetupPage::compareKits(const Kit *k1, const Kit *k2)
+{
+ const QString name1 = k1->displayName();
+ const QString name2 = k2->displayName();
+ if (name1 < name2)
+ return true;
+ if (name1 > name2)
+ return false;
+ return k1 < k2;
+}
+
+std::vector<TargetSetupWidget *> TargetSetupPage::sortedWidgetList() const
+{
+ std::vector<TargetSetupWidget *> list = m_widgets;
+ sort(list, [](const TargetSetupWidget *w1, const TargetSetupWidget *w2) {
+ return compareKits(w1->kit(), w2->kit());
+ });
+ return list;
+}
+
void TargetSetupPage::openOptions()
{
Core::ICore::showOptionsDialog(Constants::KITS_SETTINGS_PAGE_ID, this);
@@ -459,18 +507,12 @@ void TargetSetupPage::kitSelectionChanged()
m_ui->allKitsCheckBox->setCheckState(Qt::Unchecked);
}
-QList<Kit *> TargetSetupPage::sortedKitList(const Kit::Predicate &predicate)
-{
- const auto kitList = KitManager::kits(predicate);
-
- return KitManager::sortKits(kitList);
-}
-
void TargetSetupPage::kitFilterChanged(const QString &filterText)
{
// Reset currently shown kits
reset();
setupWidgets(filterText);
+ selectAtLeastOneKit();
}
void TargetSetupPage::changeAllKitsSelections()
@@ -485,12 +527,10 @@ void TargetSetupPage::changeAllKitsSelections()
bool TargetSetupPage::isUpdating() const
{
- if (m_importer)
- return m_importer->isUpdating();
- return false;
+ return m_importer && m_importer->isUpdating();
}
-void TargetSetupPage::import(const Utils::FilePath &path, bool silent)
+void TargetSetupPage::import(const FilePath &path, bool silent)
{
if (!m_importer)
return;
@@ -518,8 +558,6 @@ void TargetSetupPage::removeWidget(TargetSetupWidget *w)
{
if (!w)
return;
- if (w == m_firstWidget)
- m_firstWidget = nullptr;
w->deleteLater();
w->clearKit();
m_widgets.erase(std::find(m_widgets.begin(), m_widgets.end(), w));
@@ -527,34 +565,56 @@ void TargetSetupPage::removeWidget(TargetSetupWidget *w)
TargetSetupWidget *TargetSetupPage::addWidget(Kit *k)
{
- if (!k || (m_requiredPredicate && !m_requiredPredicate(k)))
- return nullptr;
-
- // Not all projects have BuildConfigurations, that is perfectly fine.
- auto *widget = new TargetSetupWidget(k, m_projectPath);
-
- m_baseLayout->removeWidget(m_importWidget);
- foreach (QWidget *potentialWidget, m_potentialWidgets)
- m_baseLayout->removeWidget(potentialWidget);
- m_baseLayout->removeItem(m_spacer);
-
- widget->setKitSelected(m_preferredPredicate && m_preferredPredicate(k));
- m_widgets.push_back(widget);
+ const auto widget = new TargetSetupWidget(k, m_projectPath);
+ setInitialCheckState(widget);
+ updateWidget(widget);
connect(widget, &TargetSetupWidget::selectedToggled,
this, &TargetSetupPage::kitSelectionChanged);
- m_baseLayout->addWidget(widget);
+ connect(widget, &TargetSetupWidget::selectedToggled, this, &QWizardPage::completeChanged);
+
+
+ // Insert widget, sorted.
+ const auto insertionPos = std::find_if(m_widgets.begin(), m_widgets.end(),
+ [k](const TargetSetupWidget *w) {
+ return compareKits(k, w->kit());
+ });
+ const bool addedToEnd = insertionPos == m_widgets.end();
+ m_widgets.insert(insertionPos, widget);
+ if (addedToEnd) {
+ removeAdditionalWidgets();
+ m_baseLayout->addWidget(widget);
+ addAdditionalWidgets();
+ } else {
+ reLayout();
+ }
+ return widget;
+}
+void TargetSetupPage::addAdditionalWidgets()
+{
m_baseLayout->addWidget(m_importWidget);
- foreach (QWidget *widget, m_potentialWidgets)
+ for (QWidget * const widget : qAsConst(m_potentialWidgets))
m_baseLayout->addWidget(widget);
m_baseLayout->addItem(m_spacer);
+}
- connect(widget, &TargetSetupWidget::selectedToggled, this, &QWizardPage::completeChanged);
+void TargetSetupPage::removeAdditionalWidgets(QLayout *layout)
+{
+ layout->removeWidget(m_importWidget);
+ for (QWidget * const potentialWidget : qAsConst(m_potentialWidgets))
+ layout->removeWidget(potentialWidget);
+ layout->removeItem(m_spacer);
+}
- if (!m_firstWidget)
- m_firstWidget = widget;
+void TargetSetupPage::updateWidget(TargetSetupWidget *widget)
+{
+ QTC_ASSERT(widget, return );
+ widget->update(m_requiredPredicate);
+}
- return widget;
+bool TargetSetupPage::isUsable(const Kit *kit) const
+{
+ return kit->isValid() && (!m_requiredPredicate || m_requiredPredicate(kit));
}
bool TargetSetupPage::setupProject(Project *project)
@@ -596,17 +656,9 @@ void TargetSetupPage::setUseScrollArea(bool b)
m_ui->scrollAreaWidget->setVisible(b);
m_ui->centralWidget->setVisible(!b);
- if (oldBaseLayout) {
- oldBaseLayout->removeWidget(m_importWidget);
- foreach (QWidget *widget, m_potentialWidgets)
- oldBaseLayout->removeWidget(widget);
- oldBaseLayout->removeItem(m_spacer);
- }
-
- m_baseLayout->addWidget(m_importWidget);
- foreach (QWidget *widget, m_potentialWidgets)
- m_baseLayout->addWidget(widget);
- m_baseLayout->addItem(m_spacer);
+ if (oldBaseLayout)
+ removeAdditionalWidgets(oldBaseLayout);
+ addAdditionalWidgets();
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/targetsetuppage.h b/src/plugins/projectexplorer/targetsetuppage.h
index 102ffbd57c..7ac07015c6 100644
--- a/src/plugins/projectexplorer/targetsetuppage.h
+++ b/src/plugins/projectexplorer/targetsetuppage.h
@@ -66,9 +66,9 @@ public:
void initializePage() override;
// Call these before initializePage!
- void setRequiredKitPredicate(const ProjectExplorer::Kit::Predicate &predicate);
- void setPreferredKitPredicate(const ProjectExplorer::Kit::Predicate &predicate);
- void setProjectPath(const QString &dir);
+ void setRequiredKitPredicate(const Kit::Predicate &predicate);
+ void setPreferredKitPredicate(const Kit::Predicate &predicate);
+ void setProjectPath(const Utils::FilePath &dir);
void setProjectImporter(ProjectImporter *importer);
bool importLineEditHasFocus() const;
@@ -91,39 +91,47 @@ public:
void kitFilterChanged(const QString &filterText);
private:
- void handleKitAddition(ProjectExplorer::Kit *k);
- void handleKitRemoval(ProjectExplorer::Kit *k);
- void handleKitUpdate(ProjectExplorer::Kit *k);
+ void handleKitAddition(Kit *k);
+ void handleKitRemoval(Kit *k);
+ void handleKitUpdate(Kit *k);
void updateVisibility();
+ void reLayout();
+ static bool compareKits(const Kit *k1, const Kit *k2);
+ std::vector<Internal::TargetSetupWidget *> sortedWidgetList() const;
+
void kitSelectionChanged();
- static QList<Kit *> sortedKitList(const Kit::Predicate &predicate);
bool isUpdating() const;
void selectAtLeastOneKit();
void removeWidget(Kit *k) { removeWidget(widget(k)); }
void removeWidget(Internal::TargetSetupWidget *w);
Internal::TargetSetupWidget *addWidget(Kit *k);
+ void addAdditionalWidgets();
+ void removeAdditionalWidgets(QLayout *layout);
+ void removeAdditionalWidgets() { removeAdditionalWidgets(m_baseLayout); }
+ void updateWidget(Internal::TargetSetupWidget *widget);
+ bool isUsable(const Kit *kit) const;
void setupImports();
void import(const Utils::FilePath &path, bool silent = false);
void setupWidgets(const QString &filterText = QString());
void reset();
+ void setInitialCheckState(Internal::TargetSetupWidget *widget);
Internal::TargetSetupWidget *widget(Kit *k, Internal::TargetSetupWidget *fallback = nullptr) const
{ return widget(k->id(), fallback); }
Internal::TargetSetupWidget *widget(const Core::Id kitId,
Internal::TargetSetupWidget *fallback = nullptr) const;
- ProjectExplorer::Kit::Predicate m_requiredPredicate;
- ProjectExplorer::Kit::Predicate m_preferredPredicate;
+ Kit::Predicate m_requiredPredicate;
+ Kit::Predicate m_preferredPredicate;
QPointer<ProjectImporter> m_importer;
QLayout *m_baseLayout = nullptr;
- QString m_projectPath;
+ Utils::FilePath m_projectPath;
QString m_defaultShadowBuildLocation;
std::vector<Internal::TargetSetupWidget *> m_widgets;
- Internal::TargetSetupWidget *m_firstWidget = nullptr;
Internal::TargetSetupPageUi *m_ui;
diff --git a/src/plugins/projectexplorer/targetsetupwidget.cpp b/src/plugins/projectexplorer/targetsetupwidget.cpp
index 6aa66517e3..12a16d31c1 100644
--- a/src/plugins/projectexplorer/targetsetupwidget.cpp
+++ b/src/plugins/projectexplorer/targetsetupwidget.cpp
@@ -28,7 +28,6 @@
#include "buildconfiguration.h"
#include "buildinfo.h"
#include "projectexplorerconstants.h"
-#include "kit.h"
#include "kitmanager.h"
#include "kitoptionspage.h"
@@ -40,6 +39,7 @@
#include <utils/hostosinfo.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
+#include <utils/utilsicons.h>
#include <QCheckBox>
#include <QHBoxLayout>
@@ -47,6 +47,8 @@
#include <QLabel>
#include <QPushButton>
+using namespace Utils;
+
namespace ProjectExplorer {
namespace Internal {
@@ -54,7 +56,7 @@ namespace Internal {
// TargetSetupWidget
// -------------------------------------------------------------------------
-TargetSetupWidget::TargetSetupWidget(Kit *k, const QString &projectPath) :
+TargetSetupWidget::TargetSetupWidget(Kit *k, const FilePath &projectPath) :
m_kit(k)
{
Q_ASSERT(m_kit);
@@ -67,7 +69,6 @@ TargetSetupWidget::TargetSetupWidget(Kit *k, const QString &projectPath) :
m_detailsWidget->setUseCheckBox(true);
m_detailsWidget->setChecked(false);
m_detailsWidget->setSummaryFontBold(true);
- m_detailsWidget->setToolTip(m_kit->toHtml());
vboxLayout->addWidget(m_detailsWidget);
auto panel = new Utils::FadingWidget(m_detailsWidget);
@@ -76,8 +77,6 @@ TargetSetupWidget::TargetSetupWidget(Kit *k, const QString &projectPath) :
panelLayout->addWidget(m_manageButton);
m_detailsWidget->setToolWidget(panel);
- handleKitUpdate(m_kit);
-
auto widget = new QWidget;
auto layout = new QVBoxLayout;
widget->setLayout(layout);
@@ -85,7 +84,7 @@ TargetSetupWidget::TargetSetupWidget(Kit *k, const QString &projectPath) :
auto w = new QWidget;
m_newBuildsLayout = new QGridLayout;
- m_newBuildsLayout->setMargin(0);
+ m_newBuildsLayout->setContentsMargins(0, 0, 0, 0);
if (Utils::HostOsInfo::isMacHost())
m_newBuildsLayout->setSpacing(0);
w->setLayout(m_newBuildsLayout);
@@ -99,9 +98,6 @@ TargetSetupWidget::TargetSetupWidget(Kit *k, const QString &projectPath) :
connect(m_detailsWidget, &Utils::DetailsWidget::checked,
this, &TargetSetupWidget::targetCheckBoxToggled);
- connect(KitManager::instance(), &KitManager::kitUpdated,
- this, &TargetSetupWidget::handleKitUpdate);
-
connect(m_manageButton, &QAbstractButton::clicked, this, &TargetSetupWidget::manageKit);
}
@@ -208,7 +204,7 @@ void TargetSetupWidget::manageKit()
}
}
-void TargetSetupWidget::setProjectPath(const QString &projectPath)
+void TargetSetupWidget::setProjectPath(const FilePath &projectPath)
{
if (!m_kit)
return;
@@ -225,7 +221,27 @@ void TargetSetupWidget::expandWidget()
m_detailsWidget->setState(Utils::DetailsWidget::Expanded);
}
-const QList<BuildInfo> TargetSetupWidget::buildInfoList(const Kit *k, const QString &projectPath)
+void TargetSetupWidget::update(const Kit::Predicate &predicate)
+{
+ m_detailsWidget->setSummaryText(kit()->displayName());
+
+ // Kits that we deem invalid get a warning icon, but users can still select them,
+ // e.g. in case we misdetected an ABI mismatch.
+ // Kits that don't fulfill the project predicate are not selectable, because we cannot
+ // guarantee that we can handle the project sensibly (e.g. qmake project without Qt).
+ if (predicate && !predicate(kit())) {
+ setEnabled(false);
+ m_detailsWidget->setToolTip(tr("You cannot use this kit, because it does not fulfill "
+ "the project's prerequisites."));
+ return;
+ }
+ setEnabled(true);
+ m_detailsWidget->setIcon(kit()->isValid() ? kit()->icon() : Icons::CRITICAL.icon());
+ m_detailsWidget->setToolTip(m_kit->toHtml());
+ updateDefaultBuildDirectories();
+}
+
+const QList<BuildInfo> TargetSetupWidget::buildInfoList(const Kit *k, const FilePath &projectPath)
{
if (auto factory = BuildConfigurationFactory::find(k, projectPath))
return factory->allAvailableSetups(k, projectPath);
@@ -235,15 +251,6 @@ const QList<BuildInfo> TargetSetupWidget::buildInfoList(const Kit *k, const QStr
return {info};
}
-void TargetSetupWidget::handleKitUpdate(Kit *k)
-{
- if (k != m_kit)
- return;
-
- m_detailsWidget->setIcon(k->icon());
- m_detailsWidget->setSummaryText(k->displayName());
-}
-
const QList<BuildInfo> TargetSetupWidget::selectedBuildInfoList() const
{
QList<BuildInfo> result;
@@ -264,6 +271,24 @@ void TargetSetupWidget::clear()
emit selectedToggled();
}
+void TargetSetupWidget::updateDefaultBuildDirectories()
+{
+ for (const BuildInfo &buildInfo : buildInfoList(m_kit, m_projectPath)) {
+ if (!buildInfo.factory())
+ continue;
+ for (BuildInfoStore &buildInfoStore : m_infoStore) {
+ if (buildInfoStore.buildInfo.buildType == buildInfo.buildType) {
+ if (!buildInfoStore.customBuildDir) {
+ m_ignoreChange = true;
+ buildInfoStore.pathChooser->setFileName(buildInfo.buildDirectory);
+ m_ignoreChange = false;
+ }
+ break;
+ }
+ }
+ }
+}
+
void TargetSetupWidget::checkBoxToggled(bool b)
{
auto box = qobject_cast<QCheckBox *>(sender());
@@ -295,6 +320,7 @@ void TargetSetupWidget::pathChanged()
});
QTC_ASSERT(it != m_infoStore.end(), return);
it->buildInfo.buildDirectory = pathChooser->fileName();
+ it->customBuildDir = true;
reportIssues(static_cast<int>(std::distance(m_infoStore.begin(), it)));
}
@@ -320,7 +346,7 @@ QPair<Task::TaskType, QString> TargetSetupWidget::findIssues(const BuildInfo &in
QString buildDir = info.buildDirectory.toString();
Tasks issues;
if (info.factory())
- issues = info.factory()->reportIssues(m_kit, m_projectPath, buildDir);
+ issues = info.factory()->reportIssues(m_kit, m_projectPath.toString(), buildDir);
QString text;
Task::TaskType highestType = Task::Unknown;
diff --git a/src/plugins/projectexplorer/targetsetupwidget.h b/src/plugins/projectexplorer/targetsetupwidget.h
index 62dca1af52..80f64ad918 100644
--- a/src/plugins/projectexplorer/targetsetupwidget.h
+++ b/src/plugins/projectexplorer/targetsetupwidget.h
@@ -28,6 +28,7 @@
#include "projectexplorer_export.h"
#include "buildinfo.h"
+#include "kit.h"
#include "task.h"
#include <QWidget>
@@ -48,7 +49,6 @@ class PathChooser;
namespace ProjectExplorer {
class BuildInfo;
-class Kit;
namespace Internal {
@@ -57,8 +57,7 @@ class TargetSetupWidget : public QWidget
Q_OBJECT
public:
- TargetSetupWidget(Kit *k,
- const QString &projectPath);
+ TargetSetupWidget(Kit *k, const Utils::FilePath &projectPath);
Kit *kit() const;
void clearKit();
@@ -69,16 +68,15 @@ public:
void addBuildInfo(const BuildInfo &info, bool isImport);
const QList<BuildInfo> selectedBuildInfoList() const;
- void setProjectPath(const QString &projectPath);
+ void setProjectPath(const Utils::FilePath &projectPath);
void expandWidget();
+ void update(const Kit::Predicate &predicate);
signals:
void selectedToggled() const;
private:
- static const QList<BuildInfo> buildInfoList(const Kit *k, const QString &projectPath);
-
- void handleKitUpdate(ProjectExplorer::Kit *k);
+ static const QList<BuildInfo> buildInfoList(const Kit *k, const Utils::FilePath &projectPath);
void checkBoxToggled(bool b);
void pathChanged();
@@ -88,9 +86,10 @@ private:
void reportIssues(int index);
QPair<Task::TaskType, QString> findIssues(const BuildInfo &info);
void clear();
+ void updateDefaultBuildDirectories();
Kit *m_kit;
- QString m_projectPath;
+ Utils::FilePath m_projectPath;
bool m_haveImported = false;
Utils::DetailsWidget *m_detailsWidget;
QPushButton *m_manageButton;
@@ -111,11 +110,12 @@ private:
Utils::PathChooser *pathChooser = nullptr;
bool isEnabled = false;
bool hasIssues = false;
+ bool customBuildDir = false;
};
std::vector<BuildInfoStore> m_infoStore;
bool m_ignoreChange = false;
- int m_selected = 0; // Number of selected "buildconfiguartions"
+ int m_selected = 0; // Number of selected "buildconfigurations"
};
} // namespace Internal
diff --git a/src/plugins/projectexplorer/taskhub.cpp b/src/plugins/projectexplorer/taskhub.cpp
index 10b04c4d5b..d299e8d86a 100644
--- a/src/plugins/projectexplorer/taskhub.cpp
+++ b/src/plugins/projectexplorer/taskhub.cpp
@@ -71,7 +71,13 @@ public:
: QApplication::translate("TaskHub", "Warning"));
setPriority(task.type == Task::Error ? TextEditor::TextMark::NormalPriority
: TextEditor::TextMark::LowPriority);
- setToolTip(task.description);
+ if (task.category == Constants::TASK_CATEGORY_COMPILE) {
+ setToolTip("<html><body><b>" + QApplication::translate("TaskHub", "Build Issue")
+ + "</b><br/><code style=\"white-space:pre;font-family:monospace\">"
+ + task.description.toHtmlEscaped() + "</code></body></html>");
+ } else {
+ setToolTip(task.description);
+ }
setIcon(task.icon);
setVisible(!task.icon.isNull());
}
@@ -154,7 +160,7 @@ void TaskHub::addTask(Task task)
task.line = -1;
task.movedLine = task.line;
- if ((task.options & Task::AddTextMark) && task.line != -1)
+ if ((task.options & Task::AddTextMark) && task.line != -1 && task.type != Task::Unknown)
task.setMark(new TaskMark(task));
emit m_instance->taskAdded(task);
}
diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp
index c6d27bd7d4..763ec4074c 100644
--- a/src/plugins/projectexplorer/taskmodel.cpp
+++ b/src/plugins/projectexplorer/taskmodel.cpp
@@ -372,7 +372,7 @@ void TaskFilterModel::updateFilterProperties(const QString &filterText,
bool TaskFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
- Q_UNUSED(source_parent);
+ Q_UNUSED(source_parent)
return filterAcceptsTask(taskModel()->tasks().at(source_row));
}
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index 66c5ac83db..2728df11c7 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -70,6 +70,7 @@ public:
QByteArray m_id;
QSet<Core::Id> m_supportedLanguages;
mutable QString m_displayName;
+ QString m_typeDisplayName;
Core::Id m_typeId;
Core::Id m_language;
Detection m_detection = ToolChain::UninitializedDetection;
@@ -169,11 +170,6 @@ QStringList ToolChain::suggestedMkspecList() const
return {};
}
-Utils::FilePath ToolChain::suggestedDebugger() const
-{
- return ToolChainManager::defaultDebugger(targetAbi());
-}
-
Core::Id ToolChain::typeId() const
{
return d->m_typeId;
@@ -262,6 +258,16 @@ void ToolChain::setDetection(ToolChain::Detection de)
}
}
+QString ToolChain::typeDisplayName() const
+{
+ return d->m_typeDisplayName;
+}
+
+void ToolChain::setTypeDisplayName(const QString &typeName)
+{
+ d->m_typeDisplayName = typeName;
+}
+
/*!
Used by the tool chain manager to load user-generated tool chains.
@@ -432,15 +438,14 @@ const QList<ToolChainFactory *> ToolChainFactory::allToolChainFactories()
QList<ToolChain *> ToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown)
{
- Q_UNUSED(alreadyKnown);
- return QList<ToolChain *>();
+ Q_UNUSED(alreadyKnown)
+ return {};
}
-QList<ToolChain *> ToolChainFactory::autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language)
+QList<ToolChain *> ToolChainFactory::detectForImport(const ToolChainDescription &tcd)
{
- Q_UNUSED(compilerPath);
- Q_UNUSED(language);
- return QList<ToolChain *>();
+ Q_UNUSED(tcd)
+ return {};
}
bool ToolChainFactory::canCreate() const
@@ -491,6 +496,19 @@ void ToolChainFactory::autoDetectionToMap(QVariantMap &data, bool detected)
data.insert(QLatin1String(AUTODETECT_KEY), detected);
}
+ToolChain *ToolChainFactory::createToolChain(Core::Id toolChainType)
+{
+ for (ToolChainFactory *factory : qAsConst(Internal::g_toolChainFactories)) {
+ if (factory->m_supportedToolChainType == toolChainType) {
+ if (ToolChain *tc = factory->create()) {
+ tc->d->m_typeId = toolChainType;
+ return tc;
+ }
+ }
+ }
+ return nullptr;
+}
+
QSet<Core::Id> ToolChainFactory::supportedLanguages() const
{
return m_supportsAllLanguages ? ToolChainManager::allLanguages() : m_supportedLanguages;
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 1cbe478691..4c8b3061ab 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -37,17 +37,16 @@
#include <coreplugin/id.h>
#include <utils/cpplanguage_details.h>
+#include <utils/environment.h>
#include <QObject>
#include <QSet>
-#include <QString>
+#include <QStringList>
#include <QVariantMap>
#include <functional>
#include <memory>
-namespace Utils { class Environment; }
-
namespace ProjectExplorer {
namespace Internal { class ToolChainPrivate; }
@@ -72,6 +71,13 @@ class Kit;
namespace Internal { class ToolChainSettingsAccessor; }
+class PROJECTEXPLORER_EXPORT ToolChainDescription
+{
+public:
+ Utils::FilePath compilerPath;
+ Core::Id language;
+};
+
// --------------------------------------------------------------------------
// ToolChain (documentation inside)
// --------------------------------------------------------------------------
@@ -99,11 +105,12 @@ public:
QByteArray id() const;
virtual QStringList suggestedMkspecList() const;
- virtual Utils::FilePath suggestedDebugger() const;
Core::Id typeId() const;
- virtual QString typeDisplayName() const = 0;
+ QString typeDisplayName() const;
+
virtual Abi targetAbi() const = 0;
+
virtual ProjectExplorer::Abis supportedAbis() const;
virtual QString originalTargetTriple() const { return QString(); }
virtual QStringList extraCodeModelFlags() const { return QStringList(); }
@@ -121,8 +128,8 @@ public:
Utils::LanguageVersion languageVersion;
};
- using MacrosCache = std::shared_ptr<Cache<ToolChain::MacroInspectionReport, 64>>;
- using HeaderPathsCache = std::shared_ptr<Cache<HeaderPaths>>;
+ using MacrosCache = std::shared_ptr<Cache<QStringList, ToolChain::MacroInspectionReport, 64>>;
+ using HeaderPathsCache = std::shared_ptr<Cache<QPair<Utils::Environment, QStringList>, HeaderPaths>>;
// A MacroInspectionRunner is created in the ui thread and runs in another thread.
using MacroInspectionRunner = std::function<MacroInspectionReport(const QStringList &cxxflags)>;
@@ -132,9 +139,10 @@ public:
// A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread.
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(
const QStringList &cxxflags, const QString &sysRoot, const QString &originalTargetTriple)>;
- virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const = 0;
+ virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(const Utils::Environment &env) const = 0;
virtual HeaderPaths builtInHeaderPaths(const QStringList &cxxflags,
- const Utils::FilePath &sysRoot) const = 0;
+ const Utils::FilePath &sysRoot,
+ const Utils::Environment &env) const = 0;
virtual void addToEnvironment(Utils::Environment &env) const = 0;
virtual Utils::FilePath makeCommand(const Utils::Environment &env) const = 0;
@@ -164,6 +172,8 @@ public:
protected:
explicit ToolChain(Core::Id typeId);
+ void setTypeDisplayName(const QString &typeName);
+
const MacrosCache &predefinedMacrosCache() const;
const HeaderPathsCache &headerPathsCache() const;
@@ -196,7 +206,7 @@ public:
Core::Id supportedToolChainType() const;
virtual QList<ToolChain *> autoDetect(const QList<ToolChain *> &alreadyKnown);
- virtual QList<ToolChain *> autoDetect(const Utils::FilePath &compilerPath, const Core::Id &language);
+ virtual QList<ToolChain *> detectForImport(const ToolChainDescription &tcd);
virtual bool canCreate() const;
virtual ToolChain *create();
@@ -207,6 +217,8 @@ public:
static Core::Id typeIdFromMap(const QVariantMap &data);
static void autoDetectionToMap(QVariantMap &data, bool detected);
+ static ToolChain *createToolChain(Core::Id toolChainType);
+
QSet<Core::Id> supportedLanguages() const;
void setUserCreatable(bool userCreatable);
diff --git a/src/plugins/projectexplorer/toolchaincache.h b/src/plugins/projectexplorer/toolchaincache.h
index 154c09162f..4f69494d09 100644
--- a/src/plugins/projectexplorer/toolchaincache.h
+++ b/src/plugins/projectexplorer/toolchaincache.h
@@ -27,14 +27,14 @@
#include <QMutex>
#include <QMutexLocker>
-#include <QStringList>
+#include <QPair>
#include <QVector>
#include <utils/optional.h>
namespace ProjectExplorer {
-template<class T, int Size = 16>
+template<class K, class T, int Size = 16>
class Cache
{
public:
@@ -61,14 +61,14 @@ public:
return *this;
}
- void insert(const QStringList &compilerArguments, const T &values)
+ void insert(const K &key, const T &values)
{
CacheItem runResults;
- runResults.first = compilerArguments;
+ runResults.first = key;
runResults.second = values;
QMutexLocker locker(&m_mutex);
- if (!checkImpl(compilerArguments)) {
+ if (!checkImpl(key)) {
if (m_cache.size() < Size) {
m_cache.push_back(runResults);
} else {
@@ -78,10 +78,10 @@ public:
}
}
- Utils::optional<T> check(const QStringList &compilerArguments)
+ Utils::optional<T> check(const K &key)
{
QMutexLocker locker(&m_mutex);
- return checkImpl(compilerArguments);
+ return checkImpl(key);
}
void invalidate()
@@ -91,17 +91,17 @@ public:
}
private:
- Utils::optional<T> checkImpl(const QStringList &compilerArguments)
+ Utils::optional<T> checkImpl(const K &key)
{
auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) {
- return ci.first != compilerArguments;
+ return ci.first != key;
});
if (it != m_cache.end())
return m_cache.back().second;
return {};
}
- using CacheItem = QPair<QStringList, T>;
+ using CacheItem = QPair<K, T>;
QMutex m_mutex;
QVector<CacheItem> m_cache;
diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp
index ffea568dbe..b3ac697bb2 100644
--- a/src/plugins/projectexplorer/toolchainmanager.cpp
+++ b/src/plugins/projectexplorer/toolchainmanager.cpp
@@ -63,7 +63,6 @@ class ToolChainManagerPrivate
public:
~ToolChainManagerPrivate();
- QMap<QString, FilePath> m_abiToDebugger;
std::unique_ptr<ToolChainSettingsAccessor> m_accessor;
QList<ToolChain *> m_toolChains; // prioritized List
@@ -186,11 +185,6 @@ ToolChain *ToolChainManager::findToolChain(const QByteArray &id)
return tc;
}
-FilePath ToolChainManager::defaultDebugger(const Abi &abi)
-{
- return d->m_abiToDebugger.value(abi.toString());
-}
-
bool ToolChainManager::isLoaded()
{
return bool(d->m_accessor);
diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h
index 4de51c2b2a..894ec71da2 100644
--- a/src/plugins/projectexplorer/toolchainmanager.h
+++ b/src/plugins/projectexplorer/toolchainmanager.h
@@ -68,8 +68,6 @@ public:
static QList<ToolChain *> findToolChains(const Abi &abi);
static ToolChain *findToolChain(const QByteArray &id);
- static Utils::FilePath defaultDebugger(const Abi &abi);
-
static bool isLoaded();
static bool registerToolChain(ToolChain *tc);
diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp
index 0b9e6fad60..ea5a07f0fe 100644
--- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp
+++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp
@@ -299,31 +299,29 @@ const char TestToolChainType[] = "TestToolChainType";
class TTC : public ToolChain
{
public:
- TTC() : ToolChain(TestToolChainType) {}
-
- TTC(const QByteArray &t, bool v = true) :
+ TTC(const QByteArray &t = {}, bool v = true) :
ToolChain(TestToolChainType),
token(t),
m_valid(v)
{
m_toolChains.append(this);
setLanguage(Constants::CXX_LANGUAGE_ID);
+ setTypeDisplayName("Test Tool Chain");
}
static QList<TTC *> toolChains();
static bool hasToolChains() { return !m_toolChains.isEmpty(); }
- QString typeDisplayName() const override { return QString("Test Tool Chain"); }
Abi targetAbi() const override { return Abi::hostAbi(); }
bool isValid() const override { return m_valid; }
MacroInspectionRunner createMacroInspectionRunner() const override { return MacroInspectionRunner(); }
- Macros predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return Macros(); }
- LanguageExtensions languageExtensions(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return LanguageExtension::None; }
- WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return WarningFlags::NoWarnings; }
- BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override { return BuiltInHeaderPathsRunner(); }
- HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, const FilePath &sysRoot) const override
- { Q_UNUSED(cxxflags); Q_UNUSED(sysRoot); return {}; }
- void addToEnvironment(Environment &env) const override { Q_UNUSED(env); }
+ Macros predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags) return Macros(); }
+ LanguageExtensions languageExtensions(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags) return LanguageExtension::None; }
+ WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags) return WarningFlags::NoWarnings; }
+ BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(const Utils::Environment &) const override { return BuiltInHeaderPathsRunner(); }
+ HeaderPaths builtInHeaderPaths(const QStringList &cxxflags, const FilePath &sysRoot, const Utils::Environment &) const override
+ { Q_UNUSED(cxxflags) Q_UNUSED(sysRoot) return {}; }
+ void addToEnvironment(Environment &env) const override { Q_UNUSED(env) }
FilePath makeCommand(const Environment &) const override { return FilePath::fromString("make"); }
FilePath compilerCommand() const override { return Utils::FilePath::fromString("/tmp/test/gcc"); }
IOutputParser *outputParser() const override { return nullptr; }
diff --git a/src/plugins/projectexplorer/userfileaccessor.cpp b/src/plugins/projectexplorer/userfileaccessor.cpp
index f166425a1d..676bcf7990 100644
--- a/src/plugins/projectexplorer/userfileaccessor.cpp
+++ b/src/plugins/projectexplorer/userfileaccessor.cpp
@@ -469,9 +469,7 @@ QVariantMap UserFileAccessor::prepareToWriteSettings(const QVariantMap &data) co
QVariantMap UserFileVersion14Upgrader::upgrade(const QVariantMap &map)
{
QVariantMap result;
- QMapIterator<QString, QVariant> it(map);
- while (it.hasNext()) {
- it.next();
+ for (auto it = map.cbegin(), end = map.cend(); it != end; ++it) {
if (it.value().type() == QVariant::Map)
result.insert(it.key(), upgrade(it.value().toMap()));
else if (it.key() == "AutotoolsProjectManager.AutotoolsBuildConfiguration.BuildDirectory"
diff --git a/src/plugins/pythoneditor/CMakeLists.txt b/src/plugins/python/CMakeLists.txt
index 2cd855ce7e..7ecc160f3a 100644
--- a/src/plugins/pythoneditor/CMakeLists.txt
+++ b/src/plugins/python/CMakeLists.txt
@@ -1,11 +1,15 @@
-add_qtc_plugin(PythonEditor
+add_qtc_plugin(Python
PLUGIN_DEPENDS Core ProjectExplorer TextEditor
SOURCES
+ python.qrc
pythoneditor.cpp pythoneditor.h
- pythoneditorconstants.h
- pythoneditorplugin.cpp pythoneditorplugin.h
+ pythonconstants.h
+ pythonplugin.cpp pythonplugin.h
pythonformattoken.h
pythonhighlighter.cpp pythonhighlighter.h
pythonindenter.cpp pythonindenter.h
+ pythonproject.cpp pythonproject.h
+ pythonrunconfiguration.cpp pythonrunconfiguration.h
+ pythonsettings.cpp pythonsettings.h
pythonscanner.cpp pythonscanner.h
)
diff --git a/src/plugins/pythoneditor/PythonEditor.json.in b/src/plugins/python/Python.json.in
index 89269328b3..b74b0e4863 100644
--- a/src/plugins/pythoneditor/PythonEditor.json.in
+++ b/src/plugins/python/Python.json.in
@@ -1,5 +1,5 @@
{
- \"Name\" : \"PythonEditor\",
+ \"Name\" : \"Python\",
\"Version\" : \"$$QTCREATOR_VERSION\",
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
\"Vendor\" : \"The Qt Company Ltd\",
@@ -13,7 +13,7 @@
\"Alternatively, this plugin 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 plugin. 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.\"
],
\"Category\" : \"Other Languages\",
- \"Description\" : \"Editor and file creation wizards for Python. Example plugin for QtCreator API demonstration.\",
+ \"Description\" : \"Plugin for supporting the Python language.\",
\"Url\" : \"http://www.qt.io\",
$$dependencyList,
diff --git a/src/plugins/python/images/settingscategory_python.png b/src/plugins/python/images/settingscategory_python.png
new file mode 100644
index 0000000000..36ad4c2c3c
--- /dev/null
+++ b/src/plugins/python/images/settingscategory_python.png
Binary files differ
diff --git a/src/plugins/python/images/settingscategory_python@2x.png b/src/plugins/python/images/settingscategory_python@2x.png
new file mode 100644
index 0000000000..84f7819d86
--- /dev/null
+++ b/src/plugins/python/images/settingscategory_python@2x.png
Binary files differ
diff --git a/src/plugins/python/python.pro b/src/plugins/python/python.pro
new file mode 100644
index 0000000000..ec4ea74c06
--- /dev/null
+++ b/src/plugins/python/python.pro
@@ -0,0 +1,29 @@
+include(../../qtcreatorplugin.pri)
+
+DEFINES += \
+ PYTHON_LIBRARY
+
+HEADERS += \
+ pythonplugin.h \
+ pythoneditor.h \
+ pythonconstants.h \
+ pythonhighlighter.h \
+ pythonindenter.h \
+ pythonformattoken.h \
+ pythonproject.h \
+ pythonrunconfiguration.h \
+ pythonscanner.h \
+ pythonsettings.h
+
+SOURCES += \
+ pythonplugin.cpp \
+ pythoneditor.cpp \
+ pythonhighlighter.cpp \
+ pythonindenter.cpp \
+ pythonproject.cpp \
+ pythonrunconfiguration.cpp \
+ pythonscanner.cpp \
+ pythonsettings.cpp
+
+RESOURCES += \
+ python.qrc
diff --git a/src/plugins/python/python.qbs b/src/plugins/python/python.qbs
new file mode 100644
index 0000000000..c90f76d5d1
--- /dev/null
+++ b/src/plugins/python/python.qbs
@@ -0,0 +1,37 @@
+import qbs 1.0
+
+QtcPlugin {
+ name: "Python"
+
+ Depends { name: "Qt.widgets" }
+ Depends { name: "Utils" }
+
+ Depends { name: "Core" }
+ Depends { name: "TextEditor" }
+ Depends { name: "ProjectExplorer" }
+
+ Group {
+ name: "General"
+ files: [
+ "python.qrc",
+ "pythoneditor.cpp",
+ "pythoneditor.h",
+ "pythonconstants.h",
+ "pythonplugin.cpp",
+ "pythonplugin.h",
+ "pythonhighlighter.h",
+ "pythonhighlighter.cpp",
+ "pythonindenter.cpp",
+ "pythonindenter.h",
+ "pythonformattoken.h",
+ "pythonproject.cpp",
+ "pythonproject.h",
+ "pythonrunconfiguration.cpp",
+ "pythonrunconfiguration.h",
+ "pythonscanner.h",
+ "pythonscanner.cpp",
+ "pythonsettings.cpp",
+ "pythonsettings.h",
+ ]
+ }
+}
diff --git a/src/plugins/python/python.qrc b/src/plugins/python/python.qrc
new file mode 100644
index 0000000000..1a6da2a242
--- /dev/null
+++ b/src/plugins/python/python.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/python">
+ <file>images/settingscategory_python.png</file>
+ <file>images/settingscategory_python@2x.png</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/pythoneditor/pythoneditor_dependencies.pri b/src/plugins/python/python_dependencies.pri
index b9502f0997..5f2a87c283 100644
--- a/src/plugins/pythoneditor/pythoneditor_dependencies.pri
+++ b/src/plugins/python/python_dependencies.pri
@@ -1,4 +1,4 @@
-QTC_PLUGIN_NAME = PythonEditor
+QTC_PLUGIN_NAME = Python
QTC_LIB_DEPENDS += \
extensionsystem \
utils
diff --git a/src/plugins/pythoneditor/pythoneditorconstants.h b/src/plugins/python/pythonconstants.h
index a84281aaa5..0fba0603e9 100644
--- a/src/plugins/pythoneditor/pythoneditorconstants.h
+++ b/src/plugins/python/pythonconstants.h
@@ -27,13 +27,16 @@
#include <QtGlobal>
-namespace PythonEditor {
+namespace Python {
namespace Constants {
const char C_PYTHONEDITOR_ID[] = "PythonEditor.PythonEditor";
const char C_EDITOR_DISPLAY_NAME[] =
QT_TRANSLATE_NOOP("OpenWith::Editors", "Python Editor");
+const char C_PYTHONOPTIONS_PAGE_ID[] = "PythonEditor.OptionsPage";
+const char C_PYTHON_SETTINGS_CATEGORY[] = "P.Python";
+
/*******************************************************************************
* MIME type
******************************************************************************/
@@ -41,4 +44,4 @@ const char C_PY_MIMETYPE[] = "text/x-python";
const char C_PY_MIME_ICON[] = "text-x-python";
} // namespace Constants
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythoneditor.cpp b/src/plugins/python/pythoneditor.cpp
index d0f27ae63c..145e88e137 100644
--- a/src/plugins/pythoneditor/pythoneditor.cpp
+++ b/src/plugins/python/pythoneditor.cpp
@@ -24,8 +24,8 @@
****************************************************************************/
#include "pythoneditor.h"
-#include "pythoneditorconstants.h"
-#include "pythoneditorplugin.h"
+#include "pythonconstants.h"
+#include "pythonplugin.h"
#include "pythonindenter.h"
#include "pythonhighlighter.h"
@@ -39,7 +39,7 @@
using namespace TextEditor;
-namespace PythonEditor {
+namespace Python {
namespace Internal {
PythonEditorFactory::PythonEditorFactory()
@@ -62,4 +62,4 @@ PythonEditorFactory::PythonEditorFactory()
}
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythoneditor.h b/src/plugins/python/pythoneditor.h
index 96bcc8c03b..7224008bd0 100644
--- a/src/plugins/pythoneditor/pythoneditor.h
+++ b/src/plugins/python/pythoneditor.h
@@ -27,7 +27,7 @@
#include <texteditor/texteditor.h>
-namespace PythonEditor {
+namespace Python {
namespace Internal {
class PythonEditorFactory : public TextEditor::TextEditorFactory
@@ -37,4 +37,4 @@ public:
};
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonformattoken.h b/src/plugins/python/pythonformattoken.h
index c98f3a1fef..8a7465d769 100644
--- a/src/plugins/pythoneditor/pythonformattoken.h
+++ b/src/plugins/python/pythonformattoken.h
@@ -25,7 +25,7 @@
#pragma once
-namespace PythonEditor {
+namespace Python {
namespace Internal {
enum Format {
@@ -68,4 +68,4 @@ private:
};
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonhighlighter.cpp b/src/plugins/python/pythonhighlighter.cpp
index b485c2a450..c809e25b84 100644
--- a/src/plugins/pythoneditor/pythonhighlighter.cpp
+++ b/src/plugins/python/pythonhighlighter.cpp
@@ -41,7 +41,7 @@
#include <texteditor/texteditorconstants.h>
#include <utils/qtcassert.h>
-namespace PythonEditor {
+namespace Python {
namespace Internal {
/**
@@ -198,4 +198,4 @@ void PythonHighlighter::highlightImport(Scanner &scanner)
}
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonhighlighter.h b/src/plugins/python/pythonhighlighter.h
index 63c35dfaf3..3c798d82d0 100644
--- a/src/plugins/pythoneditor/pythonhighlighter.h
+++ b/src/plugins/python/pythonhighlighter.h
@@ -27,7 +27,7 @@
#include <texteditor/syntaxhighlighter.h>
-namespace PythonEditor {
+namespace Python {
namespace Internal {
class Scanner;
@@ -47,4 +47,4 @@ private:
};
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonindenter.cpp b/src/plugins/python/pythonindenter.cpp
index a6fb880dcd..dff38907ee 100644
--- a/src/plugins/pythoneditor/pythonindenter.cpp
+++ b/src/plugins/python/pythonindenter.cpp
@@ -30,7 +30,7 @@
#include <algorithm>
-namespace PythonEditor {
+namespace Python {
static bool isEmptyLine(const QString &t)
{
@@ -124,4 +124,4 @@ int PythonIndenter::getIndentDiff(const QString &previousLine,
return 0;
}
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonindenter.h b/src/plugins/python/pythonindenter.h
index ff9378e007..243e6f178c 100644
--- a/src/plugins/pythoneditor/pythonindenter.h
+++ b/src/plugins/python/pythonindenter.h
@@ -27,7 +27,7 @@
#include <texteditor/textindenter.h>
-namespace PythonEditor {
+namespace Python {
class PythonIndenter : public TextEditor::TextIndenter
{
@@ -44,4 +44,4 @@ private:
const TextEditor::TabSettings &tabSettings) const;
};
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/python/pythonplugin.cpp b/src/plugins/python/pythonplugin.cpp
new file mode 100644
index 0000000000..bdb0d6a32e
--- /dev/null
+++ b/src/plugins/python/pythonplugin.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "pythonplugin.h"
+
+#include "pythoneditor.h"
+#include "pythonproject.h"
+#include "pythonsettings.h"
+#include "pythonrunconfiguration.h"
+
+#include <coreplugin/fileiconprovider.h>
+
+#include <projectexplorer/buildtargetinfo.h>
+#include <projectexplorer/localenvironmentaspect.h>
+#include <projectexplorer/projectmanager.h>
+#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/taskhub.h>
+
+#include <utils/theme/theme.h>
+
+using namespace ProjectExplorer;
+
+namespace Python {
+namespace Internal {
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// PythonPlugin
+//
+////////////////////////////////////////////////////////////////////////////////////
+
+class PythonPluginPrivate
+{
+public:
+ PythonEditorFactory editorFactory;
+ PythonOutputFormatterFactory outputFormatterFactory;
+ PythonRunConfigurationFactory runConfigFactory;
+
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+};
+
+PythonPlugin::~PythonPlugin()
+{
+ delete d;
+}
+
+bool PythonPlugin::initialize(const QStringList &arguments, QString *errorMessage)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
+
+ d = new PythonPluginPrivate;
+
+ ProjectManager::registerProjectType<PythonProject>(PythonMimeType);
+
+ PythonSettings::init();
+
+ return true;
+}
+
+void PythonPlugin::extensionsInitialized()
+{
+ // Add MIME overlay icons (these icons displayed at Project dock panel)
+ QString imageFile = Utils::creatorTheme()->imageFile(Utils::Theme::IconOverlayPro,
+ Constants::FILEOVERLAY_PY);
+ Core::FileIconProvider::registerIconOverlayForSuffix(imageFile, "py");
+
+ TaskHub::addCategory(PythonErrorTaskCategory, "Python", true);
+}
+
+} // namespace Internal
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.h b/src/plugins/python/pythonplugin.h
index d5b9f05acc..5b2e395d91 100644
--- a/src/plugins/pythoneditor/pythoneditorplugin.h
+++ b/src/plugins/python/pythonplugin.h
@@ -27,24 +27,24 @@
#include <extensionsystem/iplugin.h>
-namespace PythonEditor {
+namespace Python {
namespace Internal {
-class PythonEditorPlugin : public ExtensionSystem::IPlugin
+class PythonPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "PythonEditor.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Python.json")
public:
- PythonEditorPlugin() = default;
- ~PythonEditorPlugin() final;
+ PythonPlugin() = default;
+ ~PythonPlugin() final;
private:
bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final;
- class PythonEditorPluginPrivate *d = nullptr;
+ class PythonPluginPrivate *d = nullptr;
};
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/python/pythonproject.cpp b/src/plugins/python/pythonproject.cpp
new file mode 100644
index 0000000000..c38394a0be
--- /dev/null
+++ b/src/plugins/python/pythonproject.cpp
@@ -0,0 +1,444 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "pythonproject.h"
+
+#include "pythonconstants.h"
+
+#include <projectexplorer/buildtargetinfo.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/target.h>
+
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QProcessEnvironment>
+#include <QRegularExpression>
+
+#include <coreplugin/documentmanager.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/messagemanager.h>
+
+#include <utils/fileutils.h>
+
+using namespace Core;
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Python {
+namespace Internal {
+
+class PythonProjectNode : public ProjectNode
+{
+public:
+ PythonProjectNode(PythonProject *project);
+
+ bool supportsAction(ProjectAction action, const Node *node) const override;
+ bool addFiles(const QStringList &filePaths, QStringList *) override;
+ RemovedFilesFromProject removeFiles(const QStringList &filePaths, QStringList *) override;
+ bool deleteFiles(const QStringList &) override;
+ bool renameFile(const QString &filePath, const QString &newFilePath) override;
+
+private:
+ PythonProject *m_project;
+};
+
+
+/**
+ * @brief Provides displayName relative to project node
+ */
+class PythonFileNode : public FileNode
+{
+public:
+ PythonFileNode(const FilePath &filePath, const QString &nodeDisplayName,
+ FileType fileType = FileType::Source)
+ : FileNode(filePath, fileType)
+ , m_displayName(nodeDisplayName)
+ {}
+
+ QString displayName() const override { return m_displayName; }
+private:
+ QString m_displayName;
+};
+
+static QStringList readLines(const FilePath &projectFile)
+{
+ const QString projectFileName = projectFile.fileName();
+ QSet<QString> visited = { projectFileName };
+ QStringList lines = { projectFileName };
+
+ QFile file(projectFile.toString());
+ if (file.open(QFile::ReadOnly)) {
+ QTextStream stream(&file);
+
+ while (true) {
+ const QString line = stream.readLine();
+ if (line.isNull())
+ break;
+ if (visited.contains(line))
+ continue;
+ lines.append(line);
+ visited.insert(line);
+ }
+ }
+
+ return lines;
+}
+
+static QStringList readLinesJson(const FilePath &projectFile, QString *errorMessage)
+{
+ const QString projectFileName = projectFile.fileName();
+ QStringList lines = { projectFileName };
+
+ QFile file(projectFile.toString());
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ *errorMessage = PythonProject::tr("Unable to open \"%1\" for reading: %2")
+ .arg(projectFile.toUserOutput(), file.errorString());
+ return lines;
+ }
+
+ const QByteArray content = file.readAll();
+
+ // This assumes the project file is formed with only one field called
+ // 'files' that has a list associated of the files to include in the project.
+ if (content.isEmpty()) {
+ *errorMessage = PythonProject::tr("Unable to read \"%1\": The file is empty.")
+ .arg(projectFile.toUserOutput());
+ return lines;
+ }
+
+ QJsonParseError error;
+ const QJsonDocument doc = QJsonDocument::fromJson(content, &error);
+ if (doc.isNull()) {
+ const int line = content.left(error.offset).count('\n') + 1;
+ *errorMessage = PythonProject::tr("Unable to parse \"%1\":%2: %3")
+ .arg(projectFile.toUserOutput()).arg(line)
+ .arg(error.errorString());
+ return lines;
+ }
+
+ const QJsonObject obj = doc.object();
+ if (obj.contains("files")) {
+ const QJsonValue files = obj.value("files");
+ const QJsonArray files_array = files.toArray();
+ QSet<QString> visited;
+ for (const auto &file : files_array)
+ visited.insert(file.toString());
+
+ lines.append(Utils::toList(visited));
+ }
+
+ return lines;
+}
+
+PythonProject::PythonProject(const FilePath &fileName)
+ : Project(Constants::C_PY_MIMETYPE, fileName)
+{
+ setId(PythonProjectId);
+ setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
+ setDisplayName(fileName.toFileInfo().completeBaseName());
+
+ setNeedsBuildConfigurations(false);
+
+ connect(this, &PythonProject::projectFileIsDirty, this, [this]() { refresh(); });
+}
+
+void PythonProject::refresh(Target *target)
+{
+ ParseGuard guard = guardParsingRun();
+ parseProject();
+
+ const QDir baseDir(projectDirectory().toString());
+ QList<BuildTargetInfo> appTargets;
+ auto newRoot = std::make_unique<PythonProjectNode>(this);
+ for (const QString &f : qAsConst(m_files)) {
+ const QString displayName = baseDir.relativeFilePath(f);
+ const FileType fileType = f.endsWith(".pyproject") || f.endsWith(".pyqtc") ? FileType::Project
+ : FileType::Source;
+ newRoot->addNestedNode(std::make_unique<PythonFileNode>(FilePath::fromString(f),
+ displayName, fileType));
+ if (fileType == FileType::Source) {
+ BuildTargetInfo bti;
+ bti.buildKey = f;
+ bti.targetFilePath = FilePath::fromString(f);
+ bti.projectFilePath = projectFilePath();
+ appTargets.append(bti);
+ }
+ }
+ setRootProjectNode(std::move(newRoot));
+
+ if (!target)
+ target = activeTarget();
+ if (target)
+ target->setApplicationTargets(appTargets);
+
+ guard.markAsSuccess();
+}
+
+bool PythonProject::saveRawFileList(const QStringList &rawFileList)
+{
+ const bool result = saveRawList(rawFileList, projectFilePath().toString());
+// refresh(PythonProject::Files);
+ return result;
+}
+
+bool PythonProject::saveRawList(const QStringList &rawList, const QString &fileName)
+{
+ FileChangeBlocker changeGuarg(fileName);
+ bool result = false;
+
+ // New project file
+ if (fileName.endsWith(".pyproject")) {
+ FileSaver saver(fileName, QIODevice::ReadOnly | QIODevice::Text);
+ if (!saver.hasError()) {
+ QString content = QTextStream(saver.file()).readAll();
+ if (saver.finalize(ICore::mainWindow())) {
+ QString errorMessage;
+ result = writePyProjectFile(fileName, content, rawList, &errorMessage);
+ if (!errorMessage.isEmpty())
+ MessageManager::write(errorMessage);
+ }
+ }
+ } else { // Old project file
+ FileSaver saver(fileName, QIODevice::WriteOnly | QIODevice::Text);
+ if (!saver.hasError()) {
+ QTextStream stream(saver.file());
+ for (const QString &filePath : rawList)
+ stream << filePath << '\n';
+ saver.setResult(&stream);
+ result = saver.finalize(ICore::mainWindow());
+ }
+ }
+
+ return result;
+}
+
+bool PythonProject::writePyProjectFile(const QString &fileName, QString &content,
+ const QStringList &rawList, QString *errorMessage)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ *errorMessage = PythonProject::tr("Unable to open \"%1\" for reading: %2")
+ .arg(fileName, file.errorString());
+ return false;
+ }
+
+ // Build list of files with the current rawList for the JSON file
+ QString files("[");
+ for (const QString &f : rawList)
+ if (!f.endsWith(".pyproject"))
+ files += QString("\"%1\",").arg(f);
+ files = files.left(files.lastIndexOf(',')); // Removing leading comma
+ files += ']';
+
+ // Removing everything inside square parenthesis
+ // to replace it with the new list of files for the JSON file.
+ QRegularExpression pattern(R"(\[.*\])");
+ content.replace(pattern, files);
+ file.write(content.toUtf8());
+
+ return true;
+}
+
+bool PythonProject::addFiles(const QStringList &filePaths)
+{
+ QStringList newList = m_rawFileList;
+
+ const QDir baseDir(projectDirectory().toString());
+ for (const QString &filePath : filePaths)
+ newList.append(baseDir.relativeFilePath(filePath));
+
+ return saveRawFileList(newList);
+}
+
+bool PythonProject::removeFiles(const QStringList &filePaths)
+{
+ QStringList newList = m_rawFileList;
+
+ for (const QString &filePath : filePaths) {
+ const QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
+ if (i != m_rawListEntries.end())
+ newList.removeOne(i.value());
+ }
+
+ return saveRawFileList(newList);
+}
+
+bool PythonProject::renameFile(const QString &filePath, const QString &newFilePath)
+{
+ QStringList newList = m_rawFileList;
+
+ const QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
+ if (i != m_rawListEntries.end()) {
+ const int index = newList.indexOf(i.value());
+ if (index != -1) {
+ const QDir baseDir(projectDirectory().toString());
+ newList.replace(index, baseDir.relativeFilePath(newFilePath));
+ }
+ }
+
+ return saveRawFileList(newList);
+}
+
+void PythonProject::parseProject()
+{
+ m_rawListEntries.clear();
+ const FilePath filePath = projectFilePath();
+ // The PySide project file is JSON based
+ if (filePath.endsWith(".pyproject")) {
+ QString errorMessage;
+ m_rawFileList = readLinesJson(filePath, &errorMessage);
+ if (!errorMessage.isEmpty())
+ MessageManager::write(errorMessage);
+ }
+ // To keep compatibility with PyQt we keep the compatibility with plain
+ // text files as project files.
+ else if (filePath.endsWith(".pyqtc"))
+ m_rawFileList = readLines(filePath);
+
+ m_files = processEntries(m_rawFileList, &m_rawListEntries);
+}
+/**
+ * Expands environment variables in the given \a string when they are written
+ * like $$(VARIABLE).
+ */
+static void expandEnvironmentVariables(const QProcessEnvironment &env, QString &string)
+{
+ static QRegExp candidate(QLatin1String("\\$\\$\\((.+)\\)"));
+
+ int index = candidate.indexIn(string);
+ while (index != -1) {
+ const QString value = env.value(candidate.cap(1));
+
+ string.replace(index, candidate.matchedLength(), value);
+ index += value.length();
+
+ index = candidate.indexIn(string, index);
+ }
+}
+
+/**
+ * Expands environment variables and converts the path from relative to the
+ * project to an absolute path.
+ *
+ * The \a map variable is an optional argument that will map the returned
+ * absolute paths back to their original \a paths.
+ */
+QStringList PythonProject::processEntries(const QStringList &paths,
+ QHash<QString, QString> *map) const
+{
+ const QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ const QDir projectDir(projectDirectory().toString());
+
+ QFileInfo fileInfo;
+ QStringList absolutePaths;
+ for (const QString &path : paths) {
+ QString trimmedPath = path.trimmed();
+ if (trimmedPath.isEmpty())
+ continue;
+
+ expandEnvironmentVariables(env, trimmedPath);
+
+ trimmedPath = FilePath::fromUserInput(trimmedPath).toString();
+
+ fileInfo.setFile(projectDir, trimmedPath);
+ if (fileInfo.exists()) {
+ const QString absPath = fileInfo.absoluteFilePath();
+ absolutePaths.append(absPath);
+ if (map)
+ map->insert(absPath, trimmedPath);
+ }
+ }
+ absolutePaths.removeDuplicates();
+ return absolutePaths;
+}
+
+Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *errorMessage)
+{
+ Project::RestoreResult res = Project::fromMap(map, errorMessage);
+ if (res == RestoreResult::Ok) {
+ refresh();
+
+ if (!activeTarget())
+ addTargetForDefaultKit();
+ }
+
+ return res;
+}
+
+bool PythonProject::setupTarget(Target *t)
+{
+ refresh(t);
+ return Project::setupTarget(t);
+}
+
+PythonProjectNode::PythonProjectNode(PythonProject *project)
+ : ProjectNode(project->projectDirectory())
+ , m_project(project)
+{
+ setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
+ setAddFileFilter("*.py");
+}
+
+bool PythonProjectNode::supportsAction(ProjectAction action, const Node *node) const
+{
+ if (node->asFileNode()) {
+ return action == ProjectAction::Rename
+ || action == ProjectAction::RemoveFile;
+ }
+ if (node->isFolderNodeType() || node->isProjectNodeType()) {
+ return action == ProjectAction::AddNewFile
+ || action == ProjectAction::RemoveFile
+ || action == ProjectAction::AddExistingFile;
+ }
+ return ProjectNode::supportsAction(action, node);
+}
+
+bool PythonProjectNode::addFiles(const QStringList &filePaths, QStringList *)
+{
+ return m_project->addFiles(filePaths);
+}
+
+RemovedFilesFromProject PythonProjectNode::removeFiles(const QStringList &filePaths, QStringList *)
+{
+ return m_project->removeFiles(filePaths) ? RemovedFilesFromProject::Ok
+ : RemovedFilesFromProject::Error;
+}
+
+bool PythonProjectNode::deleteFiles(const QStringList &)
+{
+ return true;
+}
+
+bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
+{
+ return m_project->renameFile(filePath, newFilePath);
+}
+
+} // namespace Internal
+} // namespace Python
diff --git a/src/plugins/python/pythonproject.h b/src/plugins/python/pythonproject.h
new file mode 100644
index 0000000000..6f2d4b6d73
--- /dev/null
+++ b/src/plugins/python/pythonproject.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/project.h>
+
+namespace Python {
+namespace Internal {
+
+const char PythonMimeType[] = "text/x-python-project"; // ### FIXME
+const char PythonProjectId[] = "PythonProject";
+const char PythonErrorTaskCategory[] = "Task.Category.Python";
+
+class PythonProject : public ProjectExplorer::Project
+{
+ Q_OBJECT
+public:
+ explicit PythonProject(const Utils::FilePath &filename);
+
+ bool addFiles(const QStringList &filePaths);
+ bool removeFiles(const QStringList &filePaths);
+ bool renameFile(const QString &filePath, const QString &newFilePath);
+ void refresh(ProjectExplorer::Target *target = nullptr);
+
+ bool needsConfiguration() const final { return false; }
+
+ bool writePyProjectFile(const QString &fileName, QString &content,
+ const QStringList &rawList, QString *errorMessage);
+
+private:
+ RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
+ bool setupTarget(ProjectExplorer::Target *t) override;
+
+ bool saveRawFileList(const QStringList &rawFileList);
+ bool saveRawList(const QStringList &rawList, const QString &fileName);
+ void parseProject();
+ QStringList processEntries(const QStringList &paths,
+ QHash<QString, QString> *map = nullptr) const;
+
+ QStringList m_rawFileList;
+ QStringList m_files;
+ QHash<QString, QString> m_rawListEntries;
+};
+
+} // namespace Internal
+} // namespace Python
diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp
new file mode 100644
index 0000000000..bb61f275ae
--- /dev/null
+++ b/src/plugins/python/pythonrunconfiguration.cpp
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "pythonconstants.h"
+#include "pythonproject.h"
+#include "pythonrunconfiguration.h"
+#include "pythonsettings.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/editormanager/editormanager.h>
+
+#include <projectexplorer/localenvironmentaspect.h>
+#include <projectexplorer/projectconfigurationaspects.h>
+#include <projectexplorer/runconfigurationaspects.h>
+#include <projectexplorer/target.h>
+#include <projectexplorer/taskhub.h>
+
+#include <utils/fileutils.h>
+#include <utils/outputformatter.h>
+#include <utils/theme/theme.h>
+
+#include <QBoxLayout>
+#include <QComboBox>
+#include <QFormLayout>
+#include <QPlainTextEdit>
+#include <QPushButton>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Python {
+namespace Internal {
+
+static QTextCharFormat linkFormat(const QTextCharFormat &inputFormat, const QString &href)
+{
+ QTextCharFormat result = inputFormat;
+ result.setForeground(creatorTheme()->color(Theme::TextColorLink));
+ result.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ result.setAnchor(true);
+ result.setAnchorHref(href);
+ return result;
+}
+
+class PythonOutputFormatter : public OutputFormatter
+{
+public:
+ PythonOutputFormatter()
+ // Note that moc dislikes raw string literals.
+ : filePattern("^(\\s*)(File \"([^\"]+)\", line (\\d+), .*$)")
+ {
+ TaskHub::clearTasks(PythonErrorTaskCategory);
+ }
+
+private:
+ void appendMessage(const QString &text, OutputFormat format) final
+ {
+ const bool isTrace = (format == StdErrFormat
+ || format == StdErrFormatSameLine)
+ && (text.startsWith("Traceback (most recent call last):")
+ || text.startsWith("\nTraceback (most recent call last):"));
+
+ if (!isTrace) {
+ OutputFormatter::appendMessage(text, format);
+ return;
+ }
+
+ const QTextCharFormat frm = charFormat(format);
+ const Core::Id id(PythonErrorTaskCategory);
+ QVector<Task> tasks;
+ const QStringList lines = text.split('\n');
+ unsigned taskId = unsigned(lines.size());
+
+ for (const QString &line : lines) {
+ const QRegularExpressionMatch match = filePattern.match(line);
+ if (match.hasMatch()) {
+ QTextCursor tc = plainTextEdit()->textCursor();
+ tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
+ tc.insertText('\n' + match.captured(1));
+ tc.insertText(match.captured(2), linkFormat(frm, match.captured(2)));
+
+ const auto fileName = FilePath::fromString(match.captured(3));
+ const int lineNumber = match.capturedRef(4).toInt();
+ Task task(Task::Warning,
+ QString(), fileName, lineNumber, id);
+ task.taskId = --taskId;
+ tasks.append(task);
+ } else {
+ if (!tasks.isEmpty()) {
+ Task &task = tasks.back();
+ if (!task.description.isEmpty())
+ task.description += ' ';
+ task.description += line.trimmed();
+ }
+ OutputFormatter::appendMessage('\n' + line, format);
+ }
+ }
+ if (!tasks.isEmpty()) {
+ tasks.back().type = Task::Error;
+ for (auto rit = tasks.crbegin(), rend = tasks.crend(); rit != rend; ++rit)
+ TaskHub::addTask(*rit);
+ }
+ }
+
+ void handleLink(const QString &href) final
+ {
+ const QRegularExpressionMatch match = filePattern.match(href);
+ if (!match.hasMatch())
+ return;
+ const QString fileName = match.captured(3);
+ const int lineNumber = match.capturedRef(4).toInt();
+ Core::EditorManager::openEditorAt(fileName, lineNumber);
+ }
+
+ const QRegularExpression filePattern;
+};
+
+////////////////////////////////////////////////////////////////
+
+class InterpreterAspect : public ProjectConfigurationAspect
+{
+ Q_OBJECT
+
+public:
+ InterpreterAspect() = default;
+
+ Interpreter currentInterpreter() const;
+ void updateInterpreters(const QList<Interpreter> &interpreters);
+ void setDefaultInterpreter(const Interpreter &interpreter) { m_defaultId = interpreter.id; }
+
+ void fromMap(const QVariantMap &) override;
+ void toMap(QVariantMap &) const override;
+ void addToConfigurationLayout(QFormLayout *layout) override;
+
+private:
+ void updateCurrentInterpreter();
+ void updateComboBox();
+ QList<Interpreter> m_interpreters;
+ QPointer<QComboBox> m_comboBox;
+ QString m_defaultId;
+ QString m_currentId;
+};
+
+Interpreter InterpreterAspect::currentInterpreter() const
+{
+ return m_comboBox ? m_interpreters.value(m_comboBox->currentIndex()) : Interpreter();
+}
+
+void InterpreterAspect::updateInterpreters(const QList<Interpreter> &interpreters)
+{
+ m_interpreters = interpreters;
+ if (m_comboBox)
+ updateComboBox();
+}
+
+void InterpreterAspect::fromMap(const QVariantMap &map)
+{
+ m_currentId = map.value(settingsKey(), m_defaultId).toString();
+}
+
+void InterpreterAspect::toMap(QVariantMap &map) const
+{
+ map.insert(settingsKey(), m_currentId);
+}
+
+void InterpreterAspect::addToConfigurationLayout(QFormLayout *layout)
+{
+ if (QTC_GUARD(m_comboBox.isNull()))
+ m_comboBox = new QComboBox;
+
+ updateComboBox();
+ connect(m_comboBox,
+ &QComboBox::currentTextChanged,
+ this,
+ &InterpreterAspect::updateCurrentInterpreter);
+
+ auto manageButton = new QPushButton(tr("Manage..."));
+ connect(manageButton, &QPushButton::clicked, []() {
+ Core::ICore::showOptionsDialog(Constants::C_PYTHONOPTIONS_PAGE_ID);
+ });
+
+ auto rowLayout = new QHBoxLayout;
+ rowLayout->addWidget(m_comboBox);
+ rowLayout->addWidget(manageButton);
+ layout->addRow(tr("Interpreter"), rowLayout);
+}
+
+void InterpreterAspect::updateCurrentInterpreter()
+{
+ m_currentId = currentInterpreter().id;
+ m_comboBox->setToolTip(currentInterpreter().command.toUserOutput());
+ emit changed();
+}
+
+void InterpreterAspect::updateComboBox()
+{
+ int currentIndex = -1;
+ int defaultIndex = -1;
+ const QString currentId = m_currentId;
+ m_comboBox->clear();
+ for (const Interpreter &interpreter : m_interpreters) {
+ int index = m_comboBox->count();
+ m_comboBox->addItem(interpreter.name);
+ m_comboBox->setItemData(index, interpreter.command.toUserOutput(), Qt::ToolTipRole);
+ if (interpreter.id == currentId)
+ currentIndex = index;
+ if (interpreter.id == m_defaultId)
+ defaultIndex = index;
+ }
+ if (currentIndex >= 0)
+ m_comboBox->setCurrentIndex(currentIndex);
+ else if (defaultIndex >= 0)
+ m_comboBox->setCurrentIndex(defaultIndex);
+ updateCurrentInterpreter();
+}
+
+class MainScriptAspect : public BaseStringAspect
+{
+ Q_OBJECT
+
+public:
+ MainScriptAspect() = default;
+};
+
+PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
+ : RunConfiguration(target, id)
+{
+ auto interpreterAspect = addAspect<InterpreterAspect>();
+ interpreterAspect->setSettingsKey("PythonEditor.RunConfiguation.Interpreter");
+
+ connect(PythonSettings::instance(), &PythonSettings::interpretersChanged,
+ interpreterAspect, &InterpreterAspect::updateInterpreters);
+
+ interpreterAspect->updateInterpreters(PythonSettings::interpreters());
+ interpreterAspect->setDefaultInterpreter(PythonSettings::defaultInterpreter());
+
+ auto scriptAspect = addAspect<MainScriptAspect>();
+ scriptAspect->setSettingsKey("PythonEditor.RunConfiguation.Script");
+ scriptAspect->setLabelText(tr("Script:"));
+ scriptAspect->setDisplayStyle(BaseStringAspect::LabelDisplay);
+
+ addAspect<LocalEnvironmentAspect>(target);
+
+ auto argumentsAspect = addAspect<ArgumentsAspect>();
+
+ addAspect<TerminalAspect>();
+
+ setCommandLineGetter([this, interpreterAspect, argumentsAspect] {
+ CommandLine cmd{interpreterAspect->currentInterpreter().command, {mainScript()}};
+ cmd.addArgs(argumentsAspect->arguments(macroExpander()), CommandLine::Raw);
+ return cmd;
+ });
+
+ connect(target, &Target::applicationTargetsChanged,
+ this, &PythonRunConfiguration::updateTargetInformation);
+ connect(target->project(), &Project::parsingFinished,
+ this, &PythonRunConfiguration::updateTargetInformation);
+}
+
+void PythonRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &)
+{
+ updateTargetInformation();
+}
+
+bool PythonRunConfiguration::supportsDebugger() const
+{
+ return true;
+}
+
+QString PythonRunConfiguration::mainScript() const
+{
+ return aspect<MainScriptAspect>()->value();
+}
+
+QString PythonRunConfiguration::arguments() const
+{
+ return aspect<ArgumentsAspect>()->arguments(macroExpander());
+}
+
+QString PythonRunConfiguration::interpreter() const
+{
+ return aspect<InterpreterAspect>()->currentInterpreter().command.toString();
+}
+
+void PythonRunConfiguration::updateTargetInformation()
+{
+ const BuildTargetInfo bti = buildTargetInfo();
+ const QString script = bti.targetFilePath.toString();
+ setDefaultDisplayName(tr("Run %1").arg(script));
+ aspect<MainScriptAspect>()->setValue(script);
+}
+
+PythonRunConfigurationFactory::PythonRunConfigurationFactory()
+{
+ registerRunConfiguration<PythonRunConfiguration>("PythonEditor.RunConfiguration.");
+ addSupportedProjectType(PythonProjectId);
+}
+
+PythonOutputFormatterFactory::PythonOutputFormatterFactory()
+{
+ setFormatterCreator([](Target *t) -> OutputFormatter * {
+ if (t->project()->mimeType() == Constants::C_PY_MIMETYPE)
+ return new PythonOutputFormatter;
+ return nullptr;
+ });
+}
+
+} // namespace Internal
+} // namespace Python
+
+#include "pythonrunconfiguration.moc"
diff --git a/src/plugins/python/pythonrunconfiguration.h b/src/plugins/python/pythonrunconfiguration.h
new file mode 100644
index 0000000000..753be4c296
--- /dev/null
+++ b/src/plugins/python/pythonrunconfiguration.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/runcontrol.h>
+
+namespace Python {
+namespace Internal {
+
+class PythonRunConfiguration : public ProjectExplorer::RunConfiguration
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool supportsDebugger READ supportsDebugger)
+ Q_PROPERTY(QString interpreter READ interpreter)
+ Q_PROPERTY(QString mainScript READ mainScript)
+ Q_PROPERTY(QString arguments READ arguments)
+
+public:
+ PythonRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
+
+private:
+ void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &) final;
+
+ bool supportsDebugger() const;
+ QString mainScript() const;
+ QString arguments() const;
+ QString interpreter() const;
+
+ void updateTargetInformation();
+};
+
+class PythonRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
+{
+public:
+ PythonRunConfigurationFactory();
+};
+
+class PythonOutputFormatterFactory : public ProjectExplorer::OutputFormatterFactory
+{
+public:
+ PythonOutputFormatterFactory();
+};
+
+} // namespace Internal
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonscanner.cpp b/src/plugins/python/pythonscanner.cpp
index 9e80f30e6f..abb6251e15 100644
--- a/src/plugins/pythoneditor/pythonscanner.cpp
+++ b/src/plugins/python/pythonscanner.cpp
@@ -25,10 +25,10 @@
#include "pythonscanner.h"
-#include "pythoneditorconstants.h"
-#include "pythoneditorplugin.h"
+#include "pythonconstants.h"
+#include "pythonplugin.h"
-namespace PythonEditor {
+namespace Python {
namespace Internal {
Scanner::Scanner(const QChar *text, const int length)
@@ -389,4 +389,4 @@ void Scanner::parseState(State &state, QChar &savedData) const
}
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/pythoneditor/pythonscanner.h b/src/plugins/python/pythonscanner.h
index c6844097de..5d37f3ba11 100644
--- a/src/plugins/pythoneditor/pythonscanner.h
+++ b/src/plugins/python/pythonscanner.h
@@ -29,7 +29,7 @@
#include <QString>
-namespace PythonEditor {
+namespace Python {
namespace Internal {
/**
@@ -95,4 +95,4 @@ private:
};
} // namespace Internal
-} // namespace PythonEditor
+} // namespace Python
diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp
new file mode 100644
index 0000000000..839d3f4451
--- /dev/null
+++ b/src/plugins/python/pythonsettings.cpp
@@ -0,0 +1,487 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "pythonsettings.h"
+
+#include "pythonconstants.h"
+
+#include <coreplugin/dialogs/ioptionspage.h>
+#include "coreplugin/icore.h"
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
+#include <utils/detailswidget.h>
+#include <utils/environment.h>
+#include <utils/listmodel.h>
+#include <utils/pathchooser.h>
+#include <utils/synchronousprocess.h>
+#include <utils/treemodel.h>
+
+#include <QDir>
+#include <QLabel>
+#include <QPushButton>
+#include <QPointer>
+#include <QSettings>
+#include <QStackedWidget>
+#include <QTreeView>
+#include <QVBoxLayout>
+#include <QWidget>
+
+namespace Python {
+namespace Internal {
+
+using namespace Utils;
+
+class InterpreterDetailsWidget : public QWidget
+{
+public:
+ InterpreterDetailsWidget()
+ : m_name(new QLineEdit)
+ , m_executable(new Utils::PathChooser())
+ {
+ auto mainLayout = new QGridLayout();
+ mainLayout->addWidget(new QLabel(tr("Name:")), 0, 0);
+ mainLayout->addWidget(m_name, 0, 1);
+ mainLayout->addWidget(new QLabel(tr("Executable")), 1, 0);
+ mainLayout->addWidget(m_executable, 1, 1);
+ m_executable->setExpectedKind(Utils::PathChooser::ExistingCommand);
+ setLayout(mainLayout);
+ }
+
+ void updateInterpreter(const Interpreter &interpreter)
+ {
+ m_name->setText(interpreter.name);
+ m_executable->setPath(interpreter.command.toString());
+ m_currentId = interpreter.id;
+ }
+
+ Interpreter toInterpreter()
+ {
+ return {m_currentId, m_name->text(), FilePath::fromUserInput(m_executable->path())};
+ }
+ QLineEdit *m_name = nullptr;
+ PathChooser *m_executable = nullptr;
+ QString m_currentId;
+};
+
+
+class InterpreterOptionsWidget : public QWidget
+{
+public:
+ InterpreterOptionsWidget(const QList<Interpreter> &interpreters,
+ const QString &defaultInterpreter);
+
+ void apply();
+
+private:
+ QTreeView m_view;
+ ListModel<Interpreter> m_model;
+ InterpreterDetailsWidget *m_detailsWidget = nullptr;
+ QPushButton *m_deleteButton = nullptr;
+ QPushButton *m_makeDefaultButton = nullptr;
+ QString m_defaultId;
+
+ void currentChanged(const QModelIndex &index, const QModelIndex &previous);
+ void addItem();
+ void deleteItem();
+ void makeDefault();
+};
+
+InterpreterOptionsWidget::InterpreterOptionsWidget(const QList<Interpreter> &interpreters, const QString &defaultInterpreter)
+ : m_detailsWidget(new InterpreterDetailsWidget())
+ , m_defaultId(defaultInterpreter)
+{
+ m_model.setDataAccessor([this](const Interpreter &interpreter, int, int role) -> QVariant {
+ if (role == Qt::DisplayRole)
+ return interpreter.name;
+ if (role == Qt::FontRole) {
+ QFont f = font();
+ f.setBold(interpreter.id == m_defaultId);
+ return f;
+ }
+ return {};
+ });
+
+ for (const Interpreter &interpreter : interpreters)
+ m_model.appendItem(interpreter);
+
+ auto mainLayout = new QVBoxLayout();
+ auto layout = new QHBoxLayout();
+ m_view.setModel(&m_model);
+ m_view.setHeaderHidden(true);
+ m_view.setSelectionMode(QAbstractItemView::SingleSelection);
+ m_view.setSelectionBehavior(QAbstractItemView::SelectItems);
+ connect(m_view.selectionModel(),
+ &QItemSelectionModel::currentChanged,
+ this,
+ &InterpreterOptionsWidget::currentChanged);
+ auto buttonLayout = new QVBoxLayout();
+ auto addButton = new QPushButton(InterpreterOptionsWidget::tr("&Add"));
+ connect(addButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::addItem);
+ m_deleteButton = new QPushButton(InterpreterOptionsWidget::tr("&Delete"));
+ m_deleteButton->setEnabled(false);
+ connect(m_deleteButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::deleteItem);
+ m_makeDefaultButton = new QPushButton(InterpreterOptionsWidget::tr("&Make Default"));
+ m_makeDefaultButton->setEnabled(false);
+ connect(m_makeDefaultButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::makeDefault);
+ mainLayout->addLayout(layout);
+ mainLayout->addWidget(m_detailsWidget);
+ m_detailsWidget->hide();
+ setLayout(mainLayout);
+ layout->addWidget(&m_view);
+ layout->addLayout(buttonLayout);
+ buttonLayout->addWidget(addButton);
+ buttonLayout->addWidget(m_deleteButton);
+ buttonLayout->addWidget(m_makeDefaultButton);
+ buttonLayout->addStretch(10);
+}
+
+void InterpreterOptionsWidget::apply()
+{
+ const QModelIndex &index = m_view.currentIndex();
+ if (index.isValid()) {
+ m_model.itemAt(index.row())->itemData = m_detailsWidget->toInterpreter();
+ emit m_model.dataChanged(index, index);
+ }
+
+ QList<Interpreter> interpreters;
+ for (const ListItem<Interpreter> *treeItem : m_model)
+ interpreters << treeItem->itemData;
+ PythonSettings::setInterpreter(interpreters, m_defaultId);
+}
+
+void InterpreterOptionsWidget::currentChanged(const QModelIndex &index, const QModelIndex &previous)
+{
+ if (previous.isValid()) {
+ m_model.itemAt(previous.row())->itemData = m_detailsWidget->toInterpreter();
+ emit m_model.dataChanged(previous, previous);
+ }
+ if (index.isValid()) {
+ m_detailsWidget->updateInterpreter(m_model.itemAt(index.row())->itemData);
+ m_detailsWidget->show();
+ } else {
+ m_detailsWidget->hide();
+ }
+ m_deleteButton->setEnabled(index.isValid());
+ m_makeDefaultButton->setEnabled(index.isValid());
+}
+
+void InterpreterOptionsWidget::addItem()
+{
+ const QModelIndex &index = m_model.indexForItem(
+ m_model.appendItem({QUuid::createUuid().toString(), QString("Python"), FilePath()}));
+ QTC_ASSERT(index.isValid(), return);
+ m_view.setCurrentIndex(index);
+}
+
+void InterpreterOptionsWidget::deleteItem()
+{
+ const QModelIndex &index = m_view.currentIndex();
+ if (index.isValid())
+ m_model.destroyItem(m_model.itemAt(index.row()));
+}
+
+class InterpreterOptionsPage : public Core::IOptionsPage
+{
+ Q_OBJECT
+
+public:
+ InterpreterOptionsPage();
+
+ void setInterpreter(const QList<Interpreter> &interpreters) { m_interpreters = interpreters; }
+ QList<Interpreter> interpreters() const { return m_interpreters; }
+ void setDefaultInterpreter(const QString &defaultId)
+ { m_defaultInterpreterId = defaultId; }
+ Interpreter defaultInterpreter() const;
+
+ QWidget *widget() override;
+ void apply() override;
+ void finish() override;
+
+private:
+ QPointer<InterpreterOptionsWidget> m_widget;
+ QList<Interpreter> m_interpreters;
+ QString m_defaultInterpreterId;
+};
+
+InterpreterOptionsPage::InterpreterOptionsPage()
+{
+ setId(Constants::C_PYTHONOPTIONS_PAGE_ID);
+ setDisplayName(tr("Interpreters"));
+ setCategory(Constants::C_PYTHON_SETTINGS_CATEGORY);
+ setDisplayCategory(tr("Python"));
+ setCategoryIcon(Utils::Icon({{":/python/images/settingscategory_python.png",
+ Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint));
+}
+
+Interpreter InterpreterOptionsPage::defaultInterpreter() const
+{
+ if (m_defaultInterpreterId.isEmpty())
+ return {};
+ return Utils::findOrDefault(m_interpreters, [this](const Interpreter &interpreter) {
+ return interpreter.id == m_defaultInterpreterId;
+ });
+}
+
+QWidget *InterpreterOptionsPage::widget()
+{
+ if (!m_widget)
+ m_widget = new InterpreterOptionsWidget(m_interpreters, m_defaultInterpreterId);
+ return m_widget;
+}
+
+void InterpreterOptionsPage::apply()
+{
+ if (m_widget)
+ m_widget->apply();
+}
+
+void InterpreterOptionsPage::finish()
+{
+ delete m_widget;
+ m_widget = nullptr;
+}
+
+static bool alreadyRegistered(const QList<Interpreter> &pythons, const FilePath &pythonExecutable)
+{
+ return Utils::anyOf(pythons, [pythonExecutable](const Interpreter &interpreter) {
+ return interpreter.command.toFileInfo().canonicalFilePath()
+ == pythonExecutable.toFileInfo().canonicalFilePath();
+ });
+}
+
+Interpreter interpreterForPythonExecutable(const FilePath &python,
+ const QString &defaultName,
+ bool windowedSuffix = false)
+{
+ SynchronousProcess pythonProcess;
+ pythonProcess.setProcessChannelMode(QProcess::MergedChannels);
+ SynchronousProcessResponse response = pythonProcess.runBlocking(
+ CommandLine(python, {"--version"}));
+ QString name;
+ if (response.result == SynchronousProcessResponse::Finished)
+ name = response.stdOut().trimmed();
+ if (name.isEmpty())
+ name = defaultName;
+ if (windowedSuffix)
+ name += " (Windowed)";
+ return Interpreter{QUuid::createUuid().toString(), name, python};
+}
+
+static InterpreterOptionsPage &interpreterOptionsPage()
+{
+ static InterpreterOptionsPage page;
+ return page;
+}
+
+void InterpreterOptionsWidget::makeDefault()
+{
+ const QModelIndex &index = m_view.currentIndex();
+ if (index.isValid()) {
+ QModelIndex defaultIndex;
+ if (auto *defaultItem = m_model.findItemByData(
+ [this](const Interpreter &interpreter) { return interpreter.id == m_defaultId; })) {
+ defaultIndex = m_model.indexForItem(defaultItem);
+ }
+ m_defaultId = m_model.itemAt(index.row())->itemData.id;
+ emit m_model.dataChanged(index, index, {Qt::FontRole});
+ if (defaultIndex.isValid())
+ emit m_model.dataChanged(defaultIndex, defaultIndex, {Qt::FontRole});
+ }
+}
+
+constexpr char settingsGroupKey[] = "Python";
+constexpr char interpreterKey[] = "Interpeter";
+constexpr char defaultKey[] = "DefaultInterpeter";
+
+struct SavedSettings
+{
+ QList<Interpreter> pythons;
+ QString defaultId;
+};
+
+static SavedSettings fromSettings(QSettings *settings)
+{
+ QList<Interpreter> pythons;
+ settings->beginGroup(settingsGroupKey);
+ const QVariantList interpreters = settings->value(interpreterKey).toList();
+ for (const QVariant &interpreterVar : interpreters) {
+ auto interpreterList = interpreterVar.toList();
+ if (interpreterList.size() != 3)
+ continue;
+ pythons << Interpreter{interpreterList.value(0).toString(),
+ interpreterList.value(1).toString(),
+ FilePath::fromVariant(interpreterList.value(2))};
+ }
+
+ const QString defaultId = settings->value(defaultKey).toString();
+
+ settings->endGroup();
+
+ return {pythons, defaultId};
+}
+
+static void toSettings(QSettings *settings, const SavedSettings &savedSettings)
+{
+ settings->beginGroup(settingsGroupKey);
+ const QVariantList interpretersVar
+ = Utils::transform(savedSettings.pythons, [](const Interpreter &interpreter) {
+ return QVariant({interpreter.id, interpreter.name, interpreter.command.toVariant()});
+ });
+ settings->setValue(interpreterKey, interpretersVar);
+ settings->setValue(defaultKey, savedSettings.defaultId);
+ settings->endGroup();
+}
+
+static void addPythonsFromRegistry(QList<Interpreter> &pythons)
+{
+ QSettings pythonRegistry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore",
+ QSettings::NativeFormat);
+ for (const QString &versionGroup : pythonRegistry.childGroups()) {
+ pythonRegistry.beginGroup(versionGroup);
+ QString name = pythonRegistry.value("DisplayName").toString();
+ QVariant regVal = pythonRegistry.value("InstallPath/ExecutablePath");
+ if (regVal.isValid()) {
+ const FilePath &executable = FilePath::fromUserInput(regVal.toString());
+ if (executable.exists() && !alreadyRegistered(pythons, executable)) {
+ pythons << Interpreter{QUuid::createUuid().toString(),
+ name,
+ FilePath::fromUserInput(regVal.toString())};
+ }
+ }
+ regVal = pythonRegistry.value("InstallPath/WindowedExecutablePath");
+ if (regVal.isValid()) {
+ const FilePath &executable = FilePath::fromUserInput(regVal.toString());
+ if (executable.exists() && !alreadyRegistered(pythons, executable)) {
+ pythons << Interpreter{QUuid::createUuid().toString(),
+ name + InterpreterOptionsPage::tr(" (Windowed)"),
+ FilePath::fromUserInput(regVal.toString())};
+ }
+ }
+ regVal = pythonRegistry.value("InstallPath/.");
+ if (regVal.isValid()) {
+ const FilePath &path = FilePath::fromUserInput(regVal.toString());
+ const FilePath &python = path.pathAppended(HostOsInfo::withExecutableSuffix("python"));
+ if (python.exists() && !alreadyRegistered(pythons, python))
+ pythons << interpreterForPythonExecutable(python, "Python " + versionGroup);
+ const FilePath &pythonw = path.pathAppended(
+ HostOsInfo::withExecutableSuffix("pythonw"));
+ if (pythonw.exists() && !alreadyRegistered(pythons, pythonw))
+ pythons << interpreterForPythonExecutable(pythonw, "Python " + versionGroup, true);
+ }
+ pythonRegistry.endGroup();
+ }
+}
+
+static void addPythonsFromPath(QList<Interpreter> &pythons)
+{
+ const auto &env = Environment::systemEnvironment();
+
+ if (HostOsInfo::isWindowsHost()) {
+ for (const FilePath &executable : env.findAllInPath("python")) {
+ if (executable.exists() && !alreadyRegistered(pythons, executable))
+ pythons << interpreterForPythonExecutable(executable, "Python from Path");
+ }
+ for (const FilePath &executable : env.findAllInPath("pythonw")) {
+ if (executable.exists() && !alreadyRegistered(pythons, executable))
+ pythons << interpreterForPythonExecutable(executable, "Python from Path", true);
+ }
+ } else {
+ const QStringList filters = {"python",
+ "python[1-9].[0-9]",
+ "python[1-9].[1-9][0-9]",
+ "python[1-9]"};
+ for (const FilePath &path : env.path()) {
+ const QDir dir(path.toString());
+ for (const QFileInfo &fi : dir.entryInfoList(filters)) {
+ const FilePath executable = Utils::FilePath::fromFileInfo(fi);
+ if (executable.exists() && !alreadyRegistered(pythons, executable))
+ pythons << interpreterForPythonExecutable(executable, "Python from Path");
+ }
+ }
+ }
+}
+
+static QString idForPythonFromPath(QList<Interpreter> pythons)
+{
+ const FilePath &pythonFromPath = Environment::systemEnvironment().searchInPath("python");
+ if (pythonFromPath.isEmpty())
+ return {};
+ const Interpreter &defaultInterpreter
+ = findOrDefault(pythons, [pythonFromPath](const Interpreter &interpreter) {
+ return interpreter.command == pythonFromPath;
+ });
+ return defaultInterpreter.id;
+}
+
+static PythonSettings *settingsInstance = nullptr;
+PythonSettings::PythonSettings() = default;
+
+void PythonSettings::init()
+{
+ QTC_ASSERT(!settingsInstance, return );
+ settingsInstance = new PythonSettings();
+
+ const SavedSettings &settings = fromSettings(Core::ICore::settings());
+ QList<Interpreter> pythons = settings.pythons;
+
+ if (HostOsInfo::isWindowsHost())
+ addPythonsFromRegistry(pythons);
+ addPythonsFromPath(pythons);
+
+ const QString &defaultId = !settings.defaultId.isEmpty() ? settings.defaultId
+ : idForPythonFromPath(pythons);
+ setInterpreter(pythons, defaultId);
+}
+
+void PythonSettings::setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId)
+{
+ interpreterOptionsPage().setInterpreter(interpreters);
+ interpreterOptionsPage().setDefaultInterpreter(defaultId);
+ toSettings(Core::ICore::settings(), {interpreters, defaultId});
+ if (QTC_GUARD(settingsInstance))
+ emit settingsInstance->interpretersChanged(interpreters, defaultId);
+}
+
+PythonSettings *PythonSettings::instance()
+{
+ QTC_CHECK(settingsInstance);
+ return settingsInstance;
+}
+
+QList<Interpreter> PythonSettings::interpreters()
+{
+ return interpreterOptionsPage().interpreters();
+}
+
+Interpreter PythonSettings::defaultInterpreter()
+{
+ return interpreterOptionsPage().defaultInterpreter();
+}
+
+} // namespace Internal
+} // namespace Python
+
+#include "pythonsettings.moc"
diff --git a/src/plugins/python/pythonsettings.h b/src/plugins/python/pythonsettings.h
new file mode 100644
index 0000000000..583d4fb212
--- /dev/null
+++ b/src/plugins/python/pythonsettings.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/fileutils.h>
+
+#include <QUuid>
+
+namespace Python {
+namespace Internal {
+
+class Interpreter
+{
+public:
+ QString id;
+ QString name;
+ Utils::FilePath command;
+};
+
+class PythonSettings : public QObject
+{
+ Q_OBJECT
+public:
+ static void init();
+
+ static QList<Interpreter> interpreters();
+ static Interpreter defaultInterpreter();
+ static void setInterpreter(const QList<Interpreter> &interpreters, const QString &defaultId);
+ static PythonSettings *instance();
+
+signals:
+ void interpretersChanged(const QList<Interpreter> &interpreters, const QString &defaultId);
+
+private:
+ PythonSettings();
+};
+
+} // namespace Internal
+} // namespace PythonEditor
diff --git a/src/plugins/pythoneditor/pythoneditor.pro b/src/plugins/pythoneditor/pythoneditor.pro
deleted file mode 100644
index ba8fee6464..0000000000
--- a/src/plugins/pythoneditor/pythoneditor.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-include(../../qtcreatorplugin.pri)
-
-DEFINES += \
- PYTHONEDITOR_LIBRARY
-
-HEADERS += \
- pythoneditorplugin.h \
- pythoneditor.h \
- pythoneditorconstants.h \
- pythonhighlighter.h \
- pythonindenter.h \
- pythonformattoken.h \
- pythonscanner.h \
-
-SOURCES += \
- pythoneditorplugin.cpp \
- pythoneditor.cpp \
- pythonhighlighter.cpp \
- pythonindenter.cpp \
- pythonscanner.cpp
diff --git a/src/plugins/pythoneditor/pythoneditor.qbs b/src/plugins/pythoneditor/pythoneditor.qbs
deleted file mode 100644
index c3cc572a7d..0000000000
--- a/src/plugins/pythoneditor/pythoneditor.qbs
+++ /dev/null
@@ -1,25 +0,0 @@
-import qbs 1.0
-
-QtcPlugin {
- name: "PythonEditor"
-
- Depends { name: "Qt.widgets" }
- Depends { name: "Utils" }
-
- Depends { name: "Core" }
- Depends { name: "TextEditor" }
- Depends { name: "ProjectExplorer" }
-
- Group {
- name: "General"
- files: [
- "pythoneditor.cpp", "pythoneditor.h",
- "pythoneditorconstants.h",
- "pythoneditorplugin.cpp", "pythoneditorplugin.h",
- "pythonhighlighter.h", "pythonhighlighter.cpp",
- "pythonindenter.cpp", "pythonindenter.h",
- "pythonformattoken.h",
- "pythonscanner.h", "pythonscanner.cpp",
- ]
- }
-}
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp
deleted file mode 100644
index 6752713897..0000000000
--- a/src/plugins/pythoneditor/pythoneditorplugin.cpp
+++ /dev/null
@@ -1,763 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "pythoneditorplugin.h"
-#include "pythoneditor.h"
-#include "pythoneditorconstants.h"
-#include "pythonhighlighter.h"
-
-#include <coreplugin/icore.h>
-#include <coreplugin/coreconstants.h>
-#include <coreplugin/documentmanager.h>
-#include <coreplugin/fileiconprovider.h>
-#include <coreplugin/id.h>
-#include <coreplugin/messagemanager.h>
-#include <coreplugin/editormanager/editormanager.h>
-
-#include <projectexplorer/buildtargetinfo.h>
-#include <projectexplorer/kitmanager.h>
-#include <projectexplorer/localenvironmentaspect.h>
-#include <projectexplorer/runcontrol.h>
-#include <projectexplorer/runconfiguration.h>
-#include <projectexplorer/runconfigurationaspects.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/projectmanager.h>
-#include <projectexplorer/projectnodes.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/task.h>
-#include <projectexplorer/taskhub.h>
-
-#include <texteditor/texteditorconstants.h>
-
-#include <utils/algorithm.h>
-#include <utils/outputformatter.h>
-#include <utils/qtcprocess.h>
-#include <utils/utilsicons.h>
-
-#include <QDir>
-#include <QRegExp>
-#include <QRegularExpression>
-#include <QRegularExpressionMatch>
-#include <QTextCursor>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonParseError>
-#include <QJsonValue>
-#include <QJsonArray>
-
-using namespace Core;
-using namespace ProjectExplorer;
-using namespace PythonEditor::Constants;
-using namespace Utils;
-
-namespace PythonEditor {
-namespace Internal {
-
-const char PythonMimeType[] = "text/x-python-project"; // ### FIXME
-const char PythonProjectId[] = "PythonProject";
-const char PythonErrorTaskCategory[] = "Task.Category.Python";
-
-class PythonProject : public Project
-{
- Q_OBJECT
-public:
- explicit PythonProject(const Utils::FilePath &filename);
-
- bool addFiles(const QStringList &filePaths);
- bool removeFiles(const QStringList &filePaths);
- bool setFiles(const QStringList &filePaths);
- bool renameFile(const QString &filePath, const QString &newFilePath);
- void refresh(Target *target = nullptr);
-
- bool needsConfiguration() const final { return false; }
- bool needsBuildConfigurations() const final { return false; }
-
- bool writePyProjectFile(const QString &fileName, QString &content,
- const QStringList &rawList, QString *errorMessage);
-
-private:
- RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
- bool setupTarget(Target *t) override
- {
- refresh(t);
- return Project::setupTarget(t);
- }
-
- bool saveRawFileList(const QStringList &rawFileList);
- bool saveRawList(const QStringList &rawList, const QString &fileName);
- void parseProject();
- QStringList processEntries(const QStringList &paths,
- QHash<QString, QString> *map = nullptr) const;
-
- QStringList m_rawFileList;
- QStringList m_files;
- QHash<QString, QString> m_rawListEntries;
-};
-
-class PythonProjectNode : public ProjectNode
-{
-public:
- PythonProjectNode(PythonProject *project);
-
- bool supportsAction(ProjectAction action, const Node *node) const override;
- bool addFiles(const QStringList &filePaths, QStringList *) override;
- bool removeFiles(const QStringList &filePaths, QStringList *) override;
- bool deleteFiles(const QStringList &) override;
- bool renameFile(const QString &filePath, const QString &newFilePath) override;
-
-private:
- PythonProject *m_project;
-};
-
-static QTextCharFormat linkFormat(const QTextCharFormat &inputFormat, const QString &href)
-{
- QTextCharFormat result = inputFormat;
- result.setForeground(creatorTheme()->color(Theme::TextColorLink));
- result.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- result.setAnchor(true);
- result.setAnchorHref(href);
- return result;
-}
-
-class PythonOutputFormatter : public OutputFormatter
-{
-public:
- PythonOutputFormatter(Project *)
- // Note that moc dislikes raw string literals.
- : filePattern("^(\\s*)(File \"([^\"]+)\", line (\\d+), .*$)")
- {
- TaskHub::clearTasks(PythonErrorTaskCategory);
- }
-
-private:
- void appendMessage(const QString &text, OutputFormat format) final
- {
- const bool isTrace = (format == StdErrFormat
- || format == StdErrFormatSameLine)
- && (text.startsWith("Traceback (most recent call last):")
- || text.startsWith("\nTraceback (most recent call last):"));
-
- if (!isTrace) {
- OutputFormatter::appendMessage(text, format);
- return;
- }
-
- const QTextCharFormat frm = charFormat(format);
- const Core::Id id(PythonErrorTaskCategory);
- QVector<Task> tasks;
- const QStringList lines = text.split('\n');
- unsigned taskId = unsigned(lines.size());
-
- for (const QString &line : lines) {
- const QRegularExpressionMatch match = filePattern.match(line);
- if (match.hasMatch()) {
- QTextCursor tc = plainTextEdit()->textCursor();
- tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
- tc.insertText('\n' + match.captured(1));
- tc.insertText(match.captured(2), linkFormat(frm, match.captured(2)));
-
- const auto fileName = FilePath::fromString(match.captured(3));
- const int lineNumber = match.capturedRef(4).toInt();
- Task task(Task::Warning,
- QString(), fileName, lineNumber, id);
- task.taskId = --taskId;
- tasks.append(task);
- } else {
- if (!tasks.isEmpty()) {
- Task &task = tasks.back();
- if (!task.description.isEmpty())
- task.description += ' ';
- task.description += line.trimmed();
- }
- OutputFormatter::appendMessage('\n' + line, format);
- }
- }
- if (!tasks.isEmpty()) {
- tasks.back().type = Task::Error;
- for (auto rit = tasks.crbegin(), rend = tasks.crend(); rit != rend; ++rit)
- TaskHub::addTask(*rit);
- }
- }
-
- void handleLink(const QString &href) final
- {
- const QRegularExpressionMatch match = filePattern.match(href);
- if (!match.hasMatch())
- return;
- const QString fileName = match.captured(3);
- const int lineNumber = match.capturedRef(4).toInt();
- Core::EditorManager::openEditorAt(fileName, lineNumber);
- }
-
- const QRegularExpression filePattern;
-};
-
-////////////////////////////////////////////////////////////////
-
-class InterpreterAspect : public BaseStringAspect
-{
- Q_OBJECT
-
-public:
- InterpreterAspect() = default;
-};
-
-class MainScriptAspect : public BaseStringAspect
-{
- Q_OBJECT
-
-public:
- MainScriptAspect() = default;
-};
-
-class PythonRunConfiguration : public RunConfiguration
-{
- Q_OBJECT
-
- Q_PROPERTY(bool supportsDebugger READ supportsDebugger)
- Q_PROPERTY(QString interpreter READ interpreter)
- Q_PROPERTY(QString mainScript READ mainScript)
- Q_PROPERTY(QString arguments READ arguments)
-
-public:
- PythonRunConfiguration(Target *target, Core::Id id);
-
-private:
- void doAdditionalSetup(const RunConfigurationCreationInfo &) final { updateTargetInformation(); }
- Runnable runnable() const final;
-
- bool supportsDebugger() const { return true; }
- QString mainScript() const { return aspect<MainScriptAspect>()->value(); }
- QString arguments() const { return aspect<ArgumentsAspect>()->arguments(macroExpander()); }
- QString interpreter() const { return aspect<InterpreterAspect>()->value(); }
-
- void updateTargetInformation();
-};
-
-PythonRunConfiguration::PythonRunConfiguration(Target *target, Core::Id id)
- : RunConfiguration(target, id)
-{
- const Environment sysEnv = Environment::systemEnvironment();
- const QString exec = sysEnv.searchInPath("python").toString();
-
- auto interpreterAspect = addAspect<InterpreterAspect>();
- interpreterAspect->setSettingsKey("PythonEditor.RunConfiguation.Interpreter");
- interpreterAspect->setLabelText(tr("Interpreter:"));
- interpreterAspect->setDisplayStyle(BaseStringAspect::PathChooserDisplay);
- interpreterAspect->setHistoryCompleter("PythonEditor.Interpreter.History");
- interpreterAspect->setValue(exec.isEmpty() ? "python" : exec);
-
- auto scriptAspect = addAspect<MainScriptAspect>();
- scriptAspect->setSettingsKey("PythonEditor.RunConfiguation.Script");
- scriptAspect->setLabelText(tr("Script:"));
- scriptAspect->setDisplayStyle(BaseStringAspect::LabelDisplay);
-
- addAspect<LocalEnvironmentAspect>(target);
- addAspect<ArgumentsAspect>();
- addAspect<TerminalAspect>();
-
- setOutputFormatter<PythonOutputFormatter>();
- setExecutableGetter([this] {
- return FilePath::fromString(aspect<InterpreterAspect>()->value());
- });
-
- connect(target, &Target::applicationTargetsChanged,
- this, &PythonRunConfiguration::updateTargetInformation);
- connect(target->project(), &Project::parsingFinished,
- this, &PythonRunConfiguration::updateTargetInformation);
-}
-
-void PythonRunConfiguration::updateTargetInformation()
-{
- const BuildTargetInfo bti = buildTargetInfo();
- const QString script = bti.targetFilePath.toString();
- setDefaultDisplayName(tr("Run %1").arg(script));
- aspect<MainScriptAspect>()->setValue(script);
-}
-
-Runnable PythonRunConfiguration::runnable() const
-{
- CommandLine cmd{executable(), {}};
- cmd.addArg(mainScript());
- cmd.addArgs(aspect<ArgumentsAspect>()->arguments(macroExpander()));
-
- Runnable r;
- r.setCommandLine(cmd);
- r.environment = aspect<EnvironmentAspect>()->environment();
- return r;
-}
-
-class PythonRunConfigurationFactory : public RunConfigurationFactory
-{
-public:
- PythonRunConfigurationFactory()
- {
- registerRunConfiguration<PythonRunConfiguration>("PythonEditor.RunConfiguration.");
- addSupportedProjectType(PythonProjectId);
- }
-};
-
-PythonProject::PythonProject(const FilePath &fileName) :
- Project(Constants::C_PY_MIMETYPE, fileName, [this]() { refresh(); })
-{
- setId(PythonProjectId);
- setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
- setDisplayName(fileName.toFileInfo().completeBaseName());
-}
-
-static QStringList readLines(const Utils::FilePath &projectFile)
-{
- const QString projectFileName = projectFile.fileName();
- QSet<QString> visited = { projectFileName };
- QStringList lines = { projectFileName };
-
- QFile file(projectFile.toString());
- if (file.open(QFile::ReadOnly)) {
- QTextStream stream(&file);
-
- while (true) {
- const QString line = stream.readLine();
- if (line.isNull())
- break;
- if (visited.contains(line))
- continue;
- lines.append(line);
- visited.insert(line);
- }
- }
-
- return lines;
-}
-
-static QStringList readLinesJson(const Utils::FilePath &projectFile,
- QString *errorMessage)
-{
- const QString projectFileName = projectFile.fileName();
- QStringList lines = { projectFileName };
-
- QFile file(projectFile.toString());
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- *errorMessage = PythonProject::tr("Unable to open \"%1\" for reading: %2")
- .arg(projectFile.toUserOutput(), file.errorString());
- return lines;
- }
-
- const QByteArray content = file.readAll();
-
- // This assumes te project file is formed with only one field called
- // 'files' that has a list associated of the files to include in the project.
- if (content.isEmpty()) {
- *errorMessage = PythonProject::tr("Unable to read \"%1\": The file is empty.")
- .arg(projectFile.toUserOutput());
- return lines;
- }
-
- QJsonParseError error;
- const QJsonDocument doc = QJsonDocument::fromJson(content, &error);
- if (doc.isNull()) {
- const int line = content.left(error.offset).count('\n') + 1;
- *errorMessage = PythonProject::tr("Unable to parse \"%1\":%2: %3")
- .arg(projectFile.toUserOutput()).arg(line)
- .arg(error.errorString());
- return lines;
- }
-
- const QJsonObject obj = doc.object();
- if (obj.contains("files")) {
- const QJsonValue files = obj.value("files");
- const QJsonArray files_array = files.toArray();
- QSet<QString> visited;
- for (const auto &file : files_array)
- visited.insert(file.toString());
-
- lines.append(Utils::toList(visited));
- }
-
- return lines;
-}
-
-bool PythonProject::saveRawFileList(const QStringList &rawFileList)
-{
- const bool result = saveRawList(rawFileList, projectFilePath().toString());
-// refresh(PythonProject::Files);
- return result;
-}
-
-bool PythonProject::saveRawList(const QStringList &rawList, const QString &fileName)
-{
- FileChangeBlocker changeGuarg(fileName);
- bool result = false;
-
- // New project file
- if (fileName.endsWith(".pyproject")) {
- FileSaver saver(fileName, QIODevice::ReadOnly | QIODevice::Text);
- if (!saver.hasError()) {
- QString content = QTextStream(saver.file()).readAll();
- if (saver.finalize(ICore::mainWindow())) {
- QString errorMessage;
- result = writePyProjectFile(fileName, content, rawList, &errorMessage);
- if (!errorMessage.isEmpty())
- Core::MessageManager::write(errorMessage);
- }
- }
- } else { // Old project file
- FileSaver saver(fileName, QIODevice::WriteOnly | QIODevice::Text);
- if (!saver.hasError()) {
- QTextStream stream(saver.file());
- for (const QString &filePath : rawList)
- stream << filePath << '\n';
- saver.setResult(&stream);
- result = saver.finalize(ICore::mainWindow());
- }
- }
-
- return result;
-}
-
-bool PythonProject::writePyProjectFile(const QString &fileName, QString &content,
- const QStringList &rawList, QString *errorMessage)
-{
- QFile file(fileName);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- *errorMessage = PythonProject::tr("Unable to open \"%1\" for reading: %2")
- .arg(fileName, file.errorString());
- return false;
- }
-
- // Build list of files with the current rawList for the JSON file
- QString files("[");
- for (const QString &f : rawList)
- if (!f.endsWith(".pyproject"))
- files += QString("\"%1\",").arg(f);
- files = files.left(files.lastIndexOf(',')); // Removing leading comma
- files += ']';
-
- // Removing everything inside square parenthesis
- // to replace it with the new list of files for the JSON file.
- QRegularExpression pattern(R"(\[.*\])");
- content.replace(pattern, files);
- file.write(content.toUtf8());
-
- return true;
-}
-
-bool PythonProject::addFiles(const QStringList &filePaths)
-{
- QStringList newList = m_rawFileList;
-
- const QDir baseDir(projectDirectory().toString());
- for (const QString &filePath : filePaths)
- newList.append(baseDir.relativeFilePath(filePath));
-
- return saveRawFileList(newList);
-}
-
-bool PythonProject::removeFiles(const QStringList &filePaths)
-{
- QStringList newList = m_rawFileList;
-
- for (const QString &filePath : filePaths) {
- const QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
- if (i != m_rawListEntries.end())
- newList.removeOne(i.value());
- }
-
- return saveRawFileList(newList);
-}
-
-bool PythonProject::setFiles(const QStringList &filePaths)
-{
- QStringList newList;
- const QDir baseDir(projectDirectory().toString());
- for (const QString &filePath : filePaths)
- newList.append(baseDir.relativeFilePath(filePath));
-
- return saveRawFileList(newList);
-}
-
-bool PythonProject::renameFile(const QString &filePath, const QString &newFilePath)
-{
- QStringList newList = m_rawFileList;
-
- const QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
- if (i != m_rawListEntries.end()) {
- const int index = newList.indexOf(i.value());
- if (index != -1) {
- const QDir baseDir(projectDirectory().toString());
- newList.replace(index, baseDir.relativeFilePath(newFilePath));
- }
- }
-
- return saveRawFileList(newList);
-}
-
-void PythonProject::parseProject()
-{
- m_rawListEntries.clear();
- const Utils::FilePath filePath = projectFilePath();
- // The PySide project file is JSON based
- if (filePath.endsWith(".pyproject")) {
- QString errorMessage;
- m_rawFileList = readLinesJson(filePath, &errorMessage);
- if (!errorMessage.isEmpty())
- Core::MessageManager::write(errorMessage);
- }
- // To keep compatibility with PyQt we keep the compatibility with plain
- // text files as project files.
- else if (filePath.endsWith(".pyqtc"))
- m_rawFileList = readLines(filePath);
-
- m_files = processEntries(m_rawFileList, &m_rawListEntries);
-}
-
-/**
- * @brief Provides displayName relative to project node
- */
-class PythonFileNode : public FileNode
-{
-public:
- PythonFileNode(const Utils::FilePath &filePath, const QString &nodeDisplayName,
- FileType fileType = FileType::Source)
- : FileNode(filePath, fileType)
- , m_displayName(nodeDisplayName)
- {}
-
- QString displayName() const override { return m_displayName; }
-private:
- QString m_displayName;
-};
-
-void PythonProject::refresh(Target *target)
-{
- emitParsingStarted();
- parseProject();
-
- const QDir baseDir(projectDirectory().toString());
- QList<BuildTargetInfo> appTargets;
- auto newRoot = std::make_unique<PythonProjectNode>(this);
- for (const QString &f : qAsConst(m_files)) {
- const QString displayName = baseDir.relativeFilePath(f);
- const FileType fileType = f.endsWith(".pyproject") || f.endsWith(".pyqtc") ? FileType::Project
- : FileType::Source;
- newRoot->addNestedNode(std::make_unique<PythonFileNode>(FilePath::fromString(f),
- displayName, fileType));
- if (fileType == FileType::Source) {
- BuildTargetInfo bti;
- bti.buildKey = f;
- bti.targetFilePath = FilePath::fromString(f);
- bti.projectFilePath = projectFilePath();
- appTargets.append(bti);
- }
- }
- setRootProjectNode(std::move(newRoot));
-
- if (!target)
- target = activeTarget();
- if (target)
- target->setApplicationTargets(appTargets);
-
- emitParsingFinished(true);
-}
-
-/**
- * Expands environment variables in the given \a string when they are written
- * like $$(VARIABLE).
- */
-static void expandEnvironmentVariables(const QProcessEnvironment &env, QString &string)
-{
- static QRegExp candidate(QLatin1String("\\$\\$\\((.+)\\)"));
-
- int index = candidate.indexIn(string);
- while (index != -1) {
- const QString value = env.value(candidate.cap(1));
-
- string.replace(index, candidate.matchedLength(), value);
- index += value.length();
-
- index = candidate.indexIn(string, index);
- }
-}
-
-/**
- * Expands environment variables and converts the path from relative to the
- * project to an absolute path.
- *
- * The \a map variable is an optional argument that will map the returned
- * absolute paths back to their original \a entries.
- */
-QStringList PythonProject::processEntries(const QStringList &paths,
- QHash<QString, QString> *map) const
-{
- const QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- const QDir projectDir(projectDirectory().toString());
-
- QFileInfo fileInfo;
- QStringList absolutePaths;
- for (const QString &path : paths) {
- QString trimmedPath = path.trimmed();
- if (trimmedPath.isEmpty())
- continue;
-
- expandEnvironmentVariables(env, trimmedPath);
-
- trimmedPath = FilePath::fromUserInput(trimmedPath).toString();
-
- fileInfo.setFile(projectDir, trimmedPath);
- if (fileInfo.exists()) {
- const QString absPath = fileInfo.absoluteFilePath();
- absolutePaths.append(absPath);
- if (map)
- map->insert(absPath, trimmedPath);
- }
- }
- absolutePaths.removeDuplicates();
- return absolutePaths;
-}
-
-Project::RestoreResult PythonProject::fromMap(const QVariantMap &map, QString *errorMessage)
-{
- Project::RestoreResult res = Project::fromMap(map, errorMessage);
- if (res == RestoreResult::Ok) {
- refresh();
-
- Kit *defaultKit = KitManager::defaultKit();
- if (!activeTarget() && defaultKit)
- addTarget(createTarget(defaultKit));
- }
-
- return res;
-}
-
-PythonProjectNode::PythonProjectNode(PythonProject *project)
- : ProjectNode(project->projectDirectory())
- , m_project(project)
-{
- setDisplayName(project->projectFilePath().toFileInfo().completeBaseName());
- setAddFileFilter("*.py");
-}
-
-QHash<QString, QStringList> sortFilesIntoPaths(const QString &base, const QSet<QString> &files)
-{
- QHash<QString, QStringList> filesInPath;
- const QDir baseDir(base);
-
- for (const QString &absoluteFileName : files) {
- const QFileInfo fileInfo(absoluteFileName);
- const FilePath absoluteFilePath = FilePath::fromString(fileInfo.path());
- QString relativeFilePath;
-
- if (absoluteFilePath.isChildOf(baseDir)) {
- relativeFilePath = absoluteFilePath.relativeChildPath(FilePath::fromString(base)).toString();
- } else {
- // 'file' is not part of the project.
- relativeFilePath = baseDir.relativeFilePath(absoluteFilePath.toString());
- if (relativeFilePath.endsWith('/'))
- relativeFilePath.chop(1);
- }
-
- filesInPath[relativeFilePath].append(absoluteFileName);
- }
- return filesInPath;
-}
-
-bool PythonProjectNode::supportsAction(ProjectAction action, const Node *node) const
-{
- if (node->asFileNode()) {
- return action == ProjectAction::Rename
- || action == ProjectAction::RemoveFile;
- }
- if (node->isFolderNodeType() || node->isProjectNodeType()) {
- return action == ProjectAction::AddNewFile
- || action == ProjectAction::RemoveFile
- || action == ProjectAction::AddExistingFile;
- }
- return ProjectNode::supportsAction(action, node);
-}
-
-bool PythonProjectNode::addFiles(const QStringList &filePaths, QStringList *)
-{
- return m_project->addFiles(filePaths);
-}
-
-bool PythonProjectNode::removeFiles(const QStringList &filePaths, QStringList *)
-{
- return m_project->removeFiles(filePaths);
-}
-
-bool PythonProjectNode::deleteFiles(const QStringList &)
-{
- return true;
-}
-
-bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
-{
- return m_project->renameFile(filePath, newFilePath);
-}
-
-////////////////////////////////////////////////////////////////////////////////////
-//
-// PythonEditorPlugin
-//
-////////////////////////////////////////////////////////////////////////////////////
-
-class PythonEditorPluginPrivate
-{
-public:
- PythonEditorFactory editorFactory;
- PythonRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, PythonRunConfiguration> runWorkerFactory;
-};
-
-PythonEditorPlugin::~PythonEditorPlugin()
-{
- delete d;
-}
-
-bool PythonEditorPlugin::initialize(const QStringList &arguments, QString *errorMessage)
-{
- Q_UNUSED(arguments)
- Q_UNUSED(errorMessage)
-
- d = new PythonEditorPluginPrivate;
-
- ProjectManager::registerProjectType<PythonProject>(PythonMimeType);
-
- return true;
-}
-
-void PythonEditorPlugin::extensionsInitialized()
-{
- // Add MIME overlay icons (these icons displayed at Project dock panel)
- QString imageFile = creatorTheme()->imageFile(Theme::IconOverlayPro,
- ProjectExplorer::Constants::FILEOVERLAY_PY);
- FileIconProvider::registerIconOverlayForSuffix(imageFile, "py");
-
- TaskHub::addCategory(PythonErrorTaskCategory, "Python", true);
-}
-
-} // namespace Internal
-} // namespace PythonEditor
-
-#include "pythoneditorplugin.moc"
diff --git a/src/plugins/qbsprojectmanager/CMakeLists.txt b/src/plugins/qbsprojectmanager/CMakeLists.txt
index e02a516f1a..997e710a83 100644
--- a/src/plugins/qbsprojectmanager/CMakeLists.txt
+++ b/src/plugins/qbsprojectmanager/CMakeLists.txt
@@ -13,11 +13,9 @@ add_qtc_plugin(QbsProjectManager
propertyprovider.h
qbsbuildconfiguration.cpp qbsbuildconfiguration.h
qbsbuildstep.cpp qbsbuildstep.h
- qbsbuildstepconfigwidget.ui
qbscleanstep.cpp qbscleanstep.h
qbscleanstepconfigwidget.ui
qbsinstallstep.cpp qbsinstallstep.h
- qbsinstallstepconfigwidget.ui
qbskitinformation.cpp qbskitinformation.h
qbslogsink.cpp qbslogsink.h
qbsnodes.cpp qbsnodes.h
@@ -34,5 +32,4 @@ add_qtc_plugin(QbsProjectManager
qbsprojectmanagerplugin.cpp qbsprojectmanagerplugin.h
qbsprojectmanagersettings.cpp qbsprojectmanagersettings.h
qbsprojectparser.cpp qbsprojectparser.h
- qbsrunconfiguration.cpp qbsrunconfiguration.h
)
diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp
index 3f8f5e84cb..cfb7b63991 100644
--- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp
+++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp
@@ -45,6 +45,8 @@
#include <android/androidconstants.h>
#include <ios/iosconstants.h>
+#include <qtsupport/baseqtversion.h>
+#include <qtsupport/qtkitinformation.h>
#include <winrt/winrtconstants.h>
#include <QDir>
@@ -126,11 +128,11 @@ static QStringList toolchainList(const ProjectExplorer::ToolChain *tc)
{
QStringList list;
if (tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID
- || (tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_ID
+ || (tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_TYPEID
&& tc->compilerCommand().toString().contains("clang"))) {
list << QLatin1String("clang") << QLatin1String("llvm") << QLatin1String("gcc");
} else if (tc->typeId() == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
- || tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_ID) {
+ || tc->typeId() == Android::Constants::ANDROID_TOOLCHAIN_TYPEID) {
list << QLatin1String("gcc"); // TODO: Detect llvm-gcc
} else if (tc->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) {
list << QLatin1String("mingw") << QLatin1String("gcc");
@@ -293,6 +295,18 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor
data.insert("Android.ndk.ndkDir", ndkDir);
}
}
+ data.remove(QBS_ARCHITECTURES);
+ data.remove(QBS_ARCHITECTURE);
+ QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(k);
+ if (qtVersion) {
+ QStringList abis;
+ for (const auto &abi : qtVersion->qtAbis())
+ abis << abi.param();
+ if (abis.size() == 1)
+ data.insert(QLatin1String(QBS_ARCHITECTURE), abis.first());
+ else
+ data.insert(QLatin1String(QBS_ARCHITECTURES), abis);
+ }
} else {
Utils::FilePath cCompilerPath;
if (tcC)
diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
index f3fd3d9f56..93cbde2eb1 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp
@@ -59,13 +59,13 @@ using namespace Utils;
namespace QbsProjectManager {
namespace Internal {
-static FilePath defaultBuildDirectory(const QString &projectFilePath, const Kit *k,
+static FilePath defaultBuildDirectory(const FilePath &projectFilePath, const Kit *k,
const QString &bcName,
BuildConfiguration::BuildType buildType)
{
- const QString projectName = QFileInfo(projectFilePath).completeBaseName();
+ const QString projectName = projectFilePath.toFileInfo().completeBaseName();
ProjectMacroExpander expander(projectFilePath, projectName, k, bcName, buildType);
- QString projectDir = Project::projectDirectory(FilePath::fromString(projectFilePath)).toString();
+ QString projectDir = Project::projectDirectory(projectFilePath).toString();
QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate());
return FilePath::fromString(FileUtils::resolvePath(projectDir, buildPath));
}
@@ -86,24 +86,29 @@ QbsBuildConfiguration::QbsBuildConfiguration(Target *target, Core::Id id)
connect(m_configurationName, &BaseStringAspect::changed,
this, &BuildConfiguration::buildDirectoryChanged);
- connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged);
- connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
+ connect(this, &BuildConfiguration::environmentChanged,
+ this, &QbsBuildConfiguration::triggerReparseIfActive);
+ connect(this, &BuildConfiguration::buildDirectoryChanged,
+ this, &QbsBuildConfiguration::triggerReparseIfActive);
+ connect(this, &QbsBuildConfiguration::qbsConfigurationChanged,
+ this, &QbsBuildConfiguration::triggerReparseIfActive);
}
-void QbsBuildConfiguration::initialize(const BuildInfo &info)
+void QbsBuildConfiguration::initialize()
{
- BuildConfiguration::initialize(info);
+ BuildConfiguration::initialize();
- QVariantMap configData = info.extraInfo.value<QVariantMap>();
+ QVariantMap configData = extraInfo().value<QVariantMap>();
configData.insert(QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY),
- (info.buildType == BuildConfiguration::Debug)
+ (initialBuildType() == BuildConfiguration::Debug)
? QLatin1String(Constants::QBS_VARIANT_DEBUG)
: QLatin1String(Constants::QBS_VARIANT_RELEASE));
- Utils::FilePath buildDir = info.buildDirectory;
+ Utils::FilePath buildDir = initialBuildDirectory();
if (buildDir.isEmpty())
- buildDir = defaultBuildDirectory(target()->project()->projectFilePath().toString(),
- target()->kit(), info.displayName, info.buildType);
+ buildDir = defaultBuildDirectory(target()->project()->projectFilePath(),
+ target()->kit(), initialDisplayName(),
+ initialBuildType());
setBuildDirectory(buildDir);
// Add the build configuration.
@@ -111,24 +116,30 @@ void QbsBuildConfiguration::initialize(const BuildInfo &info)
QString configName = bd.take("configName").toString();
if (configName.isEmpty()) {
configName = "qtc_" + target()->kit()->fileSystemFriendlyName() + '_'
- + Utils::FileUtils::fileSystemFriendlyName(info.displayName);
+ + Utils::FileUtils::fileSystemFriendlyName(initialDisplayName());
}
m_configurationName->setValue(configName);
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
auto bs = new QbsBuildStep(buildSteps);
- if (info.buildType == Release)
+ if (initialBuildType() == Release)
bs->setQmlDebuggingEnabled(false);
bs->setQbsConfiguration(bd);
buildSteps->appendStep(bs);
BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
- cleanSteps->appendStep(new QbsCleanStep(cleanSteps));
+ cleanSteps->appendStep(Constants::QBS_CLEANSTEP_ID);
emit qbsConfigurationChanged();
}
+void QbsBuildConfiguration::triggerReparseIfActive()
+{
+ if (isActive())
+ qbsProject()->delayParsing();
+}
+
bool QbsBuildConfiguration::fromMap(const QVariantMap &map)
{
if (!BuildConfiguration::fromMap(map))
@@ -158,23 +169,9 @@ QVariantMap QbsBuildConfiguration::qbsConfiguration() const
return config;
}
-Internal::QbsProject *QbsBuildConfiguration::project() const
-{
- return qobject_cast<Internal::QbsProject *>(BuildConfiguration::project());
-}
-
-bool QbsBuildConfiguration::isEnabled() const
-{
- return !project()->isParsing() && project()->hasParseResult();
-}
-
-QString QbsBuildConfiguration::disabledReason() const
+Internal::QbsProject *QbsBuildConfiguration::qbsProject() const
{
- if (project()->isParsing())
- return tr("Parsing the Qbs project.");
- if (!project()->hasParseResult())
- return tr("Parsing of Qbs project has failed.");
- return QString();
+ return qobject_cast<Internal::QbsProject *>(project());
}
BuildConfiguration::BuildType QbsBuildConfiguration::buildType() const
@@ -369,6 +366,39 @@ QbsBuildConfigurationFactory::QbsBuildConfigurationFactory()
});
}
+QList<BuildInfo> QbsBuildConfigurationFactory::availableBuilds(const Kit *k, const FilePath &projectPath, bool forSetup) const
+{
+ QList<BuildInfo> result;
+
+ if (forSetup) {
+
+ BuildInfo info = createBuildInfo(k, BuildConfiguration::Debug);
+ //: The name of the debug build configuration created by default for a qbs project.
+ info.displayName = tr("Debug");
+ //: Non-ASCII characters in directory suffix may cause build issues.
+ info.buildDirectory
+ = defaultBuildDirectory(projectPath, k, tr("Debug", "Shadow build directory suffix"),
+ info.buildType);
+ result << info;
+
+ info = createBuildInfo(k, BuildConfiguration::Release);
+ //: The name of the release build configuration created by default for a qbs project.
+ info.displayName = tr("Release");
+ //: Non-ASCII characters in directory suffix may cause build issues.
+ info.buildDirectory
+ = defaultBuildDirectory(projectPath, k, tr("Release", "Shadow build directory suffix"),
+ info.buildType);
+ result << info;
+
+ } else {
+
+ result << createBuildInfo(k, BuildConfiguration::Debug);
+
+ }
+
+ return result;
+}
+
BuildInfo QbsBuildConfigurationFactory::createBuildInfo(const Kit *k,
BuildConfiguration::BuildType type) const
{
@@ -382,35 +412,5 @@ BuildInfo QbsBuildConfigurationFactory::createBuildInfo(const Kit *k,
return info;
}
-QList<BuildInfo> QbsBuildConfigurationFactory::availableBuilds(const Target *parent) const
-{
- return {createBuildInfo(parent->kit(), BuildConfiguration::Debug)};
-}
-
-QList<BuildInfo> QbsBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
-{
- QList<BuildInfo> result;
-
- BuildInfo info = createBuildInfo(k, BuildConfiguration::Debug);
- //: The name of the debug build configuration created by default for a qbs project.
- info.displayName = tr("Debug");
- //: Non-ASCII characters in directory suffix may cause build issues.
- info.buildDirectory
- = defaultBuildDirectory(projectPath, k, tr("Debug", "Shadow build directory suffix"),
- info.buildType);
- result << info;
-
- info = createBuildInfo(k, BuildConfiguration::Release);
- //: The name of the release build configuration created by default for a qbs project.
- info.displayName = tr("Release");
- //: Non-ASCII characters in directory suffix may cause build issues.
- info.buildDirectory
- = defaultBuildDirectory(projectPath, k, tr("Release", "Shadow build directory suffix"),
- info.buildType);
- result << info;
-
- return result;
-}
-
} // namespace Internal
} // namespace QbsProjectManager
diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
index f34e552a40..0dbd442efb 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
+++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h
@@ -48,15 +48,12 @@ class QbsBuildConfiguration : public ProjectExplorer::BuildConfiguration
QbsBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
public:
- void initialize(const ProjectExplorer::BuildInfo &info) override;
+ void initialize() override;
QbsBuildStep *qbsStep() const;
QVariantMap qbsConfiguration() const;
- Internal::QbsProject *project() const override;
-
- bool isEnabled() const override;
- QString disabledReason() const override;
+ Internal::QbsProject *qbsProject() const;
BuildType buildType() const override;
@@ -78,6 +75,7 @@ signals:
private:
bool fromMap(const QVariantMap &map) override;
+ void triggerReparseIfActive();
QStringList m_changedFiles;
QStringList m_activeFileTags;
@@ -92,9 +90,8 @@ class QbsBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationF
public:
QbsBuildConfigurationFactory();
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override;
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
+ QList<ProjectExplorer::BuildInfo> availableBuilds
+ (const ProjectExplorer::Kit *k, const Utils::FilePath &projectPath, bool forSetup) const override;
private:
ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k,
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
index da09f51c05..25d16c08ad 100644
--- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp
@@ -31,8 +31,6 @@
#include "qbsprojectmanagerconstants.h"
#include "qbsprojectmanagersettings.h"
-#include "ui_qbsbuildstepconfigwidget.h"
-
#include <coreplugin/icore.h>
#include <coreplugin/variablechooser.h>
#include <projectexplorer/buildsteplist.h>
@@ -41,24 +39,36 @@
#include <projectexplorer/target.h>
#include <qtsupport/qtversionmanager.h>
#include <utils/macroexpander.h>
+#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/utilsicons.h>
-#include <qbs.h>
+#include <QBoxLayout>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QFormLayout>
+#include <QLabel>
+#include <QPlainTextEdit>
+#include <QSpinBox>
-static const char QBS_CONFIG[] = "Qbs.Configuration";
-static const char QBS_DRY_RUN[] = "Qbs.DryRun";
-static const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing";
-static const char QBS_MAXJOBCOUNT[] = "Qbs.MaxJobs";
-static const char QBS_SHOWCOMMANDLINES[] = "Qbs.ShowCommandLines";
-static const char QBS_INSTALL[] = "Qbs.Install";
-static const char QBS_CLEAN_INSTALL_ROOT[] = "Qbs.CleanInstallRoot";
+#include <qbs.h>
// --------------------------------------------------------------------
// Constants:
// --------------------------------------------------------------------
+const char QBS_CONFIG[] = "Qbs.Configuration";
+const char QBS_DRY_RUN[] = "Qbs.DryRun";
+const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing";
+const char QBS_MAXJOBCOUNT[] = "Qbs.MaxJobs";
+const char QBS_SHOWCOMMANDLINES[] = "Qbs.ShowCommandLines";
+const char QBS_INSTALL[] = "Qbs.Install";
+const char QBS_CLEAN_INSTALL_ROOT[] = "Qbs.CleanInstallRoot";
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
namespace QbsProjectManager {
namespace Internal {
@@ -67,7 +77,6 @@ class QbsBuildStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
Q_OBJECT
public:
QbsBuildStepConfigWidget(QbsBuildStep *step);
- ~QbsBuildStepConfigWidget() override;
private:
void updateState();
@@ -92,8 +101,6 @@ private:
bool validateProperties(Utils::FancyLineEdit *edit, QString *errorMessage);
- Ui::QbsBuildStepConfigWidget *m_ui;
-
class Property
{
public:
@@ -114,7 +121,22 @@ private:
};
QList<Property> m_propertyCache;
- bool m_ignoreChange;
+ bool m_ignoreChange = false;
+
+ QComboBox *buildVariantComboBox;
+ QSpinBox *jobSpinBox;
+ QCheckBox *qmlDebuggingLibraryCheckBox;
+ FancyLineEdit *propertyEdit;
+ PathChooser *installDirChooser;
+ QLabel *qmlDebuggingWarningIcon;
+ QLabel *qmlDebuggingWarningText;
+ QCheckBox *keepGoingCheckBox;
+ QCheckBox *showCommandLinesCheckBox;
+ QCheckBox *forceProbesCheckBox;
+ QCheckBox *installCheckBox;
+ QCheckBox *cleanInstallRootCheckBox;
+ QCheckBox *defaultInstallDirCheckBox;
+ QPlainTextEdit *commandLineTextEdit;
};
// --------------------------------------------------------------------
@@ -340,8 +362,7 @@ void QbsBuildStep::buildingDone(bool success)
void QbsBuildStep::reparsingDone(bool success)
{
- disconnect(qbsProject(), &ProjectExplorer::Project::parsingFinished,
- this, &QbsBuildStep::reparsingDone);
+ disconnect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone);
m_parsingProject = false;
if (m_job) { // This was a scheduled reparsing after building.
finish();
@@ -367,7 +388,7 @@ void QbsBuildStep::handleProgress(int value)
void QbsBuildStep::handleCommandDescriptionReport(const QString &highlight, const QString &message)
{
- Q_UNUSED(highlight);
+ Q_UNUSED(highlight)
emit addOutput(message, OutputFormat::Stdout);
}
@@ -469,8 +490,7 @@ void QbsBuildStep::setCleanInstallRoot(bool clean)
void QbsBuildStep::parseProject()
{
m_parsingProject = true;
- connect(qbsProject(), &ProjectExplorer::Project::parsingFinished,
- this, &QbsBuildStep::reparsingDone);
+ connect(project(), &Project::parsingFinished, this, &QbsBuildStep::reparsingDone);
qbsProject()->parseCurrentBuildConfiguration();
}
@@ -526,7 +546,7 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step) :
BuildStepConfigWidget(step),
m_ignoreChange(false)
{
- connect(step, &ProjectExplorer::ProjectConfiguration::displayNameChanged,
+ connect(step, &ProjectConfiguration::displayNameChanged,
this, &QbsBuildStepConfigWidget::updateState);
connect(step, &QbsBuildStep::qbsConfigurationChanged,
this, &QbsBuildStepConfigWidget::updateState);
@@ -534,76 +554,158 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step) :
this, &QbsBuildStepConfigWidget::updateState);
connect(&QbsProjectManagerSettings::instance(), &QbsProjectManagerSettings::settingsBaseChanged,
this, &QbsBuildStepConfigWidget::updateState);
- step->target()->subscribeSignal(&ProjectExplorer::BuildConfiguration::buildDirectoryChanged,
- this, [this]() {
- if (this->step()->buildConfiguration() == sender())
- updateState();
- });
+ connect(step->buildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
+ this, &QbsBuildStepConfigWidget::updateState);
setContentsMargins(0, 0, 0, 0);
- m_ui = new Ui::QbsBuildStepConfigWidget;
- m_ui->setupUi(this);
- m_ui->installDirChooser->setExpectedKind(Utils::PathChooser::Directory);
+ buildVariantComboBox = new QComboBox(this);
+ buildVariantComboBox->addItem(tr("Debug"));
+ buildVariantComboBox->addItem(tr("Release"));
+
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(buildVariantComboBox->sizePolicy().hasHeightForWidth());
+ buildVariantComboBox->setSizePolicy(sizePolicy);
+
+ auto horizontalLayout_5 = new QHBoxLayout();
+ horizontalLayout_5->addWidget(buildVariantComboBox);
+ horizontalLayout_5->addItem(new QSpacerItem(70, 13, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ jobSpinBox = new QSpinBox(this);
+
+ auto horizontalLayout_6 = new QHBoxLayout();
+ horizontalLayout_6->addWidget(jobSpinBox);
+ horizontalLayout_6->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ qmlDebuggingLibraryCheckBox = new QCheckBox(this);
+ qmlDebuggingWarningIcon = new QLabel(this);
+ qmlDebuggingWarningText = new QLabel(this);
+
+ auto qmlDebuggingLayout = new QHBoxLayout();
+ qmlDebuggingLayout->addWidget(qmlDebuggingLibraryCheckBox);
+ qmlDebuggingLayout->addWidget(qmlDebuggingWarningIcon);
+ qmlDebuggingLayout->addWidget(qmlDebuggingWarningText);
+ qmlDebuggingLayout->addItem(new QSpacerItem(40, 5, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ propertyEdit = new FancyLineEdit(this);
+
+ keepGoingCheckBox = new QCheckBox(this);
+
+ showCommandLinesCheckBox = new QCheckBox(this);
+
+ forceProbesCheckBox = new QCheckBox(this);
+
+ auto flagsLayout = new QHBoxLayout();
+ flagsLayout->addWidget(keepGoingCheckBox);
+ flagsLayout->addWidget(showCommandLinesCheckBox);
+ flagsLayout->addWidget(forceProbesCheckBox);
+ flagsLayout->addItem(new QSpacerItem(40, 13, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ installCheckBox = new QCheckBox(this);
+
+ cleanInstallRootCheckBox = new QCheckBox(this);
+
+ defaultInstallDirCheckBox = new QCheckBox(this);
+
+ auto installLayout = new QHBoxLayout();
+ installLayout->addWidget(installCheckBox);
+ installLayout->addWidget(cleanInstallRootCheckBox);
+ installLayout->addWidget(defaultInstallDirCheckBox);
+ installLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
+
+ installDirChooser = new PathChooser(this);
+ installDirChooser->setExpectedKind(PathChooser::Directory);
+
+ commandLineTextEdit = new QPlainTextEdit(this);
+ commandLineTextEdit->setUndoRedoEnabled(false);
+ commandLineTextEdit->setReadOnly(true);
+ commandLineTextEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse);
+
+ auto formLayout = new QFormLayout(this);
+ formLayout->addRow(tr("Build variant:"), horizontalLayout_5);
+ formLayout->addRow(tr("Parallel jobs:"), horizontalLayout_6);
+ formLayout->addRow(tr("Enable QML debugging:"), qmlDebuggingLayout);
+ formLayout->addRow(tr("Properties:"), propertyEdit);
+ formLayout->addRow(tr("Flags:"), flagsLayout);
+ formLayout->addRow(tr("Installation flags:"), installLayout);
+ formLayout->addRow(tr("Installation directory:"), installDirChooser);
+ formLayout->addRow(tr("Equivalent command line:"), commandLineTextEdit);
+
+ QWidget::setTabOrder(buildVariantComboBox, jobSpinBox);
+ QWidget::setTabOrder(jobSpinBox, qmlDebuggingLibraryCheckBox);
+ QWidget::setTabOrder(qmlDebuggingLibraryCheckBox, propertyEdit);
+ QWidget::setTabOrder(propertyEdit, keepGoingCheckBox);
+ QWidget::setTabOrder(keepGoingCheckBox, showCommandLinesCheckBox);
+ QWidget::setTabOrder(showCommandLinesCheckBox, forceProbesCheckBox);
+ QWidget::setTabOrder(forceProbesCheckBox, installCheckBox);
+ QWidget::setTabOrder(installCheckBox, cleanInstallRootCheckBox);
+ QWidget::setTabOrder(cleanInstallRootCheckBox, commandLineTextEdit);
+
+ jobSpinBox->setToolTip(tr("Number of concurrent build jobs."));
+ propertyEdit->setToolTip(tr("Properties to pass to the project."));
+ keepGoingCheckBox->setToolTip(tr("Keep going when errors occur (if at all possible)."));
+ keepGoingCheckBox->setText(tr("Keep going"));
+ showCommandLinesCheckBox->setText(tr("Show command lines"));
+ forceProbesCheckBox->setText(tr("Force probes"));
+ installCheckBox->setText(tr("Install"));
+ cleanInstallRootCheckBox->setText(tr("Clean install root"));
+ defaultInstallDirCheckBox->setText(tr("Use default location"));
auto chooser = new Core::VariableChooser(this);
- chooser->addSupportedWidget(m_ui->propertyEdit);
- chooser->addSupportedWidget(m_ui->installDirChooser->lineEdit());
- m_ui->propertyEdit->setValidationFunction([this](Utils::FancyLineEdit *edit,
- QString *errorMessage) {
+ chooser->addSupportedWidget(propertyEdit);
+ chooser->addSupportedWidget(installDirChooser->lineEdit());
+ propertyEdit->setValidationFunction([this](FancyLineEdit *edit, QString *errorMessage) {
return validateProperties(edit, errorMessage);
});
- m_ui->qmlDebuggingWarningIcon->setPixmap(Utils::Icons::WARNING.pixmap());
- connect(m_ui->buildVariantComboBox,
+ qmlDebuggingWarningIcon->setPixmap(Utils::Icons::WARNING.pixmap());
+
+ connect(buildVariantComboBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &QbsBuildStepConfigWidget::changeBuildVariant);
- connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled,
+ connect(keepGoingCheckBox, &QAbstractButton::toggled,
this, &QbsBuildStepConfigWidget::changeKeepGoing);
- connect(m_ui->jobSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
+ connect(jobSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
this, &QbsBuildStepConfigWidget::changeJobCount);
- connect(m_ui->showCommandLinesCheckBox, &QCheckBox::toggled, this,
+ connect(showCommandLinesCheckBox, &QCheckBox::toggled, this,
&QbsBuildStepConfigWidget::changeShowCommandLines);
- connect(m_ui->installCheckBox, &QCheckBox::toggled, this,
+ connect(installCheckBox, &QCheckBox::toggled, this,
&QbsBuildStepConfigWidget::changeInstall);
- connect(m_ui->cleanInstallRootCheckBox, &QCheckBox::toggled, this,
+ connect(cleanInstallRootCheckBox, &QCheckBox::toggled, this,
&QbsBuildStepConfigWidget::changeCleanInstallRoot);
- connect(m_ui->defaultInstallDirCheckBox, &QCheckBox::toggled, this,
+ connect(defaultInstallDirCheckBox, &QCheckBox::toggled, this,
&QbsBuildStepConfigWidget::changeUseDefaultInstallDir);
- connect(m_ui->installDirChooser, &Utils::PathChooser::rawPathChanged, this,
+ connect(installDirChooser, &Utils::PathChooser::rawPathChanged, this,
&QbsBuildStepConfigWidget::changeInstallDir);
- connect(m_ui->forceProbesCheckBox, &QCheckBox::toggled, this,
+ connect(forceProbesCheckBox, &QCheckBox::toggled, this,
&QbsBuildStepConfigWidget::changeForceProbes);
- connect(m_ui->qmlDebuggingLibraryCheckBox, &QAbstractButton::toggled,
+ connect(qmlDebuggingLibraryCheckBox, &QAbstractButton::toggled,
this, &QbsBuildStepConfigWidget::linkQmlDebuggingLibraryChecked);
updateState();
}
-QbsBuildStepConfigWidget::~QbsBuildStepConfigWidget()
-{
- delete m_ui;
-}
-
void QbsBuildStepConfigWidget::updateState()
{
if (!m_ignoreChange) {
- m_ui->keepGoingCheckBox->setChecked(qbsStep()->keepGoing());
- m_ui->jobSpinBox->setValue(qbsStep()->maxJobs());
- m_ui->showCommandLinesCheckBox->setChecked(qbsStep()->showCommandLines());
- m_ui->installCheckBox->setChecked(qbsStep()->install());
- m_ui->cleanInstallRootCheckBox->setChecked(qbsStep()->cleanInstallRoot());
- m_ui->forceProbesCheckBox->setChecked(qbsStep()->forceProbes());
+ keepGoingCheckBox->setChecked(qbsStep()->keepGoing());
+ jobSpinBox->setValue(qbsStep()->maxJobs());
+ showCommandLinesCheckBox->setChecked(qbsStep()->showCommandLines());
+ installCheckBox->setChecked(qbsStep()->install());
+ cleanInstallRootCheckBox->setChecked(qbsStep()->cleanInstallRoot());
+ forceProbesCheckBox->setChecked(qbsStep()->forceProbes());
updatePropertyEdit(qbsStep()->qbsConfiguration(QbsBuildStep::PreserveVariables));
- m_ui->qmlDebuggingLibraryCheckBox->setChecked(qbsStep()->isQmlDebuggingEnabled());
- m_ui->installDirChooser->setFileName(qbsStep()->installRoot(QbsBuildStep::PreserveVariables));
- m_ui->defaultInstallDirCheckBox->setChecked(!qbsStep()->hasCustomInstallRoot());
+ qmlDebuggingLibraryCheckBox->setChecked(qbsStep()->isQmlDebuggingEnabled());
+ installDirChooser->setFileName(qbsStep()->installRoot(QbsBuildStep::PreserveVariables));
+ defaultInstallDirCheckBox->setChecked(!qbsStep()->hasCustomInstallRoot());
}
updateQmlDebuggingOption();
const QString buildVariant = qbsStep()->buildVariant();
const int idx = (buildVariant == Constants::QBS_VARIANT_DEBUG) ? 0 : 1;
- m_ui->buildVariantComboBox->setCurrentIndex(idx);
+ buildVariantComboBox->setCurrentIndex(idx);
QString command = static_cast<QbsBuildConfiguration *>(step()->buildConfiguration())
->equivalentCommandLine(qbsStep());
@@ -613,7 +715,7 @@ void QbsBuildStepConfigWidget::updateState()
if (qbsStep()->isQmlDebuggingEnabled())
command.append(' ').append(Constants::QBS_CONFIG_QUICK_DEBUG_KEY).append(":true");
- m_ui->commandLineTextEdit->setPlainText(command);
+ commandLineTextEdit->setPlainText(command);
setSummaryText(tr("<b>Qbs:</b> %1").arg(command));
}
@@ -623,16 +725,15 @@ void QbsBuildStepConfigWidget::updateQmlDebuggingOption()
QString warningText;
bool supported = QtSupport::BaseQtVersion::isQmlDebuggingSupported(step()->target()->kit(),
&warningText);
- m_ui->qmlDebuggingLibraryCheckBox->setEnabled(supported);
+ qmlDebuggingLibraryCheckBox->setEnabled(supported);
if (supported && qbsStep()->isQmlDebuggingEnabled())
warningText = tr("Might make your application vulnerable. Only use in a safe environment.");
- m_ui->qmlDebuggingWarningText->setText(warningText);
- m_ui->qmlDebuggingWarningIcon->setVisible(!warningText.isEmpty());
+ qmlDebuggingWarningText->setText(warningText);
+ qmlDebuggingWarningIcon->setVisible(!warningText.isEmpty());
}
-
void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data)
{
QVariantMap editable = data;
@@ -649,7 +750,7 @@ void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data)
for (QVariantMap::const_iterator i = editable.constBegin(); i != editable.constEnd(); ++i)
propertyList.append(i.key() + ':' + i.value().toString());
- m_ui->propertyEdit->setText(Utils::QtcProcess::joinArgs(propertyList));
+ propertyEdit->setText(QtcProcess::joinArgs(propertyList));
}
void QbsBuildStepConfigWidget::changeBuildVariant(int idx)
@@ -703,11 +804,11 @@ void QbsBuildStepConfigWidget::changeUseDefaultInstallDir(bool useDefault)
{
m_ignoreChange = true;
QVariantMap config = qbsStep()->qbsConfiguration(QbsBuildStep::PreserveVariables);
- m_ui->installDirChooser->setEnabled(!useDefault);
+ installDirChooser->setEnabled(!useDefault);
if (useDefault)
config.remove(Constants::QBS_INSTALL_ROOT_KEY);
else
- config.insert(Constants::QBS_INSTALL_ROOT_KEY, m_ui->installDirChooser->rawPath());
+ config.insert(Constants::QBS_INSTALL_ROOT_KEY, installDirChooser->rawPath());
qbsStep()->setQbsConfiguration(config);
m_ignoreChange = false;
}
diff --git a/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui b/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui
deleted file mode 100644
index 562dcc3e85..0000000000
--- a/src/plugins/qbsprojectmanager/qbsbuildstepconfigwidget.ui
+++ /dev/null
@@ -1,319 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QbsProjectManager::Internal::QbsBuildStepConfigWidget</class>
- <widget class="QWidget" name="QbsProjectManager::Internal::QbsBuildStepConfigWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>809</width>
- <height>416</height>
- </rect>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="buildVariantLabel">
- <property name="text">
- <string>Build variant:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <widget class="QComboBox" name="buildVariantComboBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <item>
- <property name="text">
- <string>Debug</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Release</string>
- </property>
- </item>
- </widget>
- </item>
- <item>
- <spacer name="spacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>70</width>
- <height>13</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="jobsLabel">
- <property name="text">
- <string>Parallel jobs:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <widget class="QSpinBox" name="jobSpinBox">
- <property name="toolTip">
- <string>Number of concurrent build jobs.</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="qmlDebuggingLabel">
- <property name="text">
- <string>Enable QML debugging:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QCheckBox" name="qmlDebuggingLibraryCheckBox">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="qmlDebuggingWarningIcon"/>
- </item>
- <item>
- <widget class="QLabel" name="qmlDebuggingWarningText">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>5</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="propertyLabel">
- <property name="text">
- <string>Properties:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="Utils::FancyLineEdit" name="propertyEdit">
- <property name="toolTip">
- <string>Properties to pass to the project.</string>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="flagsLabel">
- <property name="text">
- <string>Flags:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QCheckBox" name="keepGoingCheckBox">
- <property name="toolTip">
- <string>Keep going when errors occur (if at all possible).</string>
- </property>
- <property name="text">
- <string>Keep going</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="showCommandLinesCheckBox">
- <property name="text">
- <string>Show command lines</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="forceProbesCheckBox">
- <property name="text">
- <string>Force probes</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="checkBoxSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>13</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="installFlagsLabel">
- <property name="text">
- <string>Installation flags:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QCheckBox" name="installCheckBox">
- <property name="text">
- <string>Install</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="cleanInstallRootCheckBox">
- <property name="text">
- <string>Clean install root</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="defaultInstallDirCheckBox">
- <property name="text">
- <string>Use default location</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="installDirLabel">
- <property name="text">
- <string>Installation directory:</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="Utils::PathChooser" name="installDirChooser"/>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="commandLineKeyLabel">
- <property name="text">
- <string>Equivalent command line:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- <item row="7" column="1">
- <widget class="QPlainTextEdit" name="commandLineTextEdit">
- <property name="undoRedoEnabled">
- <bool>false</bool>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="plainText">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- </layout>
- <zorder>buildVariantLabel</zorder>
- <zorder>qmlDebuggingLabel</zorder>
- <zorder>propertyLabel</zorder>
- <zorder>propertyEdit</zorder>
- <zorder>commandLineKeyLabel</zorder>
- <zorder>flagsLabel</zorder>
- <zorder>jobsLabel</zorder>
- <zorder>commandLineTextEdit</zorder>
- <zorder>installFlagsLabel</zorder>
- <zorder>defaultInstallDirCheckBox</zorder>
- <zorder>installDirChooser</zorder>
- <zorder>installDirLabel</zorder>
- </widget>
- <customwidgets>
- <customwidget>
- <class>Utils::FancyLineEdit</class>
- <extends>QLineEdit</extends>
- <header location="global">utils/fancylineedit.h</header>
- </customwidget>
- <customwidget>
- <class>Utils::PathChooser</class>
- <extends>QLineEdit</extends>
- <header location="global">utils/pathchooser.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>buildVariantComboBox</tabstop>
- <tabstop>jobSpinBox</tabstop>
- <tabstop>qmlDebuggingLibraryCheckBox</tabstop>
- <tabstop>propertyEdit</tabstop>
- <tabstop>keepGoingCheckBox</tabstop>
- <tabstop>showCommandLinesCheckBox</tabstop>
- <tabstop>forceProbesCheckBox</tabstop>
- <tabstop>installCheckBox</tabstop>
- <tabstop>cleanInstallRootCheckBox</tabstop>
- <tabstop>commandLineTextEdit</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/qbsprojectmanager/qbscleanstep.cpp b/src/plugins/qbsprojectmanager/qbscleanstep.cpp
index 167299a0bb..7b64b888ce 100644
--- a/src/plugins/qbsprojectmanager/qbscleanstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbscleanstep.cpp
@@ -58,18 +58,16 @@ QbsCleanStep::QbsCleanStep(ProjectExplorer::BuildStepList *bsl) :
m_keepGoingAspect->setSettingsKey("Qbs.DryKeepGoing");
m_keepGoingAspect->setLabel(tr("Keep going"));
- m_effectiveCommandAspect = addAspect<BaseStringAspect>();
- m_effectiveCommandAspect->setDisplayStyle(BaseStringAspect::TextEditDisplay);
- m_effectiveCommandAspect->setLabelText(tr("Equivalent command line:"));
-
- updateState();
-
- connect(this, &ProjectExplorer::ProjectConfiguration::displayNameChanged,
- this, &QbsCleanStep::updateState);
- connect(m_dryRunAspect, &BaseBoolAspect::changed,
- this, &QbsCleanStep::updateState);
- connect(m_keepGoingAspect, &BaseBoolAspect::changed,
- this, &QbsCleanStep::updateState);
+ auto effectiveCommandAspect = addAspect<BaseStringAspect>();
+ effectiveCommandAspect->setDisplayStyle(BaseStringAspect::TextEditDisplay);
+ effectiveCommandAspect->setLabelText(tr("Equivalent command line:"));
+
+ setSummaryUpdater([this, effectiveCommandAspect] {
+ QString command = static_cast<QbsBuildConfiguration *>(buildConfiguration())
+ ->equivalentCommandLine(this);
+ effectiveCommandAspect->setValue(command);
+ return tr("<b>Qbs:</b> %1").arg(command);
+ });
}
QbsCleanStep::~QbsCleanStep()
@@ -119,15 +117,6 @@ void QbsCleanStep::doRun()
this, &QbsCleanStep::handleProgress);
}
-ProjectExplorer::BuildStepConfigWidget *QbsCleanStep::createConfigWidget()
-{
- auto w = BuildStep::createConfigWidget();
- connect(this, &QbsCleanStep::stateChanged, w, [this, w] {
- w->setSummaryText(tr("<b>Qbs:</b> %1").arg(m_effectiveCommandAspect->value()));
- });
- return w;
-}
-
void QbsCleanStep::doCancel()
{
if (m_job)
@@ -149,7 +138,7 @@ void QbsCleanStep::cleaningDone(bool success)
void QbsCleanStep::handleTaskStarted(const QString &desciption, int max)
{
- Q_UNUSED(desciption);
+ Q_UNUSED(desciption)
m_maxProgress = max;
}
@@ -159,14 +148,6 @@ void QbsCleanStep::handleProgress(int value)
emit progress(value * 100 / m_maxProgress, m_description);
}
-void QbsCleanStep::updateState()
-{
- QString command = static_cast<QbsBuildConfiguration *>(buildConfiguration())
- ->equivalentCommandLine(this);
- m_effectiveCommandAspect->setValue(command);
- emit stateChanged();
-}
-
void QbsCleanStep::createTaskAndOutput(ProjectExplorer::Task::TaskType type, const QString &message, const QString &file, int line)
{
ProjectExplorer::Task task = ProjectExplorer::Task(type, message,
diff --git a/src/plugins/qbsprojectmanager/qbscleanstep.h b/src/plugins/qbsprojectmanager/qbscleanstep.h
index bfac0d2b68..fa07d35292 100644
--- a/src/plugins/qbsprojectmanager/qbscleanstep.h
+++ b/src/plugins/qbsprojectmanager/qbscleanstep.h
@@ -47,26 +47,20 @@ public:
bool dryRun() const { return m_dryRunAspect->value(); }
bool keepGoing() const { return m_keepGoingAspect->value(); }
-signals:
- void stateChanged();
-
private:
bool init() override;
void doRun() override;
void doCancel() override;
- ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
void cleaningDone(bool success);
void handleTaskStarted(const QString &desciption, int max);
void handleProgress(int value);
- void updateState();
void createTaskAndOutput(ProjectExplorer::Task::TaskType type,
const QString &message, const QString &file, int line);
ProjectExplorer::BaseBoolAspect *m_dryRunAspect = nullptr;
ProjectExplorer::BaseBoolAspect *m_keepGoingAspect = nullptr;
- ProjectExplorer::BaseStringAspect *m_effectiveCommandAspect = nullptr;
QStringList m_products;
diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
index ddfaadf8df..d0ea258853 100644
--- a/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
+++ b/src/plugins/qbsprojectmanager/qbsinstallstep.cpp
@@ -30,8 +30,6 @@
#include "qbsproject.h"
#include "qbsprojectmanagerconstants.h"
-#include "ui_qbsinstallstepconfigwidget.h"
-
#include <coreplugin/icore.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/deployconfiguration.h>
@@ -40,7 +38,14 @@
#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
+#include <QCheckBox>
#include <QFileInfo>
+#include <QFormLayout>
+#include <QLabel>
+#include <QPlainTextEdit>
+#include <QSpacerItem>
+
+using namespace ProjectExplorer;
// --------------------------------------------------------------------
// Constants:
@@ -53,6 +58,29 @@ static const char QBS_KEEP_GOING[] = "Qbs.DryKeepGoing";
namespace QbsProjectManager {
namespace Internal {
+class QbsInstallStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+public:
+ QbsInstallStepConfigWidget(QbsInstallStep *step);
+
+private:
+ void updateState();
+
+ void changeRemoveFirst(bool rf) { m_step->setRemoveFirst(rf); }
+ void changeDryRun(bool dr) { m_step->setDryRun(dr); }
+ void changeKeepGoing(bool kg) { m_step->setKeepGoing(kg); }
+
+private:
+ QbsInstallStep *m_step;
+ bool m_ignoreChange;
+
+ QCheckBox *m_dryRunCheckBox;
+ QCheckBox *m_keepGoingCheckBox;
+ QCheckBox *m_removeFirstCheckBox;
+ QPlainTextEdit *m_commandLineTextEdit;
+ QLabel *m_installRootValueLabel;
+};
+
// --------------------------------------------------------------------
// QbsInstallStep:
// --------------------------------------------------------------------
@@ -248,60 +276,88 @@ QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) :
setContentsMargins(0, 0, 0, 0);
- auto project = static_cast<QbsProject *>(m_step->project());
-
- m_ui = new Ui::QbsInstallStepConfigWidget;
- m_ui->setupUi(this);
-
- connect(m_ui->removeFirstCheckBox, &QAbstractButton::toggled,
+ auto installRootLabel = new QLabel(this);
+
+ auto flagsLabel = new QLabel(this);
+
+ m_dryRunCheckBox = new QCheckBox(this);
+ m_keepGoingCheckBox = new QCheckBox(this);
+ m_removeFirstCheckBox = new QCheckBox(this);
+
+ auto horizontalLayout = new QHBoxLayout();
+ horizontalLayout->addWidget(m_dryRunCheckBox);
+ horizontalLayout->addWidget(m_keepGoingCheckBox);
+ horizontalLayout->addWidget(m_removeFirstCheckBox);
+ horizontalLayout->addStretch(1);
+
+ auto commandLineKeyLabel = new QLabel(this);
+ QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(commandLineKeyLabel->sizePolicy().hasHeightForWidth());
+ commandLineKeyLabel->setSizePolicy(sizePolicy);
+ commandLineKeyLabel->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop);
+
+ m_commandLineTextEdit = new QPlainTextEdit(this);
+ QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ sizePolicy1.setHorizontalStretch(0);
+ sizePolicy1.setVerticalStretch(0);
+ sizePolicy1.setHeightForWidth(m_commandLineTextEdit->sizePolicy().hasHeightForWidth());
+ m_commandLineTextEdit->setSizePolicy(sizePolicy1);
+ m_commandLineTextEdit->setReadOnly(true);
+ m_commandLineTextEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse);
+
+ m_installRootValueLabel = new QLabel(this);
+
+ auto formLayout = new QFormLayout(this);
+ formLayout->setWidget(0, QFormLayout::LabelRole, installRootLabel);
+ formLayout->setWidget(0, QFormLayout::FieldRole, m_installRootValueLabel);
+ formLayout->setWidget(1, QFormLayout::LabelRole, flagsLabel);
+ formLayout->setLayout(1, QFormLayout::FieldRole, horizontalLayout);
+ formLayout->setWidget(2, QFormLayout::LabelRole, commandLineKeyLabel);
+ formLayout->setWidget(2, QFormLayout::FieldRole, m_commandLineTextEdit);
+
+ QWidget::setTabOrder(m_dryRunCheckBox, m_keepGoingCheckBox);
+ QWidget::setTabOrder(m_keepGoingCheckBox, m_removeFirstCheckBox);
+ QWidget::setTabOrder(m_removeFirstCheckBox, m_commandLineTextEdit);
+
+ installRootLabel->setText(QbsInstallStep::tr("Install root:"));
+ flagsLabel->setText(QbsInstallStep::tr("Flags:"));
+ m_dryRunCheckBox->setText(QbsInstallStep::tr("Dry run"));
+ m_keepGoingCheckBox->setText(QbsInstallStep::tr("Keep going"));
+ m_removeFirstCheckBox->setText(QbsInstallStep::tr("Remove first"));
+ commandLineKeyLabel->setText(QbsInstallStep::tr("Equivalent command line:"));
+ m_installRootValueLabel->setText(QString());
+
+ connect(m_removeFirstCheckBox, &QAbstractButton::toggled,
this, &QbsInstallStepConfigWidget::changeRemoveFirst);
- connect(m_ui->dryRunCheckBox, &QAbstractButton::toggled,
+ connect(m_dryRunCheckBox, &QAbstractButton::toggled,
this, &QbsInstallStepConfigWidget::changeDryRun);
- connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled,
+ connect(m_keepGoingCheckBox, &QAbstractButton::toggled,
this, &QbsInstallStepConfigWidget::changeKeepGoing);
- connect(project, &ProjectExplorer::Project::parsingFinished,
+ connect(m_step->project(), &Project::parsingFinished,
this, &QbsInstallStepConfigWidget::updateState);
updateState();
}
-QbsInstallStepConfigWidget::~QbsInstallStepConfigWidget()
-{
- delete m_ui;
-}
-
void QbsInstallStepConfigWidget::updateState()
{
if (!m_ignoreChange) {
- m_ui->installRootValueLabel->setText(m_step->installRoot());
- m_ui->removeFirstCheckBox->setChecked(m_step->removeFirst());
- m_ui->dryRunCheckBox->setChecked(m_step->dryRun());
- m_ui->keepGoingCheckBox->setChecked(m_step->keepGoing());
+ m_installRootValueLabel->setText(m_step->installRoot());
+ m_removeFirstCheckBox->setChecked(m_step->removeFirst());
+ m_dryRunCheckBox->setChecked(m_step->dryRun());
+ m_keepGoingCheckBox->setChecked(m_step->keepGoing());
}
QString command = m_step->buildConfig()->equivalentCommandLine(m_step);
- m_ui->commandLineTextEdit->setPlainText(command);
+ m_commandLineTextEdit->setPlainText(command);
setSummaryText(tr("<b>Qbs:</b> %1").arg(command));
}
-void QbsInstallStepConfigWidget::changeRemoveFirst(bool rf)
-{
- m_step->setRemoveFirst(rf);
-}
-
-void QbsInstallStepConfigWidget::changeDryRun(bool dr)
-{
- m_step->setDryRun(dr);
-}
-
-void QbsInstallStepConfigWidget::changeKeepGoing(bool kg)
-{
- m_step->setKeepGoing(kg);
-}
-
// --------------------------------------------------------------------
// QbsInstallStepFactory:
// --------------------------------------------------------------------
diff --git a/src/plugins/qbsprojectmanager/qbsinstallstep.h b/src/plugins/qbsprojectmanager/qbsinstallstep.h
index 6b5c62eb73..5f58d006a3 100644
--- a/src/plugins/qbsprojectmanager/qbsinstallstep.h
+++ b/src/plugins/qbsprojectmanager/qbsinstallstep.h
@@ -35,8 +35,6 @@
namespace QbsProjectManager {
namespace Internal {
-class QbsInstallStepConfigWidget;
-
class QbsInstallStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
@@ -86,29 +84,6 @@ private:
friend class QbsInstallStepConfigWidget;
};
-namespace Ui { class QbsInstallStepConfigWidget; }
-
-class QbsInstallStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget
-{
- Q_OBJECT
-public:
- QbsInstallStepConfigWidget(QbsInstallStep *step);
- ~QbsInstallStepConfigWidget() override;
-
-private:
- void updateState();
-
- void changeRemoveFirst(bool rf);
- void changeDryRun(bool dr);
- void changeKeepGoing(bool kg);
-
-private:
- Ui::QbsInstallStepConfigWidget *m_ui;
-
- QbsInstallStep *m_step;
- bool m_ignoreChange;
-};
-
class QbsInstallStepFactory : public ProjectExplorer::BuildStepFactory
{
public:
diff --git a/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui b/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui
deleted file mode 100644
index 69c5102203..0000000000
--- a/src/plugins/qbsprojectmanager/qbsinstallstepconfigwidget.ui
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QbsProjectManager::Internal::QbsInstallStepConfigWidget</class>
- <widget class="QWidget" name="QbsProjectManager::Internal::QbsInstallStepConfigWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>474</width>
- <height>146</height>
- </rect>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="installRootLabel">
- <property name="text">
- <string>Install root:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="flagsLabel">
- <property name="text">
- <string>Flags:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QCheckBox" name="dryRunCheckBox">
- <property name="text">
- <string>Dry run</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="keepGoingCheckBox">
- <property name="text">
- <string>Keep going</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="removeFirstCheckBox">
- <property name="text">
- <string>Remove first</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="commandLineKeyLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Equivalent command line:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QPlainTextEdit" name="commandLineTextEdit">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="plainText">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="installRootValueLabel">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>dryRunCheckBox</tabstop>
- <tabstop>keepGoingCheckBox</tabstop>
- <tabstop>removeFirstCheckBox</tabstop>
- <tabstop>commandLineTextEdit</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/qbsprojectmanager/qbslogsink.cpp b/src/plugins/qbsprojectmanager/qbslogsink.cpp
index 9e635c2958..d73f844052 100644
--- a/src/plugins/qbsprojectmanager/qbslogsink.cpp
+++ b/src/plugins/qbsprojectmanager/qbslogsink.cpp
@@ -77,7 +77,7 @@ void QbsLogSink::doPrintWarning(const qbs::ErrorInfo &warning)
void QbsLogSink::doPrintMessage(qbs::LoggerLevel level, const QString &message, const QString &tag)
{
- Q_UNUSED(tag);
+ Q_UNUSED(tag)
{
QMutexLocker l(&m_mutex);
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp
index 62762069b2..719897ec78 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp
@@ -28,7 +28,7 @@
#include "qbsnodetreebuilder.h"
#include "qbsproject.h"
#include "qbsprojectmanagerconstants.h"
-#include "qbsrunconfiguration.h"
+#include "qbsprojectmanagerplugin.h"
#include <android/androidconstants.h>
#include <coreplugin/fileiconprovider.h>
@@ -266,7 +266,8 @@ bool QbsGroupNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
m_qbsGroupData, notAdded);
}
-bool QbsGroupNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject QbsGroupNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
QStringList notRemovedDummy;
if (!notRemoved)
@@ -275,13 +276,13 @@ bool QbsGroupNode::removeFiles(const QStringList &filePaths, QStringList *notRem
const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid()) {
*notRemoved += filePaths;
- return false;
+ return RemovedFilesFromProject::Error;
}
const QbsProductNode *prdNode = parentQbsProductNode(this);
if (!prdNode || !prdNode->qbsProductData().isValid()) {
*notRemoved += filePaths;
- return false;
+ return RemovedFilesFromProject::Error;
}
return prjNode->project()->removeFilesFromProduct(filePaths, prdNode->qbsProductData(),
@@ -310,6 +311,13 @@ FolderNode::AddNewInformation QbsGroupNode::addNewInformation(const QStringList
return info;
}
+QVariant QbsGroupNode::data(Core::Id role) const
+{
+ if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED)
+ return m_qbsGroupData.properties().getModuleProperty("Qt.core", "enableKeywords");
+ return QVariant();
+}
+
// --------------------------------------------------------------------
// QbsProductNode:
// --------------------------------------------------------------------
@@ -351,7 +359,8 @@ bool QbsProductNode::addFiles(const QStringList &filePaths, QStringList *notAdde
QTC_ASSERT(false, return false);
}
-bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject QbsProductNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
QStringList notRemovedDummy;
if (!notRemoved)
@@ -360,7 +369,7 @@ bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notR
const QbsProjectNode *prjNode = parentQbsProjectNode(this);
if (!prjNode || !prjNode->qbsProject().isValid()) {
*notRemoved += filePaths;
- return false;
+ return RemovedFilesFromProject::Error;
}
qbs::GroupData grp = findMainQbsGroup(m_qbsProductData);
@@ -369,7 +378,7 @@ bool QbsProductNode::removeFiles(const QStringList &filePaths, QStringList *notR
notRemoved);
}
- QTC_ASSERT(false, return false);
+ QTC_ASSERT(false, return RemovedFilesFromProject::Error);
}
bool QbsProductNode::renameFile(const QString &filePath, const QString &newFilePath)
@@ -382,6 +391,12 @@ bool QbsProductNode::renameFile(const QString &filePath, const QString &newFileP
return prjNode->project()->renameFileInProduct(filePath, newFilePath, m_qbsProductData, grp);
}
+void QbsProductNode::build()
+{
+ QbsProjectManagerPlugin::buildNamedProduct(static_cast<QbsProject *>(getProject()),
+ QbsProject::uniqueProductName(qbsProductData()));
+}
+
QStringList QbsProductNode::targetApplications() const
{
return QStringList{m_qbsProductData.targetExecutable()};
@@ -424,6 +439,9 @@ QVariant QbsProductNode::data(Core::Id role) const
if (role == Android::Constants::AndroidApk)
return m_qbsProductData.targetExecutable();
+ if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED)
+ return m_qbsProductData.moduleProperties().getModuleProperty("Qt.core", "enableKeywords");
+
return {};
}
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h
index 3d8f90c3df..e31fc2b9b9 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.h
+++ b/src/plugins/qbsprojectmanager/qbsnodes.h
@@ -47,11 +47,13 @@ public:
bool showInSimpleTree() const final { return false; }
bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
private:
AddNewInformation addNewInformation(const QStringList &files, Node *context) const override;
+ QVariant data(Core::Id role) const override;
qbs::GroupData m_qbsGroupData;
QString m_productPath;
@@ -68,8 +70,10 @@ public:
bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const final;
bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
+ void build() override;
QStringList targetApplications() const override;
QString buildKey() const override;
diff --git a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
index f7f143b025..f7bbde2a13 100644
--- a/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodetreebuilder.cpp
@@ -82,7 +82,7 @@ void setupArtifacts(FolderNode *root, const QList<qbs::ArtifactData> &artifacts)
};
auto node = std::make_unique<FileNode>(path, type);
node->setIsGenerated(isGenerated);
- node->setListInProject(!isGenerated || ad.fileTags().toSet().intersects(sourceTags));
+ node->setListInProject(!isGenerated || Utils::toSet(ad.fileTags()).intersects(sourceTags));
root->addNestedNode(std::move(node));
}
root->compress();
@@ -194,7 +194,7 @@ QStringList unreferencedBuildSystemFiles(const qbs::Project &p)
return result;
const std::set<QString> &available = p.buildSystemFiles();
- QList<QString> referenced = referencedBuildSystemFiles(p.projectData()).toList();
+ QList<QString> referenced = Utils::toList(referencedBuildSystemFiles(p.projectData()));
Utils::sort(referenced);
std::set_difference(available.begin(), available.end(), referenced.begin(), referenced.end(),
std::back_inserter(result));
diff --git a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp
index 5a79d42062..3f3fe351ce 100644
--- a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.cpp
@@ -52,7 +52,7 @@ class QbsProfilesSettingsWidget : public QWidget
{
Q_OBJECT
public:
- QbsProfilesSettingsWidget(QWidget *parent = nullptr);
+ QbsProfilesSettingsWidget();
void apply();
@@ -64,10 +64,8 @@ private:
qbs::SettingsModel m_model;
};
-QbsProfilesSettingsPage::QbsProfilesSettingsPage(QObject *parent)
- : Core::IOptionsPage(parent)
- , m_useQtcSettingsDirPersistent(QbsProjectManagerSettings::useCreatorSettingsDirForQbs())
-
+QbsProfilesSettingsPage::QbsProfilesSettingsPage()
+ : m_useQtcSettingsDirPersistent(QbsProjectManagerSettings::useCreatorSettingsDirForQbs())
{
setId("Y.QbsProfiles");
setDisplayName(QCoreApplication::translate("QbsProjectManager", "Qbs"));
@@ -97,9 +95,8 @@ void QbsProfilesSettingsPage::finish()
}
-QbsProfilesSettingsWidget::QbsProfilesSettingsWidget(QWidget *parent)
- : QWidget(parent)
- , m_model(QbsProjectManagerSettings::qbsSettingsBaseDir(), qbs::Settings::UserScope)
+QbsProfilesSettingsWidget::QbsProfilesSettingsWidget()
+ : m_model(QbsProjectManagerSettings::qbsSettingsBaseDir(), qbs::Settings::UserScope)
{
m_model.setEditable(false);
m_ui.setupUi(this);
diff --git a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h
index f146b92c72..6227c6f999 100644
--- a/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h
+++ b/src/plugins/qbsprojectmanager/qbsprofilessettingspage.h
@@ -34,7 +34,7 @@ class QbsProfilesSettingsWidget;
class QbsProfilesSettingsPage : public Core::IOptionsPage
{
public:
- QbsProfilesSettingsPage(QObject *parent = nullptr);
+ QbsProfilesSettingsPage();
private:
QWidget *widget() override;
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index 209e87b4bc..341a58d8f8 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -37,20 +37,23 @@
#include <coreplugin/documentmanager.h>
#include <coreplugin/icontext.h>
-#include <coreplugin/id.h>
#include <coreplugin/icore.h>
+#include <coreplugin/id.h>
#include <coreplugin/iversioncontrol.h>
-#include <coreplugin/vcsmanager.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
+#include <coreplugin/vcsmanager.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojectupdater.h>
+#include <cpptools/cpptoolsconstants.h>
+#include <cpptools/generatedcodemodelsupport.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/buildenvironmentwidget.h>
#include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h>
+#include <projectexplorer/headerpath.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h>
@@ -58,14 +61,13 @@
#include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h>
#include <projectexplorer/toolchain.h>
-#include <projectexplorer/headerpath.h>
-#include <qtsupport/qtcppkitinfo.h>
-#include <qtsupport/qtkitinformation.h>
-#include <cpptools/generatedcodemodelsupport.h>
-#include <qmljstools/qmljsmodelmanager.h>
-#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
+#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <qmljstools/qmljsmodelmanager.h>
+#include <qtsupport/qtcppkitinfo.h>
+#include <qtsupport/qtkitinformation.h>
#include <qbs.h>
@@ -121,14 +123,15 @@ private:
// QbsProject:
// --------------------------------------------------------------------
-QbsProject::QbsProject(const FilePath &fileName) :
- Project(Constants::MIME_TYPE, fileName, [this] { delayParsing(); }),
- m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
+QbsProject::QbsProject(const FilePath &fileName)
+ : Project(Constants::MIME_TYPE, fileName)
+ , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{
m_parsingDelay.setInterval(1000); // delay parsing by 1s.
setId(Constants::PROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
+ setCanBuildProducts();
rebuildProjectTree();
@@ -145,16 +148,13 @@ QbsProject::QbsProject(const FilePath &fileName) :
}
m_qbsProjects.erase(it);
});
- auto delayedParsing = [this]() {
- if (static_cast<ProjectConfiguration *>(sender())->isActive())
- delayParsing();
- };
- subscribeSignal(&BuildConfiguration::environmentChanged, this, delayedParsing);
- subscribeSignal(&BuildConfiguration::buildDirectoryChanged, this, delayedParsing);
- subscribeSignal(&QbsBuildConfiguration::qbsConfigurationChanged, this, delayedParsing);
- subscribeSignal(&Target::activeBuildConfigurationChanged, this, delayedParsing);
+
+ connect(this, &Project::activeBuildConfigurationChanged,
+ this, &QbsProject::delayParsing);
connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing);
+
+ connect(this, &QbsProject::projectFileIsDirty, this, &QbsProject::delayParsing);
}
QbsProject::~QbsProject()
@@ -169,8 +169,6 @@ QbsProject::~QbsProject()
m_qbsUpdateFutureInterface = nullptr;
}
qDeleteAll(m_extraCompilers);
- std::for_each(m_qbsDocuments.cbegin(), m_qbsDocuments.cend(),
- [](Core::IDocument *doc) { doc->deleteLater(); });
}
void QbsProject::projectLoaded()
@@ -219,36 +217,6 @@ bool QbsProject::isProjectEditable() const
return m_qbsProject.isValid() && !isParsing() && !BuildManager::isBuilding();
}
-class ChangeExpector
-{
-public:
- ChangeExpector(const QString &filePath, const QSet<IDocument *> &documents)
- : m_document(nullptr)
- {
- foreach (IDocument * const doc, documents) {
- if (doc->filePath().toString() == filePath) {
- m_document = doc;
- break;
- }
- }
- QTC_ASSERT(m_document, return);
- DocumentManager::expectFileChange(filePath);
- m_wasInDocumentManager = DocumentManager::removeDocument(m_document);
- QTC_CHECK(m_wasInDocumentManager);
- }
-
- ~ChangeExpector()
- {
- QTC_ASSERT(m_document, return);
- DocumentManager::addDocument(m_document);
- DocumentManager::unexpectFileChange(m_document->filePath().toString());
- }
-
-private:
- IDocument *m_document;
- bool m_wasInDocumentManager;
-};
-
bool QbsProject::ensureWriteableQbsFile(const QString &file)
{
// Ensure that the file is not read only
@@ -277,7 +245,7 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths,
QTC_ASSERT(m_qbsProject.isValid(), return false);
QStringList allPaths = groupData.allFilePaths();
const QString productFilePath = productData.location().filePath();
- ChangeExpector expector(productFilePath, m_qbsDocuments);
+ Core::FileChangeBlocker expector(productFilePath);
ensureWriteableQbsFile(productFilePath);
foreach (const QString &path, filePaths) {
qbs::ErrorInfo err = m_qbsProject.addFiles(productData, groupData, QStringList() << path);
@@ -295,31 +263,50 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths,
return notAdded->isEmpty();
}
-bool QbsProject::removeFilesFromProduct(const QStringList &filePaths,
- const qbs::ProductData productData,
- const qbs::GroupData groupData,
- QStringList *notRemoved)
+RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &filePaths,
+ const qbs::ProductData &productData,
+ const qbs::GroupData &groupData,
+ QStringList *notRemoved)
{
- QTC_ASSERT(m_qbsProject.isValid(), return false);
- QStringList allPaths = groupData.allFilePaths();
+ QTC_ASSERT(m_qbsProject.isValid(), return RemovedFilesFromProject::Error);
+
+ const QList<qbs::ArtifactData> allWildcardsInGroup = groupData.sourceArtifactsFromWildcards();
+ QStringList wildcardFiles;
+ QStringList nonWildcardFiles;
+ for (const QString &filePath : filePaths) {
+ if (contains(allWildcardsInGroup, [filePath](const qbs::ArtifactData &artifact) {
+ return artifact.filePath() == filePath; })) {
+ wildcardFiles << filePath;
+ } else {
+ nonWildcardFiles << filePath;
+ }
+ }
const QString productFilePath = productData.location().filePath();
- ChangeExpector expector(productFilePath, m_qbsDocuments);
+ Core::FileChangeBlocker expector(productFilePath);
ensureWriteableQbsFile(productFilePath);
- foreach (const QString &path, filePaths) {
- qbs::ErrorInfo err
- = m_qbsProject.removeFiles(productData, groupData, QStringList() << path);
+ for (const QString &path : qAsConst(nonWildcardFiles)) {
+ const qbs::ErrorInfo err = m_qbsProject.removeFiles(productData, groupData, {path});
if (err.hasError()) {
MessageManager::write(err.toString());
*notRemoved += path;
- } else {
- allPaths.removeOne(path);
}
}
+
if (notRemoved->count() != filePaths.count()) {
m_projectData = m_qbsProject.projectData();
delayedUpdateAfterParse();
}
- return notRemoved->isEmpty();
+
+ const bool success = notRemoved->isEmpty();
+ if (!wildcardFiles.isEmpty()) {
+ *notRemoved += wildcardFiles;
+ delayParsing();
+ }
+ if (!success)
+ return RemovedFilesFromProject::Error;
+ if (!wildcardFiles.isEmpty())
+ return RemovedFilesFromProject::Wildcard;
+ return RemovedFilesFromProject::Ok;
}
bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newPath,
@@ -329,8 +316,10 @@ bool QbsProject::renameFileInProduct(const QString &oldPath, const QString &newP
if (newPath.isEmpty())
return false;
QStringList dummy;
- if (!removeFilesFromProduct(QStringList(oldPath), productData, groupData, &dummy))
+ if (removeFilesFromProduct(QStringList(oldPath), productData, groupData, &dummy)
+ != RemovedFilesFromProject::Ok) {
return false;
+ }
qbs::ProductData newProductData;
foreach (const qbs::ProductData &p, m_projectData.allProducts()) {
if (uniqueProductName(p) == uniqueProductName(productData)) {
@@ -422,11 +411,6 @@ QString QbsProject::profileForTarget(const Target *t) const
return QbsManager::profileForKit(t->kit());
}
-bool QbsProject::hasParseResult() const
-{
- return qbsProject().isValid();
-}
-
qbs::Project QbsProject::qbsProject() const
{
return m_qbsProject;
@@ -446,25 +430,17 @@ bool QbsProject::checkCancelStatus()
qCDebug(qbsPmLog) << "Cancel request while parsing, starting re-parse";
m_qbsProjectParser->deleteLater();
m_qbsProjectParser = nullptr;
- emitParsingFinished(false);
+ m_guard = {};
parseCurrentBuildConfiguration();
return true;
}
-static QSet<QString> toQStringSet(const std::set<QString> &src)
-{
- QSet<QString> result;
- result.reserve(int(src.size()));
- std::copy(src.begin(), src.end(), Utils::inserter(result));
- return result;
-}
-
void QbsProject::updateAfterParse()
{
qCDebug(qbsPmLog) << "Updating data after parse";
OpTimer opTimer("updateAfterParse");
updateProjectNodes();
- updateDocuments(toQStringSet(m_qbsProject.buildSystemFiles()));
+ updateDocuments(m_qbsProject.buildSystemFiles());
updateBuildTargetData();
updateCppCodeModel();
updateQmlJsCodeModel();
@@ -511,6 +487,8 @@ void QbsProject::handleQbsParsingDone(bool success)
m_qbsProject = m_qbsProjectParser->qbsProject();
m_qbsProjects.insert(activeTarget(), m_qbsProject);
bool dataChanged = false;
+ bool envChanged = m_lastParseEnv != m_qbsProjectParser->environment();
+ m_lastParseEnv = m_qbsProjectParser->environment();
if (success) {
QTC_ASSERT(m_qbsProject.isValid(), return);
const qbs::ProjectData &projectData = m_qbsProject.projectData();
@@ -530,7 +508,10 @@ void QbsProject::handleQbsParsingDone(bool success)
if (dataChanged)
updateAfterParse();
- emitParsingFinished(success);
+ else if (envChanged)
+ updateCppCodeModel();
+ m_guard.markAsSuccess();
+ m_guard = {};
}
void QbsProject::rebuildProjectTree()
@@ -691,20 +672,15 @@ QString QbsProject::uniqueProductName(const qbs::ProductData &product)
return product.name() + QLatin1Char('.') + product.multiplexConfigurationId();
}
-void QbsProject::configureAsExampleProject(const QSet<Id> &platforms)
+void QbsProject::configureAsExampleProject()
{
QList<BuildInfo> infoList;
- QList<Kit *> kits = KitManager::kits();
- const auto qtVersionMatchesPlatform = [platforms](const QtSupport::BaseQtVersion *version) {
- return platforms.isEmpty() || platforms.intersects(version->targetDeviceTypes());
- };
- foreach (Kit *k, kits) {
- const QtSupport::BaseQtVersion * const qtVersion
- = QtSupport::QtKitAspect::qtVersion(k);
- if (!qtVersion || !qtVersionMatchesPlatform(qtVersion))
- continue;
- if (auto factory = BuildConfigurationFactory::find(k, projectFilePath().toString()))
- infoList << factory->allAvailableSetups(k, projectFilePath().toString());
+ const QList<Kit *> kits = KitManager::kits();
+ for (Kit *k : kits) {
+ if (QtSupport::QtKitAspect::qtVersion(k) != nullptr) {
+ if (auto factory = BuildConfigurationFactory::find(k, projectFilePath()))
+ infoList << factory->allAvailableSetups(k, projectFilePath());
+ }
}
setup(infoList);
prepareForParsing();
@@ -713,6 +689,8 @@ void QbsProject::configureAsExampleProject(const QSet<Id> &platforms)
void QbsProject::parse(const QVariantMap &config, const Environment &env, const QString &dir,
const QString &configName)
{
+ m_guard = guardParsingRun();
+
prepareForParsing();
QTC_ASSERT(!m_qbsProjectParser, return);
@@ -720,7 +698,6 @@ void QbsProject::parse(const QVariantMap &config, const Environment &env, const
QbsManager::updateProfileIfNecessary(activeTarget()->kit());
m_qbsProjectParser->parse(config, env, dir, configName);
- emitParsingStarted();
}
void QbsProject::prepareForParsing()
@@ -740,58 +717,37 @@ void QbsProject::prepareForParsing()
m_qbsUpdateFutureInterface->reportStarted();
}
-void QbsProject::updateDocuments(const QSet<QString> &files)
+void QbsProject::updateDocuments(const std::set<QString> &files)
{
OpTimer opTimer("updateDocuments");
- // Update documents:
- QSet<QString> newFiles = files;
- QTC_ASSERT(!newFiles.isEmpty(), newFiles << projectFilePath().toString());
- QSet<QString> oldFiles;
- foreach (IDocument *doc, m_qbsDocuments)
- oldFiles.insert(doc->filePath().toString());
-
- QSet<QString> filesToAdd = newFiles;
- filesToAdd.subtract(oldFiles);
- QSet<QString> filesToRemove = oldFiles;
- filesToRemove.subtract(newFiles);
-
- QSet<IDocument *> currentDocuments = m_qbsDocuments;
- foreach (IDocument *doc, currentDocuments) {
- if (filesToRemove.contains(doc->filePath().toString())) {
- m_qbsDocuments.remove(doc);
- doc->deleteLater();
- }
- }
- QSet<IDocument *> toAdd;
+
+ const QVector<FilePath> filePaths = transform<QVector>(files, &FilePath::fromString);
+
const FilePath buildDir = FilePath::fromString(m_projectData.buildDirectory());
- for (const QString &f : qAsConst(filesToAdd)) {
- // A changed qbs file (project, module etc) should trigger a re-parse, but not if
- // the file was generated by qbs itself, in which case that might cause an infinite loop.
- const FilePath fp = FilePath::fromString(f);
- static const ProjectDocument::ProjectCallback noOpCallback = []{};
- const ProjectDocument::ProjectCallback reparseCallback = [this]() { delayParsing(); };
- toAdd.insert(new ProjectDocument(Constants::MIME_TYPE, fp, fp.isChildOf(buildDir)
- ? noOpCallback : reparseCallback));
- }
- m_qbsDocuments.unite(toAdd);
+ const QVector<FilePath> nonBuildDirFilePaths = filtered(filePaths,
+ [buildDir](const FilePath &p) {
+ return p.isChildOf(buildDir);
+ });
+
+ setExtraProjectFiles(nonBuildDirFilePaths);
}
-static CppTools::ProjectFile::Kind cppFileType(const qbs::ArtifactData &sourceFile)
+static QString getMimeType(const qbs::ArtifactData &sourceFile)
{
- if (sourceFile.fileTags().contains(QLatin1String("hpp"))) {
+ if (sourceFile.fileTags().contains("hpp")) {
if (CppTools::ProjectFile::isAmbiguousHeader(sourceFile.filePath()))
- return CppTools::ProjectFile::AmbiguousHeader;
- return CppTools::ProjectFile::CXXHeader;
+ return QString(CppTools::Constants::AMBIGUOUS_HEADER_MIMETYPE);
+ return QString(CppTools::Constants::CPP_HEADER_MIMETYPE);
}
- if (sourceFile.fileTags().contains(QLatin1String("cpp")))
- return CppTools::ProjectFile::CXXSource;
- if (sourceFile.fileTags().contains(QLatin1String("c")))
- return CppTools::ProjectFile::CSource;
- if (sourceFile.fileTags().contains(QLatin1String("objc")))
- return CppTools::ProjectFile::ObjCSource;
- if (sourceFile.fileTags().contains(QLatin1String("objcpp")))
- return CppTools::ProjectFile::ObjCXXSource;
- return CppTools::ProjectFile::Unsupported;
+ if (sourceFile.fileTags().contains("cpp"))
+ return QString(CppTools::Constants::CPP_SOURCE_MIMETYPE);
+ if (sourceFile.fileTags().contains("c"))
+ return QString(CppTools::Constants::C_SOURCE_MIMETYPE);
+ if (sourceFile.fileTags().contains("objc"))
+ return QString(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE);
+ if (sourceFile.fileTags().contains("objcpp"))
+ return QString(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE);
+ return {};
}
static QString groupLocationToCallGroupId(const qbs::CodeLocation &location)
@@ -918,7 +874,7 @@ void QbsProject::updateCppCodeModel()
QtSupport::CppKitInfo kitInfo(this);
QTC_ASSERT(kitInfo.isValid(), return);
- CppTools::RawProjectParts rpps;
+ RawProjectParts rpps;
foreach (const qbs::ProductData &prd, m_projectData.allProducts()) {
QString cPch;
QString cxxPch;
@@ -942,13 +898,13 @@ void QbsProject::updateCppCodeModel()
std::for_each(sourceArtifacts.cbegin(), sourceArtifacts.cend(), pchFinder);
}
- const CppTools::ProjectPart::QtVersion qtVersionForPart =
- prd.moduleProperties().getModuleProperty("Qt.core", "version").isValid()
- ? kitInfo.projectPartQtVersion
- : CppTools::ProjectPart::NoQt;
+ const Utils::QtVersion qtVersionForPart
+ = prd.moduleProperties().getModuleProperty("Qt.core", "version").isValid()
+ ? kitInfo.projectPartQtVersion
+ : Utils::QtVersion::None;
foreach (const qbs::GroupData &grp, prd.groups()) {
- CppTools::RawProjectPart rpp;
+ RawProjectPart rpp;
rpp.setQtVersion(qtVersionForPart);
const qbs::PropertyMap &props = grp.properties();
rpp.setCallGroupId(groupLocationToCallGroupId(grp.location()));
@@ -964,15 +920,19 @@ void QbsProject::updateCppCodeModel()
QLatin1String(CONFIG_DEFINES));
rpp.setMacros(Utils::transform<QVector>(list, [](const QString &s) { return ProjectExplorer::Macro::fromKeyValue(s); }));
- list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE),
- QLatin1String(CONFIG_INCLUDEPATHS));
- list.append(props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE),
- QLatin1String(CONFIG_SYSTEM_INCLUDEPATHS)));
- list.removeDuplicates();
ProjectExplorer::HeaderPaths grpHeaderPaths;
- foreach (const QString &p, list)
+ list = props.getModulePropertiesAsStringList(CONFIG_CPP_MODULE, CONFIG_INCLUDEPATHS);
+ list.removeDuplicates();
+ for (const QString &p : qAsConst(list))
grpHeaderPaths += {FilePath::fromUserInput(p).toString(), HeaderPathType::User};
+ list = props.getModulePropertiesAsStringList(CONFIG_CPP_MODULE,
+ CONFIG_SYSTEM_INCLUDEPATHS);
+
+ list.removeDuplicates();
+ for (const QString &p : qAsConst(list))
+ grpHeaderPaths += {FilePath::fromUserInput(p).toString(), HeaderPathType::System};
+
list = props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE),
QLatin1String(CONFIG_FRAMEWORKPATHS));
list.append(props.getModulePropertiesAsStringList(QLatin1String(CONFIG_CPP_MODULE),
@@ -987,8 +947,8 @@ void QbsProject::updateCppCodeModel()
rpp.setProjectFileLocation(grp.location().filePath(),
grp.location().line(), grp.location().column());
rpp.setBuildSystemTarget(uniqueProductName(prd));
- rpp.setBuildTargetType(prd.isRunnable() ? CppTools::ProjectPart::Executable
- : CppTools::ProjectPart::Library);
+ rpp.setBuildTargetType(prd.isRunnable() ? ProjectExplorer::BuildTargetType::Executable
+ : ProjectExplorer::BuildTargetType::Library);
QHash<QString, qbs::ArtifactData> filePathToSourceArtifact;
bool hasCFiles = false;
@@ -1051,12 +1011,13 @@ void QbsProject::updateCppCodeModel()
<< grp.name() << "in product" << prd.name();
qCWarning(qbsPmLog) << "Expect problems with code model";
}
- rpp.setPreCompiledHeaders(pchFiles.toList());
- rpp.setFiles(grp.allFilePaths(), [filePathToSourceArtifact](const QString &filePath) {
- // Keep this lambda thread-safe!
- return CppTools::ProjectFile(filePath,
- cppFileType(filePathToSourceArtifact.value(filePath)));
- });
+ rpp.setPreCompiledHeaders(Utils::toList(pchFiles));
+ rpp.setFiles(grp.allFilePaths(),
+ {},
+ [filePathToSourceArtifact](const QString &filePath) {
+ // Keep this lambda thread-safe!
+ return getMimeType(filePathToSourceArtifact.value(filePath));
+ });
rpps.append(rpp);
@@ -1064,7 +1025,7 @@ void QbsProject::updateCppCodeModel()
}
CppTools::GeneratedCodeModelSupport::update(m_extraCompilers);
- m_cppCodeModelUpdater->update({this, kitInfo, rpps});
+ m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps});
}
void QbsProject::updateQmlJsCodeModel()
@@ -1174,8 +1135,6 @@ void QbsProject::updateBuildTargetData()
OpTimer optimer("updateBuildTargetData");
updateApplicationTargets();
updateDeploymentInfo();
- if (activeTarget())
- activeTarget()->updateDefaultRunConfigurations();
}
} // namespace Internal
diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h
index f186bb2c13..56798792bf 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.h
+++ b/src/plugins/qbsprojectmanager/qbsproject.h
@@ -67,8 +67,8 @@ public:
// for shared data.
bool addFilesToProduct(const QStringList &filePaths, const qbs::ProductData productData,
const qbs::GroupData groupData, QStringList *notAdded);
- bool removeFilesFromProduct(const QStringList &filePaths,
- const qbs::ProductData productData, const qbs::GroupData groupData,
+ ProjectExplorer::RemovedFilesFromProject removeFilesFromProduct(const QStringList &filePaths,
+ const qbs::ProductData &productData, const qbs::GroupData &groupData,
QStringList *notRemoved);
bool renameFileInProduct(const QString &oldPath,
const QString &newPath, const qbs::ProductData productData,
@@ -82,7 +82,6 @@ public:
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags);
QString profileForTarget(const ProjectExplorer::Target *t) const;
- bool hasParseResult() const;
void parseCurrentBuildConfiguration();
void scheduleParsing() { m_parsingScheduled = true; }
bool parsingScheduled() const { return m_parsingScheduled; }
@@ -98,7 +97,7 @@ public:
static QString uniqueProductName(const qbs::ProductData &product);
- void configureAsExampleProject(const QSet<Core::Id> &platforms) final;
+ void configureAsExampleProject() final;
void delayParsing();
@@ -117,7 +116,7 @@ private:
const QString &configName);
void prepareForParsing();
- void updateDocuments(const QSet<QString> &files);
+ void updateDocuments(const std::set<QString> &files);
void updateCppCodeModel();
void updateQmlJsCodeModel();
void updateApplicationTargets();
@@ -144,7 +143,7 @@ private:
QHash<ProjectExplorer::Target *, qbs::Project> m_qbsProjects;
qbs::Project m_qbsProject; // for activeTarget()
qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData()
- QSet<Core::IDocument *> m_qbsDocuments;
+ Utils::Environment m_lastParseEnv;
QbsProjectParser *m_qbsProjectParser = nullptr;
@@ -166,6 +165,8 @@ private:
bool m_extraCompilersPending = false;
QHash<QString, Utils::Environment> m_envCache;
+
+ ParseGuard m_guard;
};
} // namespace Internal
diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp
index 69c4e5af1d..dd8600095d 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp
@@ -87,13 +87,12 @@ QbsProjectImporter::QbsProjectImporter(const FilePath &path) : QtProjectImporter
{
}
-static QString buildDir(const QString &projectFilePath, const Kit *k)
+static QString buildDir(const FilePath &projectFilePath, const Kit *k)
{
- const QString projectName = QFileInfo(projectFilePath).completeBaseName();
+ const QString projectName = projectFilePath.toFileInfo().completeBaseName();
ProjectMacroExpander expander(projectFilePath, projectName, k, QString(),
BuildConfiguration::Unknown);
- const QString projectDir
- = Project::projectDirectory(FilePath::fromString(projectFilePath)).toString();
+ const QString projectDir = Project::projectDirectory(projectFilePath).toString();
const QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate());
return FileUtils::resolvePath(projectDir, buildPath);
}
@@ -125,7 +124,7 @@ QStringList QbsProjectImporter::importCandidates()
seenCandidates.insert(projectDir);
const auto &kits = KitManager::kits();
for (Kit * const k : kits) {
- QFileInfo fi(buildDir(projectFilePath().toString(), k));
+ QFileInfo fi(buildDir(projectFilePath(), k));
const QString candidate = fi.absolutePath();
if (!seenCandidates.contains(candidate)) {
seenCandidates.insert(candidate);
@@ -209,9 +208,9 @@ Kit *QbsProjectImporter::createKit(void *directoryData) const
return createTemporaryKit(qtVersionData,[this, bgData](Kit *k) -> void {
QList<ToolChainData> tcData;
if (!bgData->cxxCompilerPath.isEmpty())
- tcData << findOrCreateToolChains(bgData->cxxCompilerPath, Constants::CXX_LANGUAGE_ID);
+ tcData << findOrCreateToolChains({bgData->cxxCompilerPath, Constants::CXX_LANGUAGE_ID});
if (!bgData->cCompilerPath.isEmpty())
- tcData << findOrCreateToolChains(bgData->cCompilerPath, Constants::C_LANGUAGE_ID);
+ tcData << findOrCreateToolChains({bgData->cCompilerPath, Constants::C_LANGUAGE_ID});
foreach (const ToolChainData &tc, tcData) {
if (!tc.tcs.isEmpty())
ToolChainKitAspect::setToolChain(k, tc.tcs.first());
@@ -224,7 +223,7 @@ const QList<BuildInfo> QbsProjectImporter::buildInfoListForKit(const Kit *k, voi
{
qCDebug(qbsPmLog) << "creating build info for kit" << k->displayName();
const auto factory = qobject_cast<QbsBuildConfigurationFactory *>(
- BuildConfigurationFactory::find(k, projectFilePath().toString()));
+ BuildConfigurationFactory::find(k, projectFilePath()));
if (!factory) {
qCDebug(qbsPmLog) << "no build config factory found";
return {};
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro
index 831422f262..1b8896b33c 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanager.pro
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.pro
@@ -37,8 +37,7 @@ HEADERS = \
qbsprojectmanagerconstants.h \
qbsprojectmanagerplugin.h \
qbsprojectmanagersettings.h \
- qbsprojectparser.h \
- qbsrunconfiguration.h
+ qbsprojectparser.h
SOURCES = \
customqbspropertiesdialog.cpp \
@@ -59,14 +58,11 @@ SOURCES = \
qbsprojectmanager.cpp \
qbsprojectmanagerplugin.cpp \
qbsprojectmanagersettings.cpp \
- qbsprojectparser.cpp \
- qbsrunconfiguration.cpp
+ qbsprojectparser.cpp
FORMS = \
customqbspropertiesdialog.ui \
- qbsbuildstepconfigwidget.ui \
qbscleanstepconfigwidget.ui \
- qbsinstallstepconfigwidget.ui \
qbsprofilessettingswidget.ui
RESOURCES += \
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs
index 1ef3f1b63b..5c933991af 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs
@@ -68,13 +68,11 @@ QtcPlugin {
"qbsbuildconfiguration.h",
"qbsbuildstep.cpp",
"qbsbuildstep.h",
- "qbsbuildstepconfigwidget.ui",
"qbscleanstep.cpp",
"qbscleanstep.h",
"qbscleanstepconfigwidget.ui",
"qbsinstallstep.cpp",
"qbsinstallstep.h",
- "qbsinstallstepconfigwidget.ui",
"qbskitinformation.cpp",
"qbskitinformation.h",
"qbslogsink.cpp",
@@ -105,8 +103,6 @@ QtcPlugin {
"qbsprojectmanagersettings.h",
"qbsprojectparser.cpp",
"qbsprojectparser.h",
- "qbsrunconfiguration.cpp",
- "qbsrunconfiguration.h",
]
// QML typeinfo stuff
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
index f8eb477e64..bc123b09c7 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
@@ -35,7 +35,6 @@
#include "qbsproject.h"
#include "qbsprojectmanager.h"
#include "qbsprojectmanagerconstants.h"
-#include "qbsrunconfiguration.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -91,9 +90,7 @@ public:
QbsBuildStepFactory buildStepFactory;
QbsCleanStepFactory cleanStepFactory;
QbsInstallStepFactory installStepFactory;
- QbsRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, QbsRunConfiguration> runWorkerFactory;
- QbsProfilesSettingsPage profilesSetttingsPage;
+ QbsProfilesSettingsPage profilesSettingsPage;
QbsKitAspect qbsKitAspect;
};
@@ -104,8 +101,8 @@ QbsProjectManagerPlugin::~QbsProjectManagerPlugin()
bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
d = new QbsProjectManagerPluginPrivate;
@@ -578,5 +575,11 @@ void QbsProjectManagerPlugin::reparseProject(QbsProject *project)
project->parseCurrentBuildConfiguration();
}
+void QbsProjectManagerPlugin::buildNamedProduct(QbsProject *project, const QString &product)
+{
+ QbsProjectManagerPlugin::runStepsForProducts(project, QStringList(product),
+ {Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)});
+}
+
} // namespace Internal
} // namespace QbsProjectManager
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h
index f7b37e8d80..267b7777ae 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h
@@ -42,6 +42,10 @@ class QbsProjectManagerPlugin : public ExtensionSystem::IPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QbsProjectManager.json")
+public:
+ static void buildNamedProduct(QbsProject *project, const QString &product);
+
+private:
~QbsProjectManagerPlugin() final;
bool initialize(const QStringList &arguments, QString *errorMessage) final;
@@ -77,8 +81,8 @@ class QbsProjectManagerPlugin : public ExtensionSystem::IPlugin
const QStringList &activeFileTags);
void buildSingleFile(QbsProject *project, const QString &file);
- void runStepsForProducts(QbsProject *project, const QStringList &products,
- const QList<Core::Id> &stepTypes);
+ static void runStepsForProducts(QbsProject *project, const QStringList &products,
+ const QList<Core::Id> &stepTypes);
QbsProjectManagerPluginPrivate *d = nullptr;
QAction *m_reparseQbs = nullptr;
diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp
index 3d67a087e3..10196cbd37 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectparser.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectparser.cpp
@@ -82,6 +82,7 @@ void QbsProjectParser::parse(const QVariantMap &config, const Environment &env,
QTC_ASSERT(!dir.isEmpty(), return);
m_currentProgressBase = 0;
+ m_environment = env;
qbs::SetupProjectParameters params;
QVariantMap userConfig = config;
@@ -186,7 +187,7 @@ void QbsProjectParser::handleQbsParsingProgress(int progress)
void QbsProjectParser::handleQbsParsingTaskSetup(const QString &description, int maximumProgressValue)
{
- Q_UNUSED(description);
+ Q_UNUSED(description)
if (m_fi) {
m_currentProgressBase = m_fi->progressValue();
m_fi->setProgressRange(0, m_currentProgressBase + maximumProgressValue);
diff --git a/src/plugins/qbsprojectmanager/qbsprojectparser.h b/src/plugins/qbsprojectmanager/qbsprojectparser.h
index 4c54d08b3b..37b9e5f6d2 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectparser.h
+++ b/src/plugins/qbsprojectmanager/qbsprojectparser.h
@@ -50,6 +50,7 @@ public:
const QString &configName);
void startRuleExecution();
void cancel();
+ Utils::Environment environment() const { return m_environment; }
qbs::Project qbsProject() const;
qbs::ErrorInfo error();
@@ -69,6 +70,7 @@ private:
void handleRuleExecutionDone();
+ Utils::Environment m_environment;
QString m_projectFilePath;
qbs::SetupProjectJob *m_qbsSetupProjectJob = nullptr;
qbs::BuildJob *m_ruleExecutionJob = nullptr;
diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
deleted file mode 100644
index d4960b3524..0000000000
--- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qbsrunconfiguration.h"
-
-#include "qbsnodes.h"
-#include "qbspmlogging.h"
-#include "qbsprojectmanagerconstants.h"
-#include "qbsproject.h"
-
-#include <projectexplorer/buildmanager.h>
-#include <projectexplorer/deploymentdata.h>
-#include <projectexplorer/localenvironmentaspect.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/runcontrol.h>
-#include <projectexplorer/runconfigurationaspects.h>
-#include <projectexplorer/target.h>
-
-#include <qtsupport/qtoutputformatter.h>
-
-#include <QFileInfo>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace QbsProjectManager {
-namespace Internal {
-
-// --------------------------------------------------------------------
-// QbsRunConfiguration:
-// --------------------------------------------------------------------
-
-QbsRunConfiguration::QbsRunConfiguration(Target *target, Core::Id id)
- : RunConfiguration(target, id)
-{
- auto envAspect = addAspect<LocalEnvironmentAspect>(target);
- envAspect->addModifier([this](Environment &env) {
- bool usingLibraryPaths = aspect<UseLibraryPathsAspect>()->value();
-
- BuildTargetInfo bti = buildTargetInfo();
- if (bti.runEnvModifier)
- bti.runEnvModifier(env, usingLibraryPaths);
- });
-
- addAspect<ExecutableAspect>();
- addAspect<ArgumentsAspect>();
- addAspect<WorkingDirectoryAspect>();
- addAspect<TerminalAspect>();
-
- setOutputFormatter<QtSupport::QtOutputFormatter>();
-
- auto libAspect = addAspect<UseLibraryPathsAspect>();
- connect(libAspect, &UseLibraryPathsAspect::changed,
- envAspect, &EnvironmentAspect::environmentChanged);
- if (HostOsInfo::isMacHost()) {
- auto dyldAspect = addAspect<UseDyldSuffixAspect>();
- connect(dyldAspect, &UseDyldSuffixAspect::changed,
- envAspect, &EnvironmentAspect::environmentChanged);
- envAspect->addModifier([dyldAspect](Environment &env) {
- if (dyldAspect->value())
- env.set("DYLD_IMAGE_SUFFIX", "_debug");
- });
- }
-
- connect(project(), &Project::parsingFinished, this,
- [envAspect]() { envAspect->buildEnvironmentHasChanged(); });
-
- connect(target, &Target::deploymentDataChanged,
- this, &QbsRunConfiguration::updateTargetInformation);
- connect(target, &Target::applicationTargetsChanged,
- this, &QbsRunConfiguration::updateTargetInformation);
- // Handles device changes, etc.
- connect(target, &Target::kitChanged,
- this, &QbsRunConfiguration::updateTargetInformation);
-
- auto qbsProject = static_cast<QbsProject *>(target->project());
- connect(qbsProject, &Project::parsingFinished,
- this, &QbsRunConfiguration::updateTargetInformation);
-}
-
-QVariantMap QbsRunConfiguration::toMap() const
-{
- return RunConfiguration::toMap();
-}
-
-bool QbsRunConfiguration::fromMap(const QVariantMap &map)
-{
- if (!RunConfiguration::fromMap(map))
- return false;
-
- updateTargetInformation();
- return true;
-}
-
-void QbsRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &info)
-{
- setDefaultDisplayName(info.displayName);
- updateTargetInformation();
-}
-
-Utils::FilePath QbsRunConfiguration::executableToRun(const BuildTargetInfo &targetInfo) const
-{
- const FilePath appInBuildDir = targetInfo.targetFilePath;
- if (target()->deploymentData().localInstallRoot().isEmpty())
- return appInBuildDir;
- const QString deployedAppFilePath = target()->deploymentData()
- .deployableForLocalFile(appInBuildDir.toString()).remoteFilePath();
- if (deployedAppFilePath.isEmpty())
- return appInBuildDir;
- const FilePath appInLocalInstallDir = target()->deploymentData().localInstallRoot()
- + deployedAppFilePath;
- return appInLocalInstallDir.exists() ? appInLocalInstallDir : appInBuildDir;
-}
-
-void QbsRunConfiguration::updateTargetInformation()
-{
- BuildTargetInfo bti = buildTargetInfo();
- const FilePath executable = executableToRun(bti);
- auto terminalAspect = aspect<TerminalAspect>();
- terminalAspect->setUseTerminalHint(bti.usesTerminal);
-
- aspect<ExecutableAspect>()->setExecutable(executable);
-
- if (!executable.isEmpty()) {
- QString defaultWorkingDir = QFileInfo(executable.toString()).absolutePath();
- if (!defaultWorkingDir.isEmpty()) {
- auto wdAspect = aspect<WorkingDirectoryAspect>();
- wdAspect->setDefaultWorkingDirectory(FilePath::fromString(defaultWorkingDir));
- }
- }
-
- emit enabledChanged();
-}
-
-// --------------------------------------------------------------------
-// QbsRunConfigurationFactory:
-// --------------------------------------------------------------------
-
-QbsRunConfigurationFactory::QbsRunConfigurationFactory()
-{
- registerRunConfiguration<QbsRunConfiguration>("Qbs.RunConfiguration:");
- addSupportedProjectType(Constants::PROJECT_ID);
- addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
-}
-
-} // namespace Internal
-} // namespace QbsProjectManager
diff --git a/src/plugins/qmakeprojectmanager/CMakeLists.txt b/src/plugins/qmakeprojectmanager/CMakeLists.txt
index 5cd7b6cc19..685b92226e 100644
--- a/src/plugins/qmakeprojectmanager/CMakeLists.txt
+++ b/src/plugins/qmakeprojectmanager/CMakeLists.txt
@@ -14,7 +14,6 @@ add_qtc_plugin(QmakeProjectManager
customwidgetwizard/filenamingparameters.h
customwidgetwizard/plugingenerator.cpp customwidgetwizard/plugingenerator.h
customwidgetwizard/pluginoptions.h
- desktopqmakerunconfiguration.cpp desktopqmakerunconfiguration.h
externaleditors.cpp externaleditors.h
librarydetailscontroller.cpp librarydetailscontroller.h
librarydetailswidget.ui
@@ -41,9 +40,7 @@ add_qtc_plugin(QmakeProjectManager
qmakeprojectmanagerplugin.cpp qmakeprojectmanagerplugin.h
qmakesettings.cpp qmakesettings.h
qmakestep.cpp qmakestep.h qmakestep.ui
- qtmodulesinfo.cpp qtmodulesinfo.h
wizards/filespage.cpp wizards/filespage.h
- wizards/modulespage.cpp wizards/modulespage.h
wizards/qtprojectparameters.cpp wizards/qtprojectparameters.h
wizards/qtwizard.cpp wizards/qtwizard.h
wizards/simpleprojectwizard.cpp wizards/simpleprojectwizard.h
diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp
index bfef5875e3..998a33fddd 100644
--- a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp
+++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp
@@ -58,7 +58,7 @@ static bool validateLibraryPath(const Utils::FilePath &filePath,
const Utils::PathChooser *pathChooser,
QString *errorMessage)
{
- Q_UNUSED(errorMessage);
+ Q_UNUSED(errorMessage)
if (!filePath.exists())
return false;
diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizarddialog.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizarddialog.cpp
index c241ffd36e..9a96295fe9 100644
--- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizarddialog.cpp
+++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizarddialog.cpp
@@ -41,7 +41,7 @@ CustomWidgetWizardDialog::CustomWidgetWizardDialog(const Core::BaseFileWizardFac
const QString &templateName,
const QIcon &icon, QWidget *parent,
const Core::WizardDialogParameters &parameters) :
- BaseQmakeProjectWizardDialog(factory, false, parent, parameters),
+ BaseQmakeProjectWizardDialog(factory, parent, parameters),
m_widgetsPage(new CustomWidgetWidgetsWizardPage),
m_pluginPage(new CustomWidgetPluginWizardPage)
{
diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp
deleted file mode 100644
index 8cf53db49b..0000000000
--- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "desktopqmakerunconfiguration.h"
-
-#include "qmakeprojectmanagerconstants.h"
-
-#include <projectexplorer/localenvironmentaspect.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/projectnodes.h>
-#include <projectexplorer/runconfigurationaspects.h>
-#include <projectexplorer/runcontrol.h>
-#include <projectexplorer/target.h>
-
-#include <qtsupport/qtkitinformation.h>
-#include <qtsupport/qtoutputformatter.h>
-#include <qtsupport/qtsupportconstants.h>
-
-#include <utils/fileutils.h>
-#include <utils/pathchooser.h>
-#include <utils/persistentsettings.h>
-#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
-#include <utils/stringutils.h>
-#include <utils/utilsicons.h>
-
-#include <QDir>
-#include <QFileInfo>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace QmakeProjectManager {
-namespace Internal {
-
-//
-// DesktopQmakeRunConfiguration
-//
-
-DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target, Core::Id id)
- : RunConfiguration(target, id)
-{
- auto envAspect = addAspect<LocalEnvironmentAspect>(target);
- envAspect->addModifier([this](Environment &env) {
- BuildTargetInfo bti = buildTargetInfo();
- if (bti.runEnvModifier)
- bti.runEnvModifier(env, aspect<UseLibraryPathsAspect>()->value());
- });
-
- addAspect<ExecutableAspect>();
- addAspect<ArgumentsAspect>();
- addAspect<WorkingDirectoryAspect>();
- addAspect<TerminalAspect>();
-
- setOutputFormatter<QtSupport::QtOutputFormatter>();
-
- auto libAspect = addAspect<UseLibraryPathsAspect>();
- connect(libAspect, &UseLibraryPathsAspect::changed,
- envAspect, &EnvironmentAspect::environmentChanged);
-
- if (HostOsInfo::isMacHost()) {
- auto dyldAspect = addAspect<UseDyldSuffixAspect>();
- connect(dyldAspect, &UseLibraryPathsAspect::changed,
- envAspect, &EnvironmentAspect::environmentChanged);
- envAspect->addModifier([dyldAspect](Environment &env) {
- if (dyldAspect->value())
- env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug"));
- });
- }
-
- connect(target->project(), &Project::parsingFinished,
- this, &DesktopQmakeRunConfiguration::updateTargetInformation);
-}
-
-void DesktopQmakeRunConfiguration::updateTargetInformation()
-{
- setDefaultDisplayName(defaultDisplayName());
- aspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
-
- BuildTargetInfo bti = buildTargetInfo();
-
- auto wda = aspect<WorkingDirectoryAspect>();
- wda->setDefaultWorkingDirectory(bti.workingDirectory);
- if (wda->pathChooser())
- wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory());
-
- auto terminalAspect = aspect<TerminalAspect>();
- terminalAspect->setUseTerminalHint(bti.usesTerminal);
-
- aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
-}
-
-bool DesktopQmakeRunConfiguration::fromMap(const QVariantMap &map)
-{
- if (!RunConfiguration::fromMap(map))
- return false;
- updateTargetInformation();
- return true;
-}
-
-void DesktopQmakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreationInfo &)
-{
- updateTargetInformation();
-}
-
-FilePath DesktopQmakeRunConfiguration::proFilePath() const
-{
- return FilePath::fromString(buildKey());
-}
-
-QString DesktopQmakeRunConfiguration::defaultDisplayName()
-{
- FilePath profile = proFilePath();
- if (!profile.isEmpty())
- return profile.toFileInfo().completeBaseName();
- return tr("Qt Run Configuration");
-}
-
-//
-// DesktopQmakeRunConfigurationFactory
-//
-
-DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory()
-{
- registerRunConfiguration<DesktopQmakeRunConfiguration>("Qt4ProjectManager.Qt4RunConfiguration:");
- addSupportedProjectType(QmakeProjectManager::Constants::QMAKEPROJECT_ID);
- addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
-}
-
-} // namespace Internal
-} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager.png b/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager.png
index bdb33780cc..b75e0422f7 100644
--- a/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager.png
+++ b/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager.png
Binary files differ
diff --git a/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager@2x.png b/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager@2x.png
index 8e8e26599f..8c708b52e3 100644
--- a/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager@2x.png
+++ b/src/plugins/qmakeprojectmanager/images/qmakeprojectmanager@2x.png
Binary files differ
diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
index 0bb6eed49f..b9c96fbb20 100644
--- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp
@@ -78,21 +78,21 @@ namespace QmakeProjectManager {
// Helpers:
// --------------------------------------------------------------------
-QString QmakeBuildConfiguration::shadowBuildDirectory(const QString &proFilePath, const Kit *k,
+QString QmakeBuildConfiguration::shadowBuildDirectory(const FilePath &proFilePath, const Kit *k,
const QString &suffix,
BuildConfiguration::BuildType buildType)
{
if (proFilePath.isEmpty())
return QString();
- const QString projectName = QFileInfo(proFilePath).completeBaseName();
+ const QString projectName = proFilePath.toFileInfo().completeBaseName();
ProjectMacroExpander expander(proFilePath, projectName, k, suffix, buildType);
- QString projectDir = Project::projectDirectory(FilePath::fromString(proFilePath)).toString();
+ QString projectDir = Project::projectDirectory(proFilePath).toString();
QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate());
return FileUtils::resolvePath(projectDir, buildPath);
}
-static FilePath defaultBuildDirectory(const QString &projectPath,
+static FilePath defaultBuildDirectory(const FilePath &projectPath,
const Kit *k,
const QString &suffix,
BuildConfiguration::BuildType type)
@@ -101,7 +101,6 @@ static FilePath defaultBuildDirectory(const QString &projectPath,
suffix, type));
}
-const char USE_SHADOW_BUILD_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild";
const char BUILD_CONFIGURATION_KEY[] = "Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration";
enum { debug = 0 };
@@ -128,23 +127,23 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id)
this, &QmakeBuildConfiguration::qtVersionsChanged);
}
-void QmakeBuildConfiguration::initialize(const BuildInfo &info)
+void QmakeBuildConfiguration::initialize()
{
- BuildConfiguration::initialize(info);
+ BuildConfiguration::initialize();
BuildStepList *buildSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
auto qmakeStep = new QMakeStep(buildSteps);
buildSteps->appendStep(qmakeStep);
- buildSteps->appendStep(new QmakeMakeStep(buildSteps));
+ buildSteps->appendStep(Constants::MAKESTEP_BS_ID);
BuildStepList *cleanSteps = stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
- cleanSteps->appendStep(new QmakeMakeStep(cleanSteps));
+ cleanSteps->appendStep(Constants::MAKESTEP_BS_ID);
- const QmakeExtraBuildInfo qmakeExtra = info.extraInfo.value<QmakeExtraBuildInfo>();
+ const QmakeExtraBuildInfo qmakeExtra = extraInfo().value<QmakeExtraBuildInfo>();
BaseQtVersion *version = QtKitAspect::qtVersion(target()->kit());
BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig();
- if (info.buildType == BuildConfiguration::Debug)
+ if (initialBuildType() == BuildConfiguration::Debug)
config |= BaseQtVersion::DebugBuild;
else
config &= ~BaseQtVersion::DebugBuild;
@@ -158,10 +157,11 @@ void QmakeBuildConfiguration::initialize(const BuildInfo &info)
setQMakeBuildConfiguration(config);
- FilePath directory = info.buildDirectory;
+ FilePath directory = initialBuildDirectory();
if (directory.isEmpty()) {
- directory = defaultBuildDirectory(target()->project()->projectFilePath().toString(),
- target()->kit(), info.displayName, buildType());
+ directory = defaultBuildDirectory(target()->project()->projectFilePath(),
+ target()->kit(), initialDisplayName(),
+ initialBuildType());
}
setBuildDirectory(directory);
@@ -180,7 +180,6 @@ QmakeBuildConfiguration::~QmakeBuildConfiguration() = default;
QVariantMap QmakeBuildConfiguration::toMap() const
{
QVariantMap map(BuildConfiguration::toMap());
- map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
return map;
}
@@ -190,7 +189,6 @@ bool QmakeBuildConfiguration::fromMap(const QVariantMap &map)
if (!BuildConfiguration::fromMap(map))
return false;
- m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
m_qmakeBuildConfiguration = BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
m_lastKitState = LastKitState(target()->kit());
@@ -255,15 +253,6 @@ void QmakeBuildConfiguration::setFileNodeBuild(FileNode *node)
m_fileNodeBuild = node;
}
-/// returns whether this is a shadow build configuration or not
-/// note, even if shadowBuild() returns true, it might be using the
-/// source directory as the shadow build directory, thus it
-/// still is a in-source build
-bool QmakeBuildConfiguration::isShadowBuild() const
-{
- return buildDirectory() != target()->project()->projectDirectory();
-}
-
QString QmakeBuildConfiguration::makefile() const
{
auto rootNode = dynamic_cast<QmakeProFileNode *>(target()->project()->rootProjectNode());
@@ -311,11 +300,6 @@ bool QmakeBuildConfiguration::isBuildDirAtSafeLocation() const
buildDirectory().toString());
}
-void QmakeBuildConfiguration::emitQMakeBuildConfigurationChanged()
-{
- emit qmakeBuildConfigurationChanged();
-}
-
QStringList QmakeBuildConfiguration::configCommandLineArguments() const
{
QStringList result;
@@ -556,26 +540,6 @@ QString QmakeBuildConfiguration::extractSpecFromArguments(QString *args,
return parsedSpec.toString();
}
-bool QmakeBuildConfiguration::isEnabled() const
-{
- return m_isEnabled;
-}
-
-QString QmakeBuildConfiguration::disabledReason() const
-{
- if (!m_isEnabled)
- return tr("Parsing the .pro file");
- return QString();
-}
-
-void QmakeBuildConfiguration::setEnabled(bool enabled)
-{
- if (m_isEnabled == enabled)
- return;
- m_isEnabled = enabled;
- emit enabledChanged();
-}
-
/*!
\class QmakeBuildConfigurationFactory
*/
@@ -602,7 +566,7 @@ QmakeBuildConfigurationFactory::QmakeBuildConfigurationFactory()
}
BuildInfo QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k,
- const QString &projectPath,
+ const FilePath &projectPath,
BuildConfiguration::BuildType type) const
{
BaseQtVersion *version = QtKitAspect::qtVersion(k);
@@ -639,10 +603,9 @@ BuildInfo QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k,
info.kitId = k->id();
// check if this project is in the source directory:
- FilePath projectFilePath = FilePath::fromString(projectPath);
- if (version && version->isInSourceDirectory(projectFilePath)) {
+ if (version && version->isInSourceDirectory(projectPath)) {
// assemble build directory
- QString projectDirectory = projectFilePath.toFileInfo().absolutePath();
+ QString projectDirectory = projectPath.toFileInfo().absolutePath();
QDir qtSourceDir = QDir(version->sourcePath().toString());
QString relativeProjectPath = qtSourceDir.relativeFilePath(projectDirectory);
QString qtBuildDir = version->qmakeProperty("QT_INSTALL_PREFIX");
@@ -657,7 +620,7 @@ BuildInfo QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k,
return info;
}
-static QList<BuildConfiguration::BuildType> availableBuildTypes(const BaseQtVersion *version)
+static const QList<BuildConfiguration::BuildType> availableBuildTypes(const BaseQtVersion *version)
{
QList<BuildConfiguration::BuildType> types = {BuildConfiguration::Debug,
BuildConfiguration::Release};
@@ -666,32 +629,25 @@ static QList<BuildConfiguration::BuildType> availableBuildTypes(const BaseQtVers
return types;
}
-QList<BuildInfo> QmakeBuildConfigurationFactory::availableBuilds(const Target *parent) const
+QList<BuildInfo> QmakeBuildConfigurationFactory::availableBuilds(const Kit *k, const FilePath &projectPath, bool forSetup) const
{
QList<BuildInfo> result;
- const QString projectFilePath = parent->project()->projectFilePath().toString();
+ BaseQtVersion *qtVersion = QtKitAspect::qtVersion(k);
- foreach (BuildConfiguration::BuildType buildType,
- availableBuildTypes(QtKitAspect::qtVersion(parent->kit()))) {
- BuildInfo info = createBuildInfo(parent->kit(), projectFilePath, buildType);
- info.displayName.clear(); // ask for a name
- info.buildDirectory.clear(); // This depends on the displayName
- result << info;
- }
+ if (forSetup && (!qtVersion || !qtVersion->isValid()))
+ return {};
- return result;
-}
-QList<BuildInfo> QmakeBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const
-{
- QList<BuildInfo> result;
- BaseQtVersion *qtVersion = QtKitAspect::qtVersion(k);
- if (!qtVersion || !qtVersion->isValid())
- return result;
+ for (BuildConfiguration::BuildType buildType : availableBuildTypes(qtVersion)) {
+ BuildInfo info = createBuildInfo(k, projectPath, buildType);
+ if (!forSetup) {
+ info.displayName.clear(); // ask for a name
+ info.buildDirectory.clear(); // This depends on the displayName
+ }
+ result << info;
- foreach (BuildConfiguration::BuildType buildType, availableBuildTypes(qtVersion))
- result << createBuildInfo(k, projectPath, buildType);
+ }
return result;
}
diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h
index 20b98103e8..7fd4c7dfeb 100644
--- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h
+++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h
@@ -46,9 +46,8 @@ public:
QmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id);
~QmakeBuildConfiguration() override;
- void initialize(const ProjectExplorer::BuildInfo &info) override;
+ void initialize() override;
ProjectExplorer::NamedWidget *createConfigWidget() override;
- bool isShadowBuild() const;
void setSubNodeBuild(QmakeProFileNode *node);
QmakeProFileNode *subNodeBuild() const;
@@ -60,15 +59,9 @@ public:
void setQMakeBuildConfiguration(QtSupport::BaseQtVersion::QmakeBuildConfigs config);
/// suffix should be unique
- static QString shadowBuildDirectory(const QString &profilePath, const ProjectExplorer::Kit *k,
+ static QString shadowBuildDirectory(const Utils::FilePath &profilePath, const ProjectExplorer::Kit *k,
const QString &suffix, BuildConfiguration::BuildType type);
- /// \internal for qmakestep
- // used by qmake step to notify that the qmake args have changed
- // not really nice, the build configuration should save the arguments
- // since they are needed for reevaluation
- void emitQMakeBuildConfigurationChanged();
-
QStringList configCommandLineArguments() const;
// Those functions are used in a few places.
@@ -89,11 +82,6 @@ public:
QVariantMap toMap() const override;
- bool isEnabled() const override;
- QString disabledReason() const override;
- /// \internal For QmakeProject, since that manages the parsing information
- void setEnabled(bool enabled);
-
BuildType buildType() const override;
void addToEnvironment(Utils::Environment &env) const override;
@@ -109,7 +97,6 @@ signals:
/// emitted for setQMakeBuildConfig, not emitted for Qt version changes, even
/// if those change the qmakebuildconfig
void qmakeBuildConfigurationChanged();
- void shadowBuildChanged();
protected:
bool fromMap(const QVariantMap &map) override;
@@ -135,8 +122,6 @@ private:
};
LastKitState m_lastKitState;
- bool m_shadowBuild = true;
- bool m_isEnabled = true;
QtSupport::BaseQtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration;
QmakeProFileNode *m_subNodeBuild = nullptr;
ProjectExplorer::FileNode *m_fileNodeBuild = nullptr;
@@ -149,11 +134,11 @@ class QMAKEPROJECTMANAGER_EXPORT QmakeBuildConfigurationFactory : public Project
public:
QmakeBuildConfigurationFactory();
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *parent) const override;
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *k,
- const QString &projectPath) const override;
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *k,
+ const Utils::FilePath &projectPath,
+ bool forSetup) const override;
private:
- ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k, const QString &projectPath,
+ ProjectExplorer::BuildInfo createBuildInfo(const ProjectExplorer::Kit *k, const Utils::FilePath &projectPath,
ProjectExplorer::BuildConfiguration::BuildType type) const;
};
diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
index 3b4642a6df..ec318b63e6 100644
--- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp
@@ -53,10 +53,8 @@ using namespace ProjectExplorer;
using namespace QmakeProjectManager;
using namespace QmakeProjectManager::Internal;
-const char MAKESTEP_BS_ID[] = "Qt4ProjectManager.MakeStep";
-
QmakeMakeStep::QmakeMakeStep(BuildStepList *bsl)
- : MakeStep(bsl, MAKESTEP_BS_ID)
+ : MakeStep(bsl, Constants::MAKESTEP_BS_ID)
{
if (bsl->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
setClean(true);
@@ -70,18 +68,19 @@ bool QmakeMakeStep::init()
if (!bc)
emit addTask(Task::buildConfigurationMissingTask());
- Utils::FilePath make = effectiveMakeCommand();
- if (make.isEmpty())
+ const Utils::CommandLine unmodifiedMake = effectiveMakeCommand();
+ const Utils::FilePath makeExecutable = unmodifiedMake.executable();
+ if (makeExecutable.isEmpty())
emit addTask(makeCommandMissingTask());
- if (!bc || make.isEmpty()) {
+ if (!bc || makeExecutable.isEmpty()) {
emitFaultyConfigurationMessage();
return false;
}
// Ignore all but the first make step for a non-top-level build. See QTCREATORBUG-15794.
m_ignoredNonTopLevelBuild = (bc->fileNodeBuild() || bc->subNodeBuild())
- && static_cast<BuildStepList *>(parent())->firstOfType<QmakeMakeStep>() != this;
+ && stepList()->firstOfType<QmakeMakeStep>() != this;
ProcessParameters *pp = processParameters();
pp->setMacroExpander(bc->macroExpander());
@@ -93,14 +92,12 @@ bool QmakeMakeStep::init()
workingDirectory = bc->buildDirectory().toString();
pp->setWorkingDirectory(Utils::FilePath::fromString(workingDirectory));
- pp->setCommand(make);
-
// If we are cleaning, then make can fail with a error code, but that doesn't mean
// we should stop the clean queue
// That is mostly so that rebuild works on a already clean project
setIgnoreReturnValue(isClean());
- QString args;
+ Utils::CommandLine makeCmd(makeExecutable);
QmakeProjectManager::QmakeProFileNode *subProFile = bc->subNodeBuild();
if (subProFile) {
@@ -116,22 +113,22 @@ bool QmakeMakeStep::init()
else
makefile += ".Release";
}
- if (makefile != "Makefile") {
- Utils::QtcProcess::addArg(&args, "-f");
- Utils::QtcProcess::addArg(&args, makefile);
- }
+
+ if (makefile != "Makefile")
+ makeCmd.addArgs({"-f", makefile});
+
m_makeFileToCheck = QDir(workingDirectory).filePath(makefile);
} else {
if (!bc->makefile().isEmpty()) {
- Utils::QtcProcess::addArg(&args, "-f");
- Utils::QtcProcess::addArg(&args, bc->makefile());
+ makeCmd.addArgs({"-f", bc->makefile()});
m_makeFileToCheck = QDir(workingDirectory).filePath(bc->makefile());
} else {
m_makeFileToCheck = QDir(workingDirectory).filePath("Makefile");
}
}
- Utils::QtcProcess::addArgs(&args, allArguments());
+ makeCmd.addArgs(unmodifiedMake.arguments(), Utils::CommandLine::Raw);
+
if (bc->fileNodeBuild() && subProFile) {
QString objectsDir = subProFile->objectsDirectory();
if (objectsDir.isEmpty()) {
@@ -152,10 +149,11 @@ bool QmakeMakeStep::init()
QString objectFile = relObjectsDir +
bc->fileNodeBuild()->filePath().toFileInfo().baseName() +
subProFile->objectExtension();
- Utils::QtcProcess::addArg(&args, objectFile);
+ makeCmd.addArg(objectFile);
}
+
pp->setEnvironment(environment(bc));
- pp->setArguments(args);
+ pp->setCommandLine(makeCmd);
pp->resolveAll();
setOutputParser(new ProjectExplorer::GnuMakeParser());
@@ -175,8 +173,7 @@ bool QmakeMakeStep::init()
// A user doing "make clean" indicates they want a proper rebuild, so make sure to really
// execute qmake on the next build.
- if (static_cast<BuildStepList *>(parent())->id()
- == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
+ if (stepList()->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
const auto qmakeStep = bc->qmakeStep();
if (qmakeStep)
qmakeStep->setForced(true);
@@ -221,7 +218,7 @@ void QmakeMakeStep::finish(bool success)
QmakeMakeStepFactory::QmakeMakeStepFactory()
{
- registerStep<QmakeMakeStep>(MAKESTEP_BS_ID);
+ registerStep<QmakeMakeStep>(Constants::MAKESTEP_BS_ID);
setSupportedProjectType(Constants::QMAKEPROJECT_ID);
setDisplayName(MakeStep::defaultDisplayName());
}
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
index a71ab8c3d6..a51c09f0ac 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -24,7 +24,9 @@
****************************************************************************/
#include "qmakenodes.h"
+
#include "qmakeproject.h"
+#include "qmakeprojectmanager.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/runconfiguration.h>
@@ -82,7 +84,7 @@ QmakeProFileNode *QmakePriFileNode::proFileNode() const
bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) const
{
- if (action == Rename || action == DuplicateFile) {
+ if (action == Rename) {
const FileNode *fileNode = node->asFileNode();
return (fileNode && fileNode->fileType() != FileType::Project)
|| dynamic_cast<const ResourceEditor::ResourceTopLevelNode *>(node);
@@ -193,10 +195,28 @@ bool QmakePriFileNode::addFiles(const QStringList &filePaths, QStringList *notAd
return pri->addFiles(actualFilePaths, notAdded);
}
-bool QmakePriFileNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject QmakePriFileNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
- QmakePriFile *pri = priFile();
- return pri ? pri->removeFiles(filePaths, notRemoved) : false;
+ QmakePriFile * const pri = priFile();
+ if (!pri)
+ return RemovedFilesFromProject::Error;
+ QStringList wildcardFiles;
+ QStringList nonWildcardFiles;
+ for (const QString &file : filePaths) {
+ if (pri->proFile()->isFileFromWildcard(file))
+ wildcardFiles << file;
+ else
+ nonWildcardFiles << file;
+ }
+ const bool success = pri->removeFiles(nonWildcardFiles, notRemoved);
+ if (notRemoved)
+ *notRemoved += wildcardFiles;
+ if (!success)
+ return RemovedFilesFromProject::Error;
+ if (!wildcardFiles.isEmpty())
+ return RemovedFilesFromProject::Wildcard;
+ return RemovedFilesFromProject::Ok;
}
bool QmakePriFileNode::deleteFiles(const QStringList &filePaths)
@@ -217,6 +237,13 @@ bool QmakePriFileNode::renameFile(const QString &filePath, const QString &newFil
return pri ? pri->renameFile(filePath, newFilePath) : false;
}
+bool QmakePriFileNode::addDependencies(const QStringList &dependencies)
+{
+ if (QmakePriFile * const pri = priFile())
+ return pri->addDependencies(dependencies);
+ return false;
+}
+
FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringList &files, Node *context) const
{
Q_UNUSED(files)
@@ -255,6 +282,11 @@ bool QmakeProFileNode::validParse() const
return pro && pro->validParse();
}
+void QmakeProFileNode::build()
+{
+ QmakeManager::buildProduct(getProject(), this);
+}
+
QStringList QmakeProFileNode::targetApplications() const
{
QStringList apps;
@@ -307,6 +339,9 @@ QVariant QmakeProFileNode::data(Core::Id role) const
return info.buildDir.toString();
}
+ if (role == ProjectExplorer::Constants::QT_KEYWORDS_ENABLED)
+ return !proFile()->variableValue(Variable::Config).contains("no_keywords");
+
QTC_CHECK(false);
return {};
}
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h
index 92b84fbcb0..7d9138615e 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -56,10 +56,12 @@ public:
QStringList subProjectFileNamePatterns() const override;
bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved = nullptr) override;
bool deleteFiles(const QStringList &filePaths) override;
bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
+ bool addDependencies(const QStringList &dependencies) override;
AddNewInformation addNewInformation(const QStringList &files, Node *context) const override;
bool deploysFolder(const QString &folder) const override;
@@ -97,6 +99,8 @@ public:
bool parseInProgress() const override;
bool validParse() const override;
+ void build() override;
+
QStringList targetApplications() const override;
AddNewInformation addNewInformation(const QStringList &files, Node *context) const override;
QVariant data(Core::Id role) const override;
diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
index d2fc8051de..e02c037aa1 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
@@ -145,13 +145,13 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi
const auto proFile = dynamic_cast<const QmakeProFile *>(pri);
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
- const QSet<FilePath> &newFilePaths = Utils::filtered(pri->files(type), [&toExclude](const Utils::FilePath &fn) {
- return !Utils::contains(toExclude, [&fn](const Utils::FilePath &ex) { return fn.isChildOf(ex); });
+ const SourceFiles &newFilePaths = Utils::filtered(pri->files(type), [&toExclude](const SourceFile &fn) {
+ return !Utils::contains(toExclude, [&fn](const Utils::FilePath &ex) { return fn.first.isChildOf(ex); });
});
if (proFile) {
- for (const FilePath &fp : newFilePaths) {
+ for (const SourceFile &fp : newFilePaths) {
for (const ExtraCompiler *ec : proFile->extraCompilers()) {
- if (ec->source() == fp)
+ if (ec->source() == fp.first)
generatedFiles << ec->targets();
}
}
@@ -165,33 +165,36 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi
vfolder->setAddFileFilter(fileTypes.at(i).addFileFilter);
if (type == FileType::Resource) {
- for (const FilePath &file : newFilePaths) {
+ for (const auto &file : newFilePaths) {
auto vfs = pri->project()->qmakeVfs();
QString contents;
QString errorMessage;
// Prefer the cumulative file if it's non-empty, based on the assumption
// that it contains more "stuff".
- int cid = vfs->idForFileName(file.toString(), QMakeVfs::VfsCumulative);
+ int cid = vfs->idForFileName(file.first.toString(), QMakeVfs::VfsCumulative);
vfs->readFile(cid, &contents, &errorMessage);
// If the cumulative evaluation botched the file too much, try the exact one.
if (contents.isEmpty()) {
- int eid = vfs->idForFileName(file.toString(), QMakeVfs::VfsExact);
+ int eid = vfs->idForFileName(file.first.toString(), QMakeVfs::VfsExact);
vfs->readFile(eid, &contents, &errorMessage);
}
auto topLevel = std::make_unique<ResourceEditor::ResourceTopLevelNode>
- (file, vfolder->filePath(), contents);
- const QString baseName = file.toFileInfo().completeBaseName();
+ (file.first, vfolder->filePath(), contents);
+ topLevel->setEnabled(file.second == FileOrigin::ExactParse);
+ const QString baseName = file.first.toFileInfo().completeBaseName();
topLevel->setIsGenerated(baseName.startsWith("qmake_")
|| baseName.endsWith("_qmlcache"));
vfolder->addNode(std::move(topLevel));
}
} else {
- for (const FilePath &fn : newFilePaths) {
+ for (const auto &fn : newFilePaths) {
// Qmake will flag everything in SOURCES as source, even when the
// qt quick compiler moves qrc files into it:-/ Get better data based on
// the filename.
- type = FileNode::fileTypeForFileName(fn);
- vfolder->addNestedNode(std::make_unique<FileNode>(fn, type));
+ type = FileNode::fileTypeForFileName(fn.first);
+ auto fileNode = std::make_unique<FileNode>(fn.first, type);
+ fileNode->setEnabled(fn.second == FileOrigin::ExactParse);
+ vfolder->addNestedNode(std::move(fileNode));
}
for (FolderNode *fn : vfolder->folderNodes())
fn->compress();
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
index 1fffb8d209..fc3be830c7 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp
@@ -103,6 +103,7 @@ namespace QmakeProjectManager {
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)); }
namespace Internal {
@@ -124,7 +125,8 @@ class QmakePriFileEvalResult
public:
QSet<FilePath> folders;
QSet<FilePath> recursiveEnumerateFiles;
- QMap<FileType, QSet<FilePath>> foundFiles;
+ QMap<FileType, QSet<FilePath>> foundFilesExact;
+ QMap<FileType, QSet<FilePath>> foundFilesCumulative;
};
class QmakeIncludedPriFile
@@ -228,14 +230,15 @@ void QmakePriFile::makeEmpty()
m_children.clear();
}
-QSet<FilePath> QmakePriFile::files(const FileType &type) const
+SourceFiles QmakePriFile::files(const FileType &type) const
{
return m_files.value(type);
}
const QSet<FilePath> QmakePriFile::collectFiles(const FileType &type) const
{
- QSet<FilePath> allFiles = files(type);
+ QSet<FilePath> allFiles = transform(files(type),
+ [](const SourceFile &sf) { return sf.first; });
for (const QmakePriFile * const priFile : qAsConst(m_children)) {
if (!dynamic_cast<const QmakeProFile *>(priFile))
allFiles.unite(priFile->collectFiles(type));
@@ -308,13 +311,14 @@ static QStringList fileListForVar(
void QmakePriFile::extractSources(
QHash<int, QmakePriFileEvalResult *> proToResult, QmakePriFileEvalResult *fallback,
- QVector<ProFileEvaluator::SourceFile> sourceFiles, FileType type)
+ QVector<ProFileEvaluator::SourceFile> sourceFiles, FileType type, bool cumulative)
{
foreach (const ProFileEvaluator::SourceFile &source, sourceFiles) {
auto *result = proToResult.value(source.proFileId);
if (!result)
result = fallback;
- result->foundFiles[type].insert(FilePath::fromString(source.fileName));
+ auto &foundFiles = cumulative ? result->foundFilesCumulative : result->foundFilesExact;
+ foundFiles[type].insert(FilePath::fromString(source.fileName));
}
}
@@ -356,11 +360,13 @@ void QmakePriFile::processValues(QmakePriFileEvalResult &result)
for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) {
auto type = static_cast<FileType>(i);
- QSet<FilePath> &foundFiles = result.foundFiles[type];
- result.recursiveEnumerateFiles.subtract(foundFiles);
- QSet<FilePath> newFilePaths = filterFilesProVariables(type, foundFiles);
- newFilePaths += filterFilesRecursiveEnumerata(type, result.recursiveEnumerateFiles);
- foundFiles = newFilePaths;
+ for (QSet<FilePath> * const foundFiles
+ : {&result.foundFilesExact[type], &result.foundFilesCumulative[type]}) {
+ result.recursiveEnumerateFiles.subtract(*foundFiles);
+ QSet<FilePath> newFilePaths = filterFilesProVariables(type, *foundFiles);
+ newFilePaths += filterFilesRecursiveEnumerata(type, result.recursiveEnumerateFiles);
+ *foundFiles = newFilePaths;
+ }
}
}
@@ -371,7 +377,15 @@ void QmakePriFile::update(const Internal::QmakePriFileEvalResult &result)
for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) {
const auto type = static_cast<FileType>(i);
- m_files[type] = result.foundFiles.value(type);
+ SourceFiles &files = m_files[type];
+ files.clear();
+ const QSet<FilePath> exactFps = result.foundFilesExact.value(type);
+ for (const FilePath &exactFp : exactFps)
+ files << qMakePair(exactFp, FileOrigin::ExactParse);
+ for (const FilePath &cumulativeFp : result.foundFilesCumulative.value(type)) {
+ if (!exactFps.contains(cumulativeFp))
+ files << qMakePair(cumulativeFp, FileOrigin::CumulativeParse);
+ }
}
}
@@ -439,9 +453,18 @@ bool QmakePriFile::folderChanged(const QString &changedFolder, const QSet<FilePa
qCDebug(qmakeParse()) << "For type" << static_cast<int>(type) <<"\n"
<< "added files" << add << "\n"
<< "removed files" << remove;
-
- m_files[type].unite(add);
- m_files[type].subtract(remove);
+ SourceFiles &currentFiles = m_files[type];
+ for (const FilePath &fp : add) {
+ if (!contains(currentFiles, [&fp](const SourceFile &sf) { return sf.first == fp; }))
+ currentFiles.insert(qMakePair(fp, FileOrigin::ExactParse));
+ }
+ for (const FilePath &fp : remove) {
+ const auto it = std::find_if(currentFiles.begin(), currentFiles.end(),
+ [&fp](const SourceFile &sf) {
+ return sf.first == fp; });
+ if (it != currentFiles.end())
+ currentFiles.erase(it);
+ }
}
}
return true;
@@ -632,6 +655,52 @@ bool QmakePriFile::renameFile(const QString &filePath, const QString &newFilePat
return changeProFileOptional;
}
+bool QmakePriFile::addDependencies(const QStringList &dependencies)
+{
+ if (dependencies.isEmpty())
+ return true;
+ if (!prepareForChange())
+ return false;
+
+ QStringList qtDependencies = filtered(dependencies, [](const QString &dep) {
+ return dep.length() > 3 && dep.startsWith("Qt.");
+ });
+ qtDependencies = transform(qtDependencies, [](const QString &dep) {
+ return dep.mid(3);
+ });
+ qtDependencies.removeOne("core");
+ if (qtDependencies.isEmpty())
+ return true;
+
+ const QPair<ProFile *, QStringList> pair = readProFile();
+ ProFile * const includeFile = pair.first;
+ if (!includeFile)
+ return false;
+ QStringList lines = pair.second;
+
+ const QString indent = continuationIndent();
+ const ProWriter::PutFlags appendFlags(ProWriter::AppendValues | ProWriter::AppendOperator);
+ if (!proFile()->variableValue(Variable::Config).contains("qt")) {
+ if (lines.removeAll("CONFIG -= qt") == 0) {
+ ProWriter::putVarValues(includeFile, &lines, {"qt"}, "CONFIG", appendFlags,
+ QString(), indent);
+ }
+ }
+
+ const QStringList currentQtDependencies = proFile()->variableValue(Variable::Qt);
+ qtDependencies = filtered(qtDependencies, [currentQtDependencies](const QString &dep) {
+ return !currentQtDependencies.contains(dep);
+ });
+ if (!qtDependencies.isEmpty()) {
+ ProWriter::putVarValues(includeFile, &lines, qtDependencies, "QT", appendFlags,
+ QString(), indent);
+ }
+
+ save(lines);
+ includeFile->deref();
+ return true;
+}
+
bool QmakePriFile::saveModifiedEditors()
{
Core::IDocument *document
@@ -704,27 +773,30 @@ bool QmakePriFile::ensureWriteableProFile(const QString &file)
return true;
}
-QPair<ProFile *, QStringList> QmakePriFile::readProFile(const QString &file)
+QPair<ProFile *, QStringList> QmakePriFile::readProFile()
{
QStringList lines;
ProFile *includeFile = nullptr;
{
QString contents;
{
- FileReader reader;
- if (!reader.fetch(file, QIODevice::Text)) {
- QmakeProject::proFileParseError(reader.errorString());
+ QString errorMsg;
+ if (TextFileFormat::readFile(
+ filePath().toString(),
+ Core::EditorManager::defaultTextCodec(),
+ &contents,
+ &m_textFormat,
+ &errorMsg) != TextFileFormat::ReadSuccess) {
+ QmakeProject::proFileParseError(errorMsg);
return qMakePair(includeFile, lines);
}
- const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
- contents = codec->toUnicode(reader.data());
- lines = contents.split(QLatin1Char('\n'));
+ lines = contents.split('\n');
}
QMakeVfs vfs;
QtSupport::ProMessageHandler handler;
QMakeParser parser(nullptr, &vfs, &handler);
- includeFile = parser.parsedProBlock(QStringRef(&contents), 0, file, 1);
+ includeFile = parser.parsedProBlock(QStringRef(&contents), 0, filePath().toString(), 1);
}
return qMakePair(includeFile, lines);
}
@@ -742,7 +814,7 @@ bool QmakePriFile::renameFile(const QString &oldName,
if (!prepareForChange())
return false;
- QPair<ProFile *, QStringList> pair = readProFile(filePath().toString());
+ QPair<ProFile *, QStringList> pair = readProFile();
ProFile *includeFile = pair.first;
QStringList lines = pair.second;
@@ -788,7 +860,7 @@ void QmakePriFile::changeFiles(const QString &mimeType,
if (!prepareForChange())
return;
- QPair<ProFile *, QStringList> pair = readProFile(filePath().toString());
+ QPair<ProFile *, QStringList> pair = readProFile();
ProFile *includeFile = pair.first;
QStringList lines = pair.second;
@@ -830,7 +902,7 @@ bool QmakePriFile::setProVariable(const QString &var, const QStringList &values,
if (!prepareForChange())
return false;
- QPair<ProFile *, QStringList> pair = readProFile(filePath().toString());
+ QPair<ProFile *, QStringList> pair = readProFile();
ProFile *includeFile = pair.first;
QStringList lines = pair.second;
@@ -849,11 +921,13 @@ bool QmakePriFile::setProVariable(const QString &var, const QStringList &values,
void QmakePriFile::save(const QStringList &lines)
{
{
+ QTC_ASSERT(m_textFormat.codec, return);
FileChangeBlocker changeGuard(filePath().toString());
- FileSaver saver(filePath().toString(), QIODevice::Text);
- const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
- saver.write(codec->fromUnicode(lines.join(QLatin1Char('\n'))));
- saver.finalize(Core::ICore::mainWindow());
+ QString errorMsg;
+ if (!m_textFormat.writeFile(filePath().toString(), lines.join('\n'), &errorMsg)) {
+ QMessageBox::critical(Core::ICore::mainWindow(), QCoreApplication::translate(
+ "QmakePriFile", "File Error"), errorMsg);
+ }
}
// This is a hack.
@@ -916,10 +990,7 @@ QStringList QmakePriFile::varNames(FileType type, QtSupport::ProFileReader *read
vars << QLatin1String("DISTFILES");
break;
default:
- vars << QLatin1String("OTHER_FILES");
- vars << QLatin1String("DISTFILES");
- vars << QLatin1String("ICON");
- vars << QLatin1String("QMAKE_INFO_PLIST");
+ vars << "DISTFILES" << "ICON" << "OTHER_FILES" << "QMAKE_INFO_PLIST" << "TRANSLATIONS";
break;
}
return vars;
@@ -1209,6 +1280,14 @@ void QmakeProFile::asyncUpdate()
m_parseFutureWatcher.setFuture(future);
}
+bool QmakeProFile::isFileFromWildcard(const QString &filePath) const
+{
+ const QFileInfo fileInfo(filePath);
+ const auto directoryIterator = m_wildcardDirectoryContents.constFind(fileInfo.path());
+ return (directoryIterator != m_wildcardDirectoryContents.end()
+ && directoryIterator.value().contains(fileInfo.fileName()));
+}
+
QmakeEvalInput QmakeProFile::evalInput() const
{
QmakeEvalInput input;
@@ -1395,14 +1474,14 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input)
auto sourceFiles = exactReader->absoluteFileValues(
qmakeVariable, input.projectDir, vPathsExact, &handled, result->directoriesWithWildcards);
exactSourceFiles[qmakeVariable] = sourceFiles;
- extractSources(proToResult, &result->includedFiles.result, sourceFiles, type);
+ extractSources(proToResult, &result->includedFiles.result, sourceFiles, type, false);
}
const QStringList vPathsCumulative = fullVPaths(
baseVPathsCumulative, cumulativeReader, qmakeVariable, input.projectDir);
auto sourceFiles = cumulativeReader->absoluteFileValues(
qmakeVariable, input.projectDir, vPathsCumulative, &handled, result->directoriesWithWildcards);
cumulativeSourceFiles[qmakeVariable] = sourceFiles;
- extractSources(proToResult, &result->includedFiles.result, sourceFiles, type);
+ extractSources(proToResult, &result->includedFiles.result, sourceFiles, type, true);
}
}
@@ -1729,11 +1808,30 @@ QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const F
}
}
+ bool tryUnfixified = false;
foreach (const ProFileEvaluator::SourceFile &el,
reader->fixifiedValues(QLatin1String("INCLUDEPATH"), projectDir, buildDir.toString(),
false)) {
- paths << sysrootify(el.fileName, sysroot.toString(), projectDir, buildDir.toString());
+ const QString sysrootifiedPath = sysrootify(el.fileName, sysroot.toString(), projectDir,
+ buildDir.toString());
+ if (IoUtils::isAbsolutePath(sysrootifiedPath) && IoUtils::exists(sysrootifiedPath))
+ paths << sysrootifiedPath;
+ else
+ tryUnfixified = true;
+ }
+
+ // If sysrootifying a fixified path does not yield a valid path, try again with the
+ // unfixified value. This can be necessary for cross-building; see QTCREATORBUG-21164.
+ if (tryUnfixified) {
+ const QStringList rawValues = reader->values("INCLUDEPATH");
+ for (const QString &p : rawValues) {
+ const QString sysrootifiedPath = sysrootify(QDir::cleanPath(p), sysroot.toString(),
+ projectDir, buildDir.toString());
+ if (IoUtils::isAbsolutePath(sysrootifiedPath) && IoUtils::exists(sysrootifiedPath))
+ paths << sysrootifiedPath;
+ }
}
+
// paths already contains moc dir and ui dir, due to corrrectly parsing uic.prf and moc.prf
// except if those directories don't exist at the time of parsing
// thus we add those directories manually (without checking for existence)
diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
index 76caaa0927..a6e7fa4ad5 100644
--- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h
@@ -31,11 +31,13 @@
#include <coreplugin/idocument.h>
#include <cpptools/generatedcodemodelsupport.h>
+#include <utils/textfileformat.h>
+#include <QFutureWatcher>
#include <QHash>
-#include <QStringList>
#include <QMap>
-#include <QFutureWatcher>
+#include <QPair>
+#include <QStringList>
#include <memory>
@@ -111,6 +113,11 @@ class QmakePriFileEvalResult;
class InstallsList;
+enum class FileOrigin { ExactParse, CumulativeParse };
+uint qHash(FileOrigin fo);
+using SourceFile = QPair<Utils::FilePath, FileOrigin>;
+using SourceFiles = QSet<SourceFile>;
+
// Implements ProjectNode for qmake .pri files
class QMAKEPROJECTMANAGER_EXPORT QmakePriFile
{
@@ -134,7 +141,7 @@ public:
void makeEmpty();
// Files of the specified type declared in this file.
- QSet<Utils::FilePath> files(const ProjectExplorer::FileType &type) const;
+ SourceFiles files(const ProjectExplorer::FileType &type) const;
// Files of the specified type declared in this file and in included .pri files.
const QSet<Utils::FilePath> collectFiles(const ProjectExplorer::FileType &type) const;
@@ -151,6 +158,7 @@ public:
bool deleteFiles(const QStringList &filePaths);
bool canRenameFile(const QString &filePath, const QString &newFilePath);
bool renameFile(const QString &filePath, const QString &newFilePath);
+ bool addDependencies(const QStringList &dependencies);
bool setProVariable(const QString &var, const QStringList &values,
const QString &scope = QString(),
@@ -201,17 +209,16 @@ private:
bool prepareForChange();
static bool ensureWriteableProFile(const QString &file);
- static QPair<ProFile *, QStringList> readProFile(const QString &file);
+ QPair<ProFile *, QStringList> readProFile();
static QPair<ProFile *, QStringList> readProFileFromContents(const QString &contents);
void save(const QStringList &lines);
bool saveModifiedEditors();
QStringList formResources(const QString &formFile) const;
static QStringList baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir);
static QStringList fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader, const QString &qmakeVariable, const QString &projectDir);
- static void extractSources(
- QHash<int, Internal::QmakePriFileEvalResult *> proToResult,
+ static void extractSources(QHash<int, Internal::QmakePriFileEvalResult *> proToResult,
Internal::QmakePriFileEvalResult *fallback,
- QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type);
+ QVector<ProFileEvaluator::SourceFile> sourceFiles, ProjectExplorer::FileType type, bool cumulative);
static void extractInstalls(
QHash<int, Internal::QmakePriFileEvalResult *> proToResult,
Internal::QmakePriFileEvalResult *fallback,
@@ -227,9 +234,10 @@ private:
QVector<QmakePriFile *> m_children;
std::unique_ptr<Core::IDocument> m_priFileDocument;
+ Utils::TextFileFormat m_textFormat;
// Memory is cheap...
- QMap<ProjectExplorer::FileType, QSet<Utils::FilePath>> m_files;
+ QMap<ProjectExplorer::FileType, SourceFiles> m_files;
QSet<Utils::FilePath> m_recursiveEnumerateFiles; // FIXME: Remove this?!
QSet<QString> m_watchedFolders;
bool m_includedInExactParse = true;
@@ -328,6 +336,8 @@ public:
void asyncUpdate();
+ bool isFileFromWildcard(const QString &filePath) const;
+
private:
void setParseInProgress(bool b);
void setValidParseRecursive(bool b);
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index e6dc5bb2d0..fc619f3b6c 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -34,16 +34,16 @@
#include "qmakeprojectmanagerconstants.h"
#include "qmakebuildconfiguration.h"
-#include <utils/algorithm.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
-#include <cpptools/cpprawprojectpart.h>
+#include <cpptools/cppmodelmanager.h>
+#include <cpptools/cppprojectupdater.h>
#include <cpptools/projectinfo.h>
#include <projectexplorer/headerpath.h>
-#include <cpptools/cppprojectupdater.h>
-#include <cpptools/cppmodelmanager.h>
+#include <projectexplorer/rawprojectpart.h>
+#include <utils/algorithm.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <projectexplorer/buildinfo.h>
@@ -129,6 +129,8 @@ QmakeProject::QmakeProject(const FilePath &fileName) :
setId(Constants::QMAKEPROJECT_ID);
setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
+ setCanBuildProducts();
+ setHasMakeInstallEquivalent(true);
const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
m_qmakeVfs->setTextCodec(codec);
@@ -220,25 +222,23 @@ void QmakeProject::updateCodeModels()
void QmakeProject::updateCppCodeModel()
{
- using ProjectPart = CppTools::ProjectPart;
-
m_toolChainWarnings.clear();
QtSupport::CppKitInfo kitInfo(this);
QTC_ASSERT(kitInfo.isValid(), return);
QList<ProjectExplorer::ExtraCompiler *> generators;
- CppTools::RawProjectParts rpps;
+ RawProjectParts rpps;
for (const QmakeProFile *pro : rootProFile()->allProFiles()) {
warnOnToolChainMismatch(pro);
- CppTools::RawProjectPart rpp;
+ RawProjectPart rpp;
rpp.setDisplayName(pro->displayName());
rpp.setProjectFileLocation(pro->filePath().toString());
rpp.setBuildSystemTarget(pro->filePath().toString());
const bool isExecutable = pro->projectType() == ProjectType::ApplicationTemplate;
- rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
- : CppTools::ProjectPart::Library);
+ rpp.setBuildTargetType(isExecutable ? ProjectExplorer::BuildTargetType::Executable
+ : ProjectExplorer::BuildTargetType::Library);
rpp.setFlagsForCxx({kitInfo.cxxToolChain, pro->variableValue(Variable::CppFlags)});
rpp.setFlagsForC({kitInfo.cToolChain, pro->variableValue(Variable::CFlags)});
@@ -250,7 +250,7 @@ void QmakeProject::updateCppCodeModel()
if (pro->variableValue(Variable::Config).contains(QLatin1String("qt")))
rpp.setQtVersion(kitInfo.projectPartQtVersion);
else
- rpp.setQtVersion(ProjectPart::NoQt);
+ rpp.setQtVersion(Utils::QtVersion::None);
// Header paths
ProjectExplorer::HeaderPaths headerPaths;
@@ -277,16 +277,14 @@ void QmakeProject::updateCppCodeModel()
fileList.prepend(CppTools::CppModelManager::configurationFileName());
rpp.setFiles(fileList, [cumulativeSourceFiles](const QString &filePath) {
// Keep this lambda thread-safe!
- return CppTools::ProjectFile(filePath,
- CppTools::ProjectFile::classify(filePath),
- !cumulativeSourceFiles.contains(filePath));
+ return !cumulativeSourceFiles.contains(filePath);
});
rpps.append(rpp);
}
CppTools::GeneratedCodeModelSupport::update(generators);
- m_cppCodeModelUpdater->update({this, kitInfo, rpps});
+ m_cppCodeModelUpdater->update({this, kitInfo, activeParseEnvironment(), rpps});
}
void QmakeProject::updateQmlJSCodeModel()
@@ -347,12 +345,6 @@ void QmakeProject::updateQmlJSCodeModel()
modelManager->updateProjectInfo(projectInfo, this);
}
-void QmakeProject::updateRunConfigurations()
-{
- if (activeTarget())
- activeTarget()->updateDefaultRunConfigurations();
-}
-
void QmakeProject::scheduleAsyncUpdate(QmakeProFile *file, QmakeProFile::AsyncUpdateDelay delay)
{
if (m_asyncUpdateState == ShuttingDown)
@@ -366,7 +358,6 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile *file, QmakeProFile::AsyncUp
}
file->setParseInProgressRecursive(true);
- setAllBuildConfigurationsEnabled(false);
if (m_asyncUpdateState == AsyncFullUpdatePending) {
// Just postpone
@@ -422,7 +413,6 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile::AsyncUpdateDelay delay)
}
rootProFile()->setParseInProgressRecursive(true);
- setAllBuildConfigurationsEnabled(false);
if (m_asyncUpdateState == AsyncUpdateInProgress) {
m_cancelEvaluate = true;
@@ -443,15 +433,15 @@ void QmakeProject::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
m_asyncUpdateTimer.stop();
m_asyncUpdateTimer.setInterval(qMin(m_asyncUpdateTimer.interval(),
delay == QmakeProFile::ParseLater ? UPDATE_INTERVAL : 0));
- if (!isParsing())
- emitParsingStarted();
+
m_asyncUpdateTimer.start();
}
void QmakeProject::incrementPendingEvaluateFutures()
{
+ if (m_pendingEvaluateFuturesCount == 0)
+ m_guard = guardParsingRun();
++m_pendingEvaluateFuturesCount;
- QTC_ASSERT(isParsing(), emitParsingStarted());
m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
m_asyncUpdateFutureInterface->progressMaximum() + 1);
}
@@ -480,19 +470,17 @@ void QmakeProject::decrementPendingEvaluateFutures()
if (m_asyncUpdateState == AsyncFullUpdatePending || m_asyncUpdateState == AsyncPartialUpdatePending) {
// Already parsing!
rootProFile()->setParseInProgressRecursive(true);
- setAllBuildConfigurationsEnabled(false);
startAsyncTimer(QmakeProFile::ParseLater);
} else if (m_asyncUpdateState != ShuttingDown){
// After being done, we need to call:
- setAllBuildConfigurationsEnabled(true);
m_asyncUpdateState = Base;
updateCodeModels();
updateBuildSystemData();
if (activeTarget())
activeTarget()->updateDefaultDeployConfigurations();
- updateRunConfigurations();
- emitParsingFinished(true); // Qmake always returns (some) data, even when it failed:-)
+ m_guard.markAsSuccess(); // Qmake always returns (some) data, even when it failed:-)
+ m_guard = {};
}
}
}
@@ -653,7 +641,7 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile *
Environment::const_iterator eit = env.constBegin(), eend = env.constEnd();
for (; eit != eend; ++eit)
- m_qmakeGlobals->environment.insert(env.key(eit), env.value(eit));
+ m_qmakeGlobals->environment.insert(env.key(eit), env.expandedValueForKey(env.key(eit)));
m_qmakeGlobals->setCommandLineArguments(rootProFile()->buildDir().toString(), qmakeArgs);
@@ -735,17 +723,6 @@ void QmakeProject::activeTargetWasChanged()
scheduleAsyncUpdate();
}
-void QmakeProject::setAllBuildConfigurationsEnabled(bool enabled)
-{
- foreach (Target *t, targets()) {
- foreach (BuildConfiguration *bc, t->buildConfigurations()) {
- auto qmakeBc = qobject_cast<QmakeBuildConfiguration *>(bc);
- if (qmakeBc)
- qmakeBc->setEnabled(enabled);
- }
- }
-}
-
static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file)
{
if (file->filePath() == fileName) {
@@ -763,7 +740,11 @@ static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file)
void QmakeProject::notifyChanged(const FilePath &name)
{
for (QmakeProject *project : s_projects) {
- if (project->files(QmakeProject::SourceFiles).contains(name))
+ if (!project
+ ->files([&name](const ProjectExplorer::Node *n) {
+ return Project::SourceFiles(n) && n->filePath() == name;
+ })
+ .isEmpty())
notifyChangedHelper(name, project->rootProFile());
}
}
@@ -933,19 +914,15 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder)
m_project->updateCodeModels();
}
-void QmakeProject::configureAsExampleProject(const QSet<Core::Id> &platforms)
+void QmakeProject::configureAsExampleProject()
{
QList<BuildInfo> infoList;
- QList<Kit *> kits = KitManager::kits();
- foreach (Kit *k, kits) {
- QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
- if (!version
- || (!platforms.isEmpty()
- && !Utils::contains(version->targetDeviceTypes(), [platforms](Core::Id i) { return platforms.contains(i); })))
- continue;
-
- if (auto factory = BuildConfigurationFactory::find(k, projectFilePath().toString()))
- infoList << factory->allAvailableSetups(k, projectFilePath().toString());
+ const QList<Kit *> kits = KitManager::kits();
+ for (Kit *k : kits) {
+ if (QtSupport::QtKitAspect::qtVersion(k) != nullptr) {
+ if (auto factory = BuildConfigurationFactory::find(k, projectFilePath()))
+ infoList << factory->allAvailableSetups(k, projectFilePath());
+ }
}
setup(infoList);
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h
index 42e8e57ec0..3c1b4f1ba6 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.h
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.h
@@ -95,7 +95,7 @@ public:
void watchFolders(const QStringList &l, QmakePriFile *file);
void unwatchFolders(const QStringList &l, QmakePriFile *file);
- void configureAsExampleProject(const QSet<Core::Id> &platforms) final;
+ void configureAsExampleProject() final;
void emitBuildDirectoryInitialized();
static void proFileParseError(const QString &errorMessage);
@@ -122,16 +122,12 @@ protected:
private:
ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override;
- bool hasMakeInstallEquivalent() const override { return true; }
void asyncUpdate();
void buildFinished(bool success);
void activeTargetWasChanged();
- void setAllBuildConfigurationsEnabled(bool enabled);
-
QString executableFor(const QmakeProFile *file);
- void updateRunConfigurations();
void updateCppCodeModel();
void updateQmlJSCodeModel();
@@ -180,6 +176,8 @@ private:
ProjectExplorer::Target *m_activeTarget = nullptr;
mutable ProjectExplorer::ProjectImporter *m_projectImporter = nullptr;
+
+ ParseGuard m_guard;
};
} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
index a5a2d673a1..962fd13b31 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp
@@ -44,15 +44,23 @@ using namespace QmakeProjectManager;
using namespace QmakeProjectManager::Internal;
using namespace ProjectExplorer;
+/// returns whether this is a shadow build configuration or not
+/// note, even if shadowBuild() returns true, it might be using the
+/// source directory as the shadow build directory, thus it
+/// still is a in-source build
+static bool isShadowBuild(BuildConfiguration *bc)
+{
+ return bc->buildDirectory() != bc->target()->project()->projectDirectory();
+}
+
QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
: NamedWidget(),
m_buildConfiguration(bc)
{
- const bool isShadowBuild = bc->isShadowBuild();
Project *project = bc->target()->project();
m_defaultShadowBuildDir
- = QmakeBuildConfiguration::shadowBuildDirectory(project->projectFilePath().toString(),
+ = QmakeBuildConfiguration::shadowBuildDirectory(project->projectFilePath(),
bc->target()->kit(),
Utils::FileUtils::qmakeFriendlyName(bc->displayName()),
bc->buildType());
@@ -61,7 +69,7 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
m_detailsContainer->setState(Utils::DetailsWidget::NoSummary);
auto vbox = new QVBoxLayout(this);
- vbox->setMargin(0);
+ vbox->setContentsMargins(0, 0, 0, 0);
vbox->addWidget(m_detailsContainer);
auto details = new QWidget(m_detailsContainer);
@@ -71,7 +79,7 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
shadowBuildLabel->setText(tr("Shadow build:"));
shadowBuildCheckBox = new QCheckBox(details);
- shadowBuildCheckBox->setChecked(isShadowBuild);
+ shadowBuildCheckBox->setChecked(isShadowBuild(m_buildConfiguration));
buildDirLabel = new QLabel(details);
buildDirLabel->setText(tr("Build directory:"));
@@ -115,7 +123,7 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
shadowBuildDirEdit->setHistoryCompleter(QLatin1String("Qmake.BuildDir.History"));
shadowBuildDirEdit->setEnvironment(bc->environment());
shadowBuildDirEdit->setBaseFileName(project->projectDirectory());
- if (isShadowBuild) {
+ if (isShadowBuild(m_buildConfiguration)) {
shadowBuildDirEdit->setPath(bc->rawBuildDirectory().toString());
inSourceBuildDirEdit->setVisible(false);
} else {
@@ -138,15 +146,8 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc)
connect(shadowBuildDirEdit, &Utils::PathChooser::rawPathChanged,
this, &QmakeProjectConfigWidget::shadowBuildEdited);
- project->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() {
- if (static_cast<BuildConfiguration *>(sender())->isActive())
- environmentChanged();
- });
- connect(project, &Project::activeProjectConfigurationChanged,
- this, [this](ProjectConfiguration *pc) {
- if (pc && pc->isActive())
- environmentChanged();
- });
+ connect(bc, &BuildConfiguration::enabledChanged,
+ this, &QmakeProjectConfigWidget::environmentChanged);
auto qmakeProject = static_cast<QmakeProject *>(bc->target()->project());
connect(qmakeProject, &QmakeProject::buildDirectoryInitialized,
@@ -296,7 +297,7 @@ void QmakeProjectConfigWidget::updateProblemLabel()
if (allGood) {
QString buildDirectory = m_buildConfiguration->target()->project()->projectDirectory().toString();
- if (m_buildConfiguration->isShadowBuild())
+ if (isShadowBuild(m_buildConfiguration))
buildDirectory = m_buildConfiguration->buildDirectory().toString();
Tasks issues;
issues = version->reportIssues(proFileName, buildDirectory);
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp
index fe3d1bf67d..d082961d52 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp
@@ -96,7 +96,7 @@ QStringList QmakeProjectImporter::importCandidates()
candidates << pfi.absolutePath();
foreach (Kit *k, KitManager::kits()) {
- QFileInfo fi(QmakeBuildConfiguration::shadowBuildDirectory(projectFilePath().toString(), k,
+ QFileInfo fi(QmakeBuildConfiguration::shadowBuildDirectory(projectFilePath(), k,
QString(), BuildConfiguration::Unknown));
const QString baseDir = fi.absolutePath();
@@ -235,7 +235,7 @@ const QList<BuildInfo> QmakeProjectImporter::buildInfoListForKit(const Kit *k, v
{
auto *data = static_cast<DirectoryData *>(directoryData);
auto factory = qobject_cast<QmakeBuildConfigurationFactory *>(
- BuildConfigurationFactory::find(k, projectFilePath().toString()));
+ BuildConfigurationFactory::find(k, projectFilePath()));
if (!factory)
return {};
@@ -296,7 +296,7 @@ Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersion
const QMakeStepConfig::TargetArchConfig &archConfig,
const QMakeStepConfig::OsType &osType) const
{
- Q_UNUSED(osType); // TODO use this to select the right toolchain?
+ Q_UNUSED(osType) // TODO use this to select the right toolchain?
return QtProjectImporter::createTemporaryKit(data,
[&data, parsedSpec, archConfig](Kit *k) -> void {
for (ToolChain * const tc : preferredToolChains(data.qt, parsedSpec, archConfig))
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
index adbc1709fb..fc6f56d678 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
@@ -194,6 +194,11 @@ void QmakeManager::buildFile()
}
}
+void QmakeManager::buildProduct(Project *project, Node *proFileNode)
+{
+ handleSubDirContextMenu(BUILD, false, project, proFileNode, nullptr);
+}
+
void QmakeManager::handleSubDirContextMenu(QmakeManager::Action action, bool isFileBuild)
{
handleSubDirContextMenu(action,
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h
index ab163f1a76..722ab07577 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h
@@ -62,9 +62,11 @@ public:
void buildFileContextMenu();
void buildFile();
+ static void buildProduct(ProjectExplorer::Project *project, ProjectExplorer::Node *proFileNode);
+
private:
void handleSubDirContextMenu(Action action, bool isFileBuild);
- void handleSubDirContextMenu(QmakeManager::Action action, bool isFileBuild,
+ static void handleSubDirContextMenu(QmakeManager::Action action, bool isFileBuild,
ProjectExplorer::Project *contextProject,
ProjectExplorer::Node *contextProFileNode,
ProjectExplorer::FileNode *buildableFile);
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro
index ccc64eda00..22bc00e0cd 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro
@@ -19,7 +19,6 @@ HEADERS += \
profilehighlighter.h \
profilehoverhandler.h \
wizards/qtprojectparameters.h \
- wizards/modulespage.h \
wizards/filespage.h \
wizards/qtwizard.h \
wizards/subdirsprojectwizard.h \
@@ -27,7 +26,6 @@ HEADERS += \
wizards/simpleprojectwizard.h \
qmakeprojectmanagerconstants.h \
qmakestep.h \
- qtmodulesinfo.h \
qmakeprojectconfigwidget.h \
externaleditors.h \
qmakebuildconfiguration.h \
@@ -35,7 +33,6 @@ HEADERS += \
addlibrarywizard.h \
librarydetailscontroller.h \
qmakeprojectmanager_global.h \
- desktopqmakerunconfiguration.h \
profilecompletionassist.h \
makefileparse.h \
qmakemakestep.h
@@ -54,21 +51,18 @@ SOURCES += \
profilehighlighter.cpp \
profilehoverhandler.cpp \
wizards/qtprojectparameters.cpp \
- wizards/modulespage.cpp \
wizards/filespage.cpp \
wizards/qtwizard.cpp \
wizards/subdirsprojectwizard.cpp \
wizards/subdirsprojectwizarddialog.cpp \
wizards/simpleprojectwizard.cpp \
qmakestep.cpp \
- qtmodulesinfo.cpp \
qmakeprojectconfigwidget.cpp \
externaleditors.cpp \
qmakebuildconfiguration.cpp \
qmakeparser.cpp \
addlibrarywizard.cpp \
librarydetailscontroller.cpp \
- desktopqmakerunconfiguration.cpp \
profilecompletionassist.cpp \
makefileparse.cpp \
qmakemakestep.cpp
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
index e045f60663..acdc5192c3 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs
@@ -26,7 +26,6 @@ Project {
name: "General"
files: [
"addlibrarywizard.cpp", "addlibrarywizard.h",
- "desktopqmakerunconfiguration.cpp", "desktopqmakerunconfiguration.h",
"externaleditors.cpp", "externaleditors.h",
"librarydetailscontroller.cpp", "librarydetailscontroller.h",
"librarydetailswidget.ui",
@@ -53,7 +52,6 @@ Project {
"qmakeprojectmanager_global.h",
"qmakeprojectmanagerconstants.h",
"qmakeprojectmanagerplugin.cpp", "qmakeprojectmanagerplugin.h",
- "qtmodulesinfo.cpp", "qtmodulesinfo.h",
]
}
@@ -78,7 +76,6 @@ Project {
prefix: "wizards/"
files: [
"filespage.cpp", "filespage.h",
- "modulespage.cpp", "modulespage.h",
"qtprojectparameters.cpp", "qtprojectparameters.h",
"qtwizard.cpp", "qtwizard.h",
"subdirsprojectwizard.cpp", "subdirsprojectwizard.h",
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h
index 8c3ed2a860..c3a2721ef1 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h
@@ -63,6 +63,8 @@ const char PROFILE_EVALUATE[] = "Qt4ProjectManager.ProFileEvaluate";
const char QMAKEPROJECT_ID[] = "Qt4ProjectManager.Qt4Project";
const char QMAKE_BC_ID[] = "Qt4ProjectManager.Qt4BuildConfiguration";
+const char MAKESTEP_BS_ID[] = "Qt4ProjectManager.MakeStep";
+const char QMAKE_BS_ID[] = "QtProjectManager.QMakeBuildStep";
// ICONS
const char ICON_QTQUICK_APP[] = ":/wizards/images/qtquickapp.png";
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
index bf21949215..74077eefac 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp
@@ -32,7 +32,6 @@
#include "qmakestep.h"
#include "qmakemakestep.h"
#include "qmakebuildconfiguration.h"
-#include "desktopqmakerunconfiguration.h"
#include "wizards/simpleprojectwizard.h"
#include "wizards/subdirsprojectwizard.h"
#include "customwidgetwizard/customwidgetwizard.h"
@@ -98,9 +97,6 @@ public:
QmakeMakeStepFactory makeStepFactory;
QmakeBuildConfigurationFactory buildConfigFactory;
- DesktopQmakeRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, DesktopQmakeRunConfiguration>
- runWorkerFactory;
ProFileEditorFactory profileEditorFactory;
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 104a093e4d..f8ca59f594 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -64,8 +64,6 @@ using namespace ProjectExplorer;
using namespace Utils;
namespace {
-const char QMAKE_BS_ID[] = "QtProjectManager.QMakeBuildStep";
-
const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments";
const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced";
const char QMAKE_USE_QTQUICKCOMPILER[] = "QtProjectManager.QMakeBuildStep.UseQtQuickCompiler";
@@ -74,10 +72,11 @@ const char QMAKE_QMLDEBUGLIBAUTO_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQm
const char QMAKE_QMLDEBUGLIB_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary";
}
-QMakeStep::QMakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, QMAKE_BS_ID)
+QMakeStep::QMakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, Constants::QMAKE_BS_ID)
{
//: QMakeStep default display name
setDefaultDisplayName(tr("qmake"));
+ setLowPriority();
}
QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const
@@ -182,8 +181,7 @@ bool QMakeStep::init()
else
workingDirectory = qmakeBc->buildDirectory().toString();
- m_qmakeExecutable = qtVersion->qmakeCommand();
- m_qmakeArguments = allArguments(qtVersion);
+ m_qmakeCommand = CommandLine{qtVersion->qmakeCommand(), allArguments(qtVersion), CommandLine::Raw};
m_runMakeQmake = (qtVersion->qtVersion() >= QtVersionNumber(5, 0 ,0));
QString makefile = workingDirectory + '/';
@@ -201,17 +199,16 @@ bool QMakeStep::init()
}
if (m_runMakeQmake) {
- m_makeExecutable = makeCommand();
- if (m_makeExecutable.isEmpty()) {
+ const FilePath make = makeCommand();
+ if (make.isEmpty()) {
emit addOutput(tr("Could not determine which \"make\" command to run. "
"Check the \"make\" step in the build configuration."),
BuildStep::OutputFormat::ErrorMessage);
return false;
}
- m_makeArguments = makeArguments(makefile);
+ m_makeCommand = CommandLine{make, makeArguments(makefile), CommandLine::Raw};
} else {
- m_makeExecutable.clear();
- m_makeArguments.clear();
+ m_makeCommand = {};
}
// Check whether we need to run qmake
@@ -311,12 +308,10 @@ void QMakeStep::finish(bool success)
runNextCommand();
}
-void QMakeStep::startOneCommand(const FilePath &command, const QString &args)
+void QMakeStep::startOneCommand(const CommandLine &command)
{
ProcessParameters *pp = processParameters();
- pp->setCommand(command);
- pp->setArguments(args);
- pp->resolveAll();
+ pp->setCommandLine(command);
AbstractProcessStep::doRun();
}
@@ -338,7 +333,7 @@ void QMakeStep::runNextCommand()
case State::RUN_QMAKE:
setOutputParser(new QMakeParser);
m_nextState = (m_runMakeQmake ? State::RUN_MAKE_QMAKE_ALL : State::POST_PROCESS);
- startOneCommand(m_qmakeExecutable, m_qmakeArguments);
+ startOneCommand(m_qmakeCommand);
return;
case State::RUN_MAKE_QMAKE_ALL:
{
@@ -346,7 +341,7 @@ void QMakeStep::runNextCommand()
parser->setWorkingDirectory(processParameters()->workingDirectory().toString());
setOutputParser(parser);
m_nextState = State::POST_PROCESS;
- startOneCommand(m_makeExecutable, m_makeArguments);
+ startOneCommand(m_makeCommand);
}
return;
case State::POST_PROCESS:
@@ -364,7 +359,7 @@ void QMakeStep::setUserArguments(const QString &arguments)
emit userArgumentsChanged();
- qmakeBuildConfiguration()->emitQMakeBuildConfigurationChanged();
+ emit qmakeBuildConfiguration()->qmakeBuildConfigurationChanged();
qmakeBuildConfiguration()->emitProFileEvaluateNeeded();
}
@@ -378,11 +373,21 @@ void QMakeStep::setExtraArguments(const QStringList &args)
if (m_extraArgs != args) {
m_extraArgs = args;
emit extraArgumentsChanged();
- qmakeBuildConfiguration()->emitQMakeBuildConfigurationChanged();
+ emit qmakeBuildConfiguration()->qmakeBuildConfigurationChanged();
qmakeBuildConfiguration()->emitProFileEvaluateNeeded();
}
}
+QStringList QMakeStep::extraParserArguments() const
+{
+ return m_extraParserArgs;
+}
+
+void QMakeStep::setExtraParserArguments(const QStringList &args)
+{
+ m_extraParserArgs = args;
+}
+
bool QMakeStep::linkQmlDebuggingLibrary() const
{
return m_linkQmlDebuggingLibrary;
@@ -397,7 +402,7 @@ void QMakeStep::setLinkQmlDebuggingLibrary(bool enable)
emit linkQmlDebuggingLibraryChanged();
- qmakeBuildConfiguration()->emitQMakeBuildConfigurationChanged();
+ emit qmakeBuildConfiguration()->qmakeBuildConfigurationChanged();
qmakeBuildConfiguration()->emitProFileEvaluateNeeded();
}
@@ -415,7 +420,7 @@ void QMakeStep::setUseQtQuickCompiler(bool enable)
emit useQtQuickCompilerChanged();
- qmakeBuildConfiguration()->emitQMakeBuildConfigurationChanged();
+ emit qmakeBuildConfiguration()->qmakeBuildConfigurationChanged();
qmakeBuildConfiguration()->emitProFileEvaluateNeeded();
}
@@ -432,14 +437,14 @@ void QMakeStep::setSeparateDebugInfo(bool enable)
emit separateDebugInfoChanged();
- qmakeBuildConfiguration()->emitQMakeBuildConfigurationChanged();
+ emit qmakeBuildConfiguration()->qmakeBuildConfigurationChanged();
qmakeBuildConfiguration()->emitProFileEvaluateNeeded();
}
FilePath QMakeStep::makeCommand() const
{
- auto ms = qobject_cast<BuildStepList *>(parent())->firstOfType<MakeStep>();
- return ms ? ms->effectiveMakeCommand() : FilePath();
+ auto ms = stepList()->firstOfType<MakeStep>();
+ return ms ? ms->effectiveMakeCommand().executable() : FilePath();
}
QString QMakeStep::makeArguments(const QString &makefile) const
@@ -476,7 +481,8 @@ QString QMakeStep::effectiveQMakeCall() const
QStringList QMakeStep::parserArguments()
{
- QStringList result;
+ // NOTE: extra parser args placed before the other args intentionally
+ QStringList result = m_extraParserArgs;
BaseQtVersion *qt = QtKitAspect::qtVersion(target()->kit());
QTC_ASSERT(qt, return QStringList());
for (QtcProcess::ConstArgIterator ait(allArguments(qt, ArgumentFlag::Expand)); ait.next(); ) {
@@ -591,6 +597,7 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
connect(step->qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged,
this, &QMakeStepConfigWidget::qmakeBuildConfigChanged);
connect(step->target(), &Target::kitChanged, this, &QMakeStepConfigWidget::qtVersionChanged);
+ connect(m_ui->abisListWidget, &QListWidget::itemChanged, this, &QMakeStepConfigWidget::abisChanged);
auto chooser = new Core::VariableChooser(m_ui->qmakeAdditonalArgumentsLineEdit);
chooser->addMacroExpanderProvider([step] { return step->macroExpander(); });
chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit);
@@ -660,6 +667,36 @@ void QMakeStepConfigWidget::separateDebugInfoChanged()
updateEffectiveQMakeCall();
}
+void QMakeStepConfigWidget::abisChanged()
+{
+ if (m_abisParam.isEmpty())
+ return;
+
+ QStringList args = m_step->extraArguments();
+ for (auto it = args.begin(); it != args.end(); ++it) {
+ if (it->startsWith(m_abisParam)) {
+ args.erase(it);
+ break;
+ }
+ }
+
+ QStringList abis;
+ for (int i = 0; i < m_ui->abisListWidget->count(); ++i) {
+ auto item = m_ui->abisListWidget->item(i);
+ if (item->checkState() == Qt::CheckState::Checked)
+ abis << item->text();
+ }
+ if (abis.isEmpty()) {
+ m_ui->abisListWidget->item(m_preferredAbiIndex)->setCheckState(Qt::CheckState::Checked);
+ return;
+ }
+ args << QStringLiteral("%1\"%2\"").arg(m_abisParam, abis.join(' '));
+ m_step->setExtraArguments(args);
+
+ updateSummaryLabel();
+ updateEffectiveQMakeCall();
+}
+
void QMakeStepConfigWidget::qmakeArgumentsLineEdited()
{
m_ignoreChange = true;
@@ -749,6 +786,32 @@ void QMakeStepConfigWidget::updateSummaryLabel()
setSummaryText(tr("<b>qmake:</b> No Qt version set. Cannot run qmake."));
return;
}
+ bool enableAbisSelect = qtVersion->qtAbis().size() > 1;
+ m_ui->abisLabel->setVisible(enableAbisSelect);
+ m_ui->abisListWidget->setVisible(enableAbisSelect);
+ if (enableAbisSelect && m_ui->abisListWidget->count() != qtVersion->qtAbis().size()) {
+ m_ui->abisListWidget->clear();
+ bool isAndroid = true;
+ m_preferredAbiIndex = -1;
+ for (const auto &abi : qtVersion->qtAbis()) {
+ auto item = new QListWidgetItem{abi.param(), m_ui->abisListWidget};
+ item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ item->setCheckState(Qt::Unchecked);
+ isAndroid = isAndroid && abi.osFlavor() == Abi::OSFlavor::AndroidLinuxFlavor;
+ if (isAndroid && (item->text() == "arm64-v8a" ||
+ (m_preferredAbiIndex == -1 && item->text() == "armeabi-v7a"))) {
+ m_preferredAbiIndex = m_ui->abisListWidget->count() - 1;
+ }
+ }
+ if (isAndroid)
+ m_abisParam = "ANDROID_ABIS=";
+
+ if (m_preferredAbiIndex == -1)
+ m_preferredAbiIndex = 0;
+ m_ui->abisListWidget->item(m_preferredAbiIndex)->setCheckState(Qt::Checked);
+ abisChanged();
+ }
+
// We don't want the full path to the .pro file
const QString args = m_step->allArguments(
qtVersion,
@@ -819,7 +882,7 @@ void QMakeStepConfigWidget::recompileMessageBoxFinished(int button)
QMakeStepFactory::QMakeStepFactory()
{
- registerStep<QMakeStep>(QMAKE_BS_ID);
+ registerStep<QMakeStep>(Constants::QMAKE_BS_ID);
setSupportedConfiguration(Constants::QMAKE_BC_ID);
setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
setDisplayName(QMakeStep::tr("qmake"));
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h
index 90fef01d35..0ca5a7e6e9 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.h
+++ b/src/plugins/qmakeprojectmanager/qmakestep.h
@@ -133,9 +133,13 @@ public:
// arguments set by the user
QString userArguments();
void setUserArguments(const QString &arguments);
- // QMake extra arguments. Not user editable.
+ // Extra arguments for qmake and pro file parser. Not user editable via UI.
QStringList extraArguments() const;
void setExtraArguments(const QStringList &args);
+ /* Extra arguments for pro file parser only. Not user editable via UI.
+ * This function is used in 3rd party plugin SailfishOS. */
+ QStringList extraParserArguments() const;
+ void setExtraParserArguments(const QStringList &args);
QString mkspec() const;
bool linkQmlDebuggingLibrary() const;
void setLinkQmlDebuggingLibrary(bool enable);
@@ -166,16 +170,16 @@ private:
void doCancel() override;
void finish(bool success) override;
- void startOneCommand(const Utils::FilePath &command, const QString &args);
+ void startOneCommand(const Utils::CommandLine &command);
void runNextCommand();
- Utils::FilePath m_qmakeExecutable;
- QString m_qmakeArguments;
- Utils::FilePath m_makeExecutable;
- QString m_makeArguments;
+ Utils::CommandLine m_qmakeCommand;
+ Utils::CommandLine m_makeCommand;
QString m_userArgs;
- // Extra arguments for qmake.
+ // Extra arguments for qmake and pro file parser
QStringList m_extraArgs;
+ // Extra arguments for pro file parser only
+ QStringList m_extraParserArgs;
// last values
enum class State { IDLE = 0, RUN_QMAKE, RUN_MAKE_QMAKE_ALL, POST_PROCESS };
@@ -207,6 +211,7 @@ private:
void linkQmlDebuggingLibraryChanged();
void useQtQuickCompilerChanged();
void separateDebugInfoChanged();
+ void abisChanged();
// slots for dealing with user changes in our UI
void qmakeArgumentsLineEdited();
@@ -226,6 +231,8 @@ private:
Internal::Ui::QMakeStep *m_ui = nullptr;
QMakeStep *m_step = nullptr;
bool m_ignoreChange = false;
+ int m_preferredAbiIndex = -1;
+ QString m_abisParam;
};
} // namespace QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.ui b/src/plugins/qmakeprojectmanager/qmakestep.ui
index a0d6ff79c7..ff5442c574 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.ui
+++ b/src/plugins/qmakeprojectmanager/qmakestep.ui
@@ -6,26 +6,11 @@
<rect>
<x>0</x>
<y>0</y>
- <width>440</width>
- <height>250</height>
+ <width>738</width>
+ <height>300</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
<item row="0" column="0">
<widget class="QLabel" name="label_0">
<property name="text">
@@ -275,6 +260,19 @@
</property>
</widget>
</item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="abisLabel">
+ <property name="text">
+ <string>ABIs:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QListWidget" name="abisListWidget"/>
+ </item>
</layout>
</widget>
<tabstops>
diff --git a/src/plugins/qmakeprojectmanager/qtmodulesinfo.cpp b/src/plugins/qmakeprojectmanager/qtmodulesinfo.cpp
deleted file mode 100644
index 202261bd7f..0000000000
--- a/src/plugins/qmakeprojectmanager/qtmodulesinfo.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qtmodulesinfo.h"
-#include <QDebug>
-#include <QString>
-#include <QCoreApplication>
-
-using namespace QmakeProjectManager::Internal;
-
-struct item
-{
- const char * const config;
- const QString name;
- const QString description;
- bool isDefault;
-};
-
-static inline QVector<const item*> itemVector()
-{
- static const struct item items[] = {
- {"core",
- QLatin1String("QtCore"),
- QCoreApplication::translate("QtModulesInfo", "Core non-GUI classes used by other modules"),
- true},
- {"gui",
- QLatin1String("QtGui"),
- QCoreApplication::translate("QtModulesInfo", "Base classes for graphical user interface (GUI) components. (Qt 4: Includes widgets. Qt 5: Includes OpenGL.)"),
- true},
- {"widgets",
- QLatin1String("QtWidgets"),
- QCoreApplication::translate("QtModulesInfo", "Classes to extend Qt GUI with C++ widgets (Qt 5)"),
- false},
- {"declarative",
- QLatin1String("QtDeclarative"),
- QCoreApplication::translate("QtModulesInfo", "Qt Quick 1 classes"),
- false},
- {"qml",
- QLatin1String("QtQml"),
- QCoreApplication::translate("QtModulesInfo", "Classes for QML and JavaScript languages (Qt 5)"),
- false},
- {"quick",
- QLatin1String("QtQuick"),
- QCoreApplication::translate("QtModulesInfo", "A declarative framework for building highly dynamic applications with custom user interfaces"),
- false},
- {"network",
- QLatin1String("QtNetwork"),
- QCoreApplication::translate("QtModulesInfo", "Classes for network programming"),
- false},
- {"opengl",
- QLatin1String("QtOpenGL"),
- QCoreApplication::translate("QtModulesInfo", "OpenGL support classes"),
- false},
- {"printsupport",
- QLatin1String("QtPrintSupport"),
- QCoreApplication::translate("QtModulesInfo", "Print support classes (Qt 5)"),
- false},
- {"sql",
- QLatin1String("QtSql"),
- QCoreApplication::translate("QtModulesInfo", "Classes for database integration using SQL"),
- false},
- {"script",
- QLatin1String("QtScript"),
- QCoreApplication::translate("QtModulesInfo", "Classes for evaluating Qt Scripts"),
- false},
- {"scripttools",
- QLatin1String("QtScriptTools"),
- QCoreApplication::translate("QtModulesInfo", "Additional Qt Script components"),
- false},
- {"svg",
- QLatin1String("QtSvg"),
- QCoreApplication::translate("QtModulesInfo", "Classes for displaying the contents of SVG files"),
- false},
- {"webengine",
- QLatin1String("QtWebEngine"),
- QCoreApplication::translate("QtModulesInfo", "Classes for displaying and editing Web content using Chromium backend"),
- false},
- {"webenginewidgets",
- QLatin1String("QtWebEngineWidgets"),
- QCoreApplication::translate("QtModulesInfo", "WebEngine and QWidget-based classes using Chromium backend"),
- false},
- {"webkit",
- QLatin1String("QtWebKit"),
- QCoreApplication::translate("QtModulesInfo", "Classes for displaying and editing Web content"),
- false},
- {"webkitwidgets",
- QLatin1String("QtWebKitWidgets"),
- QCoreApplication::translate("QtModulesInfo", "WebKit1 and QWidget-based classes from Qt 4 (Qt 5)"),
- false},
- {"xml",
- QLatin1String("QtXml"),
- QCoreApplication::translate("QtModulesInfo", "Classes for handling XML"),
- false},
- {"xmlpatterns",
- QLatin1String("QtXmlPatterns"),
- QCoreApplication::translate("QtModulesInfo", "An XQuery/XPath engine for XML and custom data models"),
- false},
- {"phonon",
- QLatin1String("Phonon"),
- QCoreApplication::translate("QtModulesInfo", "Multimedia framework classes (Qt 4 only)"),
- false},
- {"multimedia",
- QLatin1String("QtMultimedia"),
- QCoreApplication::translate("QtModulesInfo", "Classes for low-level multimedia functionality"),
- false},
- {"qt3support",
- QLatin1String("Qt3Support"),
- QCoreApplication::translate("QtModulesInfo", "Classes that ease porting from Qt 3 to Qt 4 (Qt 4 only)"),
- false},
- {"testlib",
- QLatin1String("QtTest"),
- QCoreApplication::translate("QtModulesInfo", "Tool classes for unit testing"),
- false},
- {"dbus",
- QLatin1String("QtDBus"),
- QCoreApplication::translate("QtModulesInfo", "Classes for Inter-Process Communication using the D-Bus"),
- false}
- };
- const int itemsCount = sizeof items / sizeof items[0];
- QVector<const item*> result;
- result.reserve(itemsCount);
- for (int i = 0; i < itemsCount; i++)
- result.append(items + i);
- return result;
-}
-
-class StaticQtModuleInfo
-{
-public:
- StaticQtModuleInfo() : items(itemVector()) {}
-
- const QVector<const item*> items;
-};
-
-Q_GLOBAL_STATIC(StaticQtModuleInfo, staticQtModuleInfo)
-
-QStringList QtModulesInfo::modules()
-{
- QStringList result;
- foreach (const item *i, staticQtModuleInfo()->items)
- result.push_back(QLatin1String(i->config));
- return result;
-}
-
-static inline const item *itemForModule(const QString &module)
-{
- foreach (const item *i, staticQtModuleInfo()->items)
- if (QLatin1String(i->config) == module)
- return i;
- return nullptr;
-}
-
-QString QtModulesInfo::moduleName(const QString &module)
-{
- const item * const i = itemForModule(module);
- return i?i->name:QString();
-}
-
-QString QtModulesInfo::moduleDescription(const QString &module)
-{
- const item * const i = itemForModule(module);
- return i?i->description:QString();
-}
-
-bool QtModulesInfo::moduleIsDefault(const QString &module)
-{
- const item * const i = itemForModule(module);
- return i?i->isDefault:false;
-}
diff --git a/src/plugins/qmakeprojectmanager/wizards/modulespage.cpp b/src/plugins/qmakeprojectmanager/wizards/modulespage.cpp
deleted file mode 100644
index b45213fc8a..0000000000
--- a/src/plugins/qmakeprojectmanager/wizards/modulespage.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "modulespage.h"
-
-#include <utils/wizard.h>
-
-#include <qmakeprojectmanager/qtmodulesinfo.h>
-
-#include <QDebug>
-
-#include <QCheckBox>
-#include <QLabel>
-#include <QLayout>
-#include <QWidget>
-
-using namespace QmakeProjectManager::Internal;
-
-ModulesPage::ModulesPage(QWidget *parent)
- : QWizardPage(parent)
-{
- setTitle(tr("Select Required Modules"));
- QLabel *label = new QLabel(tr("Select the modules you want to include in your "
- "project. The recommended modules for this project are selected by default."));
- label->setWordWrap(true);
-
- auto *vlayout = new QVBoxLayout();
- vlayout->addWidget(label);
- vlayout->addItem(new QSpacerItem(0, 20));
-
- auto *layout = new QGridLayout;
-
- const QStringList &modulesList = QtModulesInfo::modules();
- int moduleId = 0;
- int rowsCount = (modulesList.count() + 1) / 2;
- foreach (const QString &module, modulesList) {
- QCheckBox *moduleCheckBox = new QCheckBox(QtModulesInfo::moduleName(module));
- moduleCheckBox->setToolTip(QtModulesInfo::moduleDescription(module));
- moduleCheckBox->setWhatsThis(QtModulesInfo::moduleDescription(module));
- registerField(module, moduleCheckBox);
- int row = moduleId % rowsCount;
- int column = moduleId / rowsCount;
- layout->addWidget(moduleCheckBox, row, column);
- m_moduleCheckBoxMap[module] = moduleCheckBox;
- moduleId++;
- }
-
- vlayout->addLayout(layout);
- setLayout(vlayout);
-
- setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Modules"));
-}
-
-// Return the key that goes into the Qt config line for a module
-QString ModulesPage::idOfModule(const QString &module)
-{
- const QStringList &moduleIdList = QtModulesInfo::modules();
- foreach (const QString &id, moduleIdList)
- if (QtModulesInfo::moduleName(id).startsWith(module))
- return id;
- return QString();
-}
-
-QStringList ModulesPage::selectedModulesList() const
-{
- return modules(true);
-}
-
-QStringList ModulesPage::deselectedModulesList() const
-{
- return modules(false);
-}
-
-void ModulesPage::setModuleSelected(const QString &module, bool selected) const
-{
- QCheckBox *checkBox = m_moduleCheckBoxMap[module];
- Q_ASSERT(checkBox);
- checkBox->setCheckState(selected?Qt::Checked:Qt::Unchecked);
-}
-
-void ModulesPage::setModuleEnabled(const QString &module, bool enabled) const
-{
- QCheckBox *checkBox = m_moduleCheckBoxMap[module];
- Q_ASSERT(checkBox);
- checkBox->setEnabled(enabled);
-}
-
-QStringList ModulesPage::modules(bool selected) const
-{
- QStringList modules;
- foreach (const QString &module, QtModulesInfo::modules()) {
- if (selected != QtModulesInfo::moduleIsDefault(module)
- && selected == field(module).toBool())
- modules << module;
- }
- return modules;
-}
diff --git a/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp
index 0e9cd877a5..c6d90f617f 100644
--- a/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp
+++ b/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp
@@ -25,8 +25,6 @@
#include "qtwizard.h"
-#include "modulespage.h"
-
#include <qmakeprojectmanager/qmakeproject.h>
#include <qmakeprojectmanager/qmakeprojectmanager.h>
#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
@@ -39,20 +37,21 @@
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/targetsetuppage.h>
+
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
-#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <QCoreApplication>
#include <QVariant>
using namespace ProjectExplorer;
-using namespace QmakeProjectManager;
-using namespace QmakeProjectManager::Internal;
using namespace QtSupport;
+namespace QmakeProjectManager {
+namespace Internal {
+
// -------------------- QtWizard
QtWizard::QtWizard()
{
@@ -91,7 +90,7 @@ bool QtWizard::qt4ProjectPostGenerateFiles(const QWizard *w,
const auto *dialog = qobject_cast<const BaseQmakeProjectWizardDialog *>(w);
// Generate user settings
- foreach (const Core::GeneratedFile &file, generatedFiles)
+ for (const Core::GeneratedFile &file : generatedFiles)
if (file.attributes() & Core::GeneratedFile::OpenProjectAttribute) {
dialog->writeUserFile(file.path());
break;
@@ -123,8 +122,7 @@ CustomQmakeProjectWizard::CustomQmakeProjectWizard() = default;
Core::BaseFileWizard *CustomQmakeProjectWizard::create(QWidget *parent,
const Core::WizardDialogParameters &parameters) const
{
- auto *wizard = new BaseQmakeProjectWizardDialog(this, false, parent,
- parameters);
+ auto *wizard = new BaseQmakeProjectWizardDialog(this, parent, parameters);
if (!parameters.extraValues().contains(QLatin1String(ProjectExplorer::Constants::PROJECT_KIT_IDS)))
wizard->addTargetSetupPage(targetPageId);
@@ -142,7 +140,6 @@ bool CustomQmakeProjectWizard::postGenerateFiles(const QWizard *w, const Core::G
// ----------------- BaseQmakeProjectWizardDialog
BaseQmakeProjectWizardDialog::BaseQmakeProjectWizardDialog(
const Core::BaseFileWizardFactory *factory,
- bool showModulesPage,
QWidget *parent,
const Core::WizardDialogParameters &parameters)
: ProjectExplorer::BaseProjectWizardDialog(factory, parent, parameters)
@@ -152,12 +149,12 @@ BaseQmakeProjectWizardDialog::BaseQmakeProjectWizardDialog(
.toStringList(),
&Core::Id::fromString);
- init(showModulesPage);
+ connect(this, &BaseProjectWizardDialog::projectParametersChanged,
+ this, &BaseQmakeProjectWizardDialog::generateProfileName);
}
BaseQmakeProjectWizardDialog::BaseQmakeProjectWizardDialog(
const Core::BaseFileWizardFactory *factory,
- bool showModulesPage,
Utils::ProjectIntroPage *introPage,
int introId,
QWidget *parent,
@@ -168,35 +165,14 @@ BaseQmakeProjectWizardDialog::BaseQmakeProjectWizardDialog(
.value(ProjectExplorer::Constants::PROJECT_KIT_IDS)
.toStringList(),
&Core::Id::fromString);
- init(showModulesPage);
+ connect(this, &BaseProjectWizardDialog::projectParametersChanged,
+ this, &BaseQmakeProjectWizardDialog::generateProfileName);
}
BaseQmakeProjectWizardDialog::~BaseQmakeProjectWizardDialog()
{
if (m_targetSetupPage && !m_targetSetupPage->parent())
delete m_targetSetupPage;
- if (m_modulesPage && !m_modulesPage->parent())
- delete m_modulesPage;
-}
-
-void BaseQmakeProjectWizardDialog::init(bool showModulesPage)
-{
- if (showModulesPage)
- m_modulesPage = new ModulesPage;
- connect(this, &BaseProjectWizardDialog::projectParametersChanged,
- this, &BaseQmakeProjectWizardDialog::generateProfileName);
-}
-
-int BaseQmakeProjectWizardDialog::addModulesPage(int id)
-{
- if (!m_modulesPage)
- return -1;
- if (id >= 0) {
- setPage(id, m_modulesPage);
- return id;
- }
- const int newId = addPage(m_modulesPage);
- return newId;
}
int BaseQmakeProjectWizardDialog::addTargetSetupPage(int id)
@@ -220,40 +196,6 @@ int BaseQmakeProjectWizardDialog::addTargetSetupPage(int id)
return id;
}
-QStringList BaseQmakeProjectWizardDialog::selectedModulesList() const
-{
- return m_modulesPage ? m_modulesPage->selectedModulesList() : m_selectedModules;
-}
-
-void BaseQmakeProjectWizardDialog::setSelectedModules(const QString &modules, bool lock)
-{
- const QStringList modulesList = modules.split(QLatin1Char(' '));
- if (m_modulesPage) {
- foreach (const QString &module, modulesList) {
- m_modulesPage->setModuleSelected(module, true);
- m_modulesPage->setModuleEnabled(module, !lock);
- }
- } else {
- m_selectedModules = modulesList;
- }
-}
-
-QStringList BaseQmakeProjectWizardDialog::deselectedModulesList() const
-{
- return m_modulesPage ? m_modulesPage->deselectedModulesList() : m_deselectedModules;
-}
-
-void BaseQmakeProjectWizardDialog::setDeselectedModules(const QString &modules)
-{
- const QStringList modulesList = modules.split(QLatin1Char(' '));
- if (m_modulesPage) {
- foreach (const QString &module, modulesList)
- m_modulesPage->setModuleSelected(module, false);
- } else {
- m_deselectedModules = modulesList;
- }
-}
-
bool BaseQmakeProjectWizardDialog::writeUserFile(const QString &proFileName) const
{
if (!m_targetSetupPage)
@@ -267,14 +209,6 @@ bool BaseQmakeProjectWizardDialog::writeUserFile(const QString &proFileName) con
return success;
}
-bool BaseQmakeProjectWizardDialog::isQtPlatformSelected(Core::Id platform) const
-{
- QList<Core::Id> selectedKitList = selectedKits();
-
- return Utils::contains(KitManager::kits(QtKitAspect::platformPredicate(platform)),
- [selectedKitList](const Kit *k) { return selectedKitList.contains(k->id()); });
-}
-
QList<Core::Id> BaseQmakeProjectWizardDialog::selectedKits() const
{
if (!m_targetSetupPage)
@@ -282,20 +216,15 @@ QList<Core::Id> BaseQmakeProjectWizardDialog::selectedKits() const
return m_targetSetupPage->selectedKits();
}
-void BaseQmakeProjectWizardDialog::addExtensionPages(const QList<QWizardPage *> &wizardPageList)
-{
- foreach (QWizardPage *p,wizardPageList)
- addPage(p);
-}
-
void BaseQmakeProjectWizardDialog::generateProfileName(const QString &name, const QString &path)
{
if (!m_targetSetupPage)
return;
- const QString proFile =
- QDir::cleanPath(path + QLatin1Char('/') + name + QLatin1Char('/')
- + name + QLatin1String(".pro"));
+ const QString proFile = QDir::cleanPath(path + '/' + name + '/' + name + ".pro");
- m_targetSetupPage->setProjectPath(proFile);
+ m_targetSetupPage->setProjectPath(Utils::FilePath::fromString(proFile));
}
+
+} // Internal
+} // QmakeProjectManager
diff --git a/src/plugins/qmakeprojectmanager/wizards/qtwizard.h b/src/plugins/qmakeprojectmanager/wizards/qtwizard.h
index 1196c92a2a..d58f8ccf85 100644
--- a/src/plugins/qmakeprojectmanager/wizards/qtwizard.h
+++ b/src/plugins/qmakeprojectmanager/wizards/qtwizard.h
@@ -40,8 +40,6 @@ class QmakeProject;
namespace Internal {
-class ModulesPage;
-
/* Base class for wizard creating Qt projects using QtProjectParameters.
* To implement a project wizard, overwrite:
* - createWizardDialog() to create up the dialog
@@ -104,40 +102,24 @@ class BaseQmakeProjectWizardDialog : public ProjectExplorer::BaseProjectWizardDi
Q_OBJECT
protected:
explicit BaseQmakeProjectWizardDialog(const Core::BaseFileWizardFactory *factory,
- bool showModulesPage,
Utils::ProjectIntroPage *introPage,
int introId, QWidget *parent,
const Core::WizardDialogParameters &parameters);
public:
explicit BaseQmakeProjectWizardDialog(const Core::BaseFileWizardFactory *factory,
- bool showModulesPage, QWidget *parent,
+ QWidget *parent,
const Core::WizardDialogParameters &parameters);
~BaseQmakeProjectWizardDialog() override;
- int addModulesPage(int id = -1);
int addTargetSetupPage(int id = -1);
- QStringList selectedModulesList() const;
- void setSelectedModules(const QString &, bool lock = false);
-
- QStringList deselectedModulesList() const;
- void setDeselectedModules(const QString &);
-
bool writeUserFile(const QString &proFileName) const;
- bool isQtPlatformSelected(Core::Id platform) const;
QList<Core::Id> selectedKits() const;
- void addExtensionPages(const QList<QWizardPage *> &wizardPageList);
-
private:
void generateProfileName(const QString &name, const QString &path);
- inline void init(bool showModulesPage);
-
- ModulesPage *m_modulesPage = nullptr;
ProjectExplorer::TargetSetupPage *m_targetSetupPage = nullptr;
- QStringList m_selectedModules;
- QStringList m_deselectedModules;
QList<Core::Id> m_profileIds;
};
diff --git a/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp
index 77c6fdd10f..ffb85af92c 100644
--- a/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp
+++ b/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp
@@ -221,7 +221,7 @@ GeneratedFiles SimpleProjectWizard::generateFiles(const QWizard *w,
bool SimpleProjectWizard::postGenerateFiles(const QWizard *w, const GeneratedFiles &l,
QString *errorMessage) const
{
- Q_UNUSED(w);
+ Q_UNUSED(w)
return CustomProjectWizard::postGenerateOpen(l, errorMessage);
}
diff --git a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizarddialog.cpp b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizarddialog.cpp
index 1a544ba8e8..bb61539502 100644
--- a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizarddialog.cpp
+++ b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizarddialog.cpp
@@ -33,7 +33,7 @@ SubdirsProjectWizardDialog::SubdirsProjectWizardDialog(const Core::BaseFileWizar
const QString &templateName,
const QIcon &icon, QWidget *parent,
const Core::WizardDialogParameters &parameters) :
- BaseQmakeProjectWizardDialog(factory, false, parent, parameters)
+ BaseQmakeProjectWizardDialog(factory, parent, parameters)
{
setWindowIcon(icon);
setWindowTitle(templateName);
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 1786026e73..99b82116bf 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -16,6 +16,7 @@ add_qtc_plugin(QmlDesigner
designmodewidget.cpp designmodewidget.h
documentmanager.cpp documentmanager.h
documentwarningwidget.cpp documentwarningwidget.h
+ generateresource.cpp generateresource.h
openuiqmlfiledialog.cpp openuiqmlfiledialog.h openuiqmlfiledialog.ui
qmldesignerconstants.h
qmldesignericons.h
@@ -27,6 +28,8 @@ add_qtc_plugin(QmlDesigner
components/propertyeditor/propertyeditorvalue.h
components/connectioneditor/connectionviewwidget.h
SKIP_DEBUG_CMAKE_FILE_CHECK
+ EXTRA_TRANSLATIONS
+ "${PROJECT_SOURCE_DIR}/share/qtcreator/qmldesigner"
)
set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/qmldesigner")
@@ -499,6 +502,11 @@ extend_qtc_plugin(QmlDesigner
)
extend_qtc_plugin(QmlDesigner
+ SOURCES_PREFIX components/bindingeditor
+ SOURCES bindingeditor.cpp bindingeditor.h
+)
+
+extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/colortool
SOURCES colortool.cpp colortool.h
)
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
new file mode 100644
index 0000000000..2fb9587787
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp
@@ -0,0 +1,324 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "bindingeditor.h"
+
+#include <qmldesignerplugin.h>
+
+#include "texteditorview.h"
+#include "texteditorwidget.h"
+#include <texteditor/texteditor.h>
+
+#include <coreplugin/icore.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+
+#include <qmldesigner/qmldesignerplugin.h>
+#include <qmldesigner/qmldesignerconstants.h>
+#include <qmljseditor/qmljseditor.h>
+#include <qmljseditor/qmljseditorconstants.h>
+#include <qmljstools/qmljstoolsconstants.h>
+#include <qmljseditor/qmljscompletionassist.h>
+#include <qmljseditor/qmljshighlighter.h>
+#include <qmljseditor/qmljshoverhandler.h>
+#include <qmljstools/qmljsindenter.h>
+#include <qmljseditor/qmljsautocompleter.h>
+#include <qmljseditor/qmljseditordocument.h>
+#include <qmljseditor/qmljssemantichighlighter.h>
+#include <texteditor/textdocument.h>
+#include <texteditor/texteditoractionhandler.h>
+#include <texteditor/codeassist/assistinterface.h>
+#include <texteditor/codeassist/completionassistprovider.h>
+#include <texteditor/syntaxhighlighter.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
+
+#include <QDialogButtonBox>
+#include <QDebug>
+#include <QVBoxLayout>
+
+namespace QmlDesigner {
+
+static BindingEditor *s_lastBindingEditor = nullptr;
+
+const char BINDINGEDITOR_CONTEXT_ID[] = "BindingEditor.BindingEditorContext";
+
+BindingEditorWidget::BindingEditorWidget()
+ : m_context(new BindingEditorContext(this))
+{
+ Core::ICore::addContextObject(m_context);
+
+ 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(Core::useMacShortcuts ? tr("Meta+Space") : tr("Ctrl+Space")));
+
+ connect(m_completionAction, &QAction::triggered, [this]() {
+ invokeAssist(TextEditor::Completion);
+ });
+}
+
+BindingEditorWidget::~BindingEditorWidget()
+{
+ unregisterAutoCompletion();
+
+ Core::ICore::removeContextObject(m_context);
+ delete m_context;
+}
+
+void BindingEditorWidget::unregisterAutoCompletion()
+{
+ if (m_completionAction)
+ {
+ Core::ActionManager::unregisterAction(m_completionAction, TextEditor::Constants::COMPLETE_THIS);
+ delete m_completionAction;
+ m_completionAction = nullptr;
+ }
+}
+
+TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const
+{
+ Q_UNUSED(assistKind);
+ return new QmlJSEditor::QmlJSCompletionAssistInterface(document(), position(), QString(), assistReason, qmljsdocument->semanticInfo());
+}
+
+class BindingDocument : public QmlJSEditor::QmlJSEditorDocument
+{
+public:
+ BindingDocument()
+ : QmlJSEditor::QmlJSEditorDocument(BINDINGEDITOR_CONTEXT_ID)
+ , m_semanticHighlighter(new QmlJSEditor::SemanticHighlighter(this)) {}
+ ~BindingDocument() { delete m_semanticHighlighter; }
+
+protected:
+ void applyFontSettings()
+ {
+ TextDocument::applyFontSettings();
+ m_semanticHighlighter->updateFontSettings(fontSettings());
+ if (!isSemanticInfoOutdated()) {
+ m_semanticHighlighter->rerun(semanticInfo());
+ }
+ }
+
+ void triggerPendingUpdates()
+ {
+ TextDocument::triggerPendingUpdates(); // calls applyFontSettings if necessary
+ if (!isSemanticInfoOutdated()) {
+ m_semanticHighlighter->rerun(semanticInfo());
+ }
+ }
+
+private:
+ QmlJSEditor::SemanticHighlighter *m_semanticHighlighter = nullptr;
+};
+
+class BindingEditorFactory : public TextEditor::TextEditorFactory
+{
+public:
+ BindingEditorFactory() {
+ setId(BINDINGEDITOR_CONTEXT_ID);
+ setDisplayName(QCoreApplication::translate("OpenWith::Editors", BINDINGEDITOR_CONTEXT_ID));
+
+
+ setDocumentCreator([]() { return new BindingDocument; });
+ setEditorWidgetCreator([]() { return new BindingEditorWidget; });
+ setEditorCreator([]() { return new QmlJSEditor::QmlJSEditor; });
+ setAutoCompleterCreator([]() { return new QmlJSEditor::AutoCompleter; });
+ setCommentDefinition(Utils::CommentDefinition::CppStyle);
+ setParenthesesMatchingEnabled(true);
+ setCodeFoldingSupported(true);
+
+ addHoverHandler(new QmlJSEditor::QmlJSHoverHandler);
+ setCompletionAssistProvider(new QmlJSEditor::QmlJSCompletionAssistProvider);
+ }
+
+ static void decorateEditor(TextEditor::TextEditorWidget *editor)
+ {
+ editor->textDocument()->setSyntaxHighlighter(new QmlJSEditor::QmlJSHighlighter);
+ editor->textDocument()->setIndenter(new QmlJSEditor::Internal::Indenter(editor->textDocument()->document()));
+ editor->setAutoCompleter(new QmlJSEditor::AutoCompleter);
+ }
+};
+
+BindingEditorDialog::BindingEditorDialog(QWidget *parent)
+ : QDialog(parent)
+ , m_editor(nullptr)
+ , m_editorWidget(nullptr)
+ , m_verticalLayout(nullptr)
+ , m_buttonBox(nullptr)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setWindowTitle(tr("Binding Editor"));
+ setModal(false);
+
+ setupJSEditor();
+ setupUIComponents();
+
+ QObject::connect(m_buttonBox, &QDialogButtonBox::accepted,
+ this, &BindingEditorDialog::accepted);
+ QObject::connect(m_buttonBox, &QDialogButtonBox::rejected,
+ this, &BindingEditorDialog::rejected);
+}
+
+BindingEditorDialog::~BindingEditorDialog()
+{
+ delete m_editor; //m_editorWidget is handled by basetexteditor destructor
+ delete m_buttonBox;
+ delete m_verticalLayout;
+}
+
+void BindingEditorDialog::showWidget(int x, int y)
+{
+ this->show();
+ this->raise();
+ move(QPoint(x, y));
+ m_editorWidget->setFocus();
+}
+
+QString BindingEditorDialog::editorValue() const
+{
+ if (!m_editorWidget)
+ return {};
+
+ return m_editorWidget->document()->toPlainText();
+}
+
+void BindingEditorDialog::setEditorValue(const QString &text)
+{
+ if (m_editorWidget)
+ m_editorWidget->document()->setPlainText(text);
+}
+
+void BindingEditorDialog::unregisterAutoCompletion()
+{
+ if (m_editorWidget)
+ m_editorWidget->unregisterAutoCompletion();
+}
+
+void BindingEditorDialog::setupJSEditor()
+{
+ static BindingEditorFactory f;
+ m_editor = qobject_cast<TextEditor::BaseTextEditor*>(f.createEditor());
+ m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget());
+
+ Core::Context context = m_editor->context();
+ context.prepend(BINDINGEDITOR_CONTEXT_ID);
+ m_editorWidget->m_context->setContext(context);
+
+ auto qmlDesignerEditor = QmlDesignerPlugin::instance()->currentDesignDocument()->textEditor();
+
+ m_editorWidget->qmljsdocument = qobject_cast<QmlJSEditor::QmlJSEditorWidget *>(
+ qmlDesignerEditor->widget())->qmlJsEditorDocument();
+
+ m_editorWidget->setParent(this);
+
+ m_editorWidget->setLineNumbersVisible(false);
+ m_editorWidget->setMarksVisible(false);
+ m_editorWidget->setCodeFoldingSupported(false);
+ m_editorWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_editorWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_editorWidget->setTabChangesFocus(true);
+ m_editorWidget->show();
+}
+
+void BindingEditorDialog::setupUIComponents()
+{
+ m_verticalLayout = new QVBoxLayout(this);
+
+ m_buttonBox = new QDialogButtonBox(this);
+ m_buttonBox->setOrientation(Qt::Horizontal);
+ m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
+ m_editorWidget->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+
+ m_verticalLayout->addWidget(m_editorWidget);
+ m_verticalLayout->addWidget(m_buttonBox);
+
+ this->resize(600,200);
+}
+
+BindingEditor::BindingEditor(QObject *)
+{
+}
+
+BindingEditor::~BindingEditor()
+{
+ hideWidget();
+}
+
+void BindingEditor::registerDeclarativeType()
+{
+ qmlRegisterType<BindingEditor>("HelperWidgets", 2, 0, "BindingEditor");
+}
+
+void BindingEditor::showWidget(int x, int y)
+{
+ if (s_lastBindingEditor)
+ s_lastBindingEditor->hideWidget();
+ s_lastBindingEditor = this;
+
+ m_dialog = new BindingEditorDialog(Core::ICore::dialogParent());
+
+
+ QObject::connect(m_dialog, &BindingEditorDialog::accepted,
+ this, &BindingEditor::accepted);
+ QObject::connect(m_dialog, &BindingEditorDialog::rejected,
+ this, &BindingEditor::rejected);
+
+ m_dialog->setAttribute(Qt::WA_DeleteOnClose);
+ m_dialog->showWidget(x, 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();
+ }
+}
+
+QString BindingEditor::bindingValue() const
+{
+ if (!m_dialog)
+ return {};
+
+ return m_dialog->editorValue();
+}
+
+void BindingEditor::setBindingValue(const QString &text)
+{
+ if (m_dialog)
+ m_dialog->setEditorValue(text);
+}
+
+
+}
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
new file mode 100644
index 0000000000..4c57ed2847
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#ifndef BINDINGEDITOR_H
+#define BINDINGEDITOR_H
+
+#include "texteditorview.h"
+#include <texteditor/texteditor.h>
+#include <QtQml>
+
+#include <QWidget>
+#include <QDialog>
+#include <QPointer>
+
+#include <qmljseditor/qmljseditor.h>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+class QTextEdit;
+class QDialogButtonBox;
+class QVBoxLayout;
+QT_END_NAMESPACE
+
+namespace QmlDesigner {
+
+class BindingEditorContext : public Core::IContext
+{
+ Q_OBJECT
+public:
+ BindingEditorContext(QWidget *parent) : Core::IContext(parent)
+ {
+ setWidget(parent);
+ }
+};
+
+class BindingEditorWidget : public QmlJSEditor::QmlJSEditorWidget
+{
+ Q_OBJECT
+public:
+ BindingEditorWidget();
+ ~BindingEditorWidget();
+
+ void unregisterAutoCompletion();
+
+ TextEditor::AssistInterface *createAssistInterface(TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const;
+
+ QmlJSEditor::QmlJSEditorDocument *qmljsdocument = nullptr;
+ BindingEditorContext *m_context = nullptr;
+ QAction *m_completionAction = nullptr;
+};
+
+class BindingEditorDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ BindingEditorDialog(QWidget *parent = nullptr);
+ ~BindingEditorDialog() override;
+
+ void showWidget(int x, int y);
+
+ QString editorValue() const;
+ void setEditorValue(const QString &text);
+
+ void unregisterAutoCompletion();
+
+private:
+ void setupJSEditor();
+ void setupUIComponents();
+
+private:
+ TextEditor::BaseTextEditor *m_editor = nullptr;
+ BindingEditorWidget *m_editorWidget = nullptr;
+ QVBoxLayout *m_verticalLayout = nullptr;
+ QDialogButtonBox *m_buttonBox = nullptr;
+};
+
+class BindingEditor : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString text READ bindingValue WRITE setBindingValue)
+
+public:
+ BindingEditor(QObject *parent = nullptr);
+ ~BindingEditor();
+
+ static void registerDeclarativeType();
+
+ Q_INVOKABLE void showWidget(int x, int y);
+ Q_INVOKABLE void hideWidget();
+
+ QString bindingValue() const;
+ void setBindingValue(const QString &text);
+
+signals:
+ void accepted();
+ void rejected();
+
+private:
+ QPointer<BindingEditorDialog> m_dialog;
+
+};
+
+}
+
+QML_DECLARE_TYPE(QmlDesigner::BindingEditor)
+
+#endif //BINDINGEDITOR_H
diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri
new file mode 100644
index 0000000000..518905eb2a
--- /dev/null
+++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.pri
@@ -0,0 +1,3 @@
+HEADERS += $$PWD/bindingeditor.h
+
+SOURCES += $$PWD/bindingeditor.cpp
diff --git a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp
index c2a17cd7b1..b7e10a6da7 100644
--- a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp
@@ -90,7 +90,11 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent)
});
connect(comboBox,
+ #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QOverload<const QString &>::of(&QComboBox::activated),
+ #else
+ &QComboBox::textActivated,
+ #endif
this,
[this](const QString &style) {
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 37e1fdfd53..b9282a3326 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -1070,10 +1070,10 @@ DesignerActionToolBar::DesignerActionToolBar(QWidget *parentWidget) : Utils::Sty
auto horizontalLayout = new QHBoxLayout(this);
- horizontalLayout->setMargin(0);
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
horizontalLayout->setSpacing(0);
- horizontalLayout->setMargin(0);
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
horizontalLayout->setSpacing(0);
horizontalLayout->addWidget(m_toolBar);
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
index 415127cb52..c0dea6b3c5 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
@@ -63,7 +63,7 @@ void populateMenu(QSet<ActionInterface* > &actionInterfaces,
actionInterfaces.subtract(matchingFactories);
- QList<ActionInterface* > matchingFactoriesList = matchingFactories.toList();
+ QList<ActionInterface* > matchingFactoriesList = Utils::toList(matchingFactories);
Utils::sort(matchingFactoriesList, [](ActionInterface *l, ActionInterface *r) {
return l->priority() > r->priority();
});
@@ -100,8 +100,7 @@ void ModelNodeContextMenu::execute(const QPoint &position, bool selectionMenuBoo
manager.setupContext();
- QSet<ActionInterface* > factories =
- QSet<ActionInterface* >::fromList(manager.designerActions());
+ QSet<ActionInterface* > factories = Utils::toSet(manager.designerActions());
populateMenu(factories, QByteArray(), mainMenu, m_selectionContext);
diff --git a/src/plugins/qmldesigner/components/componentcore/theme.cpp b/src/plugins/qmldesigner/components/componentcore/theme.cpp
index d7eba033ca..ec4128479f 100644
--- a/src/plugins/qmldesigner/components/componentcore/theme.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/theme.cpp
@@ -93,7 +93,7 @@ void Theme::setupTheme(QQmlEngine *engine)
"Theme", [](QQmlEngine *, QJSEngine *) {
return qobject_cast<QObject*>(new Theme(Utils::creatorTheme(), nullptr));
});
- Q_UNUSED(typeIndex);
+ Q_UNUSED(typeIndex)
engine->addImageProvider(QLatin1String("icons"), new QmlDesignerIconProvider());
}
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index 6186fe736c..7a711923cc 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -541,7 +541,7 @@ void GraphicsView::drawValueScale(QPainter *painter, const QRectF &rect)
double GraphicsView::timeLabelInterval(QPainter *painter, double maxTime)
{
QFontMetrics fm(painter->font());
- int minTextSpacing = fm.width(QString("X%1X").arg(maxTime));
+ int minTextSpacing = fm.horizontalAdvance(QString("X%1X").arg(maxTime));
int deltaTime = 1;
int nextFactor = 5;
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp
index a5af39efbb..3dff7bf784 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/handleitem.cpp
@@ -76,8 +76,8 @@ QRectF HandleItem::boundingRect() const
void HandleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
QColor handleColor(isSelected() ? m_style.selectionColor : m_style.color);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp
index 4640b3eb82..836212d684 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp
@@ -61,8 +61,8 @@ QRectF KeyframeItem::boundingRect() const
void KeyframeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
QPen pen = painter->pen();
pen.setColor(Qt::black);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp
index 13fdeb72ed..cc337f25fc 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/selector.cpp
@@ -109,7 +109,7 @@ void Selector::mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playh
void Selector::mouseRelease(QMouseEvent *event, GraphicsView *view)
{
- Q_UNUSED(event);
+ Q_UNUSED(event)
applyPreSelection(view);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp
index 95ace49942..c70dcd6eda 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/treemodel.cpp
@@ -122,7 +122,7 @@ int TreeModel::rowCount(const QModelIndex &parent) const
int TreeModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return m_root->columnCount();
}
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp
index 87e299d953..37cf791871 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/treeview.cpp
@@ -108,8 +108,8 @@ void TreeView::changeCurve(unsigned int id, const AnimationCurve &curve)
void TreeView::changeSelection(const QItemSelection &selected, const QItemSelection &deselected)
{
- Q_UNUSED(selected);
- Q_UNUSED(deselected);
+ Q_UNUSED(selected)
+ Q_UNUSED(deselected)
std::vector<CurveItem *> curves;
for (auto index : selectedIndexes()) {
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp
index 4bc1cd285d..f255cfd29e 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp
@@ -70,9 +70,7 @@ QPalette singleColorPalette(const QColor &color)
{
QPalette palette;
palette.setColor(QPalette::Window, color);
- palette.setColor(QPalette::Background, color);
palette.setColor(QPalette::WindowText, color);
- palette.setColor(QPalette::Foreground, color);
palette.setColor(QPalette::Base, color);
palette.setColor(QPalette::AlternateBase, color);
palette.setColor(QPalette::ToolTipBase, color);
diff --git a/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp
index b4bfc027d5..4b66f96b56 100644
--- a/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/treeitem.cpp
@@ -233,7 +233,7 @@ NodeTreeItem::NodeTreeItem(const QString &name, const QIcon &icon)
: TreeItem(name)
, m_icon(icon)
{
- Q_UNUSED(icon);
+ Q_UNUSED(icon)
}
NodeTreeItem *NodeTreeItem::asNodeItem()
diff --git a/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp b/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp
index 22e1c86dbc..4c96433e5b 100644
--- a/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/contentnoteditableindicator.cpp
@@ -111,14 +111,12 @@ void ContentNotEditableIndicator::addAddiationEntries(const QList<FormEditorItem
void ContentNotEditableIndicator::removeEntriesWhichAreNotInTheList(const QList<FormEditorItem *> &itemList)
{
- QMutableListIterator<EntryPair> entryIterator(m_entryList);
-
- while (entryIterator.hasNext()) {
- EntryPair &entryPair = entryIterator.next();
+ for (int i = 0; i < m_entryList.size(); ++i) {
+ const EntryPair &entryPair = m_entryList.at(i);
if (!itemList.contains(entryPair.first)) {
delete entryPair.second;
entryPair.first->blurContent(false);
- entryIterator.remove();
+ m_entryList.removeAt(i--);
}
}
}
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp
index 045aec9007..71d8671296 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp
@@ -39,6 +39,7 @@
#include <QGraphicsView>
#include <QDebug>
+#include <QElapsedTimer>
#include <QList>
#include <QTime>
@@ -255,16 +256,16 @@ void FormEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
currentTool()->mousePressEvent(removeLayerItems(itemsAt(event->scenePos())), event);
}
-static QTime staticTimer()
+static QElapsedTimer staticTimer()
{
- QTime timer;
+ QElapsedTimer timer;
timer.start();
return timer;
}
void FormEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
- static QTime time = staticTimer();
+ static QElapsedTimer time = staticTimer();
QGraphicsScene::mouseMoveEvent(event);
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
index b42bf35e62..2a9eea5ea6 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
@@ -61,7 +61,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) :
setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/formeditorstylesheet.css")))));
auto fillLayout = new QVBoxLayout(this);
- fillLayout->setMargin(0);
+ fillLayout->setContentsMargins(0, 0, 0, 0);
fillLayout->setSpacing(0);
setLayout(fillLayout);
@@ -209,7 +209,7 @@ void FormEditorWidget::resetNodeInstanceView()
void FormEditorWidget::wheelEvent(QWheelEvent *event)
{
if (event->modifiers().testFlag(Qt::ControlModifier)) {
- if (event->delta() > 0)
+ if (event->angleDelta().y() > 0)
zoomAction()->zoomOut();
else
zoomAction()->zoomIn();
diff --git a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp
index 0de06fc360..c2df77b16b 100644
--- a/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/movemanipulator.cpp
@@ -181,9 +181,9 @@ QPointF MoveManipulator::findSnappingOffset(const QHash<FormEditorItem*, QRectF>
QMap<double, double> verticalOffsetMap;
QMap<double, double> horizontalOffsetMap;
- QHashIterator<FormEditorItem*, QRectF> hashIterator(boundingRectHash);
- while (hashIterator.hasNext()) {
- hashIterator.next();
+ for (auto hashIterator = boundingRectHash.cbegin(), end = boundingRectHash.cend();
+ hashIterator != end;
+ ++hashIterator) {
FormEditorItem *formEditorItem = hashIterator.key();
QRectF boundingRect = hashIterator.value();
@@ -230,10 +230,10 @@ QHash<FormEditorItem*, QRectF> MoveManipulator::tanslatedBoundingRects(const QHa
{
QHash<FormEditorItem*, QRectF> translatedBoundingRectHash;
- QHashIterator<FormEditorItem*, QRectF> hashIterator(boundingRectHash);
- while (hashIterator.hasNext()) {
+ for (auto hashIterator = boundingRectHash.cbegin(), end = boundingRectHash.cend();
+ hashIterator != end;
+ ++hashIterator) {
QPointF alignedOffset(offsetVector);
- hashIterator.next();
FormEditorItem *formEditorItem = hashIterator.key();
QRectF boundingRect = transform.mapRect(hashIterator.value());
diff --git a/src/plugins/qmldesigner/components/formeditor/movetool.cpp b/src/plugins/qmldesigner/components/formeditor/movetool.cpp
index 5011a5099c..ee2f1d57aa 100644
--- a/src/plugins/qmldesigner/components/formeditor/movetool.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/movetool.cpp
@@ -32,6 +32,8 @@
#include "resizehandleitem.h"
+#include <utils/algorithm.h>
+
#include <QApplication>
#include <QGraphicsSceneMouseEvent>
#include <QAction>
@@ -341,28 +343,20 @@ void MoveTool::beginWithPoint(const QPointF &beginPoint)
m_moveManipulator.begin(beginPoint);
}
-
-
-QList<FormEditorItem*> movalbeItems(const QList<FormEditorItem*> &itemList)
+static QList<FormEditorItem *> movableItems(const QList<FormEditorItem *> &itemList)
{
- QList<FormEditorItem*> filteredItemList(itemList);
-
- QMutableListIterator<FormEditorItem*> listIterator(filteredItemList);
- while (listIterator.hasNext()) {
- FormEditorItem *item = listIterator.next();
- if (!item->qmlItemNode().isValid()
- || !item->qmlItemNode().instanceIsMovable()
- || !item->qmlItemNode().modelIsMovable()
- || item->qmlItemNode().instanceIsInLayoutable())
- listIterator.remove();
- }
-
- return filteredItemList;
+ return Utils::filtered(itemList, [](FormEditorItem *item) {
+ const QmlItemNode node = item->qmlItemNode();
+ return node.isValid()
+ && node.instanceIsMovable()
+ && node.modelIsMovable()
+ && !node.instanceIsInLayoutable();
+ });
}
QList<FormEditorItem*> MoveTool::movingItems(const QList<FormEditorItem*> &selectedItemList)
{
- QList<FormEditorItem*> filteredItemList = movalbeItems(selectedItemList);
+ QList<FormEditorItem*> filteredItemList = movableItems(selectedItemList);
FormEditorItem* ancestorItem = ancestorIfOtherItemsAreChild(filteredItemList);
diff --git a/src/plugins/qmldesigner/components/formeditor/onedimensionalcluster.cpp b/src/plugins/qmldesigner/components/formeditor/onedimensionalcluster.cpp
index aee6bba6dc..47066dd3d2 100644
--- a/src/plugins/qmldesigner/components/formeditor/onedimensionalcluster.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/onedimensionalcluster.cpp
@@ -93,17 +93,16 @@ QList<OneDimensionalCluster> OneDimensionalCluster::reduceOneDimensionalClusterL
Utils::sort(workingList);
reducedList.clear();
bool clusterMerged = false;
- QListIterator<OneDimensionalCluster> clusterIterator(workingList);
- while (clusterIterator.hasNext())
- {
- OneDimensionalCluster currentCluster = clusterIterator.next();
- if (clusterIterator.hasNext())
- {
- OneDimensionalCluster nextCluster = clusterIterator.peekNext();
+
+ for (int i = 0, n = workingList.size(); i != n; ) {
+
+ OneDimensionalCluster currentCluster = workingList.at(i);
+ if (i + 1 < n) {
+ OneDimensionalCluster nextCluster = workingList.at(i + 1);
if ((nextCluster.mean() - currentCluster.mean()) < maximumDistance)
{
reducedList.append(currentCluster + nextCluster);
- clusterIterator.next();
+ ++i;
clusterMerged = true;
}
else
diff --git a/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp b/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp
index 55f80798d7..bc4c95232c 100644
--- a/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp
@@ -42,19 +42,14 @@ ResizeIndicator::~ResizeIndicator()
void ResizeIndicator::show()
{
- QHashIterator<FormEditorItem*, ResizeController> itemControllerIterator(m_itemControllerHash);
- while (itemControllerIterator.hasNext()) {
- ResizeController controller = itemControllerIterator.next().value();
+ for (ResizeController controller : m_itemControllerHash)
controller.show();
- }
}
+
void ResizeIndicator::hide()
{
- QHashIterator<FormEditorItem*, ResizeController> itemControllerIterator(m_itemControllerHash);
- while (itemControllerIterator.hasNext()) {
- ResizeController controller = itemControllerIterator.next().value();
+ for (ResizeController controller : m_itemControllerHash)
controller.hide();
- }
}
void ResizeIndicator::clear()
diff --git a/src/plugins/qmldesigner/components/formeditor/selectiontool.h b/src/plugins/qmldesigner/components/formeditor/selectiontool.h
index 9b685451ce..c16ef4f30f 100644
--- a/src/plugins/qmldesigner/components/formeditor/selectiontool.h
+++ b/src/plugins/qmldesigner/components/formeditor/selectiontool.h
@@ -33,6 +33,7 @@
#include "bindingindicator.h"
#include "contentnoteditableindicator.h"
+#include <QElapsedTimer>
#include <QTime>
namespace QmlDesigner {
@@ -87,7 +88,7 @@ private:
AnchorIndicator m_anchorIndicator;
BindingIndicator m_bindingIndicator;
ContentNotEditableIndicator m_contentNotEditableIndicator;
- QTime m_mousePressTimer;
+ QElapsedTimer m_mousePressTimer;
QCursor m_cursor;
bool m_itemSelectedAndMovable = false;
};
diff --git a/src/plugins/qmldesigner/components/formeditor/snapper.cpp b/src/plugins/qmldesigner/components/formeditor/snapper.cpp
index eec5c3ab1e..361a8a46b4 100644
--- a/src/plugins/qmldesigner/components/formeditor/snapper.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/snapper.cpp
@@ -311,9 +311,9 @@ QList<QLineF> Snapper::findSnappingLines(const SnapLineMap &snappingLineMap,
{
QList<QLineF> lineList;
- SnapLineMapIterator snappingLineIterator(snappingLineMap);
- while (snappingLineIterator.hasNext()) {
- snappingLineIterator.next();
+ for (auto snappingLineIterator = snappingLineMap.cbegin(), end = snappingLineMap.cend();
+ snappingLineIterator != end;
+ ++snappingLineIterator) {
if (compareLines(snapLine, snappingLineIterator.key())) { // near distance snapping lines
lineList += createSnapLine(orientation,
@@ -339,9 +339,9 @@ QList<QLineF> Snapper::findSnappingOffsetLines(const SnapLineMap &snappingOffset
{
QList<QLineF> lineList;
- SnapLineMapIterator snappingOffsetIterator(snappingOffsetMap);
- while (snappingOffsetIterator.hasNext()) {
- snappingOffsetIterator.next();
+ for (auto snappingOffsetIterator = snappingOffsetMap.cbegin(), end = snappingOffsetMap.cend();
+ snappingOffsetIterator != end;
+ ++snappingOffsetIterator) {
const QRectF &formEditorItemRect(snappingOffsetIterator.value().first);
double formEditorItemRectLowerLimit;
@@ -377,9 +377,9 @@ double Snapper::snappedOffsetForLines(const SnapLineMap &snappingLineMap,
{
QMultiMap<double, double> minimumSnappingLineMap;
- SnapLineMapIterator snappingLineIterator(snappingLineMap);
- while (snappingLineIterator.hasNext()) {
- snappingLineIterator.next();
+ for (auto snappingLineIterator = snappingLineMap.cbegin(), end = snappingLineMap.cend();
+ snappingLineIterator != end;
+ ++snappingLineIterator) {
double snapLine = snappingLineIterator.key();
double offset = value - snapLine;
double distance = qAbs(offset);
@@ -403,9 +403,9 @@ double Snapper::snappedOffsetForOffsetLines(const SnapLineMap &snappingOffsetMap
{
QMultiMap<double, double> minimumSnappingLineMap;
- SnapLineMapIterator snappingOffsetIterator(snappingOffsetMap);
- while (snappingOffsetIterator.hasNext()) {
- snappingOffsetIterator.next();
+ for (auto snappingOffsetIterator = snappingOffsetMap.cbegin(), end = snappingOffsetMap.cend();
+ snappingOffsetIterator != end;
+ ++snappingOffsetIterator) {
double snapLine = snappingOffsetIterator.key();
const QRectF &formEditorItemRect(snappingOffsetIterator.value().first);
double formEditorItemRectLowerLimit;
@@ -492,13 +492,12 @@ static QList<QLineF> mergedHorizontalLines(const QList<QLineF> &lineList)
});
QList<QLineF> lineWithTheSameY;
- QListIterator<QLineF> sortedLineListIterator(sortedLineList);
- while (sortedLineListIterator.hasNext()) {
- QLineF line = sortedLineListIterator.next();
+ for (int i = 0, n = sortedLineList.size(); i < n; ++i) {
+ QLineF line = sortedLineList.at(i);
lineWithTheSameY.append(line);
- if (sortedLineListIterator.hasNext()) {
- QLineF nextLine = sortedLineListIterator.peekNext();
+ if (i + 1 < n) {
+ QLineF nextLine = sortedLineList.at(i + 1);
if (!qFuzzyCompare(line.y1(), nextLine.y1())) {
mergedLineList.append(mergedHorizontalLine(lineWithTheSameY));
lineWithTheSameY.clear();
@@ -521,13 +520,12 @@ static QList<QLineF> mergedVerticalLines(const QList<QLineF> &lineList)
});
QList<QLineF> lineWithTheSameX;
- QListIterator<QLineF> sortedLineListIterator(sortedLineList);
- while (sortedLineListIterator.hasNext()) {
- QLineF line = sortedLineListIterator.next();
+ for (int i = 0, n = sortedLineList.size(); i < n; ++i) {
+ QLineF line = sortedLineList.at(i);
lineWithTheSameX.append(line);
- if (sortedLineListIterator.hasNext()) {
- QLineF nextLine = sortedLineListIterator.peekNext();
+ if (i + 1 < n) {
+ QLineF nextLine = sortedLineList.at(i + 1);
if (!qFuzzyCompare(line.x1(), nextLine.x1())) {
mergedLineList.append(mergedVerticalLine(lineWithTheSameX));
lineWithTheSameX.clear();
@@ -565,9 +563,9 @@ static QmlItemNode findItemOnSnappingLine(const QmlItemNode &sourceQmlItemNode,
else
compareAnchorLineType = AnchorLineLeft;
- SnapLineMapIterator snapLineIterator(snappingLines);
- while (snapLineIterator.hasNext()) {
- snapLineIterator.next();
+ for (auto snapLineIterator = snappingLines.cbegin(), end = snappingLines.cend();
+ snapLineIterator != end;
+ ++snapLineIterator) {
double snapLine = snapLineIterator.key();
if (qAbs(snapLine - anchorLine ) < 1.0) {
diff --git a/src/plugins/qmldesigner/components/formeditor/snappinglinecreator.h b/src/plugins/qmldesigner/components/formeditor/snappinglinecreator.h
index aba0a52444..032426629b 100644
--- a/src/plugins/qmldesigner/components/formeditor/snappinglinecreator.h
+++ b/src/plugins/qmldesigner/components/formeditor/snappinglinecreator.h
@@ -32,7 +32,6 @@ namespace QmlDesigner {
class FormEditorItem;
using SnapLineMap = QMultiMap<double, QPair<QRectF, FormEditorItem*> >;
-using SnapLineMapIterator = QMapIterator<double, QPair<QRectF, FormEditorItem*> >;
class FormEditorItem;
diff --git a/src/plugins/qmldesigner/components/formeditor/toolbox.cpp b/src/plugins/qmldesigner/components/formeditor/toolbox.cpp
index 3c64139748..c72db4c37c 100644
--- a/src/plugins/qmldesigner/components/formeditor/toolbox.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/toolbox.cpp
@@ -43,7 +43,7 @@ ToolBox::ToolBox(QWidget *parentWidget)
m_leftToolBar->setOrientation(Qt::Horizontal);
auto horizontalLayout = new QHBoxLayout(this);
- horizontalLayout->setMargin(0);
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
horizontalLayout->setSpacing(0);
auto stretchToolbar = new QToolBar(this);
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
index 8dd1c0727e..b37bbdfa36 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
@@ -129,7 +129,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
QWidget *lineEditFrame = new QWidget(this);
lineEditFrame->setObjectName(QStringLiteral("itemLibrarySearchInputFrame"));
auto lineEditLayout = new QGridLayout(lineEditFrame);
- lineEditLayout->setMargin(2);
+ lineEditLayout->setContentsMargins(2, 2, 2, 2);
lineEditLayout->setSpacing(0);
lineEditLayout->addItem(new QSpacerItem(5, 3, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0, 1, 3);
lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 0);
@@ -167,11 +167,11 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
auto flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
- flowLayout->setMargin(4);
+ flowLayout->setContentsMargins(4, 4, 4, 4);
m_addResourcesWidget->setVisible(false);
flowLayout = new Utils::FlowLayout(m_addResourcesWidget.data());
- flowLayout->setMargin(4);
+ flowLayout->setContentsMargins(4, 4, 4, 4);
auto button = new QToolButton(m_addResourcesWidget.data());
auto font = button->font();
font.setPixelSize(Theme::instance()->smallFontPixelSize());
diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp
index 8739ec64a8..78c0d50ad5 100644
--- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp
+++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp
@@ -93,7 +93,7 @@ static QPixmap getWavyPixmap(qreal maxRadius, const QPen &pen)
const QString pixmapKey = QStringLiteral("WaveUnderline-Bauhaus");
QPixmap pixmap;
- if (QPixmapCache::find(pixmapKey, pixmap))
+ if (QPixmapCache::find(pixmapKey, &pixmap))
return pixmap;
pixmap = generateWavyPixmap(maxRadius, pen);
@@ -258,7 +258,7 @@ static void setId(const QModelIndex &index, const QString &newId)
void NameItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
- Q_UNUSED(model);
+ Q_UNUSED(model)
auto lineEdit = static_cast<QLineEdit*>(editor);
setId(index,lineEdit->text());
lineEdit->clearFocus();
diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp
index 0fbdc04415..12103b048b 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp
@@ -59,7 +59,7 @@ NavigatorWidget::NavigatorWidget(NavigatorView *view)
auto layout = new QVBoxLayout;
layout->setSpacing(0);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
auto tabBar = new QTabBar(this);
tabBar->addTab(tr("Navigator"));
diff --git a/src/plugins/qmldesigner/components/pathtool/pathitem.cpp b/src/plugins/qmldesigner/components/pathtool/pathitem.cpp
index 76fe6f0b90..602666e895 100644
--- a/src/plugins/qmldesigner/components/pathtool/pathitem.cpp
+++ b/src/plugins/qmldesigner/components/pathtool/pathitem.cpp
@@ -104,9 +104,9 @@ void PathItem::writeCubicPath(const ModelNode &pathNode, const CubicSegment &cub
void PathItem::writePathAttributes(const ModelNode &pathNode, const QMap<QString, QVariant> &attributes)
{
- QMapIterator<QString, QVariant> attributesIterator(attributes);
- while (attributesIterator.hasNext()) {
- attributesIterator.next();
+ for (auto attributesIterator = attributes.cbegin(), end = attributes.cend();
+ attributesIterator != end;
+ ++attributesIterator) {
QList<QPair<PropertyName, QVariant> > propertyList;
propertyList.append(PropertyPair("name", attributesIterator.key()));
propertyList.append(PropertyPair("value", attributesIterator.value()));
@@ -471,7 +471,7 @@ static QRectF boundingRectForPath(const QList<ControlPoint> &controlPoints)
yMaximum = qMax(yMaximum, controlPoint.coordinate().y());
}
- return QRect(xMinimum, yMinimum, xMaximum - xMinimum, yMaximum - yMinimum);
+ return QRectF(xMinimum, yMinimum, xMaximum - xMinimum, yMaximum - yMinimum);
}
void PathItem::updateBoundingRect()
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp
index 9d2454c4e9..518dea7b8b 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp
@@ -169,7 +169,7 @@ QGradient GradientPresetItem::createGradientFromPreset(Preset value)
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
return QGradient(value);
#else
- Q_UNUSED(value);
+ Q_UNUSED(value)
return {};
#endif
}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
index e71ceef485..aec4c3b7a1 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
@@ -270,7 +270,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
qCInfo(propertyEditorBenchmark) << Q_FUNC_INFO;
- QTime time;
+ QElapsedTimer time;
if (propertyEditorBenchmark().isInfoEnabled())
time.start();
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp
index 87c281a997..c7a9e6473e 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp
@@ -44,8 +44,9 @@
#include <theme.h>
#include <coreplugin/icore.h>
-#include <utils/fileutils.h>
#include <coreplugin/messagebox.h>
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
#include <QCoreApplication>
#include <QDir>
@@ -145,7 +146,7 @@ void PropertyEditorView::changeValue(const QString &name)
if (propertyName == "className")
return;
- if (!m_selectedNode.isValid())
+ if (noValidSelection())
return;
if (propertyName == "id") {
@@ -232,7 +233,7 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
if (locked())
return;
- if (!m_selectedNode.isValid())
+ if (noValidSelection())
return;
executeInTransaction("PropertyEditorView::changeExpression", [this, name](){
@@ -296,7 +297,7 @@ void PropertyEditorView::exportPopertyAsAlias(const QString &name)
if (locked())
return;
- if (!m_selectedNode.isValid())
+ if (noValidSelection())
return;
executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){
@@ -324,7 +325,7 @@ void PropertyEditorView::removeAliasExport(const QString &name)
if (locked())
return;
- if (!m_selectedNode.isValid())
+ if (noValidSelection())
return;
executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){
@@ -528,6 +529,12 @@ void PropertyEditorView::removePropertyFromModel(const PropertyName &propertyNam
m_locked = false;
}
+bool PropertyEditorView::noValidSelection() const
+{
+ QTC_ASSERT(m_qmlBackEndForCurrentType, return true);
+ return !QmlObjectNode::isValidQmlObjectNode(m_selectedNode);
+}
+
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &,
const QList<ModelNode> &)
{
@@ -572,10 +579,7 @@ void PropertyEditorView::modelAboutToBeDetached(Model *model)
void PropertyEditorView::propertiesRemoved(const QList<AbstractProperty>& propertyList)
{
- if (!m_selectedNode.isValid())
- return;
-
- if (!QmlObjectNode(m_selectedNode).isValid())
+ if (noValidSelection())
return;
foreach (const AbstractProperty &property, propertyList) {
@@ -604,11 +608,7 @@ void PropertyEditorView::propertiesRemoved(const QList<AbstractProperty>& proper
void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
{
-
- if (!m_selectedNode.isValid())
- return;
-
- if (!QmlObjectNode(m_selectedNode).isValid())
+ if (noValidSelection())
return;
foreach (const VariantProperty &property, propertyList) {
@@ -628,10 +628,7 @@ void PropertyEditorView::variantPropertiesChanged(const QList<VariantProperty>&
void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags /*propertyChange*/)
{
- if (!m_selectedNode.isValid())
- return;
-
- if (!QmlObjectNode(m_selectedNode).isValid())
+ if (noValidSelection())
return;
foreach (const BindingProperty &property, propertyList) {
@@ -654,10 +651,7 @@ void PropertyEditorView::bindingPropertiesChanged(const QList<BindingProperty>&
void PropertyEditorView::instanceInformationsChanged(const QMultiHash<ModelNode, InformationName> &informationChangedHash)
{
- if (!m_selectedNode.isValid())
- return;
-
- if (!m_qmlBackEndForCurrentType)
+ if (noValidSelection())
return;
m_locked = true;
@@ -670,7 +664,7 @@ void PropertyEditorView::instanceInformationsChanged(const QMultiHash<ModelNode,
void PropertyEditorView::nodeIdChanged(const ModelNode& node, const QString& newId, const QString& /*oldId*/)
{
- if (!m_selectedNode.isValid())
+ if (noValidSelection())
return;
if (!QmlObjectNode(m_selectedNode).isValid())
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h
index 20047fde40..99a1d4f108 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h
@@ -114,6 +114,8 @@ private: //functions
void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value);
void removePropertyFromModel(const PropertyName &propertyName);
+ bool noValidSelection() const;
+
private: //variables
ModelNode m_selectedNode;
QWidget *m_parent;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
index e475b982d7..e6288ea861 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
@@ -31,6 +31,7 @@
#include "gradientpresetdefaultlistmodel.h"
#include "gradientpresetcustomlistmodel.h"
#include "simplecolorpalettemodel.h"
+#include "bindingeditor/bindingeditor.h"
#include "qmlanchorbindingproxy.h"
#include "theme.h"
@@ -55,6 +56,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
GradientPresetCustomListModel::registerDeclarativeType();
SimpleColorPaletteModel::registerDeclarativeType();
Internal::QmlAnchorBindingProxy::registerDeclarativeType();
+ BindingEditor::registerDeclarativeType();
}
}
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp
index 0384d7c0a3..0e68a63ff4 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinemovetool.cpp
@@ -67,14 +67,14 @@ TimelineMoveTool::TimelineMoveTool(TimelineGraphicsScene *scene, TimelineToolDel
void TimelineMoveTool::mousePressEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
- Q_UNUSED(event);
+ Q_UNUSED(item)
+ Q_UNUSED(event)
}
void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
+ Q_UNUSED(item)
if (!currentItem())
return;
@@ -116,8 +116,8 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
- Q_UNUSED(event);
+ Q_UNUSED(item)
+ Q_UNUSED(event)
if (auto *current = currentItem()) {
if (current->asTimelineFrameHandle()) {
@@ -156,18 +156,18 @@ void TimelineMoveTool::mouseReleaseEvent(TimelineMovableAbstractItem *item,
void TimelineMoveTool::mouseDoubleClickEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
- Q_UNUSED(event);
+ Q_UNUSED(item)
+ Q_UNUSED(event)
}
void TimelineMoveTool::keyPressEvent(QKeyEvent *keyEvent)
{
- Q_UNUSED(keyEvent);
+ Q_UNUSED(keyEvent)
}
void TimelineMoveTool::keyReleaseEvent(QKeyEvent *keyEvent)
{
- Q_UNUSED(keyEvent);
+ Q_UNUSED(keyEvent)
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp
index 7bd784a7dd..bf6705fbee 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp
@@ -546,10 +546,10 @@ TimelineRulerSectionItem *TimelineRulerSectionItem::create(QGraphicsScene *paren
auto layout = new QHBoxLayout(widget);
layout->addWidget(toolBar);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(toolBar);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
QGraphicsProxyWidget *proxy = parentScene->addWidget(widget);
proxy->setParentItem(item);
@@ -846,8 +846,8 @@ void TimelineBarItem::scrollOffsetChanged()
void TimelineBarItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- Q_UNUSED(option);
- Q_UNUSED(widget);
+ Q_UNUSED(option)
+ Q_UNUSED(widget)
QColor brushColorSelected = Theme::getColor(Theme::QmlDesigner_HighlightColor);
QColor brushColor = Theme::getColor(Theme::QmlDesigner_HighlightColor).darker(120);
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp
index 53367c9b67..987ac4935a 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelineselectiontool.cpp
@@ -68,8 +68,8 @@ SelectionMode TimelineSelectionTool::selectionMode(QGraphicsSceneMouseEvent *eve
void TimelineSelectionTool::mousePressEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
- Q_UNUSED(event);
+ Q_UNUSED(item)
+ Q_UNUSED(event)
if (event->buttons() == Qt::LeftButton && selectionMode(event) == SelectionMode::New)
deselect();
@@ -78,7 +78,7 @@ void TimelineSelectionTool::mousePressEvent(TimelineMovableAbstractItem *item,
void TimelineSelectionTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
+ Q_UNUSED(item)
if (event->buttons() == Qt::LeftButton) {
auto endPoint = event->scenePos();
@@ -97,8 +97,8 @@ void TimelineSelectionTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
void TimelineSelectionTool::mouseReleaseEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
- Q_UNUSED(event);
+ Q_UNUSED(item)
+ Q_UNUSED(event)
commitSelection(selectionMode(event));
@@ -108,20 +108,20 @@ void TimelineSelectionTool::mouseReleaseEvent(TimelineMovableAbstractItem *item,
void TimelineSelectionTool::mouseDoubleClickEvent(TimelineMovableAbstractItem *item,
QGraphicsSceneMouseEvent *event)
{
- Q_UNUSED(item);
- Q_UNUSED(event);
+ Q_UNUSED(item)
+ Q_UNUSED(event)
reset();
}
void TimelineSelectionTool::keyPressEvent(QKeyEvent *keyEvent)
{
- Q_UNUSED(keyEvent);
+ Q_UNUSED(keyEvent)
}
void TimelineSelectionTool::keyReleaseEvent(QKeyEvent *keyEvent)
{
- Q_UNUSED(keyEvent);
+ Q_UNUSED(keyEvent)
}
void TimelineSelectionTool::deselect()
diff --git a/src/plugins/qmldesigner/designercore/include/abstractproperty.h b/src/plugins/qmldesigner/designercore/include/abstractproperty.h
index 75cb024ccd..2a74a12539 100644
--- a/src/plugins/qmldesigner/designercore/include/abstractproperty.h
+++ b/src/plugins/qmldesigner/designercore/include/abstractproperty.h
@@ -40,7 +40,6 @@ namespace QmlDesigner {
using InternalNodePointer = QSharedPointer<InternalNode>;
using InternalPropertyPointer = QSharedPointer<InternalProperty>;
- using InternalNodeWeakPointer = QWeakPointer<InternalNode>;
}
class Model;
diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h
index dcbeb5ee74..5a8de860c2 100644
--- a/src/plugins/qmldesigner/designercore/include/abstractview.h
+++ b/src/plugins/qmldesigner/designercore/include/abstractview.h
@@ -50,7 +50,6 @@ namespace QmlDesigner {
namespace Internal {
class InternalNode;
using InternalNodePointer = QSharedPointer<InternalNode>;
- using InternalNodeWeakPointer = QWeakPointer<InternalNode>;
}
}
diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h
index 9b228d90f8..abb0300bb8 100644
--- a/src/plugins/qmldesigner/designercore/include/modelnode.h
+++ b/src/plugins/qmldesigner/designercore/include/modelnode.h
@@ -44,7 +44,6 @@ namespace Internal {
using InternalNodePointer = QSharedPointer<InternalNode>;
using InternalPropertyPointer = QSharedPointer<InternalProperty>;
- using InternalNodeWeakPointer = QWeakPointer<InternalNode>;
}
class NodeMetaInfo;
class AbstractProperty;
diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
index c0e0b41537..f77ac4645b 100644
--- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
+++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
@@ -33,6 +33,7 @@
#include <nodeinstanceclientinterface.h>
#include <nodeinstanceserverinterface.h>
+#include <QElapsedTimer>
#include <QHash>
#include <QImage>
#include <QPointer>
@@ -195,7 +196,7 @@ private: //variables
QPointer<NodeInstanceServerInterface> m_nodeInstanceServer;
QImage m_baseStatePreviewImage;
- QTime m_lastCrashTime;
+ QElapsedTimer m_lastCrashTime;
NodeInstanceServerInterface::RunModus m_runModus;
ProjectExplorer::Kit *m_currentKit = nullptr;
ProjectExplorer::Project *m_currentProject = nullptr;
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
index c48bfedce1..f316200dcc 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
@@ -204,8 +204,8 @@ void NodeInstanceView::modelAboutToBeDetached(Model * model)
void NodeInstanceView::handleCrash()
{
- int elaspsedTimeSinceLastCrash = m_lastCrashTime.restart();
- int forceRestartTime = 2000;
+ qint64 elaspsedTimeSinceLastCrash = m_lastCrashTime.restart();
+ qint64 forceRestartTime = 2000;
#ifdef QT_DEBUG
forceRestartTime = 4000;
#endif
@@ -816,9 +816,10 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
bindingPropertyList.append(node.bindingProperties());
if (node.isValid() && hasInstanceForModelNode(node)) {
NodeInstance instance = instanceForModelNode(node);
- QHashIterator<PropertyName, QVariant> auxiliaryIterator(node.auxiliaryData());
- while (auxiliaryIterator.hasNext()) {
- auxiliaryIterator.next();
+ const QHash<PropertyName, QVariant> aux = node.auxiliaryData();
+ for (auto auxiliaryIterator = aux.cbegin(), end = aux.cend();
+ auxiliaryIterator != end;
+ ++auxiliaryIterator) {
PropertyValueContainer container(instance.instanceId(), auxiliaryIterator.key(), auxiliaryIterator.value(), TypeName());
auxiliaryContainerVector.append(container);
}
diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
index 0959dd4a9e..553a47914c 100644
--- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp
@@ -395,7 +395,7 @@ QString PuppetCreator::qmlPuppetFallbackDirectory(const DesignerSettings &settin
return defaultPuppetFallbackDirectory();
return puppetFallbackDirectory;
#else
- Q_UNUSED(settings);
+ Q_UNUSED(settings)
return QString();
#endif
}
diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h
index f31039ffc2..d8b0e314f8 100644
--- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h
+++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h
@@ -47,7 +47,6 @@ class InternalNode;
using InternalNodePointer = QSharedPointer<InternalNode>;
using InternalPropertyPointer = QSharedPointer<InternalProperty>;
-using InternalNodeWeakPointer = QWeakPointer<InternalNode>;
class InternalNode
{
diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.h b/src/plugins/qmldesigner/designercore/model/internalproperty.h
index a8eb5b940c..cf10f8ef7d 100644
--- a/src/plugins/qmldesigner/designercore/model/internalproperty.h
+++ b/src/plugins/qmldesigner/designercore/model/internalproperty.h
@@ -43,13 +43,11 @@ class InternalNodeAbstractProperty;
class InternalNode;
using InternalNodePointer = QSharedPointer<InternalNode>;
-using InternalNodeWeakPointer = QWeakPointer<InternalNode>;
class QMLDESIGNERCORE_EXPORT InternalProperty
{
public:
using Pointer = QSharedPointer<InternalProperty>;
- using WeakPointer = QWeakPointer<InternalProperty>;
InternalProperty();
virtual ~InternalProperty();
@@ -86,10 +84,10 @@ protected: // functions
void setInternalWeakPointer(const Pointer &pointer);
void setDynamicTypeName(const TypeName &name);
private:
- WeakPointer m_internalPointer;
+ QWeakPointer<InternalProperty> m_internalPointer;
PropertyName m_name;
TypeName m_dynamicType;
- InternalNodeWeakPointer m_propertyOwner;
+ QWeakPointer<InternalNode> m_propertyOwner;
};
diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp
index f8cb347ba6..960ad32aed 100644
--- a/src/plugins/qmldesigner/designercore/model/model.cpp
+++ b/src/plugins/qmldesigner/designercore/model/model.cpp
@@ -502,11 +502,8 @@ QMultiHash<ModelNode, InformationName> convertModelNodeInformationHash(const QMu
{
QMultiHash<ModelNode, InformationName> convertedModelNodeInformationHash;
- QHashIterator<ModelNode, InformationName> hashIterator(informationChangeHash);
- while (hashIterator.hasNext()) {
- hashIterator.next();
- convertedModelNodeInformationHash.insert(ModelNode(hashIterator.key(), view), hashIterator.value());
- }
+ for (auto it = informationChangeHash.cbegin(), end = informationChangeHash.cend(); it != end; ++it)
+ convertedModelNodeInformationHash.insert(ModelNode(it.key(), view), it.value());
return convertedModelNodeInformationHash;
}
@@ -1393,16 +1390,10 @@ void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListPropertyPointer
void ModelPrivate::setSelectedNodes(const QList<InternalNode::Pointer> &selectedNodeList)
{
+ QList<InternalNode::Pointer> sortedSelectedList
+ = Utils::filtered(selectedNodeList, &InternalNode::isValid);
- QList<InternalNode::Pointer> sortedSelectedList(selectedNodeList);
- QMutableListIterator<InternalNode::Pointer> iterator(sortedSelectedList);
- while (iterator.hasNext()) {
- InternalNode::Pointer node(iterator.next());
- if (!node->isValid())
- iterator.remove();
- }
-
- sortedSelectedList = sortedSelectedList.toSet().toList();
+ sortedSelectedList = Utils::toList(Utils::toSet(sortedSelectedList));
Utils::sort(sortedSelectedList);
if (sortedSelectedList == m_selectedInternalNodeList)
@@ -1773,7 +1764,8 @@ QList<InternalNodePointer> ModelPrivate::allNodes() const
nodeList.append(m_rootInternalNode);
nodeList.append(m_rootInternalNode->allSubNodes());
- nodeList.append((m_nodeSet - nodeList.toSet()).toList());
+ // FIXME: This is horribly expensive compared to a loop.
+ nodeList.append(Utils::toList(m_nodeSet - Utils::toSet(nodeList)));
return nodeList;
}
diff --git a/src/plugins/qmldesigner/designercore/model/modelnodepositionstorage.cpp b/src/plugins/qmldesigner/designercore/model/modelnodepositionstorage.cpp
index 69a3849062..0c7615c7d4 100644
--- a/src/plugins/qmldesigner/designercore/model/modelnodepositionstorage.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelnodepositionstorage.cpp
@@ -37,9 +37,7 @@ void ModelNodePositionStorage::cleanupInvalidOffsets()
{
QHash<ModelNode, RewriterData> validModelNodes;
- QHashIterator<ModelNode, RewriterData> iter(m_rewriterData);
- while (iter.hasNext()) {
- iter.next();
+ for (auto iter = m_rewriterData.cbegin(), end = m_rewriterData.cend(); iter != end; ++iter) {
const ModelNode modelNode = iter.key();
if (modelNode.isValid())
validModelNodes.insert(modelNode, iter.value());
diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
index 7d55aff5a4..8174c9a1a5 100644
--- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
@@ -548,7 +548,7 @@ QString QmlObjectNode::generateTranslatableText(const QString &text)
}
return QString(QStringLiteral("qsTr(\"%1\")")).arg(text);
#else
- Q_UNUSED(text);
+ Q_UNUSED(text)
return QString();
#endif
}
diff --git a/src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp b/src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp
index 6dac375ff7..d84b088db8 100644
--- a/src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp
+++ b/src/plugins/qmldesigner/designercore/model/rewriteactioncompressor.cpp
@@ -67,10 +67,8 @@ void RewriteActionCompressor::compressImports(QList<RewriteAction *> &actions) c
QHash<Import, RewriteAction *> addedImports;
QHash<Import, RewriteAction *> removedImports;
- QMutableListIterator<RewriteAction *> iter(actions);
- iter.toBack();
- while (iter.hasPrevious()) {
- RewriteAction *action = iter.previous();
+ for (int i = actions.size(); --i >= 0; ) {
+ RewriteAction *action = actions.at(i);
if (RemoveImportRewriteAction *removeImportAction = action->asRemoveImportRewriteAction()) {
const Import import = removeImportAction->import();
@@ -113,10 +111,8 @@ void RewriteActionCompressor::compressRereparentActions(QList<RewriteAction *> &
QList<RewriteAction *> actionsToRemove;
QHash<ModelNode, ReparentNodeRewriteAction *> reparentedNodes;
- QMutableListIterator<RewriteAction*> iter(actions);
- iter.toBack();
- while (iter.hasPrevious()) {
- RewriteAction *action = iter.previous();
+ for (int i = actions.size(); --i >= 0; ) {
+ RewriteAction *action = actions.at(i);
if (ReparentNodeRewriteAction *reparentAction = action->asReparentNodeRewriteAction()) {
const ModelNode reparentedNode = reparentAction->reparentedNode();
@@ -139,10 +135,9 @@ void RewriteActionCompressor::compressRereparentActions(QList<RewriteAction *> &
void RewriteActionCompressor::compressReparentIntoSamePropertyActions(QList<RewriteAction *> &actions) const
{
QList<RewriteAction *> actionsToRemove;
- QMutableListIterator<RewriteAction *> iter(actions);
- iter.toBack();
- while (iter.hasPrevious()) {
- RewriteAction *action = iter.previous();
+
+ for (int i = actions.size(); --i >= 0; ) {
+ RewriteAction *action = actions.at(i);
if (ReparentNodeRewriteAction *reparentAction = action->asReparentNodeRewriteAction()) {
if (reparentAction->targetProperty() == reparentAction->oldParentProperty())
@@ -161,10 +156,8 @@ void RewriteActionCompressor::compressAddEditRemoveNodeActions(QList<RewriteActi
QList<RewriteAction *> actionsToRemove;
QHash<ModelNode, RewriteAction *> removedNodes;
- QMutableListIterator<RewriteAction*> iter(actions);
- iter.toBack();
- while (iter.hasPrevious()) {
- RewriteAction *action = iter.previous();
+ for (int i = actions.size(); --i >= 0; ) {
+ RewriteAction *action = actions.at(i);
if (RemoveNodeRewriteAction *removeNodeAction = action->asRemoveNodeRewriteAction()) {
const ModelNode modelNode = removeNodeAction->node();
@@ -220,15 +213,13 @@ void RewriteActionCompressor::compressPropertyActions(QList<RewriteAction *> &ac
QHash<AbstractProperty, ChangePropertyRewriteAction *> changedProperties;
QHash<AbstractProperty, AddPropertyRewriteAction *> addedProperties;
- QMutableListIterator<RewriteAction*> iter(actions);
- iter.toBack();
- while (iter.hasPrevious()) {
- RewriteAction *action = iter.previous();
+ for (int i = actions.size(); --i >= 0; ) {
+ RewriteAction *action = actions.at(i);
if (RemovePropertyRewriteAction *removeAction = action->asRemovePropertyRewriteAction()) {
const AbstractProperty property = removeAction->property();
if (AddPropertyRewriteAction *addAction = addedProperties.value(property, 0)) {
- Q_UNUSED(addAction);
+ Q_UNUSED(addAction)
} else {
removedProperties.insert(property, action);
}
@@ -271,10 +262,7 @@ void RewriteActionCompressor::compressAddEditActions(QList<RewriteAction *> &act
QSet<ModelNode> addedNodes;
QSet<RewriteAction *> dirtyActions;
- QMutableListIterator<RewriteAction*> iter(actions);
- while (iter.hasNext()) {
- RewriteAction *action = iter.next();
-
+ for (RewriteAction *action : qAsConst(actions)) {
if (action->asAddPropertyRewriteAction() || action->asChangePropertyRewriteAction()) {
AbstractProperty property;
ModelNode containedNode;
@@ -343,10 +331,8 @@ void RewriteActionCompressor::compressAddReparentActions(QList<RewriteAction *>
QList<RewriteAction *> actionsToRemove;
QMap<ModelNode, RewriteAction*> addedNodes;
- QMutableListIterator<RewriteAction*> iter(actions);
- while (iter.hasNext()) {
- RewriteAction *action = iter.next();
-
+ for (int i = 0, n = actions.size(); i < n; ++i) {
+ RewriteAction *action = actions.at(i);
if (action->asAddPropertyRewriteAction() || action->asChangePropertyRewriteAction()) {
ModelNode containedNode;
@@ -377,7 +363,7 @@ void RewriteActionCompressor::compressAddReparentActions(QList<RewriteAction *>
changeAction->containedModelNode());
}
- iter.setValue(replacementAction);
+ actions[i] = replacementAction;
delete action;
}
}
diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
index 45c07d20af..309b4e85a7 100644
--- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
@@ -52,6 +52,7 @@
#include <qmljs/qmljsinterpreter.h>
#include <qmljs/qmljsvalueowner.h>
+#include <utils/algorithm.h>
#include <utils/qrcparser.h>
#include <utils/qtcassert.h>
@@ -59,6 +60,7 @@
#include <QDir>
#include <QLoggingCategory>
#include <QRegularExpression>
+#include <QElapsedTimer>
#include <memory>
@@ -965,7 +967,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
const bool justSanityCheck = !differenceHandler.isValidator();
- QTime time;
+ QElapsedTimer time;
if (rewriterBenchmark().isInfoEnabled())
time.start();
@@ -1121,7 +1123,7 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
context->enterScope(astNode);
- QSet<PropertyName> modelPropertyNames = QSet<PropertyName>::fromList(modelNode.propertyNames());
+ QSet<PropertyName> modelPropertyNames = Utils::toSet(modelNode.propertyNames());
if (!modelNode.id().isEmpty())
modelPropertyNames.insert("id");
QList<AST::UiObjectMember *> defaultPropertyItems;
diff --git a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
index c2f36fad90..989ea8dbb4 100644
--- a/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
+++ b/src/plugins/qmldesigner/designercore/model/viewmanager.cpp
@@ -47,6 +47,7 @@
#include <utils/algorithm.h>
+#include <QElapsedTimer>
#include <QLoggingCategory>
#include <QTabWidget>
@@ -102,8 +103,7 @@ DesignDocument *ViewManager::currentDesignDocument() const
void ViewManager::attachNodeInstanceView()
{
-
- QTime time;
+ QElapsedTimer time;
if (viewBenchmark().isInfoEnabled())
time.start();
@@ -117,7 +117,7 @@ void ViewManager::attachNodeInstanceView()
void ViewManager::attachRewriterView()
{
- QTime time;
+ QElapsedTimer time;
if (viewBenchmark().isInfoEnabled())
time.start();
@@ -253,7 +253,7 @@ void ViewManager::attachViewsExceptRewriterAndComponetView()
attachNodeInstanceView();
- QTime time;
+ QElapsedTimer time;
if (viewBenchmark().isInfoEnabled())
time.start();
diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp
index 1bae709e0c..d4279be7ce 100644
--- a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp
+++ b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp
@@ -108,7 +108,7 @@ void RewriterTransaction::commit()
if (m_activeIdentifier) {
qDebug() << "Commit RewriterTransaction:" << m_identifier << m_identifierNumber;
bool success = m_identifierList.removeOne(m_identifier + QByteArrayLiteral("-") + QByteArray::number(m_identifierNumber));
- Q_UNUSED(success);
+ Q_UNUSED(success)
Q_ASSERT(success);
}
}
diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp
index f171c89c0f..759789d7ce 100644
--- a/src/plugins/qmldesigner/designmodewidget.cpp
+++ b/src/plugins/qmldesigner/designmodewidget.cpp
@@ -376,7 +376,7 @@ void DesignModeWidget::setup()
m_mainSplitter->setSizes({150, 300, 150});
QLayout *mainLayout = new QBoxLayout(QBoxLayout::RightToLeft, this);
- mainLayout->setMargin(0);
+ mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_mainSplitter);
@@ -514,7 +514,7 @@ QWidget *DesignModeWidget::createCenterWidget()
QWidget *centerWidget = new QWidget;
auto horizontalLayout = new QVBoxLayout(centerWidget);
- horizontalLayout->setMargin(0);
+ horizontalLayout->setContentsMargins(0, 0, 0, 0);
horizontalLayout->setSpacing(0);
horizontalLayout->addWidget(m_toolBar);
@@ -537,7 +537,7 @@ QWidget *DesignModeWidget::createCrumbleBarFrame()
auto frame = new Utils::StyledBar(this);
frame->setSingleRow(false);
auto layout = new QHBoxLayout(frame);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_crumbleBar->crumblePath());
diff --git a/src/plugins/qmldesigner/documentmanager.cpp b/src/plugins/qmldesigner/documentmanager.cpp
index d264f286cc..45fd495759 100644
--- a/src/plugins/qmldesigner/documentmanager.cpp
+++ b/src/plugins/qmldesigner/documentmanager.cpp
@@ -96,9 +96,9 @@ static inline void applyProperties(ModelNode &node, const QHash<PropertyName, QV
node.setAuxiliaryData(propertyName, QVariant());
}
- QHashIterator<PropertyName, QVariant> propertyIterator(propertyHash);
- while (propertyIterator.hasNext()) {
- propertyIterator.next();
+ for (auto propertyIterator = propertyHash.cbegin(), end = propertyHash.cend();
+ propertyIterator != end;
+ ++propertyIterator) {
const PropertyName propertyName = propertyIterator.key();
if (propertyName == "width" || propertyName == "height") {
node.setAuxiliaryData(propertyIterator.key(), propertyIterator.value());
diff --git a/src/plugins/qmldesigner/documentwarningwidget.cpp b/src/plugins/qmldesigner/documentwarningwidget.cpp
index bab4272395..08a2a129a9 100644
--- a/src/plugins/qmldesigner/documentwarningwidget.cpp
+++ b/src/plugins/qmldesigner/documentwarningwidget.cpp
@@ -91,7 +91,7 @@ DocumentWarningWidget::DocumentWarningWidget(QWidget *parent)
auto layout = new QVBoxLayout(this);
layout->addWidget(m_headerLabel);
auto messageLayout = new QVBoxLayout;
- messageLayout->setMargin(20);
+ messageLayout->setContentsMargins(20, 20, 20, 20);
messageLayout->setSpacing(5);
messageLayout->addWidget(m_navigateLabel);
messageLayout->addWidget(m_messageLabel);
diff --git a/src/plugins/qmldesigner/generateresource.cpp b/src/plugins/qmldesigner/generateresource.cpp
new file mode 100644
index 0000000000..e7f250e958
--- /dev/null
+++ b/src/plugins/qmldesigner/generateresource.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 <generateresource.h>
+
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/documentmanager.h>
+#include <coreplugin/messagemanager.h>
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/target.h>
+
+#include <qmlprojectmanager/qmlprojectmanagerconstants.h>
+
+#include <qtsupport/baseqtversion.h>
+#include <qtsupport/qtkitinformation.h>
+
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+#include <utils/utilsicons.h>
+#include <utils/synchronousprocess.h>
+
+#include <QAction>
+#include <QTemporaryFile>
+#include <QMap>
+#include <QProcess>
+#include <QByteArray>
+#include <QObject>
+#include <QDebug>
+
+namespace QmlDesigner {
+void GenerateResource::generateMenuEntry()
+{
+ Core::ActionContainer *buildMenu =
+ Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT);
+
+
+ const Core::Context projectContext(QmlProjectManager::Constants::QML_PROJECT_ID);
+ // ToDo: move this to QtCreator and add tr to the string then
+ auto action = new QAction(QT_TRANSLATE_NOOP("GenerateResource", "Generate Resource File"));
+ action->setEnabled(ProjectExplorer::SessionManager::startupProject() != nullptr);
+ // todo make it more intelligent when it gets enabled
+ QObject::connect(ProjectExplorer::SessionManager::instance(), &ProjectExplorer::SessionManager::startupProjectChanged, [action]() {
+ action->setEnabled(ProjectExplorer::SessionManager::startupProject());
+ });
+
+ Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.CreateResource");
+ QObject::connect(action, &QAction::triggered, [] () {
+ auto currentProject = ProjectExplorer::SessionManager::startupProject();
+ auto projectPath = currentProject->projectFilePath().parentDir().toString();
+
+ static QMap<QString, QString> lastUsedPathes;
+ auto saveLastUsedPath = [currentProject] (const QString &lastUsedPath) {
+ lastUsedPathes.insert(currentProject->displayName(), lastUsedPath);
+ };
+ saveLastUsedPath(lastUsedPathes.value(currentProject->displayName(),
+ currentProject->projectFilePath().parentDir().parentDir().toString()));
+
+ auto resourceFileName = Core:: DocumentManager::getSaveFileName(
+ QT_TRANSLATE_NOOP("GenerateResource", "Save Project As Resource"),
+ lastUsedPathes.value(currentProject->displayName()) + "/" + currentProject->displayName() + ".qmlrc",
+ QT_TRANSLATE_NOOP("GenerateResource", "QML Resource File (*.qmlrc)"));
+ if (resourceFileName.isEmpty())
+ return;
+
+ Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource",
+ QString("Generate a resource file out of project %1 to %2").arg(
+ currentProject->displayName(), QDir::toNativeSeparators(resourceFileName))));
+
+ QTemporaryFile temp(projectPath + "/XXXXXXX.create.resource.qrc");
+ if (!temp.open())
+ return;
+ temp.close();
+
+ auto rccBinary = QtSupport::QtKitAspect::qtVersion(currentProject->activeTarget()->kit())->binPath();
+#ifdef Q_OS_WIN
+ rccBinary = rccBinary.pathAppended("rcc.exe");
+#else
+ rccBinary = rccBinary.pathAppended("rcc");
+#endif
+ QProcess rccProcess;
+ rccProcess.setProgram(rccBinary.toString());
+ rccProcess.setWorkingDirectory(projectPath);
+
+ const QStringList arguments1 = {"--project", "--output", temp.fileName()};
+ const QStringList arguments2 = {"--binary", "--output", resourceFileName, temp.fileName()};
+
+ for (auto arguments : {arguments1, arguments2}) {
+ rccProcess.start(rccBinary.toString(), arguments);
+ if (!rccProcess.waitForStarted()) {
+ Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString(
+ "Unable to generate resource file: %1").arg(resourceFileName)));
+ return;
+ }
+ QByteArray stdOut;
+ QByteArray stdErr;
+ if (!Utils::SynchronousProcess::readDataFromProcess(rccProcess, 30, &stdOut, &stdErr, true)) {
+ Utils::SynchronousProcess::stopProcess(rccProcess);
+ Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString(
+ "A timeout occurred running \"%1\"").arg(rccBinary.toString() + arguments.join(" "))));
+ return ;
+
+ }
+ if (!stdOut.trimmed().isEmpty()) {
+ Core::MessageManager::write(QString::fromLocal8Bit(stdOut));
+ }
+ if (!stdErr.trimmed().isEmpty())
+ Core::MessageManager::write(QString::fromLocal8Bit(stdErr));
+
+ if (rccProcess.exitStatus() != QProcess::NormalExit) {
+ Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString(
+ "\"%1\" crashed.").arg(rccBinary.toString() + arguments.join(" "))));
+ return;
+ }
+ if (rccProcess.exitCode() != 0) {
+ Core::MessageManager::write(QT_TRANSLATE_NOOP("GenerateResource", QString(
+ "\"%1\" failed (exit code %2).").arg(rccBinary.toString() +
+ " " + arguments.join(" ")).arg(rccProcess.exitCode())));
+ return;
+ }
+
+ }
+
+ saveLastUsedPath(Utils::FilePath::fromString(resourceFileName).parentDir().toString());
+ });
+ buildMenu->addAction(cmd, ProjectExplorer::Constants::G_BUILD_RUN);
+}
+
+} // namespace QmlDesigner
+
diff --git a/src/plugins/qmldesigner/generateresource.h b/src/plugins/qmldesigner/generateresource.h
new file mode 100644
index 0000000000..4b4dadf9e8
--- /dev/null
+++ b/src/plugins/qmldesigner/generateresource.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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
+
+
+namespace QmlDesigner {
+namespace GenerateResource {
+ void generateMenuEntry();
+}
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp
index eb16cbedd1..1f14969dfc 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.cpp
+++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp
@@ -30,6 +30,7 @@
#include "settingspage.h"
#include "designmodecontext.h"
#include "openuiqmlfiledialog.h"
+#include "generateresource.h"
#include <metainfo.h>
#include <connectionview.h>
@@ -39,7 +40,9 @@
#include <timelineeditor/timelineview.h>
#include <pathtool/pathtool.h>
+#include <qmljseditor/qmljseditor.h>
#include <qmljseditor/qmljseditorconstants.h>
+#include <qmljseditor/qmljseditordocument.h>
#include <qmljstools/qmljstoolsconstants.h>
@@ -77,6 +80,29 @@ using namespace QmlDesigner::Internal;
namespace QmlDesigner {
+namespace Internal {
+
+class QtQuickDesignerFactory : public QmlJSEditor::QmlJSEditorFactory
+{
+public:
+ QtQuickDesignerFactory();
+};
+
+QtQuickDesignerFactory::QtQuickDesignerFactory()
+ : QmlJSEditorFactory(QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)
+{
+ setDisplayName(QCoreApplication::translate("OpenWith::Editors", "Qt Quick Designer"));
+
+ addMimeType(QmlJSTools::Constants::QMLUI_MIMETYPE);
+ setDocumentCreator([this]() {
+ auto document = new QmlJSEditor::QmlJSEditorDocument(id());
+ document->setIsDesignModePreferred(true);
+ return document;
+ });
+}
+
+} // namespace Internal
+
class QmlDesignerPluginPrivate
{
public:
@@ -87,6 +113,7 @@ public:
DesignModeWidget mainWidget;
DesignerSettings settings;
DesignModeContext *context = nullptr;
+ QtQuickDesignerFactory m_qtQuickDesignerFactory;
bool blockEditorChange = false;
};
@@ -99,7 +126,9 @@ static bool isInDesignerMode()
static bool checkIfEditorIsQtQuick(Core::IEditor *editor)
{
- if (editor && editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) {
+ if (editor
+ && (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
+ || editor->document()->id() == QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)) {
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QmlJS::Document::Ptr document = modelManager->ensuredGetDocumentForPath(editor->document()->filePath().toString());
if (!document.isNull())
@@ -174,11 +203,14 @@ QmlDesignerPlugin::~QmlDesignerPlugin()
// INHERITED FROM ExtensionSystem::Plugin
//
////////////////////////////////////////////////////
-bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage/* = 0*/) // =0;
+bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage/* = 0*/)
{
if (!Utils::HostOsInfo::canCreateOpenGLContext(errorMessage))
return false;
d = new QmlDesignerPluginPrivate;
+ if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool())
+ GenerateResource::generateMenuEntry();
+
return true;
}
@@ -545,4 +577,4 @@ void QmlDesignerPlugin::setSettings(const DesignerSettings &s)
}
}
-}
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri
index 503b47a83b..9eba4c9a81 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.pri
+++ b/src/plugins/qmldesigner/qmldesignerplugin.pri
@@ -4,6 +4,7 @@ HEADERS += $$PWD/qmldesignerconstants.h \
$$PWD/designmodewidget.h \
$$PWD/switchsplittabwidget.h \
$$PWD/designersettings.h \
+ $$PWD/generateresource.h \
$$PWD/settingspage.h \
$$PWD/designmodecontext.h \
$$PWD/documentmanager.h \
@@ -16,6 +17,7 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \
$$PWD/designmodewidget.cpp \
$$PWD/switchsplittabwidget.cpp \
$$PWD/designersettings.cpp \
+ $$PWD/generateresource.cpp \
$$PWD/settingspage.cpp \
$$PWD/designmodecontext.cpp \
$$PWD/documentmanager.cpp \
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro
index 52e3e19a44..625770cb72 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.pro
+++ b/src/plugins/qmldesigner/qmldesignerplugin.pro
@@ -28,6 +28,7 @@ include(components/pathtool/pathtool.pri)
include(components/timelineeditor/timelineeditor.pri)
include(components/connectioneditor/connectioneditor.pri)
include(components/curveeditor/curveeditor.pri)
+include(components/bindingeditor/bindingeditor.pri)
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index 24f77ddedd..1e82b1354d 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -609,6 +609,8 @@ Project {
name: "extension"
prefix: "components/"
files: [
+ "bindingeditor/bindingeditor.cpp",
+ "bindingeditor/bindingeditor.h",
"colortool/colortool.cpp",
"colortool/colortool.h",
"connectioneditor/addnewbackenddialog.h",
@@ -768,6 +770,8 @@ Project {
}
files: [
+ "generateresource.cpp",
+ "generateresource.h",
"designersettings.cpp",
"designersettings.h",
"designmodecontext.cpp",
diff --git a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp
index 5a3c1c4e09..2e7186db0d 100644
--- a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp
+++ b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp
@@ -130,7 +130,7 @@ QString QmlPreviewPlugin::metaInfo() const
void QmlPreviewPlugin::setQmlFile()
{
if (s_previewPlugin) {
- const Utils::FileName qmlFileName =
+ const Utils::FilePath qmlFileName =
QmlDesignerPlugin::instance()->currentDesignDocument()->fileName();
s_previewPlugin->setProperty("previewedFile", qmlFileName.toString());
}
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp
index 5c8dc78b68..a9a210248e 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.cpp
+++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp
@@ -34,7 +34,6 @@
#include <QTextBlock>
using namespace QmlJSEditor;
-using namespace Internal;
using namespace QmlJS;
static int blockStartState(const QTextBlock &block)
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.h b/src/plugins/qmljseditor/qmljsautocompleter.h
index e0834448b8..580f6d794d 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.h
+++ b/src/plugins/qmljseditor/qmljsautocompleter.h
@@ -26,11 +26,11 @@
#pragma once
#include <texteditor/autocompleter.h>
+#include <qmljseditor/qmljseditor_global.h>
namespace QmlJSEditor {
-namespace Internal {
-class AutoCompleter : public TextEditor::AutoCompleter
+class QMLJSEDITOR_EXPORT AutoCompleter : public TextEditor::AutoCompleter
{
public:
AutoCompleter();
@@ -55,5 +55,4 @@ public:
QString insertParagraphSeparator(const QTextCursor &tc) const override;
};
-} // Internal
} // QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljscompletionassist.h b/src/plugins/qmljseditor/qmljscompletionassist.h
index df697ef5e1..844e3b42d8 100644
--- a/src/plugins/qmljseditor/qmljscompletionassist.h
+++ b/src/plugins/qmljseditor/qmljscompletionassist.h
@@ -46,6 +46,7 @@ namespace QmlJS { class Value; }
namespace QmlJSEditor {
class QmlJSCompletionAssistInterface;
+class QmlJSCompletionAssistProvider;
namespace Internal {
@@ -72,19 +73,6 @@ public:
};
-class QmlJSCompletionAssistProvider : public TextEditor::CompletionAssistProvider
-{
- Q_OBJECT
-
-public:
- TextEditor::IAssistProcessor *createProcessor() const override;
-
- int activationCharSequenceLength() const override;
- bool isActivationCharSequence(const QString &sequence) const override;
- bool isContinuationChar(const QChar &c) const override;
-};
-
-
class QmlJSCompletionAssistProcessor : public TextEditor::IAssistProcessor
{
public:
@@ -131,6 +119,20 @@ private:
QmlJSTools::SemanticInfo m_semanticInfo;
};
+
+class QMLJSEDITOR_EXPORT QmlJSCompletionAssistProvider : public TextEditor::CompletionAssistProvider
+{
+ Q_OBJECT
+
+public:
+ TextEditor::IAssistProcessor *createProcessor() const override;
+
+ int activationCharSequenceLength() const override;
+ bool isActivationCharSequence(const QString &sequence) const override;
+ bool isContinuationChar(const QChar &c) const override;
+};
+
+
QStringList QMLJSEDITOR_EXPORT qmlJSAutoComplete(QTextDocument *textDocument,
int position,
const QString &fileName,
diff --git a/src/plugins/qmljseditor/qmljseditingsettingspage.cpp b/src/plugins/qmljseditor/qmljseditingsettingspage.cpp
index 37cd32fa63..7aea17c315 100644
--- a/src/plugins/qmljseditor/qmljseditingsettingspage.cpp
+++ b/src/plugins/qmljseditor/qmljseditingsettingspage.cpp
@@ -33,6 +33,10 @@
#include <QTextStream>
#include <QCheckBox>
+const char AUTO_FORMAT_ON_SAVE[] = "QmlJSEditor.AutoFormatOnSave";
+const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "QmlJSEditor.AutoFormatOnlyCurrentProject";
+const char QML_CONTEXTPANE_KEY[] = "QmlJSEditor.ContextPaneEnabled";
+const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned";
using namespace QmlJSEditor;
using namespace QmlJSEditor::Internal;
@@ -52,33 +56,22 @@ void QmlJsEditingSettings::set()
void QmlJsEditingSettings::fromSettings(QSettings *settings)
{
- settings->beginGroup(QLatin1String(QmlJSEditor::Constants::SETTINGS_CATEGORY_QML));
- m_enableContextPane = settings->value(
- QLatin1String(QmlJSEditor::Constants::QML_CONTEXTPANE_KEY),
- QVariant(false)).toBool();
- m_pinContextPane = settings->value(
- QLatin1String(QmlJSEditor::Constants::QML_CONTEXTPANEPIN_KEY),
- QVariant(false)).toBool();
- m_autoFormatOnSave = settings->value(
- QLatin1String(QmlJSEditor::Constants::AUTO_FORMAT_ON_SAVE),
- QVariant(false)).toBool();
- m_autoFormatOnlyCurrentProject = settings->value(
- QLatin1String(QmlJSEditor::Constants::AUTO_FORMAT_ONLY_CURRENT_PROJECT),
- QVariant(false)).toBool();
+ settings->beginGroup(QmlJSEditor::Constants::SETTINGS_CATEGORY_QML);
+ m_enableContextPane = settings->value(QML_CONTEXTPANE_KEY, QVariant(false)).toBool();
+ m_pinContextPane = settings->value(QML_CONTEXTPANEPIN_KEY, QVariant(false)).toBool();
+ m_autoFormatOnSave = settings->value(AUTO_FORMAT_ON_SAVE, QVariant(false)).toBool();
+ m_autoFormatOnlyCurrentProject
+ = settings->value(AUTO_FORMAT_ONLY_CURRENT_PROJECT, QVariant(false)).toBool();
settings->endGroup();
}
void QmlJsEditingSettings::toSettings(QSettings *settings) const
{
- settings->beginGroup(QLatin1String(QmlJSEditor::Constants::SETTINGS_CATEGORY_QML));
- settings->setValue(QLatin1String(QmlJSEditor::Constants::QML_CONTEXTPANE_KEY),
- m_enableContextPane);
- settings->setValue(QLatin1String(QmlJSEditor::Constants::QML_CONTEXTPANEPIN_KEY),
- m_pinContextPane);
- settings->setValue(QLatin1String(QmlJSEditor::Constants::AUTO_FORMAT_ON_SAVE),
- m_autoFormatOnSave);
- settings->setValue(QLatin1String(QmlJSEditor::Constants::AUTO_FORMAT_ONLY_CURRENT_PROJECT),
- m_autoFormatOnlyCurrentProject);
+ settings->beginGroup(QmlJSEditor::Constants::SETTINGS_CATEGORY_QML);
+ settings->setValue(QML_CONTEXTPANE_KEY, m_enableContextPane);
+ settings->setValue(QML_CONTEXTPANEPIN_KEY, m_pinContextPane);
+ settings->setValue(AUTO_FORMAT_ON_SAVE, m_autoFormatOnSave);
+ settings->setValue(AUTO_FORMAT_ONLY_CURRENT_PROJECT, m_autoFormatOnlyCurrentProject);
settings->endGroup();
}
@@ -130,8 +123,7 @@ void QmlJsEditingSettings::setAutoFormatOnlyCurrentProject(const bool autoFormat
m_autoFormatOnlyCurrentProject = autoFormatOnlyCurrentProject;
}
-QmlJsEditingSettignsPageWidget::QmlJsEditingSettignsPageWidget(QWidget *parent) :
- QWidget(parent)
+QmlJsEditingSettignsPageWidget::QmlJsEditingSettignsPageWidget()
{
m_ui.setupUi(this);
}
diff --git a/src/plugins/qmljseditor/qmljseditingsettingspage.h b/src/plugins/qmljseditor/qmljseditingsettingspage.h
index dd3010e0f2..0be399b3d5 100644
--- a/src/plugins/qmljseditor/qmljseditingsettingspage.h
+++ b/src/plugins/qmljseditor/qmljseditingsettingspage.h
@@ -82,7 +82,7 @@ class QmlJsEditingSettignsPageWidget : public QWidget
Q_OBJECT
public:
- explicit QmlJsEditingSettignsPageWidget(QWidget *parent = nullptr);
+ QmlJsEditingSettignsPageWidget();
QmlJsEditingSettings settings() const;
void setSettings(const QmlJsEditingSettings &);
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 068d12f320..f9e6dbf46c 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -92,6 +92,9 @@ enum {
UPDATE_OUTLINE_INTERVAL = 500 // msecs after new semantic info has been arrived / cursor has moved
};
+const char QML_JS_EDITOR_PLUGIN[] = "QmlJSEditorPlugin";
+const char QT_QUICK_TOOLBAR_MARKER_ID[] = "QtQuickToolbarMarkerId";
+
using namespace Core;
using namespace QmlJS;
using namespace QmlJS::AST;
@@ -99,7 +102,6 @@ using namespace QmlJSTools;
using namespace TextEditor;
namespace QmlJSEditor {
-namespace Internal {
//
// QmlJSEditorWidget
@@ -129,7 +131,7 @@ void QmlJSEditorWidget::finalizeInitialization()
textDocument()->setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8
m_modelManager = ModelManagerInterface::instance();
- m_contextPane = QmlJSEditorPlugin::quickToolBar();
+ m_contextPane = Internal::QmlJSEditorPlugin::quickToolBar();
m_modelManager->activateScan();
@@ -266,12 +268,11 @@ void QmlJSEditorWidget::updateOutlineIndexNow()
m_outlineCombo->setRootModelIndex(QModelIndex());
}
}
-} // namespace Internal
+
} // namespace QmlJSEditor
namespace QmlJSEditor {
-namespace Internal {
void QmlJSEditorWidget::updateContextPane()
{
@@ -286,8 +287,8 @@ void QmlJSEditorWidget::updateContextPane()
if (m_contextPane->isAvailable(this, info.document, newNode) &&
!m_contextPane->widget()->isVisible()) {
- QList<RefactorMarker> markers = RefactorMarker::filterOutType(
- refactorMarkers(), Constants::QT_QUICK_TOOLBAR_MARKER_ID);
+ QList<RefactorMarker> markers
+ = RefactorMarker::filterOutType(refactorMarkers(), QT_QUICK_TOOLBAR_MARKER_ID);
if (UiObjectMember *m = newNode->uiObjectMemberCast()) {
const int start = qualifiedTypeNameId(m)->identifierToken.begin();
for (UiQualifiedId *q = qualifiedTypeNameId(m); q; q = q->next) {
@@ -299,7 +300,7 @@ void QmlJSEditorWidget::updateContextPane()
tc.setPosition(end);
marker.cursor = tc;
marker.tooltip = tr("Show Qt Quick ToolBar");
- marker.type = Constants::QT_QUICK_TOOLBAR_MARKER_ID;
+ marker.type = QT_QUICK_TOOLBAR_MARKER_ID;
marker.callback = [this](TextEditorWidget *) {
showContextPane();
};
@@ -310,8 +311,8 @@ void QmlJSEditorWidget::updateContextPane()
}
setRefactorMarkers(markers);
} else if (oldNode != newNode) {
- setRefactorMarkers(RefactorMarker::filterOutType(
- refactorMarkers(), Constants::QT_QUICK_TOOLBAR_MARKER_ID));
+ setRefactorMarkers(
+ RefactorMarker::filterOutType(refactorMarkers(), QT_QUICK_TOOLBAR_MARKER_ID));
}
m_oldCursorPosition = position();
@@ -504,7 +505,7 @@ void QmlJSEditorWidget::createToolBar()
auto itemDelegate = new Utils::AnnotatedItemDelegate(this);
itemDelegate->setDelimiter(QLatin1String(" "));
- itemDelegate->setAnnotationRole(QmlOutlineModel::AnnotationRole);
+ itemDelegate->setAnnotationRole(Internal::QmlOutlineModel::AnnotationRole);
treeView->setItemDelegateForColumn(0, itemDelegate);
treeView->header()->hide();
@@ -522,7 +523,7 @@ void QmlJSEditorWidget::createToolBar()
connect(m_outlineCombo, QOverload<int>::of(&QComboBox::activated),
this, &QmlJSEditorWidget::jumpToOutlineElement);
- connect(m_qmlJsEditorDocument->outlineModel(), &QmlOutlineModel::updated,
+ connect(m_qmlJsEditorDocument->outlineModel(), &Internal::QmlOutlineModel::updated,
static_cast<QTreeView *>(m_outlineCombo->view()), &QTreeView::expandAll);
connect(this, &QmlJSEditorWidget::cursorPositionChanged,
@@ -672,7 +673,7 @@ void QmlJSEditorWidget::inspectElementUnderCursor() const
const CppComponentValue *cppValue = findCppComponentToInspect(semanticInfo, cursorPosition);
if (!cppValue) {
QString title = tr("Code Model Not Available");
- const QString documentId = Constants::QML_JS_EDITOR_PLUGIN + QStringLiteral(".NothingToShow");
+ const QString documentId = QML_JS_EDITOR_PLUGIN + QStringLiteral(".NothingToShow");
EditorManager::openEditorWithContents(Core::Constants::K_DEFAULT_TEXT_EDITOR_ID, &title,
tr("Code model not available.").toUtf8(), documentId,
EditorManager::IgnoreNavigationHistory);
@@ -680,8 +681,8 @@ void QmlJSEditorWidget::inspectElementUnderCursor() const
}
QString title = tr("Code Model of %1").arg(cppValue->metaObject()->className());
- const QString documentId = Constants::QML_JS_EDITOR_PLUGIN + QStringLiteral(".Class.")
- + cppValue->metaObject()->className();
+ const QString documentId = QML_JS_EDITOR_PLUGIN + QStringLiteral(".Class.")
+ + cppValue->metaObject()->className();
IEditor *outputEditor = EditorManager::openEditorWithContents(
Core::Constants::K_DEFAULT_TEXT_EDITOR_ID, &title, QByteArray(),
documentId, EditorManager::IgnoreNavigationHistory);
@@ -812,8 +813,8 @@ void QmlJSEditorWidget::showContextPane()
&scopeChain,
newNode, false, true);
m_oldCursorPosition = position();
- setRefactorMarkers(RefactorMarker::filterOutType(
- refactorMarkers(), Constants::QT_QUICK_TOOLBAR_MARKER_ID));
+ setRefactorMarkers(
+ RefactorMarker::filterOutType(refactorMarkers(), QT_QUICK_TOOLBAR_MARKER_ID));
}
}
@@ -827,7 +828,7 @@ void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e)
AssistInterface *interface = createAssistInterface(QuickFix, ExplicitlyInvoked);
if (interface) {
QScopedPointer<IAssistProcessor> processor(
- QmlJSEditorPlugin::quickFixAssistProvider()->createProcessor());
+ Internal::QmlJSEditorPlugin::quickFixAssistProvider()->createProcessor());
QScopedPointer<IAssistProposal> proposal(processor->perform(interface));
if (!proposal.isNull()) {
GenericProposalModelPtr model = proposal->model().staticCast<GenericProposalModel>();
@@ -936,7 +937,7 @@ QModelIndex QmlJSEditorWidget::indexForPosition(unsigned cursorPosition, const Q
{
QModelIndex lastIndex = rootIndex;
- QmlOutlineModel *model = m_qmlJsEditorDocument->outlineModel();
+ Internal::QmlOutlineModel *model = m_qmlJsEditorDocument->outlineModel();
const int rowCount = model->rowCount(rootIndex);
for (int i = 0; i < rowCount; ++i) {
QModelIndex childIndex = model->index(i, 0, rootIndex);
@@ -976,7 +977,7 @@ AssistInterface *QmlJSEditorWidget::createAssistInterface(
reason,
m_qmlJsEditorDocument->semanticInfo());
} else if (assistKind == QuickFix) {
- return new QmlJSQuickFixAssistInterface(const_cast<QmlJSEditorWidget *>(this), reason);
+ return new Internal::QmlJSQuickFixAssistInterface(const_cast<QmlJSEditorWidget *>(this), reason);
}
return nullptr;
}
@@ -1007,37 +1008,39 @@ QmlJSEditor::QmlJSEditor()
addContext(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID);
}
-bool QmlJSEditor::isDesignModePreferred() const
+QmlJSEditorDocument *QmlJSEditor::qmlJSDocument() const
{
+ return qobject_cast<QmlJSEditorDocument *>(document());
+}
- bool alwaysPreferDesignMode = false;
- // always prefer design mode for .ui.qml files
- if (textDocument() && textDocument()->mimeType() == QLatin1String(QmlJSTools::Constants::QMLUI_MIMETYPE))
- alwaysPreferDesignMode = true;
+bool QmlJSEditor::isDesignModePreferred() const
+{
// stay in design mode if we are there
- Id mode = ModeManager::currentModeId();
- return alwaysPreferDesignMode || mode == Core::Constants::MODE_DESIGN;
+ const Id mode = ModeManager::currentModeId();
+ return qmlJSDocument()->isDesignModePreferred() || mode == Core::Constants::MODE_DESIGN;
}
-
//
// QmlJSEditorFactory
//
QmlJSEditorFactory::QmlJSEditorFactory()
+ : QmlJSEditorFactory(Constants::C_QMLJSEDITOR_ID)
+{}
+
+QmlJSEditorFactory::QmlJSEditorFactory(Core::Id _id)
{
- setId(Constants::C_QMLJSEDITOR_ID);
- setDisplayName(QCoreApplication::translate("OpenWith::Editors", Constants::C_QMLJSEDITOR_DISPLAY_NAME));
+ setId(_id);
+ setDisplayName(QCoreApplication::translate("OpenWith::Editors", "QMLJS Editor"));
addMimeType(QmlJSTools::Constants::QML_MIMETYPE);
- addMimeType(QmlJSTools::Constants::QMLUI_MIMETYPE);
addMimeType(QmlJSTools::Constants::QMLPROJECT_MIMETYPE);
addMimeType(QmlJSTools::Constants::QBS_MIMETYPE);
addMimeType(QmlJSTools::Constants::QMLTYPES_MIMETYPE);
addMimeType(QmlJSTools::Constants::JS_MIMETYPE);
- setDocumentCreator([]() { return new QmlJSEditorDocument; });
+ setDocumentCreator([this]() { return new QmlJSEditorDocument(id()); });
setEditorWidgetCreator([]() { return new QmlJSEditorWidget; });
setEditorCreator([]() { return new QmlJSEditor; });
setAutoCompleterCreator([]() { return new AutoCompleter; });
@@ -1057,9 +1060,8 @@ QmlJSEditorFactory::QmlJSEditorFactory()
void QmlJSEditorFactory::decorateEditor(TextEditorWidget *editor)
{
editor->textDocument()->setSyntaxHighlighter(new QmlJSHighlighter);
- editor->textDocument()->setIndenter(new Indenter(editor->textDocument()->document()));
+ editor->textDocument()->setIndenter(new Internal::Indenter(editor->textDocument()->document()));
editor->setAutoCompleter(new AutoCompleter);
}
-} // namespace Internal
} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index 7b6b6c096b..e0a68b9a02 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -52,9 +52,7 @@ class QmlJSEditorDocument;
class QuickToolBar;
class FindReferences;
-namespace Internal {
-
-class QmlJSEditorWidget : public TextEditor::TextEditorWidget
+class QMLJSEDITOR_EXPORT QmlJSEditorWidget : public TextEditor::TextEditorWidget
{
Q_OBJECT
@@ -131,25 +129,26 @@ private:
};
-class QmlJSEditor : public TextEditor::BaseTextEditor
+class QMLJSEDITOR_EXPORT QmlJSEditor : public TextEditor::BaseTextEditor
{
Q_OBJECT
public:
QmlJSEditor();
+ QmlJSEditorDocument *qmlJSDocument() const;
bool isDesignModePreferred() const override;
};
-class QmlJSEditorFactory : public TextEditor::TextEditorFactory
+class QMLJSEDITOR_EXPORT QmlJSEditorFactory : public TextEditor::TextEditorFactory
{
Q_OBJECT
public:
QmlJSEditorFactory();
+ QmlJSEditorFactory(Core::Id id);
static void decorateEditor(TextEditor::TextEditorWidget *editor);
};
-} // namespace Internal
} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljseditorconstants.h b/src/plugins/qmljseditor/qmljseditorconstants.h
index 61624bf1ff..966b7f1c38 100644
--- a/src/plugins/qmljseditor/qmljseditorconstants.h
+++ b/src/plugins/qmljseditor/qmljseditorconstants.h
@@ -30,37 +30,20 @@
namespace QmlJSEditor {
namespace Constants {
-const char QML_JS_EDITOR_PLUGIN[] = "QmlJSEditorPlugin";
-
const char M_CONTEXT[] = "QML JS Editor.ContextMenu";
const char M_REFACTORING_MENU_INSERTION_POINT[] = "QmlJSEditor.RefactorGroup";
-const char C_QMLJSEDITOR_ID[] = "QMLProjectManager.QMLJSEditor";
-const char C_QMLJSEDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "QMLJS Editor");
-const char TASK_SEARCH[] = "QmlJSEditor.TaskSearch";
+const char C_QMLJSEDITOR_ID[] = "QmlJSEditor.QMLJSEditor";
+const char C_QTQUICKDESIGNEREDITOR_ID[] = "QmlJSEditor.QtQuickDesignerEditor";
const char SETTINGS_CATEGORY_QML[] = "J.QtQuick";
-const char RENAME_USAGES[] = "QmlJSEditor.RenameUsages";
-const char RUN_SEMANTIC_SCAN[] = "QmlJSEditor.RunSemanticScan";
-const char REFORMAT_FILE[] = "QmlJSEditor.ReformatFile";
const char SHOW_QT_QUICK_HELPER[] = "QmlJSEditor.ShowQtQuickHelper";
-const char INSPECT_ELEMENT_UNDER_CURSOR[] = "QmlJSEditor.InspectElementUnderCursor";
const char TASK_CATEGORY_QML[] = "Task.Category.Qml";
const char TASK_CATEGORY_QML_ANALYSIS[] = "Task.Category.QmlAnalysis";
const char QML_SNIPPETS_GROUP_ID[] = "QML";
-const char QML_CONTEXTPANE_KEY[] = "QmlJSEditor.ContextPaneEnabled";
-const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned";
-
-const char QML_UI_FILE_WARNING[] = "QmlJSEditor.QmlUiFileWarning";
-
-const char AUTO_FORMAT_ON_SAVE[] = "QmlJSEditor.AutoFormatOnSave";
-const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "QmlJSEditor.AutoFormatOnlyCurrentProject";
-
-const char QT_QUICK_TOOLBAR_MARKER_ID[] = "QtQuickToolbarMarkerId";
-
} // namespace Constants
} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp
index 18348907f4..bb487202c0 100644
--- a/src/plugins/qmljseditor/qmljseditordocument.cpp
+++ b/src/plugins/qmljseditor/qmljseditordocument.cpp
@@ -43,6 +43,8 @@
#include <qmljstools/qmljsmodelmanager.h>
#include <qmljstools/qmljsqtstylecodeformatter.h>
+const char QML_UI_FILE_WARNING[] = "QmlJSEditor.QmlUiFileWarning";
+
using namespace QmlJSEditor;
using namespace QmlJS;
using namespace QmlJS::AST;
@@ -561,19 +563,6 @@ void QmlJSEditorDocumentPrivate::acceptNewSemanticInfo(const SemanticInfo &seman
m_outlineModelNeedsUpdate = true;
m_semanticHighlightingNecessary = true;
- if (m_firstSementicInfo) {
- m_firstSementicInfo = false;
- if (semanticInfo.document->language() == Dialect::QmlQtQuick2Ui
- && !q->infoBar()->containsInfo(Core::Id(Constants::QML_UI_FILE_WARNING))) {
- Core::InfoBarEntry info(Core::Id(Constants::QML_UI_FILE_WARNING),
- tr("This file should only be edited in <b>Design</b> mode."));
- info.setCustomButtonInfo(tr("Switch Mode"), []() {
- Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN);
- });
- q->infoBar()->addInfo(info);
- }
- }
-
createTextMarks(m_semanticInfo);
emit q->semanticInfoUpdated(m_semanticInfo); // calls triggerPendingUpdates as necessary
}
@@ -646,10 +635,10 @@ void QmlJSEditorDocumentPrivate::cleanSemanticMarks()
} // Internal
-QmlJSEditorDocument::QmlJSEditorDocument()
+QmlJSEditorDocument::QmlJSEditorDocument(Core::Id id)
: d(new Internal::QmlJSEditorDocumentPrivate(this))
{
- setId(Constants::C_QMLJSEDITOR_ID);
+ setId(id);
connect(this, &TextEditor::TextDocument::tabSettingsChanged,
d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache);
setSyntaxHighlighter(new QmlJSHighlighter(document()));
@@ -686,6 +675,28 @@ TextEditor::IAssistProvider *QmlJSEditorDocument::quickFixAssistProvider() const
return Internal::QmlJSEditorPlugin::quickFixAssistProvider();
}
+void QmlJSEditorDocument::setIsDesignModePreferred(bool value)
+{
+ d->m_isDesignModePreferred = value;
+ if (value) {
+ if (infoBar()->canInfoBeAdded(QML_UI_FILE_WARNING)) {
+ Core::InfoBarEntry info(QML_UI_FILE_WARNING,
+ tr("This file should only be edited in <b>Design</b> mode."));
+ info.setCustomButtonInfo(tr("Switch Mode"), []() {
+ Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN);
+ });
+ infoBar()->addInfo(info);
+ }
+ } else if (infoBar()->containsInfo(QML_UI_FILE_WARNING)) {
+ infoBar()->removeInfo(QML_UI_FILE_WARNING);
+ }
+}
+
+bool QmlJSEditorDocument::isDesignModePreferred() const
+{
+ return d->m_isDesignModePreferred;
+}
+
void QmlJSEditorDocument::setDiagnosticRanges(const QVector<QTextLayout::FormatRange> &ranges)
{
d->m_diagnosticRanges = ranges;
diff --git a/src/plugins/qmljseditor/qmljseditordocument.h b/src/plugins/qmljseditor/qmljseditordocument.h
index 47671ad7c8..0b5c6e34a8 100644
--- a/src/plugins/qmljseditor/qmljseditordocument.h
+++ b/src/plugins/qmljseditor/qmljseditordocument.h
@@ -43,7 +43,7 @@ class QMLJSEDITOR_EXPORT QmlJSEditorDocument : public TextEditor::TextDocument
{
Q_OBJECT
public:
- QmlJSEditorDocument();
+ QmlJSEditorDocument(Core::Id id);
~QmlJSEditorDocument() override;
const QmlJSTools::SemanticInfo &semanticInfo() const;
@@ -54,6 +54,9 @@ public:
TextEditor::IAssistProvider *quickFixAssistProvider() const override;
+ void setIsDesignModePreferred(bool value);
+ bool isDesignModePreferred() const;
+
signals:
void updateCodeWarnings(QmlJS::Document::Ptr doc);
void semanticInfoUpdated(const QmlJSTools::SemanticInfo &semanticInfo);
diff --git a/src/plugins/qmljseditor/qmljseditordocument_p.h b/src/plugins/qmljseditor/qmljseditordocument_p.h
index 22912263ce..5f24d2cf3c 100644
--- a/src/plugins/qmljseditor/qmljseditordocument_p.h
+++ b/src/plugins/qmljseditor/qmljseditordocument_p.h
@@ -37,11 +37,12 @@ namespace TextEditor { class TextMark; }
namespace QmlJSEditor {
class QmlJSEditorDocument;
+class SemanticHighlighter;
namespace Internal {
class QmlOutlineModel;
-class SemanticHighlighter;
+
class SemanticInfoUpdater;
class QmlJSEditorDocumentPrivate : public QObject
@@ -72,14 +73,14 @@ public:
SemanticInfoUpdater *m_semanticInfoUpdater;
QmlJSTools::SemanticInfo m_semanticInfo;
QVector<QTextLayout::FormatRange> m_diagnosticRanges;
- Internal::SemanticHighlighter *m_semanticHighlighter = nullptr;
+ SemanticHighlighter *m_semanticHighlighter = nullptr;
bool m_semanticHighlightingNecessary = false;
bool m_outlineModelNeedsUpdate = false;
- bool m_firstSementicInfo = true;
QTimer m_updateOutlineModelTimer;
Internal::QmlOutlineModel *m_outlineModel = nullptr;
QVector<TextEditor::TextMark *> m_diagnosticMarks;
QVector<TextEditor::TextMark *> m_semanticMarks;
+ bool m_isDesignModePreferred = false;
};
} // Internal
diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp
index afd33c18b8..4853c6840d 100644
--- a/src/plugins/qmljseditor/qmljseditorplugin.cpp
+++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp
@@ -116,8 +116,8 @@ QmlJSEditorPlugin::~QmlJSEditorPlugin()
bool QmlJSEditorPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
d = new QmlJSEditorPluginPrivate;
@@ -141,10 +141,12 @@ QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
// recompute messages when project data changes (files added or removed)
connect(modelManager, &QmlJS::ModelManagerInterface::projectInfoUpdated,
&m_qmlTaskManager, &QmlTaskManager::updateMessages);
- connect(modelManager, &QmlJS::ModelManagerInterface::aboutToRemoveFiles,
- &m_qmlTaskManager, &QmlTaskManager::documentsRemoved);
+ connect(modelManager,
+ &QmlJS::ModelManagerInterface::aboutToRemoveFiles,
+ &m_qmlTaskManager,
+ &QmlTaskManager::documentsRemoved);
- Context context(Constants::C_QMLJSEDITOR_ID);
+ Context context(Constants::C_QMLJSEDITOR_ID, Constants::C_QTQUICKDESIGNEREDITOR_ID);
ActionContainer *contextMenu = ActionManager::createMenu(Constants::M_CONTEXT);
ActionContainer *qmlToolsMenu = ActionManager::actionContainer(Id(QmlJSTools::Constants::M_TOOLS_QMLJS));
@@ -161,26 +163,29 @@ QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
qmlToolsMenu->addAction(cmd);
QAction *renameUsagesAction = new QAction(QmlJSEditorPlugin::tr("Rename Symbol Under Cursor"), this);
- cmd = ActionManager::registerAction(renameUsagesAction, Constants::RENAME_USAGES, context);
+ cmd = ActionManager::registerAction(renameUsagesAction, "QmlJSEditor.RenameUsages", context);
cmd->setDefaultKeySequence(QKeySequence(QmlJSEditorPlugin::tr("Ctrl+Shift+R")));
connect(renameUsagesAction, &QAction::triggered, this, &QmlJSEditorPluginPrivate::renameUsages);
contextMenu->addAction(cmd);
qmlToolsMenu->addAction(cmd);
QAction *semanticScan = new QAction(QmlJSEditorPlugin::tr("Run Checks"), this);
- cmd = ActionManager::registerAction(semanticScan, Id(Constants::RUN_SEMANTIC_SCAN));
+ cmd = ActionManager::registerAction(semanticScan, Id("QmlJSEditor.RunSemanticScan"));
cmd->setDefaultKeySequence(QKeySequence(QmlJSEditorPlugin::tr("Ctrl+Shift+C")));
connect(semanticScan, &QAction::triggered, this, &QmlJSEditorPluginPrivate::runSemanticScan);
qmlToolsMenu->addAction(cmd);
m_reformatFileAction = new QAction(QmlJSEditorPlugin::tr("Reformat File"), this);
- cmd = ActionManager::registerAction(m_reformatFileAction, Id(Constants::REFORMAT_FILE), context);
+ cmd = ActionManager::registerAction(m_reformatFileAction,
+ Id("QmlJSEditor.ReformatFile"),
+ context);
connect(m_reformatFileAction, &QAction::triggered, this, &QmlJSEditorPluginPrivate::reformatFile);
qmlToolsMenu->addAction(cmd);
QAction *inspectElementAction = new QAction(QmlJSEditorPlugin::tr("Inspect API for Element Under Cursor"), this);
cmd = ActionManager::registerAction(inspectElementAction,
- Id(Constants::INSPECT_ELEMENT_UNDER_CURSOR), context);
+ Id("QmlJSEditor.InspectElementUnderCursor"),
+ context);
connect(inspectElementAction, &QAction::triggered, [] {
if (auto widget = qobject_cast<QmlJSEditorWidget *>(EditorManager::currentEditor()->widget()))
widget->inspectElementUnderCursor();
@@ -349,7 +354,8 @@ void QmlJSEditorPluginPrivate::autoFormatOnSave(IDocument *document)
return;
// Check that we are dealing with a QML/JS editor
- if (document->id() != Constants::C_QMLJSEDITOR_ID)
+ if (document->id() != Constants::C_QMLJSEDITOR_ID
+ && document->id() != Constants::C_QTQUICKDESIGNEREDITOR_ID)
return;
// Check if file is contained in the current project (if wished)
diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp
index 8b790c3351..670fc69282 100644
--- a/src/plugins/qmljseditor/qmljsfindreferences.cpp
+++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp
@@ -814,9 +814,8 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
// update snapshot from workingCopy to make sure it's up to date
// ### remove?
// ### this is a great candidate for map-reduce
- QHashIterator< QString, QPair<QString, int> > it(workingCopy.all());
- while (it.hasNext()) {
- it.next();
+ const ModelManagerInterface::WorkingCopy::Table &all = workingCopy.all();
+ for (auto it = all.cbegin(), end = all.cend(); it != end; ++it) {
const QString fileName = it.key();
Document::Ptr oldDoc = snapshot.document(fileName);
if (oldDoc && oldDoc->editorRevision() == it.value().second)
@@ -980,9 +979,9 @@ void FindReferences::displayResults(int first, int last)
connect(m_currentSearch.data(), &SearchResult::paused, this, &FindReferences::setPaused);
SearchResultWindow::instance()->popup(IOutputPane::Flags(IOutputPane::ModeSwitch | IOutputPane::WithFocus));
- FutureProgress *progress = ProgressManager::addTask(
- m_watcher.future(), tr("Searching for Usages"),
- QmlJSEditor::Constants::TASK_SEARCH);
+ FutureProgress *progress = ProgressManager::addTask(m_watcher.future(),
+ tr("Searching for Usages"),
+ "QmlJSEditor.TaskSearch");
connect(progress, &FutureProgress::clicked, m_currentSearch.data(), &SearchResult::popup);
++first;
diff --git a/src/plugins/qmljseditor/qmljshoverhandler.cpp b/src/plugins/qmljseditor/qmljshoverhandler.cpp
index 9cea65e3ef..cf73d63d7c 100644
--- a/src/plugins/qmljseditor/qmljshoverhandler.cpp
+++ b/src/plugins/qmljseditor/qmljshoverhandler.cpp
@@ -59,7 +59,6 @@ using namespace QmlJS;
using namespace TextEditor;
namespace QmlJSEditor {
-namespace Internal {
namespace {
@@ -517,6 +516,5 @@ bool QmlJSHoverHandler::setQmlHelpItem(const ScopeChain &scopeChain,
return false;
}
-} // namespace Internal
} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljshoverhandler.h b/src/plugins/qmljseditor/qmljshoverhandler.h
index be51f6c53b..afe35c2971 100644
--- a/src/plugins/qmljseditor/qmljshoverhandler.h
+++ b/src/plugins/qmljseditor/qmljshoverhandler.h
@@ -25,6 +25,7 @@
#pragma once
+#include <qmljseditor/qmljseditor_global.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <texteditor/basehoverhandler.h>
@@ -44,11 +45,10 @@ class ObjectValue;
}
namespace QmlJSEditor {
-namespace Internal {
class QmlJSEditorWidget;
-class QmlJSHoverHandler : public TextEditor::BaseHoverHandler
+class QMLJSEDITOR_EXPORT QmlJSHoverHandler : public TextEditor::BaseHoverHandler
{
Q_DECLARE_TR_FUNCTIONS(QmlJSHoverHandler)
@@ -86,5 +86,4 @@ private:
QColor m_colorTip;
};
-} // namespace Internal
} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljsoutline.cpp b/src/plugins/qmljseditor/qmljsoutline.cpp
index 0eb0d40161..abd333f468 100644
--- a/src/plugins/qmljseditor/qmljsoutline.cpp
+++ b/src/plugins/qmljseditor/qmljsoutline.cpp
@@ -105,7 +105,7 @@ QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent)
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(Core::ItemViewFind::createSearchableWrapper(m_treeView));
diff --git a/src/plugins/qmljseditor/qmljsoutline.h b/src/plugins/qmljseditor/qmljsoutline.h
index 1e4b1d20d1..b81e9f39ce 100644
--- a/src/plugins/qmljseditor/qmljsoutline.h
+++ b/src/plugins/qmljseditor/qmljsoutline.h
@@ -38,9 +38,11 @@ namespace Core { class IEditor; }
namespace QmlJS { class Editor; }
namespace QmlJSEditor {
-namespace Internal {
class QmlJSEditorWidget;
+
+namespace Internal {
+
class QmlJSOutlineTreeView;
class QmlJSOutlineFilterModel : public QSortFilterProxyModel
diff --git a/src/plugins/qmljseditor/qmljsquickfixassist.h b/src/plugins/qmljseditor/qmljsquickfixassist.h
index 83d328fc80..21aaf46073 100644
--- a/src/plugins/qmljseditor/qmljsquickfixassist.h
+++ b/src/plugins/qmljseditor/qmljsquickfixassist.h
@@ -32,10 +32,11 @@
#include <texteditor/codeassist/iassistprovider.h>
namespace QmlJSEditor {
-namespace Internal {
class QmlJSEditorWidget;
+namespace Internal {
+
class QmlJSQuickFixAssistInterface : public TextEditor::AssistInterface
{
public:
diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
index 3541793208..034c1b1301 100644
--- a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
+++ b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
@@ -54,8 +54,6 @@ using namespace QmlJS::AST;
namespace QmlJSEditor {
-using namespace Internal;
-
namespace {
static bool isIdScope(const ObjectValue *scope, const QList<const QmlComponentChain *> &chain)
@@ -522,7 +520,7 @@ private:
ScopeBuilder m_scopeBuilder;
QStringList m_stateNames;
QVector<SemanticHighlighter::Use> m_uses;
- unsigned m_lineOfLastUse;
+ int m_lineOfLastUse;
QVector<SemanticHighlighter::Use> m_delayedUses;
int m_nextExtraFormat;
int m_currentDelayedUse;
diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.h b/src/plugins/qmljseditor/qmljssemantichighlighter.h
index 42525c7385..7fa25b588f 100644
--- a/src/plugins/qmljseditor/qmljssemantichighlighter.h
+++ b/src/plugins/qmljseditor/qmljssemantichighlighter.h
@@ -25,6 +25,7 @@
#pragma once
+#include <qmljseditor/qmljseditor_global.h>
#include <texteditor/semantichighlighter.h>
#include <QFutureWatcher>
#include <QTextLayout>
@@ -42,9 +43,7 @@ namespace QmlJSEditor {
class QmlJSEditorDocument;
-namespace Internal {
-
-class SemanticHighlighter : public QObject
+class QMLJSEDITOR_EXPORT SemanticHighlighter : public QObject
{
Q_OBJECT
public:
@@ -92,5 +91,4 @@ private:
QVector<QTextLayout::FormatRange> m_diagnosticRanges;
};
-} // namespace Internal
} // namespace QmlJSEditor
diff --git a/src/plugins/qmljseditor/qmljswrapinloader.cpp b/src/plugins/qmljseditor/qmljswrapinloader.cpp
index 3766dcdbbf..d83d34e23e 100644
--- a/src/plugins/qmljseditor/qmljswrapinloader.cpp
+++ b/src/plugins/qmljseditor/qmljswrapinloader.cpp
@@ -139,9 +139,7 @@ public:
// handle inner ids
QString innerIdForwarders;
- QHashIterator<QString, SourceLocation> it(innerIds);
- while (it.hasNext()) {
- it.next();
+ for (auto it = innerIds.cbegin(), end = innerIds.cend(); it != end; ++it) {
const QString innerId = it.key();
comment += tr("// Rename all outer uses of the id \"%1\" to \"%2.item.%1\".\n").arg(
innerId, loaderId);
diff --git a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp
index 3ca3bbc999..c822e27410 100644
--- a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp
+++ b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp
@@ -75,7 +75,7 @@ QWidget *QmlJSCodeStylePreferencesFactory::createEditor(TextEditor::ICodeStylePr
QWidget *parent) const
{
auto widget = new Internal::QmlJSCodeStylePreferencesWidget(parent);
- widget->layout()->setMargin(0);
+ widget->layout()->setContentsMargins(0, 0, 0, 0);
widget->setPreferences(preferences);
return widget;
}
diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp
index 2de503b782..6379ffafc4 100644
--- a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp
+++ b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp
@@ -121,9 +121,7 @@ void QmlJSCodeStylePreferencesWidget::updatePreview()
// ------------------ CppCodeStyleSettingsPage
-QmlJSCodeStyleSettingsPage::QmlJSCodeStyleSettingsPage(/*QSharedPointer<CppFileSettings> &settings,*/
- QWidget *parent) :
- Core::IOptionsPage(parent)
+QmlJSCodeStyleSettingsPage::QmlJSCodeStyleSettingsPage()
{
setId(Constants::QML_JS_CODE_STYLE_SETTINGS_ID);
setDisplayName(QCoreApplication::translate("QmlJSTools", Constants::QML_JS_CODE_STYLE_SETTINGS_NAME));
diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.h b/src/plugins/qmljstools/qmljscodestylesettingspage.h
index c68f5a8eaf..cdafb430fc 100644
--- a/src/plugins/qmljstools/qmljscodestylesettingspage.h
+++ b/src/plugins/qmljstools/qmljscodestylesettingspage.h
@@ -71,7 +71,7 @@ class QmlJSCodeStyleSettingsPage : public Core::IOptionsPage
Q_OBJECT
public:
- explicit QmlJSCodeStyleSettingsPage(QWidget *parent = nullptr);
+ QmlJSCodeStyleSettingsPage();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.cpp b/src/plugins/qmljstools/qmljsfunctionfilter.cpp
index 324f4f7559..715347ebf3 100644
--- a/src/plugins/qmljstools/qmljsfunctionfilter.cpp
+++ b/src/plugins/qmljstools/qmljsfunctionfilter.cpp
@@ -32,6 +32,8 @@
#include <QRegularExpression>
+#include <numeric>
+
using namespace QmlJSTools::Internal;
Q_DECLARE_METATYPE(LocatorData::Entry)
@@ -56,23 +58,18 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
QFutureInterface<Core::LocatorFilterEntry> &future,
const QString &entry)
{
- QList<Core::LocatorFilterEntry> goodEntries;
- QList<Core::LocatorFilterEntry> betterEntries;
- QList<Core::LocatorFilterEntry> bestEntries;
+ QList<Core::LocatorFilterEntry> entries[int(MatchLevel::Count)];
const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
const QRegularExpression regexp = createRegExp(entry);
if (!regexp.isValid())
- return goodEntries;
+ return {};
- QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries());
- while (it.hasNext()) {
+ const QHash<QString, QList<LocatorData::Entry> > locatorEntries = m_data->entries();
+ for (const QList<LocatorData::Entry> &items : locatorEntries) {
if (future.isCanceled())
break;
- it.next();
-
- const QList<LocatorData::Entry> items = it.value();
for (const LocatorData::Entry &info : items) {
if (info.type != LocatorData::Function)
continue;
@@ -85,25 +82,21 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
filterEntry.highlightInfo = highlightInfo(match);
if (filterEntry.displayName.startsWith(entry, caseSensitivityForPrefix))
- bestEntries.append(filterEntry);
+ entries[int(MatchLevel::Best)].append(filterEntry);
else if (filterEntry.displayName.contains(entry, caseSensitivityForPrefix))
- betterEntries.append(filterEntry);
+ entries[int(MatchLevel::Better)].append(filterEntry);
else
- goodEntries.append(filterEntry);
+ entries[int(MatchLevel::Good)].append(filterEntry);
}
}
}
- if (goodEntries.size() < 1000)
- Utils::sort(goodEntries, Core::LocatorFilterEntry::compareLexigraphically);
- if (betterEntries.size() < 1000)
- Utils::sort(betterEntries, Core::LocatorFilterEntry::compareLexigraphically);
- if (bestEntries.size() < 1000)
- Utils::sort(bestEntries, Core::LocatorFilterEntry::compareLexigraphically);
+ for (auto &entry : entries) {
+ if (entry.size() < 1000)
+ Utils::sort(entry, Core::LocatorFilterEntry::compareLexigraphically);
+ }
- bestEntries += betterEntries;
- bestEntries += goodEntries;
- return bestEntries;
+ return std::accumulate(std::begin(entries), std::end(entries), QList<Core::LocatorFilterEntry>());
}
void FunctionFilter::accept(Core::LocatorFilterEntry selection,
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp
index 2d996f4985..b33846faf9 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp
@@ -111,7 +111,7 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
// Append QML2_IMPORT_PATH if it is defined in build configuration.
// It enables qmlplugindump to correctly dump custom plugins or other dependent
// plugins that are not installed in default Qt qml installation directory.
- projectInfo.qmlDumpEnvironment.appendOrSet("QML2_IMPORT_PATH", bc->environment().value("QML2_IMPORT_PATH"), ":");
+ projectInfo.qmlDumpEnvironment.appendOrSet("QML2_IMPORT_PATH", bc->environment().expandedValueForKey("QML2_IMPORT_PATH"), ":");
}
}
if (!setPreferDump && qtVersion)
diff --git a/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.cpp b/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.cpp
index 02b8161ed2..aebce83d5a 100644
--- a/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.cpp
+++ b/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.cpp
@@ -66,7 +66,7 @@ QString QmlPreviewFileOnTargetFinder::findPath(const QString &filePath, bool *su
return filePath;
ProjectExplorer::DeployableFile file
- = m_target->deploymentData().deployableForLocalFile(filePath);
+ = m_target->deploymentData().deployableForLocalFile(Utils::FilePath::fromString(filePath));
if (file.isValid())
return file.remoteFilePath();
diff --git a/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.h b/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.h
index e62396b8cf..d3b30c5ada 100644
--- a/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.h
+++ b/src/plugins/qmlpreview/qmlpreviewfileontargetfinder.h
@@ -42,8 +42,8 @@ public:
void setTarget(ProjectExplorer::Target *target);
ProjectExplorer::Target *target() const;
- QString findPath(const QString &filePath, bool *success = 0) const;
- QUrl findUrl(const QString &filePath, bool *success = 0) const;
+ QString findPath(const QString &filePath, bool *success = nullptr) const;
+ QUrl findUrl(const QString &filePath, bool *success = nullptr) const;
private:
QPointer<ProjectExplorer::Target> m_target;
diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.cpp b/src/plugins/qmlpreview/qmlpreviewplugin.cpp
index 630bd06fa1..876cdb962a 100644
--- a/src/plugins/qmlpreview/qmlpreviewplugin.cpp
+++ b/src/plugins/qmlpreview/qmlpreviewplugin.cpp
@@ -99,26 +99,95 @@ static void defaultFpsHandler(quint16 frames[8])
Core::MessageManager::write(QString::fromLatin1("QML preview: %1 fps").arg(frames[0]));
}
-bool QmlPreviewPlugin::initialize(const QStringList &arguments, QString *errorString)
+class QmlPreviewPluginPrivate : public QObject
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorString);
-
- setFileLoader(&defaultFileLoader);
- setFileClassifier(&defaultFileClassifier);
- setFpsHandler(&defaultFpsHandler);
+public:
+ explicit QmlPreviewPluginPrivate(QmlPreviewPlugin *parent);
+
+ void previewCurrentFile();
+ void onEditorChanged(Core::IEditor *editor);
+ void onEditorAboutToClose(Core::IEditor *editor);
+ void setDirty();
+ void addPreview(ProjectExplorer::RunControl *preview);
+ void removePreview(ProjectExplorer::RunControl *preview);
+ void attachToEditor();
+ void checkEditor();
+ void checkFile(const QString &fileName);
+ void triggerPreview(const QString &changedFile, const QByteArray &contents);
+
+ QString previewedFile() const;
+ void setPreviewedFile(const QString &previewedFile);
+ QmlPreviewRunControlList runningPreviews() const;
+
+ QmlPreviewFileClassifier fileClassifier() const;
+ void setFileClassifier(QmlPreviewFileClassifier fileClassifer);
+
+ float zoomFactor() const;
+ void setZoomFactor(float zoomFactor);
+
+ QmlPreview::QmlPreviewFpsHandler fpsHandler() const;
+ void setFpsHandler(QmlPreview::QmlPreviewFpsHandler fpsHandler);
+
+ QString locale() const;
+ void setLocale(const QString &locale);
+
+ QmlPreviewPlugin *q = nullptr;
+ QThread m_parseThread;
+ QString m_previewedFile;
+ QmlPreviewFileLoader m_fileLoader = nullptr;
+ Core::IEditor *m_lastEditor = nullptr;
+ QmlPreviewRunControlList m_runningPreviews;
+ bool m_dirty = false;
+ QmlPreview::QmlPreviewFileClassifier m_fileClassifer = nullptr;
+ float m_zoomFactor = -1.0;
+ QmlPreview::QmlPreviewFpsHandler m_fpsHandler = nullptr;
+ QString m_locale;
+
+ RunWorkerFactory localRunWorkerFactory{
+ RunWorkerFactory::make<LocalQmlPreviewSupport>(),
+ {Constants::QML_PREVIEW_RUN_MODE},
+ {}, // All runconfig.
+ {Constants::DESKTOP_DEVICE_TYPE}
+ };
- auto constraint = [](RunConfiguration *runConfiguration) {
- Target *target = runConfiguration ? runConfiguration->target() : nullptr;
- Kit *kit = target ? target->kit() : nullptr;
- return DeviceTypeKitAspect::deviceTypeId(kit) == Constants::DESKTOP_DEVICE_TYPE;
+ RunWorkerFactory runWorkerFactory{
+ [this](RunControl *runControl) {
+ QmlPreviewRunner *runner = new QmlPreviewRunner(runControl, m_fileLoader, m_fileClassifer,
+ m_fpsHandler, m_zoomFactor, m_locale);
+ connect(q, &QmlPreviewPlugin::updatePreviews,
+ runner, &QmlPreviewRunner::loadFile);
+ connect(q, &QmlPreviewPlugin::rerunPreviews,
+ runner, &QmlPreviewRunner::rerun);
+ connect(runner, &QmlPreviewRunner::ready,
+ this, &QmlPreviewPluginPrivate::previewCurrentFile);
+ connect(q, &QmlPreviewPlugin::zoomFactorChanged,
+ runner, &QmlPreviewRunner::zoom);
+ connect(q, &QmlPreviewPlugin::localeChanged,
+ runner, &QmlPreviewRunner::language);
+
+ connect(runner, &RunWorker::started, this, [this, runControl] {
+ addPreview(runControl);
+ });
+ connect(runner, &RunWorker::stopped, this, [this, runControl] {
+ removePreview(runControl);
+ });
+
+ return runner;
+ },
+ {Constants::QML_PREVIEW_RUNNER}
};
+};
- RunControl::registerWorker<LocalQmlPreviewSupport>(Constants::QML_PREVIEW_RUN_MODE, constraint);
+QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
+ : q(parent)
+{
+ m_fileLoader = &defaultFileLoader;
+ m_fileClassifer = &defaultFileClassifier;
+ m_fpsHandler = &defaultFpsHandler;
Core::ActionContainer *menu = Core::ActionManager::actionContainer(
Constants::M_BUILDPROJECT);
- QAction *action = new QAction(tr("QML Preview"), this);
+ QAction *action = new QAction(QmlPreviewPlugin::tr("QML Preview"), this);
action->setToolTip(QLatin1String("Preview changes to QML code live in your application."));
action->setEnabled(SessionManager::startupProject() != nullptr);
connect(SessionManager::instance(), &SessionManager::startupProjectChanged, action,
@@ -133,11 +202,11 @@ bool QmlPreviewPlugin::initialize(const QStringList &arguments, QString *errorSt
menu = Core::ActionManager::actionContainer(Constants::M_FILECONTEXT);
action = new QAction(tr("Preview File"), this);
action->setEnabled(false);
- connect(this, &QmlPreviewPlugin::runningPreviewsChanged,
+ connect(q, &QmlPreviewPlugin::runningPreviewsChanged,
action, [action](const QmlPreviewRunControlList &previews) {
action->setEnabled(!previews.isEmpty());
});
- connect(action, &QAction::triggered, this, &QmlPreviewPlugin::previewCurrentFile);
+ connect(action, &QAction::triggered, this, &QmlPreviewPluginPrivate::previewCurrentFile);
menu->addAction(Core::ActionManager::registerAction(action, "QmlPreview.Preview",
projectTreeContext),
Constants::G_FILE_OTHER);
@@ -152,36 +221,25 @@ bool QmlPreviewPlugin::initialize(const QStringList &arguments, QString *errorSt
QmlPreviewParser *parser = new QmlPreviewParser;
parser->moveToThread(&m_parseThread);
connect(this, &QObject::destroyed, parser, &QObject::deleteLater);
- connect(this, &QmlPreviewPlugin::checkDocument, parser, &QmlPreviewParser::parse);
- connect(this, &QmlPreviewPlugin::previewedFileChanged, this, &QmlPreviewPlugin::checkFile);
- connect(parser, &QmlPreviewParser::success, this, &QmlPreviewPlugin::triggerPreview);
-
- RunControl::registerWorkerCreator(Constants::QML_PREVIEW_RUN_MODE,
- [this](RunControl *runControl) {
- QmlPreviewRunner *runner = new QmlPreviewRunner(runControl, m_fileLoader, m_fileClassifer,
- m_fpsHandler, m_zoomFactor, m_locale);
- QObject::connect(this, &QmlPreviewPlugin::updatePreviews,
- runner, &QmlPreviewRunner::loadFile);
- QObject::connect(this, &QmlPreviewPlugin::rerunPreviews,
- runner, &QmlPreviewRunner::rerun);
- QObject::connect(runner, &QmlPreviewRunner::ready,
- this, &QmlPreviewPlugin::previewCurrentFile);
- QObject::connect(this, &QmlPreviewPlugin::zoomFactorChanged,
- runner, &QmlPreviewRunner::zoom);
- QObject::connect(this, &QmlPreviewPlugin::localeChanged,
- runner, &QmlPreviewRunner::language);
-
- QObject::connect(runner, &RunWorker::started, this, [this, runControl]() {
- addPreview(runControl);
- });
- QObject::connect(runner, &RunWorker::stopped, this, [this, runControl]() {
- removePreview(runControl);
- });
-
- return runner;
- });
+ connect(q, &QmlPreviewPlugin::checkDocument, parser, &QmlPreviewParser::parse);
+ connect(q, &QmlPreviewPlugin::previewedFileChanged, this, &QmlPreviewPluginPrivate::checkFile);
+ connect(parser, &QmlPreviewParser::success, this, &QmlPreviewPluginPrivate::triggerPreview);
attachToEditor();
+}
+
+QmlPreviewPlugin::~QmlPreviewPlugin()
+{
+ delete d;
+}
+
+bool QmlPreviewPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ d = new QmlPreviewPluginPrivate(this);
+
return true;
}
@@ -191,8 +249,8 @@ void QmlPreviewPlugin::extensionsInitialized()
ExtensionSystem::IPlugin::ShutdownFlag QmlPreviewPlugin::aboutToShutdown()
{
- m_parseThread.quit();
- m_parseThread.wait();
+ d->m_parseThread.quit();
+ d->m_parseThread.wait();
return SynchronousShutdown;
}
@@ -208,94 +266,94 @@ QVector<QObject *> QmlPreviewPlugin::createTestObjects() const
QString QmlPreviewPlugin::previewedFile() const
{
- return m_previewedFile;
+ return d->m_previewedFile;
}
void QmlPreviewPlugin::setPreviewedFile(const QString &previewedFile)
{
- if (m_previewedFile == previewedFile)
+ if (d->m_previewedFile == previewedFile)
return;
- m_previewedFile = previewedFile;
- emit previewedFileChanged(m_previewedFile);
+ d->m_previewedFile = previewedFile;
+ emit previewedFileChanged(d->m_previewedFile);
}
QmlPreviewRunControlList QmlPreviewPlugin::runningPreviews() const
{
- return m_runningPreviews;
+ return d->m_runningPreviews;
}
QmlPreviewFileLoader QmlPreviewPlugin::fileLoader() const
{
- return m_fileLoader;
+ return d->m_fileLoader;
}
QmlPreviewFileClassifier QmlPreviewPlugin::fileClassifier() const
{
- return m_fileClassifer;
+ return d->m_fileClassifer;
}
void QmlPreviewPlugin::setFileClassifier(QmlPreviewFileClassifier fileClassifer)
{
- if (m_fileClassifer == fileClassifer)
+ if (d->m_fileClassifer == fileClassifer)
return;
- m_fileClassifer = fileClassifer;
- emit fileClassifierChanged(m_fileClassifer);
+ d->m_fileClassifer = fileClassifer;
+ emit fileClassifierChanged(d->m_fileClassifer);
}
float QmlPreviewPlugin::zoomFactor() const
{
- return m_zoomFactor;
+ return d->m_zoomFactor;
}
void QmlPreviewPlugin::setZoomFactor(float zoomFactor)
{
- if (m_zoomFactor == zoomFactor)
+ if (d->m_zoomFactor == zoomFactor)
return;
- m_zoomFactor = zoomFactor;
- emit zoomFactorChanged(m_zoomFactor);
+ d->m_zoomFactor = zoomFactor;
+ emit zoomFactorChanged(d->m_zoomFactor);
}
QmlPreviewFpsHandler QmlPreviewPlugin::fpsHandler() const
{
- return m_fpsHandler;
+ return d->m_fpsHandler;
}
void QmlPreviewPlugin::setFpsHandler(QmlPreviewFpsHandler fpsHandler)
{
- if (m_fpsHandler == fpsHandler)
+ if (d->m_fpsHandler == fpsHandler)
return;
- m_fpsHandler = fpsHandler;
- emit fpsHandlerChanged(m_fpsHandler);
+ d->m_fpsHandler = fpsHandler;
+ emit fpsHandlerChanged(d->m_fpsHandler);
}
QString QmlPreviewPlugin::locale() const
{
- return m_locale;
+ return d->m_locale;
}
void QmlPreviewPlugin::setLocale(const QString &locale)
{
- if (m_locale == locale)
+ if (d->m_locale == locale)
return;
- m_locale = locale;
- emit localeChanged(m_locale);
+ d->m_locale = locale;
+ emit localeChanged(d->m_locale);
}
void QmlPreviewPlugin::setFileLoader(QmlPreviewFileLoader fileLoader)
{
- if (m_fileLoader == fileLoader)
+ if (d->m_fileLoader == fileLoader)
return;
- m_fileLoader = fileLoader;
- emit fileLoaderChanged(m_fileLoader);
+ d->m_fileLoader = fileLoader;
+ emit fileLoaderChanged(d->m_fileLoader);
}
-void QmlPreviewPlugin::previewCurrentFile()
+void QmlPreviewPluginPrivate::previewCurrentFile()
{
const Node *currentNode = ProjectTree::currentNode();
if (!currentNode || !currentNode->asFileNode()
@@ -304,16 +362,16 @@ void QmlPreviewPlugin::previewCurrentFile()
const QString file = currentNode->filePath().toString();
if (file != m_previewedFile)
- setPreviewedFile(file);
+ q->setPreviewedFile(file);
else
checkFile(file);
}
-void QmlPreviewPlugin::onEditorChanged(Core::IEditor *editor)
+void QmlPreviewPluginPrivate::onEditorChanged(Core::IEditor *editor)
{
if (m_lastEditor) {
Core::IDocument *doc = m_lastEditor->document();
- disconnect(doc, &Core::IDocument::contentsChanged, this, &QmlPreviewPlugin::setDirty);
+ disconnect(doc, &Core::IDocument::contentsChanged, this, &QmlPreviewPluginPrivate::setDirty);
if (m_dirty) {
m_dirty = false;
checkEditor();
@@ -324,11 +382,11 @@ void QmlPreviewPlugin::onEditorChanged(Core::IEditor *editor)
if (m_lastEditor) {
// Handle new editor
connect(m_lastEditor->document(), &Core::IDocument::contentsChanged,
- this, &QmlPreviewPlugin::setDirty);
+ this, &QmlPreviewPluginPrivate::setDirty);
}
}
-void QmlPreviewPlugin::onEditorAboutToClose(Core::IEditor *editor)
+void QmlPreviewPluginPrivate::onEditorAboutToClose(Core::IEditor *editor)
{
if (m_lastEditor != editor)
return;
@@ -336,7 +394,7 @@ void QmlPreviewPlugin::onEditorAboutToClose(Core::IEditor *editor)
// Oh no our editor is going to be closed
// get the content first
Core::IDocument *doc = m_lastEditor->document();
- disconnect(doc, &Core::IDocument::contentsChanged, this, &QmlPreviewPlugin::setDirty);
+ disconnect(doc, &Core::IDocument::contentsChanged, this, &QmlPreviewPluginPrivate::setDirty);
if (m_dirty) {
m_dirty = false;
checkEditor();
@@ -344,7 +402,7 @@ void QmlPreviewPlugin::onEditorAboutToClose(Core::IEditor *editor)
m_lastEditor = nullptr;
}
-void QmlPreviewPlugin::setDirty()
+void QmlPreviewPluginPrivate::setDirty()
{
m_dirty = true;
QTimer::singleShot(1000, this, [this](){
@@ -355,28 +413,28 @@ void QmlPreviewPlugin::setDirty()
});
}
-void QmlPreviewPlugin::addPreview(ProjectExplorer::RunControl *preview)
+void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *preview)
{
m_runningPreviews.append(preview);
- emit runningPreviewsChanged(m_runningPreviews);
+ emit q->runningPreviewsChanged(m_runningPreviews);
}
-void QmlPreviewPlugin::removePreview(ProjectExplorer::RunControl *preview)
+void QmlPreviewPluginPrivate::removePreview(ProjectExplorer::RunControl *preview)
{
m_runningPreviews.removeOne(preview);
- emit runningPreviewsChanged(m_runningPreviews);
+ emit q->runningPreviewsChanged(m_runningPreviews);
}
-void QmlPreviewPlugin::attachToEditor()
+void QmlPreviewPluginPrivate::attachToEditor()
{
Core::EditorManager *editorManager = Core::EditorManager::instance();
connect(editorManager, &Core::EditorManager::currentEditorChanged,
- this, &QmlPreviewPlugin::onEditorChanged);
+ this, &QmlPreviewPluginPrivate::onEditorChanged);
connect(editorManager, &Core::EditorManager::editorAboutToClose,
- this, &QmlPreviewPlugin::onEditorAboutToClose);
+ this, &QmlPreviewPluginPrivate::onEditorAboutToClose);
}
-void QmlPreviewPlugin::checkEditor()
+void QmlPreviewPluginPrivate::checkEditor()
{
QmlJS::Dialect::Enum dialect = QmlJS::Dialect::AnyLanguage;
Core::IDocument *doc = m_lastEditor->document();
@@ -402,10 +460,10 @@ void QmlPreviewPlugin::checkEditor()
dialect = QmlJS::Dialect::QmlQtQuick2Ui;
else
dialect = QmlJS::Dialect::NoLanguage;
- emit checkDocument(doc->filePath().toString(), doc->contents(), dialect);
+ emit q->checkDocument(doc->filePath().toString(), doc->contents(), dialect);
}
-void QmlPreviewPlugin::checkFile(const QString &fileName)
+void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
{
if (!m_fileLoader)
return;
@@ -414,23 +472,23 @@ void QmlPreviewPlugin::checkFile(const QString &fileName)
const QByteArray contents = m_fileLoader(fileName, &success);
if (success) {
- emit checkDocument(fileName, contents,
- QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName).dialect());
+ emit q->checkDocument(fileName, contents,
+ QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName).dialect());
}
}
-void QmlPreviewPlugin::triggerPreview(const QString &changedFile, const QByteArray &contents)
+void QmlPreviewPluginPrivate::triggerPreview(const QString &changedFile, const QByteArray &contents)
{
if (m_previewedFile.isEmpty())
previewCurrentFile();
else
- emit updatePreviews(m_previewedFile, changedFile, contents);
+ emit q->updatePreviews(m_previewedFile, changedFile, contents);
}
QmlPreviewParser::QmlPreviewParser()
{
static const int dialectMeta = qRegisterMetaType<QmlJS::Dialect::Enum>();
- Q_UNUSED(dialectMeta);
+ Q_UNUSED(dialectMeta)
}
void QmlPreviewParser::parse(const QString &name, const QByteArray &contents,
diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.h b/src/plugins/qmlpreview/qmlpreviewplugin.h
index 559cbb81dd..6c3175db2d 100644
--- a/src/plugins/qmlpreview/qmlpreviewplugin.h
+++ b/src/plugins/qmlpreview/qmlpreviewplugin.h
@@ -61,6 +61,8 @@ class QmlPreviewPlugin : public ExtensionSystem::IPlugin
Q_PROPERTY(QString locale READ locale WRITE setLocale NOTIFY localeChanged)
public:
+ ~QmlPreviewPlugin() override;
+
bool initialize(const QStringList &arguments, QString *errorString) override;
void extensionsInitialized() override;
ShutdownFlag aboutToShutdown() override;
@@ -101,27 +103,7 @@ signals:
void localeChanged(const QString &locale);
private:
- void previewCurrentFile();
- void onEditorChanged(Core::IEditor *editor);
- void onEditorAboutToClose(Core::IEditor *editor);
- void setDirty();
- void addPreview(ProjectExplorer::RunControl *preview);
- void removePreview(ProjectExplorer::RunControl *preview);
- void attachToEditor();
- void checkEditor();
- void checkFile(const QString &fileName);
- void triggerPreview(const QString &changedFile, const QByteArray &contents);
-
- QThread m_parseThread;
- QString m_previewedFile;
- QmlPreviewFileLoader m_fileLoader = nullptr;
- Core::IEditor *m_lastEditor = nullptr;
- QmlPreviewRunControlList m_runningPreviews;
- bool m_dirty = false;
- QmlPreview::QmlPreviewFileClassifier m_fileClassifer = nullptr;
- float m_zoomFactor = -1.0;
- QmlPreview::QmlPreviewFpsHandler m_fpsHandler = nullptr;
- QString m_locale;
+ class QmlPreviewPluginPrivate *d = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp
index 7f4178932d..26e3456338 100644
--- a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp
+++ b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp
@@ -117,18 +117,20 @@ LocalQmlPreviewSupport::LocalQmlPreviewSupport(ProjectExplorer::RunControl *runC
const QUrl serverUrl = Utils::urlFromLocalSocket();
QmlPreviewRunner *preview = qobject_cast<QmlPreviewRunner *>(
- runControl->createWorker(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE));
+ runControl->createWorker(ProjectExplorer::Constants::QML_PREVIEW_RUNNER));
preview->setServerUrl(serverUrl);
addStopDependency(preview);
addStartDependency(preview);
- ProjectExplorer::Runnable run = runnable();
+ setStarter([this, runControl, serverUrl] {
+ ProjectExplorer::Runnable run = runControl->runnable();
- Utils::QtcProcess::addArg(&run.commandLineArguments,
- QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlPreviewServices,
- serverUrl.path()));
- setRunnable(run);
+ Utils::QtcProcess::addArg(&run.commandLineArguments,
+ QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlPreviewServices,
+ serverUrl.path()));
+ doStart(run, {});
+ });
}
} // namespace QmlPreview
diff --git a/src/plugins/qmlprofiler/debugmessagesmodel.cpp b/src/plugins/qmlprofiler/debugmessagesmodel.cpp
index 1ec11ac8f7..1509c95c9d 100644
--- a/src/plugins/qmlprofiler/debugmessagesmodel.cpp
+++ b/src/plugins/qmlprofiler/debugmessagesmodel.cpp
@@ -95,7 +95,7 @@ int DebugMessagesModel::expandedRow(int index) const
int DebugMessagesModel::collapsedRow(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return Constants::QML_MIN_LEVEL;
}
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.cpp b/src/plugins/qmlprofiler/flamegraphmodel.cpp
index 7821ff8520..5673f2fbc3 100644
--- a/src/plugins/qmlprofiler/flamegraphmodel.cpp
+++ b/src/plugins/qmlprofiler/flamegraphmodel.cpp
@@ -300,7 +300,7 @@ int FlameGraphModel::rowCount(const QModelIndex &parent) const
int FlameGraphModel::columnCount(const QModelIndex &parent) const
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 1;
}
diff --git a/src/plugins/qmlprofiler/memoryusagemodel.cpp b/src/plugins/qmlprofiler/memoryusagemodel.cpp
index 1fcfc4631f..86620ed6d0 100644
--- a/src/plugins/qmlprofiler/memoryusagemodel.cpp
+++ b/src/plugins/qmlprofiler/memoryusagemodel.cpp
@@ -45,7 +45,7 @@ MemoryUsageModel::MemoryUsageModel(QmlProfilerModelManager *manager,
qint64 MemoryUsageModel::rowMaxValue(int rowNumber) const
{
- Q_UNUSED(rowNumber);
+ Q_UNUSED(rowNumber)
return m_maxSize;
}
@@ -271,7 +271,7 @@ void MemoryUsageModel::clear()
bool MemoryUsageModel::handlesTypeId(int typeId) const
{
- Q_UNUSED(typeId);
+ Q_UNUSED(typeId)
// We don't want the memory ranges allocated by some QML/JS function to be highlighted when
// propagating a typeId selection to the timeline. The actual range should be highlighted.
return false;
diff --git a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
index a734b011a2..1780dee7f2 100644
--- a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
+++ b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml
@@ -30,7 +30,6 @@ FlameGraphView {
id: root
model: flameGraphModel
- sizeRole: QmlProfilerFlameGraphModel.DurationRole
typeIdRole: QmlProfilerFlameGraphModel.TypeIdRole
sourceFileRole: QmlProfilerFlameGraphModel.FilenameRole
diff --git a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp
index 8fef692ed3..bec3496a15 100644
--- a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp
+++ b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp
@@ -57,7 +57,7 @@ void QmlProfilerAnimationsModel::clear()
void QmlProfilerAnimationsModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
- Q_UNUSED(type);
+ Q_UNUSED(type)
AnimationThread lastThread = (AnimationThread)event.number<qint32>(2);
// initial estimation of the event duration: 1/framerate
diff --git a/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp b/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp
index 2ac1850735..f7eaab21a2 100644
--- a/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp
@@ -157,8 +157,8 @@ Timeline::TimelineRenderPass::State *QmlProfilerBindingLoopsRenderPass::update(
const Timeline::TimelineRenderState *parentState, State *oldState,
int indexFrom, int indexTo, bool stateChanged, float spacing) const
{
- Q_UNUSED(stateChanged);
- Q_UNUSED(spacing);
+ Q_UNUSED(stateChanged)
+ Q_UNUSED(spacing)
auto model = qobject_cast<const QmlProfilerRangeModel *>(renderer->model());
@@ -219,7 +219,7 @@ Point2DWithOffset *BindlingLoopsGeometry::vertexData()
Q_ASSERT(attributes[1].position == 1);
Q_ASSERT(attributes[1].tupleSize == 2);
Q_ASSERT(attributes[1].type == GL_FLOAT);
- Q_UNUSED(attributes);
+ Q_UNUSED(attributes)
return static_cast<Point2DWithOffset *>(geometry->vertexData());
}
diff --git a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.cpp b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.cpp
index 37994fd436..3eea277525 100644
--- a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.cpp
@@ -29,8 +29,8 @@
namespace QmlProfiler {
namespace Internal {
-QmlProfilerConfigWidget::QmlProfilerConfigWidget(QmlProfilerSettings *settings, QWidget *parent) :
- QWidget(parent), m_ui(new Ui::QmlProfilerConfigWidget), m_settings(settings)
+QmlProfilerConfigWidget::QmlProfilerConfigWidget(QmlProfilerSettings *settings) :
+ m_ui(new Ui::QmlProfilerConfigWidget), m_settings(settings)
{
m_ui->setupUi(this);
updateUi();
diff --git a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h
index 63e24c64c7..cc80849f85 100644
--- a/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h
+++ b/src/plugins/qmlprofiler/qmlprofilerconfigwidget.h
@@ -41,7 +41,7 @@ class QmlProfilerConfigWidget : public QWidget
Q_OBJECT
public:
- explicit QmlProfilerConfigWidget(QmlProfilerSettings *settings, QWidget *parent = nullptr);
+ explicit QmlProfilerConfigWidget(QmlProfilerSettings *settings);
~QmlProfilerConfigWidget() override;
private:
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
index e14a696eba..f1349d97d9 100644
--- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
@@ -126,10 +126,6 @@ QmlProfilerModelManager::QmlProfilerModelManager(QObject *parent) :
this, &QmlProfilerModelManager::setTypeDetails);
connect(d->detailsRewriter, &Internal::QmlProfilerDetailsRewriter::eventDetailsChanged,
this, &QmlProfilerModelManager::typeDetailsFinished);
-
- quint64 allFeatures = 0;
- for (quint8 i = 0; i <= MaximumProfileFeature; ++i)
- allFeatures |= (1ull << i);
}
QmlProfilerModelManager::~QmlProfilerModelManager()
diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
index 942ab9344d..f53c604285 100644
--- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
@@ -80,34 +80,28 @@ namespace Internal {
Q_GLOBAL_STATIC(QmlProfilerSettings, qmlProfilerGlobalSettings)
-bool constraint(RunConfiguration *runConfiguration)
-{
- Target *target = runConfiguration ? runConfiguration->target() : nullptr;
- Kit *kit = target ? target->kit() : nullptr;
- return DeviceTypeKitAspect::deviceTypeId(kit)
- == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
-}
-
-class QmlProfilerRunWorkerFactory : public RunWorkerFactory
-{
-public:
- QmlProfilerRunWorkerFactory(QmlProfilerTool *tool)
- {
- addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
- setProducer([tool](RunControl *runControl) {
- return new LocalQmlProfilerSupport(tool, runControl);
- });
- addConstraint(constraint);
- }
-};
-
class QmlProfilerPluginPrivate
{
public:
QmlProfilerTool m_profilerTool;
QmlProfilerOptionsPage m_profilerOptionsPage;
QmlProfilerActions m_actions;
- QmlProfilerRunWorkerFactory m_profilerWorkerFactory{&m_profilerTool};
+
+ // The full local profiler.
+ RunWorkerFactory localQmlProfilerFactory {
+ RunWorkerFactory::make<LocalQmlProfilerSupport>(),
+ {ProjectExplorer::Constants::QML_PROFILER_RUN_MODE},
+ {},
+ {ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE}
+ };
+
+ // The bits plugged in in remote setups.
+ RunWorkerFactory qmlProfilerWorkerFactory {
+ RunWorkerFactory::make<QmlProfilerRunner>(),
+ {ProjectExplorer::Constants::QML_PROFILER_RUNNER},
+ {},
+ {}
+ };
};
bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorString)
@@ -123,14 +117,6 @@ void QmlProfilerPlugin::extensionsInitialized()
d->m_actions.registerActions();
RunConfiguration::registerAspect<QmlProfilerRunConfigurationAspect>();
-
- RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE,
- [this](RunControl *runControl) {
- auto runner = new QmlProfilerRunner(runControl);
- connect(runner, &QmlProfilerRunner::starting,
- &d->m_profilerTool, &QmlProfilerTool::finalizeRunControl);
- return runner;
- });
}
ExtensionSystem::IPlugin::ShutdownFlag QmlProfilerPlugin::aboutToShutdown()
diff --git a/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp b/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp
index 6c099feec3..50c461ef1c 100644
--- a/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp
@@ -65,7 +65,7 @@ bool QmlProfilerRangeModel::supportsBindingLoops() const
void QmlProfilerRangeModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
- Q_UNUSED(type);
+ Q_UNUSED(type)
// store starttime-based instance
if (event.rangeStage() == RangeStart) {
int index = insertStart(event.timestamp(), event.typeIndex());
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
index c9cc305d75..5d51540d3f 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
@@ -88,7 +88,8 @@ QmlProfilerRunner::~QmlProfilerRunner()
void QmlProfilerRunner::start()
{
- emit starting(this);
+ if (!d->m_profilerState)
+ QmlProfilerTool::instance()->finalizeRunControl(this);
QTC_ASSERT(d->m_profilerState, return);
reportStarted();
}
@@ -218,47 +219,46 @@ static QUrl localServerUrl(RunControl *runControl)
return serverUrl;
}
-LocalQmlProfilerSupport::LocalQmlProfilerSupport(QmlProfilerTool *profilerTool,
- RunControl *runControl)
- : LocalQmlProfilerSupport(profilerTool, runControl, localServerUrl(runControl))
+LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl)
+ : LocalQmlProfilerSupport(runControl, localServerUrl(runControl))
{
}
-LocalQmlProfilerSupport::LocalQmlProfilerSupport(QmlProfilerTool *profilerTool,
- RunControl *runControl, const QUrl &serverUrl)
+LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const QUrl &serverUrl)
: SimpleTargetRunner(runControl)
{
setId("LocalQmlProfilerSupport");
auto profiler = new QmlProfilerRunner(runControl);
profiler->setServerUrl(serverUrl);
- connect(profiler, &QmlProfilerRunner::starting,
- profilerTool, &QmlProfilerTool::finalizeRunControl);
addStopDependency(profiler);
// We need to open the local server before the application tries to connect.
// In the TCP case, it doesn't hurt either to start the profiler before.
addStartDependency(profiler);
- Runnable debuggee = runnable();
+ setStarter([this, runControl, profiler, serverUrl] {
+ Runnable debuggee = runControl->runnable();
- QString code;
- if (serverUrl.scheme() == Utils::urlSocketScheme())
- code = QString("file:%1").arg(serverUrl.path());
- else if (serverUrl.scheme() == Utils::urlTcpScheme())
- code = QString("port:%1").arg(serverUrl.port());
- else
- QTC_CHECK(false);
+ QUrl serverUrl = profiler->serverUrl();
+ QString code;
+ if (serverUrl.scheme() == Utils::urlSocketScheme())
+ code = QString("file:%1").arg(serverUrl.path());
+ else if (serverUrl.scheme() == Utils::urlTcpScheme())
+ code = QString("port:%1").arg(serverUrl.port());
+ else
+ QTC_CHECK(false);
- QString arguments = Utils::QtcProcess::quoteArg(
- QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlProfilerServices, code, true));
+ QString arguments = Utils::QtcProcess::quoteArg(
+ QmlDebug::qmlDebugCommandLineArguments(QmlDebug::QmlProfilerServices, code, true));
- if (!debuggee.commandLineArguments.isEmpty())
- arguments += ' ' + debuggee.commandLineArguments;
+ if (!debuggee.commandLineArguments.isEmpty())
+ arguments += ' ' + debuggee.commandLineArguments;
- debuggee.commandLineArguments = arguments;
+ debuggee.commandLineArguments = arguments;
- setRunnable(debuggee);
+ doStart(debuggee, {});
+ });
}
} // namespace Internal
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
index 0bdd9315cb..b846306abd 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
@@ -37,7 +37,6 @@
namespace QmlProfiler {
namespace Internal {
-class QmlProfilerTool;
class QmlProfilerRunner : public ProjectExplorer::RunWorker
{
Q_OBJECT
@@ -54,9 +53,6 @@ public:
void cancelProcess();
void notifyRemoteFinished();
-signals:
- void starting(QmlProfilerRunner *self);
-
private:
void start() override;
void stop() override;
@@ -72,8 +68,8 @@ class LocalQmlProfilerSupport : public ProjectExplorer::SimpleTargetRunner
Q_OBJECT
public:
- LocalQmlProfilerSupport(QmlProfilerTool *profilerTool, ProjectExplorer::RunControl *runControl);
- LocalQmlProfilerSupport(QmlProfilerTool *profilerTool, ProjectExplorer::RunControl *runControl,
+ LocalQmlProfilerSupport(ProjectExplorer::RunControl *runControl);
+ LocalQmlProfilerSupport(ProjectExplorer::RunControl *runControl,
const QUrl &serverUrl);
};
diff --git a/src/plugins/qmlprofiler/qmlprofilersettings.cpp b/src/plugins/qmlprofiler/qmlprofilersettings.cpp
index 11b2c99d9f..ded460bead 100644
--- a/src/plugins/qmlprofiler/qmlprofilersettings.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilersettings.cpp
@@ -35,8 +35,9 @@ namespace QmlProfiler {
namespace Internal {
QmlProfilerSettings::QmlProfilerSettings()
- : ProjectExplorer::ISettingsAspect([this] { return new QmlProfilerConfigWidget(this); })
{
+ setConfigWidgetCreator([this] { return new QmlProfilerConfigWidget(this); });
+
QVariantMap defaults;
defaults.insert(QLatin1String(Constants::FLUSH_INTERVAL), 1000);
defaults.insert(QLatin1String(Constants::FLUSH_ENABLED), false);
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
index 859f26bada..ff73b9dd41 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp
@@ -45,7 +45,7 @@ namespace Internal {
class QmlProfilerStateWidget::QmlProfilerStateWidgetPrivate
{
public:
- QmlProfilerStateWidgetPrivate(QmlProfilerStateWidget *qq) : text(nullptr) { Q_UNUSED(qq); }
+ QmlProfilerStateWidgetPrivate(QmlProfilerStateWidget *qq) : text(nullptr) { Q_UNUSED(qq) }
QLabel *text;
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp
index 6192f17bf4..ad203258a6 100644
--- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp
@@ -219,7 +219,7 @@ QVariant QmlProfilerStatisticsModel::dataForMainEntry(const QModelIndex &index,
return m_rootDuration > 0 ? "+" : "-";
case TypeIdRole:
return s_mainEntryTypeId;
- case Qt::TextColorRole:
+ case Qt::ForegroundRole:
return Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor);
case SortRole:
switch (index.column()) {
@@ -296,7 +296,7 @@ QVariant QmlProfilerStatisticsModel::data(const QModelIndex &index, int role) co
auto it = m_notes.constFind(typeIndex);
return it == m_notes.constEnd() ? QString() : it.value();
}
- case Qt::TextColorRole:
+ case Qt::ForegroundRole:
return (stats.recursive > 0 || m_notes.contains(typeIndex))
? Utils::creatorTheme()->color(Utils::Theme::Timeline_HighlightColor)
: Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor);
@@ -393,7 +393,7 @@ void QmlProfilerStatisticsModel::typeDetailsChanged(int typeIndex)
void QmlProfilerStatisticsModel::notesChanged(int typeIndex)
{
- static const QVector<int> noteRoles({Qt::ToolTipRole, Qt::TextColorRole});
+ static const QVector<int> noteRoles({Qt::ToolTipRole, Qt::ForegroundRole});
const Timeline::TimelineNotesModel *notesModel = m_modelManager->notesModel();
if (typeIndex == s_invalidTypeId) {
m_notes.clear();
@@ -564,7 +564,7 @@ QVariant QmlProfilerStatisticsRelativesModel::dataForMainEntry(qint64 totalDurat
switch (role) {
case TypeIdRole:
return QmlProfilerStatisticsModel::s_mainEntryTypeId;
- case Qt::TextColorRole:
+ case Qt::ForegroundRole:
return Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor);
case SortRole:
if (column == RelativeTotalTime)
@@ -614,7 +614,7 @@ QVariant QmlProfilerStatisticsRelativesModel::data(const QModelIndex &index, int
return type.location().column();
case Qt::ToolTipRole:
return stats.isRecursive ? tr("called recursively") : QString();
- case Qt::TextColorRole:
+ case Qt::ForegroundRole:
return stats.isRecursive
? Utils::creatorTheme()->color(Utils::Theme::Timeline_HighlightColor)
: Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor);
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index ba5228f7c1..8348acb6de 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -74,6 +74,7 @@
#include <QApplication>
#include <QDockWidget>
+#include <QElapsedTimer>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QLabel>
@@ -95,6 +96,8 @@ using namespace ProjectExplorer;
namespace QmlProfiler {
namespace Internal {
+static QmlProfilerTool *m_instance = nullptr;
+
class QmlProfilerTool::QmlProfilerToolPrivate
{
public:
@@ -120,7 +123,7 @@ public:
// elapsed time display
QLabel *m_timeLabel = nullptr;
QTimer m_recordingTimer;
- QTime m_recordingElapsedTime;
+ QElapsedTimer m_recordingElapsedTime;
bool m_toolBusy = false;
};
@@ -128,6 +131,7 @@ public:
QmlProfilerTool::QmlProfilerTool()
: d(new QmlProfilerToolPrivate)
{
+ m_instance = this;
setObjectName(QLatin1String("QmlProfilerTool"));
d->m_profilerState = new QmlProfilerStateManager(this);
@@ -246,7 +250,7 @@ QmlProfilerTool::QmlProfilerTool()
if (EditorManager *editorManager = EditorManager::instance()) {
connect(editorManager, &EditorManager::editorCreated,
model, [this, model](Core::IEditor *editor, const QString &fileName) {
- Q_UNUSED(editor);
+ Q_UNUSED(editor)
model->createMarks(d->m_viewContainer, fileName);
});
}
@@ -278,6 +282,12 @@ QmlProfilerTool::~QmlProfilerTool()
{
d->m_profilerModelManager->clearAll();
delete d;
+ m_instance = nullptr;
+}
+
+QmlProfilerTool *QmlProfilerTool::instance()
+{
+ return m_instance;
}
void QmlProfilerTool::updateRunActions()
@@ -551,7 +561,6 @@ ProjectExplorer::RunControl *QmlProfilerTool::attachToWaitingApplication()
runControl->setRunConfiguration(RunConfiguration::startupRunConfiguration());
auto profiler = new QmlProfilerRunner(runControl);
profiler->setServerUrl(serverUrl);
- connect(profiler, &QmlProfilerRunner::starting, this, &QmlProfilerTool::finalizeRunControl);
connect(d->m_profilerConnections, &QmlProfilerClientManager::connectionClosed,
runControl, &RunControl::initiateStop);
@@ -706,25 +715,6 @@ void addFeatureToMenu(QMenu *menu, ProfileFeature feature, quint64 enabledFeatur
action->setChecked(enabledFeatures & (1ULL << (feature)));
}
-template<ProfileFeature feature>
-void QmlProfilerTool::updateFeatures(quint64 features)
-{
- if (features & (1ULL << (feature))) {
- addFeatureToMenu(d->m_recordFeaturesMenu, feature,
- d->m_profilerState->requestedFeatures());
- addFeatureToMenu(d->m_displayFeaturesMenu, feature,
- d->m_profilerModelManager->visibleFeatures());
- }
- updateFeatures<static_cast<ProfileFeature>(feature + 1)>(features);
-}
-
-template<>
-void QmlProfilerTool::updateFeatures<MaximumProfileFeature>(quint64 features)
-{
- Q_UNUSED(features);
- return;
-}
-
void QmlProfilerTool::setAvailableFeatures(quint64 features)
{
if (features != d->m_profilerState->requestedFeatures())
@@ -732,7 +722,14 @@ void QmlProfilerTool::setAvailableFeatures(quint64 features)
if (d->m_recordFeaturesMenu && d->m_displayFeaturesMenu) {
d->m_recordFeaturesMenu->clear();
d->m_displayFeaturesMenu->clear();
- updateFeatures<static_cast<ProfileFeature>(0)>(features);
+ for (int feature = 0; feature < MaximumProfileFeature; ++feature) {
+ if (features & (1ULL << feature)) {
+ addFeatureToMenu(d->m_recordFeaturesMenu, ProfileFeature(feature),
+ d->m_profilerState->requestedFeatures());
+ addFeatureToMenu(d->m_displayFeaturesMenu, ProfileFeature(feature),
+ d->m_profilerModelManager->visibleFeatures());
+ }
+ }
}
}
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h
index 180f1c090c..f6d02bdc6c 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.h
+++ b/src/plugins/qmlprofiler/qmlprofilertool.h
@@ -52,6 +52,8 @@ public:
QmlProfilerTool();
~QmlProfilerTool() override;
+ static QmlProfilerTool *instance();
+
void finalizeRunControl(QmlProfilerRunner *runWorker);
bool prepareTool();
@@ -100,8 +102,6 @@ private:
void updateRunActions();
void clearDisplay();
- template<ProfileFeature feature>
- void updateFeatures(quint64 features);
bool checkForUnsavedNotes();
void setButtonsEnabled(bool enable);
void createInitialTextMarks();
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
index 79183a77b1..054cc31eae 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp
@@ -55,6 +55,8 @@ inline bool operator!=(const QmlEventType &type1, const QmlEventType &type2)
return !(type1 == type2);
}
+struct ObjectDeleteLater { void operator()(QObject *o) { o->deleteLater(); } };
+
class QmlProfilerTraceClientPrivate {
public:
QmlProfilerTraceClientPrivate(QmlProfilerTraceClient *q,
@@ -62,7 +64,7 @@ public:
QmlProfilerModelManager *modelManager)
: q(q)
, modelManager(modelManager)
- , engineControl(connection)
+ , engineControl(new QmlDebug::QmlEngineControlClient(connection))
, maximumTime(0)
, recording(false)
, requestedFeatures(0)
@@ -81,8 +83,14 @@ public:
QmlProfilerTraceClient *q;
QmlProfilerModelManager *modelManager;
- QmlDebug::QmlEngineControlClient engineControl;
- QScopedPointer<QmlDebug::QDebugMessageClient> messageClient;
+
+ // Use deleteLater here. The connection will call stateChanged() on all clients that are
+ // alive when it gets disconnected. One way to notice a disconnection is failing to send the
+ // plugin advertisement when a client unregisters. If one of the other clients is
+ // half-destructed at that point, we get invalid memory accesses. Therefore, we cannot nest the
+ // dtor calls.
+ std::unique_ptr<QmlDebug::QmlEngineControlClient, ObjectDeleteLater> engineControl;
+ std::unique_ptr<QmlDebug::QDebugMessageClient, ObjectDeleteLater> messageClient;
qint64 maximumTime;
bool recording;
quint64 requestedFeatures;
@@ -235,22 +243,22 @@ QmlProfilerTraceClient::QmlProfilerTraceClient(QmlDebug::QmlDebugConnection *cli
, d(new QmlProfilerTraceClientPrivate(this, client, modelManager))
{
setRequestedFeatures(features);
- connect(&d->engineControl, &QmlDebug::QmlEngineControlClient::engineAboutToBeAdded,
+ connect(d->engineControl.get(), &QmlDebug::QmlEngineControlClient::engineAboutToBeAdded,
this, &QmlProfilerTraceClient::sendRecordingStatus);
- connect(&d->engineControl, &QmlDebug::QmlEngineControlClient::engineAboutToBeRemoved,
+ connect(d->engineControl.get(), &QmlDebug::QmlEngineControlClient::engineAboutToBeRemoved,
this, [this](int engineId) {
// We may already be done with that engine. Then we don't need to block it.
if (d->trackedEngines.contains(engineId))
- d->engineControl.blockEngine(engineId);
+ d->engineControl->blockEngine(engineId);
});
connect(this, &QmlProfilerTraceClient::traceFinished,
- &d->engineControl, [this](qint64 timestamp, const QList<int> &engineIds) {
- Q_UNUSED(timestamp);
+ d->engineControl.get(), [this](qint64 timestamp, const QList<int> &engineIds) {
+ Q_UNUSED(timestamp)
// The engines might not be blocked because the trace can get finished before engine control
// sees them.
- for (int blocked : d->engineControl.blockedEngines()) {
+ for (int blocked : d->engineControl->blockedEngines()) {
if (engineIds.contains(blocked))
- d->engineControl.releaseEngine(blocked);
+ d->engineControl->releaseEngine(blocked);
}
});
}
@@ -317,7 +325,7 @@ void QmlProfilerTraceClient::setRequestedFeatures(quint64 features)
d->requestedFeatures = features;
if (features & static_cast<quint64>(1) << ProfileDebugMessages) {
d->messageClient.reset(new QmlDebug::QDebugMessageClient(connection()));
- connect(d->messageClient.data(), &QmlDebug::QDebugMessageClient::message, this,
+ connect(d->messageClient.get(), &QmlDebug::QDebugMessageClient::message, this,
[this](QtMsgType type, const QString &text,
const QmlDebug::QDebugContextInfo &context)
{
diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
index 075c518e77..c994c37719 100644
--- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
@@ -123,7 +123,7 @@ QmlProfilerTraceFile::QmlProfilerTraceFile(QObject *parent) : Timeline::Timeline
qRegisterMetaType<QVector<QmlEventType> >(),
qRegisterMetaType<QVector<QmlNote> >()
};
- Q_UNUSED(meta);
+ Q_UNUSED(meta)
}
void QmlProfilerTraceFile::load(QIODevice *device)
@@ -834,7 +834,7 @@ void QmlProfilerTraceFile::saveQzt(QIODevice *device)
qint64 lastProgressTimestamp = traceStart();
modelManager()->replayQmlEvents([&](const QmlEvent &event, const QmlEventType &type) {
- Q_UNUSED(type);
+ Q_UNUSED(type)
bufferStream << event;
// 32MB buffer should be plenty for efficient compression
if (buffer.data().length() > (1 << 25)) {
diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
index e96f4da649..49eeacdde3 100644
--- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
+++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
@@ -45,7 +45,6 @@ LocalQmlProfilerRunnerTest::LocalQmlProfilerRunnerTest(QObject *parent) : QObjec
void LocalQmlProfilerRunnerTest::testRunner()
{
- QmlProfilerTool tool;
QPointer<ProjectExplorer::RunControl> runControl;
QPointer<LocalQmlProfilerSupport> profiler;
ProjectExplorer::Runnable debuggee;
@@ -57,7 +56,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
int runCount = 0;
int stopCount = 0;
- debuggee.executable = "\\-/|\\-/";
+ debuggee.executable = Utils::FilePath::fromString("\\-/|\\-/");
debuggee.environment = Utils::Environment::systemEnvironment();
// should not be used anywhere but cannot be empty
@@ -66,7 +65,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
runControl->setRunnable(debuggee);
- profiler = new LocalQmlProfilerSupport(&tool, runControl, serverUrl);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
auto connectRunner = [&]() {
connect(runControl, &ProjectExplorer::RunControl::aboutToStart, this, [&]() {
@@ -110,13 +109,13 @@ void LocalQmlProfilerRunnerTest::testRunner()
QVERIFY(profiler.isNull());
serverUrl = Utils::urlFromLocalSocket();
- debuggee.executable = qApp->applicationFilePath();
+ debuggee.executable = Utils::FilePath::fromString(QCoreApplication::applicationFilePath());
// comma is used to specify a test function. In this case, an invalid one.
debuggee.commandLineArguments = QString("-test QmlProfiler,");
runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
runControl->setRunnable(debuggee);
- profiler = new LocalQmlProfilerSupport(&tool, runControl, serverUrl);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
connectRunner();
runControl->initiateStart();
@@ -135,7 +134,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
serverUrl = Utils::urlFromLocalHostAndFreePort();
runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
runControl->setRunnable(debuggee);
- profiler = new LocalQmlProfilerSupport(&tool, runControl, serverUrl);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
connectRunner();
runControl->initiateStart();
@@ -160,7 +159,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
runControl->setRunnable(debuggee);
- profiler = new LocalQmlProfilerSupport(&tool, runControl, serverUrl);
+ profiler = new LocalQmlProfilerSupport(runControl, serverUrl);
connectRunner();
runControl->initiateStart();
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp
index 70b815776b..a4f2cafaa9 100644
--- a/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp
+++ b/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp
@@ -123,7 +123,7 @@ void QmlProfilerClientManagerTest::testConnectionFailure()
QByteArray fatalAsserts = qgetenv("QTC_FATAL_ASSERTS");
qunsetenv("QTC_FATAL_ASSERTS");
MessageHandler handler(&softAssertMessageHandler);
- Q_UNUSED(handler);
+ Q_UNUSED(handler)
QFETCH(QmlProfilerModelManager *, modelManager);
QFETCH(QmlProfilerStateManager *, stateManager);
@@ -342,7 +342,7 @@ void invalidHelloMessageHandler(QtMsgType type, const QMessageLogContext &contex
void QmlProfilerClientManagerTest::testInvalidData()
{
MessageHandler handler(&invalidHelloMessageHandler);
- Q_UNUSED(handler);
+ Q_UNUSED(handler)
QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened()));
QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed()));
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp
index 3c938b3e15..50be99a19d 100644
--- a/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp
+++ b/src/plugins/qmlprofiler/tests/qmlprofilerdetailsrewriter_test.cpp
@@ -38,6 +38,9 @@
#include <QLibraryInfo>
#include <QTest>
+using namespace ProjectExplorer;
+using namespace Utils;
+
namespace QmlProfiler {
namespace Internal {
@@ -45,8 +48,8 @@ class DummyProject : public ProjectExplorer::Project
{
Q_OBJECT
public:
- DummyProject(const Utils::FilePath &file) :
- ProjectExplorer::Project(QString(), file, {})
+ DummyProject(const Utils::FilePath &file)
+ : ProjectExplorer::Project(QString(), file)
{
auto fileNode
= std::make_unique<ProjectExplorer::FileNode>(file, ProjectExplorer::FileType::Source);
@@ -68,13 +71,8 @@ public:
class DummyBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
{
public:
- QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Target *) const final
- {
- return {};
- }
-
- QList<ProjectExplorer::BuildInfo> availableSetups(const ProjectExplorer::Kit *,
- const QString &) const final
+ QList<ProjectExplorer::BuildInfo> availableBuilds(const ProjectExplorer::Kit *,
+ const FilePath &, bool) const final
{
return {};
}
@@ -91,7 +89,7 @@ QmlProfilerDetailsRewriterTest::QmlProfilerDetailsRewriterTest(QObject *parent)
void QmlProfilerDetailsRewriterTest::testMissingModelManager()
{
DummyBuildConfigurationFactory factory;
- Q_UNUSED(factory);
+ Q_UNUSED(factory)
seedRewriter();
delete m_modelManager;
@@ -101,8 +99,8 @@ void QmlProfilerDetailsRewriterTest::testMissingModelManager()
QVERIFY(!m_rewriterDone);
auto rewriteConnection = connect(&m_rewriter, &QmlProfilerDetailsRewriter::rewriteDetailsString,
this, [&](int typeId, const QString &string) {
- Q_UNUSED(typeId);
- Q_UNUSED(string);
+ Q_UNUSED(typeId)
+ Q_UNUSED(string)
QFAIL("found nonexisting file in nonexisting model manager");
});
m_rewriter.requestDetailsForLocation(44, QmlEventLocation("Test.qml", 12, 12));
@@ -115,7 +113,7 @@ void QmlProfilerDetailsRewriterTest::testMissingModelManager()
void QmlProfilerDetailsRewriterTest::testRequestDetailsForLocation()
{
DummyBuildConfigurationFactory factory;
- Q_UNUSED(factory);
+ Q_UNUSED(factory)
seedRewriter();
QVERIFY(!m_rewriterDone);
@@ -166,7 +164,7 @@ void QmlProfilerDetailsRewriterTest::testRequestDetailsForLocation()
void QmlProfilerDetailsRewriterTest::testGetLocalFile()
{
DummyBuildConfigurationFactory factory;
- Q_UNUSED(factory);
+ Q_UNUSED(factory)
seedRewriter();
QCOMPARE(m_rewriter.getLocalFile("notthere.qml"), QString());
@@ -225,13 +223,7 @@ void QmlProfilerDetailsRewriterTest::seedRewriter()
DummyProject *project = new DummyProject(Utils::FilePath::fromString(filename));
ProjectExplorer::SessionManager::addProject(project);
- {
- // Make sure the uniqe_ptr gets deleted before the project.
- // Otherwise we'll get a double free because the target is also parented to the project
- // and unique_ptr doesn't know anything about QObject parent/child relationships.
- std::unique_ptr<ProjectExplorer::Target> target = project->createTarget(kit.get());
- m_rewriter.populateFileFinder(target.get());
- }
+ m_rewriter.populateFileFinder(project->addTargetForKit(kit.get()));
ProjectExplorer::SessionManager::removeProject(project);
}
diff --git a/src/plugins/qmlprofiler/tests/qmlprofilertool_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilertool_test.cpp
index 66edba16da..ab085ea458 100644
--- a/src/plugins/qmlprofiler/tests/qmlprofilertool_test.cpp
+++ b/src/plugins/qmlprofiler/tests/qmlprofilertool_test.cpp
@@ -52,7 +52,7 @@ void QmlProfilerToolTest::testAttachToWaitingApplication()
QVERIFY(settings);
settings->setValue(QLatin1String("AnalyzerQmlAttachDialog/kitId"), newKit->id().toSetting());
- QmlProfilerTool profilerTool;
+ QmlProfilerTool &profilerTool = *QmlProfilerTool::instance();
QmlProfilerClientManager *clientManager = profilerTool.clientManager();
clientManager->setRetryInterval(10);
@@ -107,7 +107,7 @@ void QmlProfilerToolTest::testAttachToWaitingApplication()
void QmlProfilerToolTest::testClearEvents()
{
- QmlProfilerTool profilerTool;
+ QmlProfilerTool &profilerTool = *QmlProfilerTool::instance();
QmlProfilerModelManager *modelManager = profilerTool.modelManager();
QVERIFY(modelManager);
QmlProfilerStateManager *stateManager = profilerTool.stateManager();
diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
index 988c51dbfe..82190ccde6 100644
--- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
@@ -293,24 +293,6 @@ QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir
return fileSet;
}
-QmlFileFilterItem::QmlFileFilterItem(QObject *parent)
- : FileFilterBaseItem(parent)
-{
- setFilter(QLatin1String("*.qml"));
-}
-
-JsFileFilterItem::JsFileFilterItem(QObject *parent)
- : FileFilterBaseItem(parent)
-{
- setFilter(QLatin1String("*.js"));
-}
-
-void JsFileFilterItem::setFilter(const QString &filter)
-{
- FileFilterBaseItem::setFilter(filter);
- emit filterChanged();
-}
-
ImageFileFilterItem::ImageFileFilterItem(QObject *parent)
: FileFilterBaseItem(parent)
{
@@ -323,33 +305,10 @@ ImageFileFilterItem::ImageFileFilterItem(QObject *parent)
setFilter(filter);
}
-void ImageFileFilterItem::setFilter(const QString &filter)
-{
- FileFilterBaseItem::setFilter(filter);
- emit filterChanged();
-}
-
-CssFileFilterItem::CssFileFilterItem(QObject *parent)
- : FileFilterBaseItem(parent)
-{
- setFilter(QLatin1String("*.css"));
-}
-
-void CssFileFilterItem::setFilter(const QString &filter)
-{
- FileFilterBaseItem::setFilter(filter);
- emit filterChanged();
-}
-
-OtherFileFilterItem::OtherFileFilterItem(QObject *parent)
+FileFilterItem::FileFilterItem(const QString &fileFilter, QObject *parent)
: FileFilterBaseItem(parent)
{
-}
-
-void OtherFileFilterItem::setFilter(const QString &filter)
-{
- FileFilterBaseItem::setFilter(filter);
- emit filterChanged();
+ setFilter(fileFilter);
}
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
index c10d7405ef..827423e1e0 100644
--- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
+++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
@@ -107,67 +107,17 @@ private:
Utils::FileSystemWatcher *m_dirWatcher = nullptr;
QTimer m_updateFileListTimer;
-
friend class ProjectItem;
};
-class QmlFileFilterItem : public FileFilterBaseItem {
- Q_OBJECT
-
-public:
- QmlFileFilterItem(QObject *parent = nullptr);
-};
-
-class JsFileFilterItem : public FileFilterBaseItem {
- Q_OBJECT
- Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
-
- void setFilter(const QString &filter);
-
-signals:
- void filterChanged();
-
+class FileFilterItem : public FileFilterBaseItem {
public:
- JsFileFilterItem(QObject *parent = nullptr);
+ FileFilterItem(const QString &fileFilter, QObject *parent = nullptr);
};
class ImageFileFilterItem : public FileFilterBaseItem {
- Q_OBJECT
- Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
-
- void setFilter(const QString &filter);
-
-signals:
- void filterChanged();
-
public:
ImageFileFilterItem(QObject *parent = nullptr);
};
-class CssFileFilterItem : public FileFilterBaseItem {
- Q_OBJECT
- Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
-
- void setFilter(const QString &filter);
-
-signals:
- void filterChanged();
-
-public:
- CssFileFilterItem(QObject *parent = nullptr);
-};
-
-class OtherFileFilterItem : public FileFilterBaseItem {
- Q_OBJECT
- Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
-
- void setFilter(const QString &filter);
-
-signals:
- void filterChanged();
-
-public:
- OtherFileFilterItem(QObject *parent = nullptr);
-};
-
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
index 2102147c29..2b3cfa9bdc 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
@@ -37,7 +37,7 @@ enum {
namespace {
-void setupFileFilterItem(QmlProjectManager::FileFilterBaseItem *fileFilterItem, const QmlJS::SimpleReaderNode::Ptr &node)
+QmlProjectManager::FileFilterBaseItem *setupFileFilterItem(QmlProjectManager::FileFilterBaseItem *fileFilterItem, const QmlJS::SimpleReaderNode::Ptr &node)
{
const QVariant directoryProperty = node->property(QLatin1String("directory"));
if (directoryProperty.isValid())
@@ -57,6 +57,7 @@ void setupFileFilterItem(QmlProjectManager::FileFilterBaseItem *fileFilterItem,
if (debug)
qDebug() << "directory:" << directoryProperty << "recursive" << recursiveProperty << "paths" << pathsProperty;
+ return fileFilterItem;
}
} //namespace
@@ -100,37 +101,21 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fi
qDebug() << "importPath:" << importPathsProperty << "mainFile:" << mainFileProperty;
foreach (const QmlJS::SimpleReaderNode::Ptr &childNode, rootNode->children()) {
+ if (debug)
+ qDebug() << "reading type:" << childNode->name();
+
if (childNode->name() == QLatin1String("QmlFiles")) {
- if (debug)
- qDebug() << "QmlFiles";
- auto qmlFileFilterItem = new QmlFileFilterItem(projectItem);
- setupFileFilterItem(qmlFileFilterItem, childNode);
- projectItem->appendContent(qmlFileFilterItem);
+ projectItem->appendContent(setupFileFilterItem(new FileFilterItem("*.qml"), childNode));
} else if (childNode->name() == QLatin1String("JavaScriptFiles")) {
- if (debug)
- qDebug() << "JavaScriptFiles";
- auto jsFileFilterItem = new JsFileFilterItem(projectItem);
- setupFileFilterItem(jsFileFilterItem, childNode);
- projectItem->appendContent(jsFileFilterItem);
+ projectItem->appendContent(setupFileFilterItem(new FileFilterItem("*.js"), childNode));
} else if (childNode->name() == QLatin1String("ImageFiles")) {
- if (debug)
- qDebug() << "ImageFiles";
- auto imageFileFilterItem = new ImageFileFilterItem(projectItem);
- setupFileFilterItem(imageFileFilterItem, childNode);
- projectItem->appendContent(imageFileFilterItem);
-
+ projectItem->appendContent(setupFileFilterItem(new ImageFileFilterItem(projectItem), childNode));
} else if (childNode->name() == QLatin1String("CssFiles")) {
- if (debug)
- qDebug() << "CssFiles";
- auto cssFileFilterItem = new CssFileFilterItem(projectItem);
- setupFileFilterItem(cssFileFilterItem, childNode);
- projectItem->appendContent(cssFileFilterItem);
+ projectItem->appendContent(setupFileFilterItem(new FileFilterItem("*.css"), childNode));
+ } else if (childNode->name() == QLatin1String("FontFiles")) {
+ projectItem->appendContent(setupFileFilterItem(new FileFilterItem("*.ttf;*.otf"), childNode));
} else if (childNode->name() == QLatin1String("Files")) {
- if (debug)
- qDebug() << "Files";
- auto otherFileFilterItem = new OtherFileFilterItem(projectItem);
- setupFileFilterItem(otherFileFilterItem, childNode);
- projectItem->appendContent(otherFileFilterItem);
+ projectItem->appendContent(setupFileFilterItem(new FileFilterBaseItem(), childNode));
} else if (childNode->name() == "Environment") {
const auto properties = childNode->properties();
auto i = properties.constBegin();
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
index e82e90fedc..bee96ae411 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
@@ -26,6 +26,8 @@
#include "qmlprojectitem.h"
#include "filefilteritems.h"
+#include <utils/algorithm.h>
+
#include <QDir>
namespace QmlProjectManager {
@@ -68,17 +70,17 @@ void QmlProjectItem::setFileSelectors(const QStringList &selectors)
/* Returns list of absolute paths */
QStringList QmlProjectItem::files() const
{
- QStringList files;
+ QSet<QString> files;
- for (QmlProjectContentItem *contentElement : m_content) {
- if (auto fileFilter = qobject_cast<FileFilterBaseItem *>(contentElement)) {
- foreach (const QString &file, fileFilter->files()) {
- if (!files.contains(file))
- files << file;
+ for (const auto contentElement : qAsConst(m_content)) {
+ if (auto fileFilter = qobject_cast<const FileFilterBaseItem *>(contentElement)) {
+ const QStringList fileList = fileFilter->files();
+ for (const QString &file : fileList) {
+ files.insert(file);
}
}
}
- return files;
+ return files.toList();
}
/**
@@ -89,16 +91,13 @@ QStringList QmlProjectItem::files() const
*/
bool QmlProjectItem::matchesFile(const QString &filePath) const
{
- for (QmlProjectContentItem *contentElement : m_content) {
- if (auto fileFilter = qobject_cast<FileFilterBaseItem *>(contentElement)) {
- if (fileFilter->matchesFile(filePath))
- return true;
- }
- }
- return false;
+ return Utils::contains(m_content, [&filePath](const QmlProjectContentItem *item) {
+ auto fileFilter = qobject_cast<const FileFilterBaseItem *>(item);
+ return fileFilter && fileFilter->matchesFile(filePath);
+ });
}
-QList<Utils::EnvironmentItem> QmlProjectItem::environment() const
+Utils::EnvironmentItems QmlProjectItem::environment() const
{
return m_environment;
}
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
index 4ba9afcd5f..29b2e88d99 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
@@ -65,7 +65,7 @@ public:
void appendContent(QmlProjectContentItem *item) { m_content.append(item); }
- QList<Utils::EnvironmentItem> environment() const;
+ Utils::EnvironmentItems environment() const;
void addToEnviroment(const QString &key, const QString &value);
signals:
@@ -77,8 +77,8 @@ protected:
QStringList m_importPaths;
QStringList m_fileSelectors;
QString m_mainFile;
- QList<Utils::EnvironmentItem> m_environment;
- QList<QmlProjectContentItem *> m_content; // content property
+ Utils::EnvironmentItems m_environment;
+ QVector<QmlProjectContentItem *> m_content; // content property
};
} // namespace QmlProjectManager
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index 826ea09e31..d3d96c20ce 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -34,7 +34,6 @@
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
-#include <coreplugin/documentmanager.h>
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/kitinformation.h>
@@ -44,7 +43,7 @@
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
-#include <qtsupport/desktopqtversion.h>
+
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <utils/algorithm.h>
@@ -56,9 +55,8 @@ using namespace ProjectExplorer;
namespace QmlProjectManager {
-QmlProject::QmlProject(const Utils::FilePath &fileName) :
- Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName,
- [this]() { refreshProjectFile(); })
+QmlProject::QmlProject(const Utils::FilePath &fileName)
+ : Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName)
{
const QString normalized
= Utils::FileUtils::normalizePathName(fileName.toFileInfo().canonicalFilePath());
@@ -67,6 +65,10 @@ QmlProject::QmlProject(const Utils::FilePath &fileName) :
setId(QmlProjectManager::Constants::QML_PROJECT_ID);
setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
setDisplayName(fileName.toFileInfo().completeBaseName());
+
+ setNeedsBuildConfigurations(false);
+
+ connect(this, &QmlProject::projectFileIsDirty, this, &QmlProject::refreshProjectFile);
}
QmlProject::~QmlProject()
@@ -152,7 +154,7 @@ void QmlProject::parseProject(RefreshOptions options)
void QmlProject::refresh(RefreshOptions options)
{
- emitParsingStarted();
+ ParseGuard guard = guardParsingRun();
parseProject(options);
if (options & Files)
@@ -170,7 +172,7 @@ void QmlProject::refresh(RefreshOptions options)
modelManager->updateProjectInfo(projectInfo, this);
- emitParsingFinished(true);
+ guard.markAsSuccess();
}
QString QmlProject::mainFile() const
@@ -206,18 +208,13 @@ Utils::FilePath QmlProject::targetFile(const Utils::FilePath &sourceFile,
return Utils::FilePath::fromString(QDir::cleanPath(targetDir.absoluteFilePath(relative)));
}
-QList<Utils::EnvironmentItem> QmlProject::environment() const
+Utils::EnvironmentItems QmlProject::environment() const
{
if (m_projectItem)
return m_projectItem.data()->environment();
return {};
}
-bool QmlProject::validProjectFile() const
-{
- return !m_projectItem.isNull();
-}
-
QStringList QmlProject::customImportPaths() const
{
if (m_projectItem)
@@ -247,11 +244,6 @@ void QmlProject::refreshProjectFile()
refresh(QmlProject::ProjectFile | Files);
}
-bool QmlProject::needsBuildConfigurations() const
-{
- return false;
-}
-
QStringList QmlProject::makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths)
{
if (path.isEmpty())
@@ -307,7 +299,7 @@ Tasks QmlProject::projectIssues(const Kit *k) const
if (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
if (version->type() == QtSupport::Constants::DESKTOPQT) {
- if (static_cast<const QtSupport::DesktopQtVersion *>(version)->qmlsceneCommand().isEmpty()) {
+ if (version->qmlsceneCommand().isEmpty()) {
result.append(createProjectTask(Task::TaskType::Error,
tr("Qt version has no qmlscene command.")));
}
@@ -336,13 +328,15 @@ Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *erro
if (!activeTarget()) {
// find a kit that matches prerequisites (prefer default one)
- const QList<Kit*> kits = KitManager::kits([this](const Kit *k) {
+ const QList<Kit*> kits = Utils::filtered(KitManager::kits(), [this](const Kit *k) {
return !containsType(projectIssues(k), Task::TaskType::Error);
});
if (!kits.isEmpty()) {
- Kit *kit = kits.contains(KitManager::defaultKit()) ? KitManager::defaultKit() : kits.first();
- addTarget(createTarget(kit));
+ if (kits.contains(KitManager::defaultKit()))
+ addTargetForDefaultKit();
+ else
+ addTargetForKit(kits.first());
}
}
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
index b3ce817f19..9b09cbd528 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.h
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -50,8 +50,6 @@ public:
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
- bool validProjectFile() const;
-
enum RefreshOption {
ProjectFile = 0x01,
Files = 0x02,
@@ -69,7 +67,7 @@ public:
Utils::FilePath targetFile(const Utils::FilePath &sourceFile,
const ProjectExplorer::Target *target) const;
- QList<Utils::EnvironmentItem> environment() const;
+ Utils::EnvironmentItems environment() const;
QStringList customImportPaths() const;
QStringList customFileSelectors() const;
@@ -77,8 +75,6 @@ public:
void refreshProjectFile();
- bool needsBuildConfigurations() const final;
-
static QStringList makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths);
QVariant additionalData(Core::Id id, const ProjectExplorer::Target *target) const override;
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
index 7b311c2cf6..a4494e7064 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -84,7 +84,7 @@ bool QmlProjectNode::renameFile(const QString & filePath, const QString & newFil
m_project->setMainFile(newFilePath);
// make sure to change it also in the qmlproject file
- const QString qmlProjectFilePath = m_project->document()->filePath().toString();
+ const QString qmlProjectFilePath = m_project->projectFilePath().toString();
Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
TextEditor::TextDocument *document = nullptr;
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
index d20f4caa43..b44cbf0670 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
@@ -44,8 +44,11 @@ class QmlProjectPluginPrivate
{
public:
QmlProjectRunConfigurationFactory runConfigFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, QmlProjectRunConfiguration>
- runWorkerFactory{ProjectExplorer::Constants::NORMAL_RUN_MODE};
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {runConfigFactory.id()}
+ };
};
QmlProjectPlugin::~QmlProjectPlugin()
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index f2e54f6444..6e67361d11 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -38,9 +38,7 @@
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
-#include <qtsupport/qtoutputformatter.h>
#include <qtsupport/qtsupportconstants.h>
-#include <qtsupport/desktopqtversion.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
@@ -172,7 +170,7 @@ void MainQmlFileAspect::updateFileComboBox()
m_fileListModel.appendRow(new QStandardItem(QLatin1String(CURRENT_FILE)));
QModelIndex currentIndex;
- QStringList sortedFiles = Utils::transform(m_project->files(Project::AllFiles),
+ QStringList sortedFiles = Utils::transform(m_project->files(Project::SourceFiles),
&Utils::FilePath::toString);
// make paths relative to project directory
@@ -298,24 +296,27 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id)
return envModifier(Environment());
});
- setExecutableGetter([this] { return FilePath::fromString(theExecutable()); });
-
m_qmlViewerAspect = addAspect<BaseStringAspect>();
m_qmlViewerAspect->setLabelText(tr("QML Viewer:"));
- m_qmlViewerAspect->setPlaceHolderText(executable().toString());
+ m_qmlViewerAspect->setPlaceHolderText(commandLine().executable().toString());
m_qmlViewerAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
m_qmlViewerAspect->setHistoryCompleter("QmlProjectManager.viewer.history");
auto argumentAspect = addAspect<ArgumentsAspect>();
argumentAspect->setSettingsKey(Constants::QML_VIEWER_ARGUMENTS_KEY);
+ setCommandLineGetter([this] {
+ return CommandLine(FilePath::fromString(theExecutable()),
+ commandLineArguments(),
+ CommandLine::Raw);
+ });
+
auto qmlProject = qobject_cast<QmlProject *>(target->project());
QTC_ASSERT(qmlProject, return);
m_mainQmlFileAspect = addAspect<MainQmlFileAspect>(qmlProject);
connect(m_mainQmlFileAspect, &MainQmlFileAspect::changed,
this, &QmlProjectRunConfiguration::updateEnabledState);
- setOutputFormatter<QtSupport::QtOutputFormatter>();
connect(target, &Target::kitChanged,
this, &QmlProjectRunConfiguration::updateEnabledState);
@@ -326,8 +327,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id)
Runnable QmlProjectRunConfiguration::runnable() const
{
Runnable r;
- r.executable = executable().toString();
- r.commandLineArguments = commandLineArguments();
+ r.setCommandLine(commandLine());
r.environment = aspect<EnvironmentAspect>()->environment();
r.workingDirectory = static_cast<QmlProject *>(project())->targetDirectory(target()).toString();
return r;
@@ -339,10 +339,10 @@ QString QmlProjectRunConfiguration::disabledReason() const
return tr("No script file to execute.");
if (DeviceTypeKitAspect::deviceTypeId(target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE
- && !executable().exists()) {
+ && !commandLine().executable().exists()) {
return tr("No qmlscene found.");
}
- if (executable().isEmpty())
+ if (commandLine().executable().isEmpty())
return tr("No qmlscene binary specified for target device.");
return RunConfiguration::disabledReason();
}
@@ -361,8 +361,7 @@ QString QmlProjectRunConfiguration::theExecutable() const
if (deviceType == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
// If not given explicitly by Qt Version, try to pick it from $PATH.
return version->type() == QtSupport::Constants::DESKTOPQT
- ? static_cast<QtSupport::DesktopQtVersion *>(version)->qmlsceneCommand()
- : QString("qmlscene");
+ ? version->qmlsceneCommand() : QString("qmlscene");
}
IDevice::ConstPtr dev = DeviceKitAspect::device(target()->kit());
@@ -405,7 +404,7 @@ QString QmlProjectRunConfiguration::commandLineArguments() const
void QmlProjectRunConfiguration::updateEnabledState()
{
bool enabled = false;
- if (m_mainQmlFileAspect->isQmlFilePresent() && !executable().isEmpty()) {
+ if (m_mainQmlFileAspect->isQmlFilePresent() && !commandLine().executable().isEmpty()) {
Project *p = target()->project();
enabled = !p->isParsing() && p->hasParsingData();
}
@@ -431,7 +430,7 @@ bool MainQmlFileAspect::isQmlFilePresent()
|| mainScriptMimeType.matchesName(QLatin1String(QmlJSTools::Constants::QMLPROJECT_MIMETYPE))) {
// find a qml file with lowercase filename. This is slow, but only done
// in initialization/other border cases.
- const auto files = m_project->files(Project::AllFiles);
+ const auto files = m_project->files(Project::SourceFiles);
for (const Utils::FilePath &filename : files) {
const QFileInfo fi = filename.toFileInfo();
diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp
index 3f732f8805..bba9401fe9 100644
--- a/src/plugins/qnx/qnxanalyzesupport.cpp
+++ b/src/plugins/qnx/qnxanalyzesupport.cpp
@@ -25,21 +25,14 @@
#include "qnxanalyzesupport.h"
-#include "qnxdevice.h"
-#include "qnxrunconfiguration.h"
#include "slog2inforunner.h"
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
-#include <qmldebug/qmloutputparser.h>
-
-#include <ssh/sshconnection.h>
using namespace ProjectExplorer;
using namespace Utils;
@@ -53,35 +46,27 @@ QnxQmlProfilerSupport::QnxQmlProfilerSupport(RunControl *runControl)
setId("QnxQmlProfilerSupport");
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
- m_portsGatherer = new PortsGatherer(runControl);
- addStartDependency(m_portsGatherer);
+ auto portsGatherer = new PortsGatherer(runControl);
+ addStartDependency(portsGatherer);
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
addStartDependency(slog2InfoRunner);
- m_profiler = runControl->createWorker(runControl->runMode());
- m_profiler->addStartDependency(this);
- addStopDependency(m_profiler);
-}
-
-void QnxQmlProfilerSupport::start()
-{
- Port qmlPort = m_portsGatherer->findPort();
-
- QUrl serverUrl;
- serverUrl.setHost(device()->sshParameters().host());
- serverUrl.setPort(qmlPort.number());
- serverUrl.setScheme("tcp");
- m_profiler->recordData("QmlServerUrl", serverUrl);
+ auto profiler = runControl->createWorker(ProjectExplorer::Constants::QML_PROFILER_RUNNER);
+ profiler->addStartDependency(this);
+ addStopDependency(profiler);
- Runnable r = runnable();
- QtcProcess::addArg(&r.commandLineArguments,
- QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, qmlPort),
- device()->osType());
+ setStarter([this, runControl, portsGatherer, profiler] {
+ const QUrl serverUrl = portsGatherer->findEndPoint();
+ profiler->recordData("QmlServerUrl", serverUrl);
- setRunnable(r);
+ Runnable r = runControl->runnable();
+ QtcProcess::addArg(&r.commandLineArguments,
+ QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, serverUrl),
+ Utils::OsTypeOtherUnix);
- SimpleTargetRunner::start();
+ doStart(r, runControl->device());
+ });
}
} // namespace Internal
diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h
index 415459e3c1..bcf92ae0a0 100644
--- a/src/plugins/qnx/qnxanalyzesupport.h
+++ b/src/plugins/qnx/qnxanalyzesupport.h
@@ -25,24 +25,15 @@
#pragma once
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/runcontrol.h>
namespace Qnx {
namespace Internal {
class QnxQmlProfilerSupport : public ProjectExplorer::SimpleTargetRunner
{
- Q_OBJECT
-
public:
explicit QnxQmlProfilerSupport(ProjectExplorer::RunControl *runControl);
-
-private:
- void start() override;
-
- ProjectExplorer::PortsGatherer *m_portsGatherer;
- ProjectExplorer::RunWorker *m_profiler;
};
} // namespace Internal
diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp
index d05ae172ff..11a846e612 100644
--- a/src/plugins/qnx/qnxconfiguration.cpp
+++ b/src/plugins/qnx/qnxconfiguration.cpp
@@ -107,7 +107,7 @@ FilePath QnxConfiguration::qccCompilerPath() const
return m_qccCompiler;
}
-QList<EnvironmentItem> QnxConfiguration::qnxEnv() const
+EnvironmentItems QnxConfiguration::qnxEnv() const
{
return m_qnxEnv;
}
diff --git a/src/plugins/qnx/qnxconfiguration.h b/src/plugins/qnx/qnxconfiguration.h
index ebb77c825f..41649ce6bf 100644
--- a/src/plugins/qnx/qnxconfiguration.h
+++ b/src/plugins/qnx/qnxconfiguration.h
@@ -61,7 +61,7 @@ public:
Utils::FilePath qnxTarget() const;
Utils::FilePath qnxHost() const;
Utils::FilePath qccCompilerPath() const;
- QList<Utils::EnvironmentItem> qnxEnv() const;
+ Utils::EnvironmentItems qnxEnv() const;
QnxVersionNumber version() const;
QVariantMap toMap() const;
@@ -97,7 +97,7 @@ private:
Utils::FilePath m_qnxTarget;
Utils::FilePath m_qnxHost;
Utils::FilePath m_qccCompiler;
- QList<Utils::EnvironmentItem> m_qnxEnv;
+ Utils::EnvironmentItems m_qnxEnv;
QnxVersionNumber m_version;
class Target
diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp
index 0ea96961dc..54a0c5c223 100644
--- a/src/plugins/qnx/qnxdebugsupport.cpp
+++ b/src/plugins/qnx/qnxdebugsupport.cpp
@@ -97,34 +97,28 @@ class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
{
public:
QnxDebuggeeRunner(RunControl *runControl, GdbServerPortsGatherer *portsGatherer)
- : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
+ : SimpleTargetRunner(runControl)
{
setId("QnxDebuggeeRunner");
- }
-private:
- void start() final
- {
- Runnable r = runnable();
- QStringList arguments;
- if (m_portsGatherer->useGdbServer()) {
- Port pdebugPort = m_portsGatherer->gdbServerPort();
- r.executable = Constants::QNX_DEBUG_EXECUTABLE;
- arguments.append(pdebugPort.toString());
- }
- if (m_portsGatherer->useQmlServer()) {
- arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
- m_portsGatherer->qmlServerPort()));
- }
- arguments.append(QtcProcess::splitArgs(r.commandLineArguments));
- r.commandLineArguments = QtcProcess::joinArgs(arguments);
-
- setRunnable(r);
-
- SimpleTargetRunner::start();
+ setStarter([this, runControl, portsGatherer] {
+ Runnable r = runControl->runnable();
+ QStringList arguments;
+ if (portsGatherer->useGdbServer()) {
+ int pdebugPort = portsGatherer->gdbServer().port();
+ r.executable = FilePath::fromString(Constants::QNX_DEBUG_EXECUTABLE);
+ arguments.append(QString::number(pdebugPort));
+ }
+ if (portsGatherer->useQmlServer()) {
+ arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
+ portsGatherer->qmlServer()));
+ }
+ arguments.append(QtcProcess::splitArgs(r.commandLineArguments));
+ r.commandLineArguments = QtcProcess::joinArgs(arguments);
+
+ doStart(r, runControl->device());
+ });
}
-
- GdbServerPortsGatherer *m_portsGatherer;
};
@@ -183,7 +177,7 @@ public:
}
QString projectSource() const { return m_projectSource->path(); }
- QString localExecutable() const { return m_localExecutable->path(); }
+ FilePath localExecutable() const { return m_localExecutable->fileName(); }
private:
PathChooser *m_projectSource;
@@ -197,26 +191,20 @@ class PDebugRunner : public ProjectExplorer::SimpleTargetRunner
{
public:
PDebugRunner(RunControl *runControl, GdbServerPortsGatherer *portsGatherer)
- : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
+ : SimpleTargetRunner(runControl)
{
setId("PDebugRunner");
- addStartDependency(m_portsGatherer);
- }
+ addStartDependency(portsGatherer);
-private:
- void start() final
- {
- Port pdebugPort = m_portsGatherer->gdbServerPort();
+ setStarter([this, runControl, portsGatherer] {
+ const int pdebugPort = portsGatherer->gdbServer().port();
- Runnable r;
- r.executable = Constants::QNX_DEBUG_EXECUTABLE;
- r.commandLineArguments = pdebugPort.toString();
- setRunnable(r);
-
- SimpleTargetRunner::start();
+ Runnable r;
+ r.executable = FilePath::fromString(Constants::QNX_DEBUG_EXECUTABLE);
+ r.commandLineArguments = QString::number(pdebugPort);
+ doStart(r, runControl->device());
+ });
}
-
- GdbServerPortsGatherer *m_portsGatherer;
};
QnxAttachDebugSupport::QnxAttachDebugSupport(RunControl *runControl)
@@ -258,10 +246,10 @@ void QnxAttachDebugSupport::showProcessesDialog()
DeviceProcessItem process = dlg.currentProcess();
const int pid = process.pid;
// QString projectSourceDirectory = dlg.projectSource();
- QString localExecutable = dlg.localExecutable();
+ FilePath localExecutable = dlg.localExecutable();
if (localExecutable.isEmpty()) {
if (auto aspect = runConfig->aspect<SymbolFileAspect>())
- localExecutable = aspect->fileName().toString();
+ localExecutable = aspect->filePath();
}
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
diff --git a/src/plugins/qnx/qnxdevice.cpp b/src/plugins/qnx/qnxdevice.cpp
index 7794dbde1b..da5e5ca11e 100644
--- a/src/plugins/qnx/qnxdevice.cpp
+++ b/src/plugins/qnx/qnxdevice.cpp
@@ -60,9 +60,9 @@ class QnxPortsGatheringMethod : public PortsGatheringMethod
// used to be fixed. These two can now be matched to each other.
Runnable runnable(QAbstractSocket::NetworkLayerProtocol protocol) const override
{
- Q_UNUSED(protocol);
+ Q_UNUSED(protocol)
Runnable runnable;
- runnable.executable = "netstat";
+ runnable.executable = FilePath::fromString("netstat");
runnable.commandLineArguments = "-na";
return runnable;
}
@@ -82,22 +82,16 @@ class QnxPortsGatheringMethod : public PortsGatheringMethod
QnxDevice::QnxDevice()
{
+ setDisplayType(tr("QNX"));
+ setDefaultDisplayName(tr("QNX Device"));
+ setOsType(OsTypeOtherUnix);
+
addDeviceAction({tr("Deploy Qt libraries..."), [](const IDevice::Ptr &device, QWidget *parent) {
QnxDeployQtLibrariesDialog dialog(device, parent);
dialog.exec();
}});
}
-QString QnxDevice::displayType() const
-{
- return tr("QNX");
-}
-
-OsType QnxDevice::osType() const
-{
- return OsTypeOtherUnix;
-}
-
int QnxDevice::qnxVersion() const
{
if (m_versionNumber == 0)
@@ -114,7 +108,7 @@ void QnxDevice::updateVersionNumber() const
QObject::connect(&versionNumberProcess, &DeviceProcess::error, &eventLoop, &QEventLoop::quit);
Runnable r;
- r.executable = QLatin1String("uname");
+ r.executable = FilePath::fromString("uname");
r.commandLineArguments = QLatin1String("-r");
versionNumberProcess.start(r);
diff --git a/src/plugins/qnx/qnxdevice.h b/src/plugins/qnx/qnxdevice.h
index ae6a268143..3cd7a069f9 100644
--- a/src/plugins/qnx/qnxdevice.h
+++ b/src/plugins/qnx/qnxdevice.h
@@ -49,9 +49,6 @@ public:
ProjectExplorer::DeviceTester *createDeviceTester() const override;
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
- QString displayType() const override;
- Utils::OsType osType() const override;
-
int qnxVersion() const;
void fromMap(const QVariantMap &map) override;
diff --git a/src/plugins/qnx/qnxdeviceprocess.cpp b/src/plugins/qnx/qnxdeviceprocess.cpp
index 46067672dc..2b6a0c85c4 100644
--- a/src/plugins/qnx/qnxdeviceprocess.cpp
+++ b/src/plugins/qnx/qnxdeviceprocess.cpp
@@ -47,7 +47,7 @@ QnxDeviceProcess::QnxDeviceProcess(const QSharedPointer<const IDevice> &device,
QString QnxDeviceProcess::fullCommandLine(const Runnable &runnable) const
{
QStringList args = QtcProcess::splitArgs(runnable.commandLineArguments);
- args.prepend(runnable.executable);
+ args.prepend(runnable.executable.toString());
QString cmd = QtcProcess::Arguments::createUnixArgs(args).toString();
QString fullCommandLine = QLatin1String(
@@ -59,8 +59,10 @@ QString QnxDeviceProcess::fullCommandLine(const Runnable &runnable) const
fullCommandLine += QString::fromLatin1("cd %1 ; ").arg(QtcProcess::quoteArg(runnable.workingDirectory));
const Environment env = runnable.environment;
- for (auto it = env.constBegin(); it != env.constEnd(); ++it)
- fullCommandLine += QString::fromLatin1("%1='%2' ").arg(env.key(it)).arg(env.value(it));
+ for (auto it = env.constBegin(); it != env.constEnd(); ++it) {
+ fullCommandLine += QString::fromLatin1("%1='%2' ")
+ .arg(env.key(it)).arg(env.expandedValueForKey(env.key(it)));
+ }
fullCommandLine += QString::fromLatin1("%1 & echo $! > %2").arg(cmd).arg(m_pidFile);
@@ -71,7 +73,7 @@ void QnxDeviceProcess::doSignal(int sig)
{
auto signaler = new SshDeviceProcess(device(), this);
Runnable r;
- r.executable = QString::fromLatin1("kill -%2 `cat %1`").arg(m_pidFile).arg(sig);
+ r.executable = FilePath::fromString(QString("kill -%2 `cat %1`").arg(m_pidFile).arg(sig));
connect(signaler, &SshDeviceProcess::finished, signaler, &QObject::deleteLater);
signaler->start(r);
}
diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp
index 5196043ad2..51cd8d5b33 100644
--- a/src/plugins/qnx/qnxdevicetester.cpp
+++ b/src/plugins/qnx/qnxdevicetester.cpp
@@ -59,6 +59,7 @@ QnxDeviceTester::QnxDeviceTester(QObject *parent)
<< QLatin1String("grep")
<< QLatin1String("kill")
<< QLatin1String("netstat")
+ << QLatin1String("mkdir")
<< QLatin1String("print")
<< QLatin1String("printf")
<< QLatin1String("ps")
diff --git a/src/plugins/qnx/qnxdevicewizard.cpp b/src/plugins/qnx/qnxdevicewizard.cpp
index 89fbb06c64..c0e64a5390 100644
--- a/src/plugins/qnx/qnxdevicewizard.cpp
+++ b/src/plugins/qnx/qnxdevicewizard.cpp
@@ -54,7 +54,6 @@ QnxDeviceWizard::QnxDeviceWizard(QWidget *parent) :
sshParams.timeout = 10;
m_device = QnxDevice::create();
m_device->setupId(IDevice::ManuallyAdded);
- m_device->setDisplayName(tr("QNX Device"));
m_device->setType(Constants::QNX_QNX_OS_TYPE);
m_device->setMachineType(IDevice::Hardware);
m_device->setSshParameters(sshParams);
diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp
index 06f2701715..a078056136 100644
--- a/src/plugins/qnx/qnxplugin.cpp
+++ b/src/plugins/qnx/qnxplugin.cpp
@@ -115,12 +115,21 @@ public:
QnxSettingsPage settingsPage;
QnxToolChainFactory toolChainFactory;
- SimpleRunWorkerFactory<SimpleTargetRunner, QnxRunConfiguration>
- runWorkerFactory{ProjectExplorer::Constants::NORMAL_RUN_MODE};
- SimpleRunWorkerFactory<QnxDebugSupport, QnxRunConfiguration>
- debugWorkerFactory{ProjectExplorer::Constants::DEBUG_RUN_MODE};
- SimpleRunWorkerFactory<QnxQmlProfilerSupport, QnxRunConfiguration>
- qmlProfilerWorkerFactory;
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+ RunWorkerFactory debugWorkerFactory{
+ RunWorkerFactory::make<QnxDebugSupport>(),
+ {ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+ RunWorkerFactory qmlProfilerWorkerFactory{
+ RunWorkerFactory::make<QnxQmlProfilerSupport>(),
+ {}, // FIXME: Shouldn't this use the run mode id somehow?
+ {runConfigFactory.id()}
+ };
};
static QnxPluginPrivate *dd = nullptr;
diff --git a/src/plugins/qnx/qnxqtversion.cpp b/src/plugins/qnx/qnxqtversion.cpp
index ffddcf7811..b096f16a80 100644
--- a/src/plugins/qnx/qnxqtversion.cpp
+++ b/src/plugins/qnx/qnxqtversion.cpp
@@ -184,7 +184,7 @@ void QnxQtVersion::updateEnvironment() const
}
}
-QList<Utils::EnvironmentItem> QnxQtVersion::environment() const
+Utils::EnvironmentItems QnxQtVersion::environment() const
{
return QnxUtils::qnxEnvironment(sdpPath());
}
diff --git a/src/plugins/qnx/qnxqtversion.h b/src/plugins/qnx/qnxqtversion.h
index 6479954bf8..d41e19852c 100644
--- a/src/plugins/qnx/qnxqtversion.h
+++ b/src/plugins/qnx/qnxqtversion.h
@@ -73,13 +73,13 @@ protected:
private:
void updateEnvironment() const;
- QList<Utils::EnvironmentItem> environment() const;
+ Utils::EnvironmentItems environment() const;
QString m_sdpPath;
mutable QString m_cpuDir;
mutable bool m_environmentUpToDate = false;
- mutable QList<Utils::EnvironmentItem> m_qnxEnv;
+ mutable Utils::EnvironmentItems m_qnxEnv;
};
class QnxQtVersionFactory : public QtSupport::QtVersionFactory
diff --git a/src/plugins/qnx/qnxrunconfiguration.cpp b/src/plugins/qnx/qnxrunconfiguration.cpp
index d098daabb8..d9b3522207 100644
--- a/src/plugins/qnx/qnxrunconfiguration.cpp
+++ b/src/plugins/qnx/qnxrunconfiguration.cpp
@@ -27,26 +27,68 @@
#include "qnxconstants.h"
+#include <projectexplorer/deployablefile.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/target.h>
+
+#include <remotelinux/remotelinuxenvironmentaspect.h>
+
+#include <qtsupport/qtoutputformatter.h>
using namespace ProjectExplorer;
using namespace RemoteLinux;
+using namespace Utils;
namespace Qnx {
namespace Internal {
QnxRunConfiguration::QnxRunConfiguration(Target *target, Core::Id id)
- : RemoteLinuxRunConfiguration(target, id)
+ : RunConfiguration(target, id)
{
+ auto exeAspect = addAspect<ExecutableAspect>();
+ exeAspect->setLabelText(tr("Executable on device:"));
+ exeAspect->setExecutablePathStyle(OsTypeLinux);
+ exeAspect->setPlaceHolderText(tr("Remote path not set"));
+ exeAspect->makeOverridable("RemoteLinux.RunConfig.AlternateRemoteExecutable",
+ "RemoteLinux.RunConfig.UseAlternateRemoteExecutable");
+ exeAspect->setHistoryCompleter("RemoteLinux.AlternateExecutable.History");
+
+ auto symbolsAspect = addAspect<SymbolFileAspect>();
+ symbolsAspect->setLabelText(tr("Executable on host:"));
+ symbolsAspect->setDisplayStyle(SymbolFileAspect::LabelDisplay);
+
+ addAspect<ArgumentsAspect>();
+ addAspect<WorkingDirectoryAspect>();
+ addAspect<TerminalAspect>();
+ addAspect<RemoteLinuxEnvironmentAspect>(target);
+
auto libAspect = addAspect<QtLibPathAspect>();
libAspect->setSettingsKey("Qt4ProjectManager.QnxRunConfiguration.QtLibPath");
libAspect->setLabelText(tr("Path to Qt libraries on device"));
libAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
+
+ auto updateTargetInformation = [this, target, exeAspect, symbolsAspect] {
+
+ const BuildTargetInfo bti = buildTargetInfo();
+ const FilePath localExecutable = bti.targetFilePath;
+ const DeployableFile depFile = target->deploymentData().deployableForLocalFile(localExecutable);
+
+ exeAspect->setExecutable(FilePath::fromString(depFile.remoteFilePath()));
+ symbolsAspect->setFilePath(localExecutable);
+
+ emit enabledChanged();
+ };
+
+ connect(target, &Target::deploymentDataChanged, this, updateTargetInformation);
+ connect(target, &Target::applicationTargetsChanged, this, updateTargetInformation);
+ connect(target->project(), &Project::parsingFinished, this, updateTargetInformation);
+ connect(target, &Target::kitChanged, this, updateTargetInformation);
}
Runnable QnxRunConfiguration::runnable() const
{
- Runnable r = RemoteLinuxRunConfiguration::runnable();
+ Runnable r = RunConfiguration::runnable();
QString libPath = aspect<QtLibPathAspect>()->value();
if (!libPath.isEmpty()) {
r.environment.appendOrSet("LD_LIBRARY_PATH", libPath + "/lib:$LD_LIBRARY_PATH");
diff --git a/src/plugins/qnx/qnxrunconfiguration.h b/src/plugins/qnx/qnxrunconfiguration.h
index 390224d120..75ec72a66c 100644
--- a/src/plugins/qnx/qnxrunconfiguration.h
+++ b/src/plugins/qnx/qnxrunconfiguration.h
@@ -39,7 +39,7 @@ public:
QtLibPathAspect() = default;
};
-class QnxRunConfiguration : public RemoteLinux::RemoteLinuxRunConfiguration
+class QnxRunConfiguration final : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
@@ -50,7 +50,7 @@ private:
ProjectExplorer::Runnable runnable() const override;
};
-class QnxRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
+class QnxRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory
{
public:
QnxRunConfigurationFactory();
diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp
index 2b488887dd..f9a8aaa53b 100644
--- a/src/plugins/qnx/qnxsettingspage.cpp
+++ b/src/plugins/qnx/qnxsettingspage.cpp
@@ -39,8 +39,7 @@
namespace Qnx {
namespace Internal {
-QnxSettingsPage::QnxSettingsPage(QObject* parent) :
- Core::IOptionsPage(parent)
+QnxSettingsPage::QnxSettingsPage()
{
setId(Core::Id(Constants::QNX_SETTINGS_ID));
setDisplayName(tr("QNX"));
diff --git a/src/plugins/qnx/qnxsettingspage.h b/src/plugins/qnx/qnxsettingspage.h
index ae7be9bb2f..c04f238d32 100644
--- a/src/plugins/qnx/qnxsettingspage.h
+++ b/src/plugins/qnx/qnxsettingspage.h
@@ -37,8 +37,10 @@ class QnxSettingsWidget;
class QnxSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
+
public:
- explicit QnxSettingsPage(QObject *parent = nullptr);
+ QnxSettingsPage();
+
QWidget *widget() override;
void apply() override;
void finish() override;
diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp
index 0a515287ea..158d70e494 100644
--- a/src/plugins/qnx/qnxtoolchain.cpp
+++ b/src/plugins/qnx/qnxtoolchain.cpp
@@ -50,7 +50,7 @@ static Abis detectTargetAbis(const FilePath &sdpPath)
FilePath qnxTarget;
if (!sdpPath.fileName().isEmpty()) {
- QList<Utils::EnvironmentItem> environment = QnxUtils::qnxEnvironment(sdpPath.toString());
+ Utils::EnvironmentItems environment = QnxUtils::qnxEnvironment(sdpPath.toString());
foreach (const Utils::EnvironmentItem &item, environment) {
if (item.name == QLatin1String("QNX_TARGET"))
qnxTarget = FilePath::fromString(item.value);
@@ -72,12 +72,11 @@ static Abis detectTargetAbis(const FilePath &sdpPath)
return result;
}
-static void setQnxEnvironment(Environment &env, const QList<EnvironmentItem> &qnxEnv)
+static void setQnxEnvironment(Environment &env, const EnvironmentItems &qnxEnv)
{
// We only need to set QNX_HOST and QNX_TARGET needed when running qcc
foreach (const EnvironmentItem &item, qnxEnv) {
- if (item.name == QLatin1String("QNX_HOST") ||
- item.name == QLatin1String("QNX_TARGET") )
+ if (item.name == QLatin1String("QNX_HOST") || item.name == QLatin1String("QNX_TARGET"))
env.set(item.name, item.value);
}
}
@@ -104,11 +103,7 @@ QnxToolChain::QnxToolChain()
: GccToolChain(Constants::QNX_TOOLCHAIN_ID)
{
setOptionsReinterpreter(&reinterpretOptions);
-}
-
-QString QnxToolChain::typeDisplayName() const
-{
- return QnxToolChainFactory::tr("QCC");
+ setTypeDisplayName(QnxToolChainFactory::tr("QCC"));
}
std::unique_ptr<ToolChainConfigWidget> QnxToolChain::createConfigurationWidget()
@@ -118,7 +113,7 @@ std::unique_ptr<ToolChainConfigWidget> QnxToolChain::createConfigurationWidget()
void QnxToolChain::addToEnvironment(Environment &env) const
{
- if (env.value("QNX_HOST").isEmpty() || env.value("QNX_TARGET").isEmpty())
+ if (env.expandedValueForKey("QNX_HOST").isEmpty() || env.expandedValueForKey("QNX_TARGET").isEmpty())
setQnxEnvironment(env, QnxUtils::qnxEnvironment(m_sdpPath));
GccToolChain::addToEnvironment(env);
diff --git a/src/plugins/qnx/qnxtoolchain.h b/src/plugins/qnx/qnxtoolchain.h
index b514ac15f3..71e10a2879 100644
--- a/src/plugins/qnx/qnxtoolchain.h
+++ b/src/plugins/qnx/qnxtoolchain.h
@@ -36,8 +36,6 @@ class QnxToolChain : public ProjectExplorer::GccToolChain
public:
QnxToolChain();
- QString typeDisplayName() const override;
-
std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() override;
void addToEnvironment(Utils::Environment &env) const override;
diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp
index 9d61864558..3d34dd74bb 100644
--- a/src/plugins/qnx/qnxutils.cpp
+++ b/src/plugins/qnx/qnxutils.cpp
@@ -73,9 +73,9 @@ QString QnxUtils::cpuDirShortDescription(const QString &cpuDir)
return cpuDir;
}
-QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
+Utils::EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
{
- QList <Utils::EnvironmentItem> items;
+ Utils::EnvironmentItems items;
if (!QFileInfo::exists(fileName))
return items;
@@ -206,7 +206,7 @@ QList<ConfigInstallInformation> QnxUtils::installedConfigs(const QString &config
return sdpList;
}
-QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironment(const QString &sdpPath)
+Utils::EnvironmentItems QnxUtils::qnxEnvironment(const QString &sdpPath)
{
return qnxEnvironmentFromEnvFile(envFilePath(sdpPath));
}
diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h
index ae8367e43b..63ef5dd86e 100644
--- a/src/plugins/qnx/qnxutils.h
+++ b/src/plugins/qnx/qnxutils.h
@@ -70,11 +70,11 @@ class QnxUtils
public:
static QString addQuotes(const QString &string);
static QString cpuDirShortDescription(const QString &cpuDir);
- static QList<Utils::EnvironmentItem> qnxEnvironmentFromEnvFile(const QString &fileName);
+ static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const QString &fileName);
static QString envFilePath(const QString &sdpPath);
static QString defaultTargetVersion(const QString &sdpPath);
static QList<ConfigInstallInformation> installedConfigs(const QString &configPath = QString());
- static QList<Utils::EnvironmentItem> qnxEnvironment(const QString &sdpPath);
+ static Utils::EnvironmentItems qnxEnvironment(const QString &sdpPath);
static QList<QnxTarget> findTargets(const Utils::FilePath &basePath);
static ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi);
static ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis);
diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp
index aec6d74a6f..19c1670740 100644
--- a/src/plugins/qnx/slog2inforunner.cpp
+++ b/src/plugins/qnx/slog2inforunner.cpp
@@ -73,7 +73,7 @@ void Slog2InfoRunner::printMissingWarning()
void Slog2InfoRunner::start()
{
Runnable r;
- r.executable = QLatin1String("slog2info");
+ r.executable = Utils::FilePath::fromString("slog2info");
m_testProcess->start(r);
reportStarted();
}
@@ -111,7 +111,7 @@ void Slog2InfoRunner::handleTestProcessCompleted()
void Slog2InfoRunner::readLaunchTime()
{
Runnable r;
- r.executable = QLatin1String("date");
+ r.executable = Utils::FilePath::fromString("date");
r.commandLineArguments = QLatin1String("+\"%d %H:%M:%S\"");
m_launchDateTimeProcess->start(r);
}
@@ -128,7 +128,7 @@ void Slog2InfoRunner::launchSlog2Info()
QString::fromLatin1("dd HH:mm:ss"));
Runnable r;
- r.executable = QLatin1String("slog2info");
+ r.executable = Utils::FilePath::fromString("slog2info");
r.commandLineArguments = QLatin1String("-w");
m_logProcess->start(r);
}
diff --git a/src/plugins/qtsupport/CMakeLists.txt b/src/plugins/qtsupport/CMakeLists.txt
index 125e949b35..80c54bd06f 100644
--- a/src/plugins/qtsupport/CMakeLists.txt
+++ b/src/plugins/qtsupport/CMakeLists.txt
@@ -1,14 +1,13 @@
add_qtc_plugin(QtSupport
DEPENDS Qt5::Xml
PUBLIC_DEPENDS ProParser
- PLUGIN_DEPENDS Core CppTools ProjectExplorer ResourceEditor
+ PLUGIN_DEPENDS Core ProjectExplorer ResourceEditor
SOURCES
baseqtversion.cpp baseqtversion.h
codegenerator.cpp codegenerator.h
codegensettings.cpp codegensettings.h
codegensettingspage.cpp codegensettingspage.h
codegensettingspagewidget.ui
- desktopqtversion.cpp desktopqtversion.h
exampleslistmodel.cpp exampleslistmodel.h
gettingstartedwelcomepage.cpp gettingstartedwelcomepage.h
profilereader.cpp profilereader.h
@@ -26,10 +25,12 @@ add_qtc_plugin(QtSupport
qtsupportconstants.h
qtsupportplugin.cpp qtsupportplugin.h
qttestparser.cpp qttestparser.h
- qtversionfactory.cpp qtversionfactory.h
+ qtversionfactory.h
qtversioninfo.ui
qtversionmanager.cpp qtversionmanager.h qtversionmanager.ui
+ qtversions.cpp qtversions.h
screenshotcropper.cpp screenshotcropper.h
showbuildlog.ui
+ translationwizardpage.cpp translationwizardpage.h
uicgenerator.cpp uicgenerator.h
)
diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp
index 2dd4160a3b..88a406eda9 100644
--- a/src/plugins/qtsupport/baseqtversion.cpp
+++ b/src/plugins/qtsupport/baseqtversion.cpp
@@ -69,21 +69,23 @@
#include <algorithm>
using namespace Core;
-using namespace QtSupport;
-using namespace QtSupport::Internal;
using namespace ProjectExplorer;
+using namespace QtSupport::Internal;
using namespace Utils;
-static const char QTVERSIONAUTODETECTED[] = "isAutodetected";
-static const char QTVERSIONAUTODETECTIONSOURCE[] = "autodetectionSource";
-static const char QTVERSION_OVERRIDE_FEATURES[] = "overrideFeatures";
-static const char QTVERSIONQMAKEPATH[] = "QMakePath";
-static const char QTVERSIONSOURCEPATH[] = "SourcePath";
+namespace QtSupport {
+namespace Internal {
-static const char QTVERSION_ABIS[] = "Abis";
+const char QTVERSIONAUTODETECTED[] = "isAutodetected";
+const char QTVERSIONAUTODETECTIONSOURCE[] = "autodetectionSource";
+const char QTVERSION_OVERRIDE_FEATURES[] = "overrideFeatures";
+const char QTVERSIONQMAKEPATH[] = "QMakePath";
+const char QTVERSIONSOURCEPATH[] = "SourcePath";
-static const char MKSPEC_VALUE_LIBINFIX[] = "QT_LIBINFIX";
-static const char MKSPEC_VALUE_NAMESPACE[] = "QT_NAMESPACE";
+const char QTVERSION_ABIS[] = "Abis";
+
+const char MKSPEC_VALUE_LIBINFIX[] = "QT_LIBINFIX";
+const char MKSPEC_VALUE_NAMESPACE[] = "QT_NAMESPACE";
static QSet<Id> versionedIds(const QByteArray &prefix, int major, int minor)
{
@@ -109,6 +111,96 @@ static QSet<Id> versionedIds(const QByteArray &prefix, int major, int minor)
return result;
}
+// Wrapper to make the std::unique_ptr<Utils::MacroExpander> "copyable":
+class MacroExpanderWrapper
+{
+public:
+ MacroExpanderWrapper() = default;
+ MacroExpanderWrapper(const MacroExpanderWrapper &other) { Q_UNUSED(other) }
+ MacroExpanderWrapper(MacroExpanderWrapper &&other) = default;
+
+ MacroExpander *macroExpander(const BaseQtVersion *qtversion) const;
+private:
+ mutable std::unique_ptr<MacroExpander> m_expander;
+};
+
+enum HostBinaries { Designer, Linguist, Uic, QScxmlc };
+
+class BaseQtVersionPrivate
+{
+public:
+ BaseQtVersionPrivate(BaseQtVersion *parent) : q(parent) {}
+
+ void setupQmakePathAndId(const FilePath &path);
+ void updateVersionInfo();
+
+ QString findHostBinary(HostBinaries binary) const;
+ void updateMkspec();
+ QHash<ProKey, ProString> versionInfo();
+ static bool queryQMakeVariables(const FilePath &binary,
+ const Environment &env,
+ QHash<ProKey, ProString> *versionInfo,
+ QString *error = nullptr);
+ static QString qmakeProperty(const QHash<ProKey, ProString> &versionInfo,
+ const QByteArray &name,
+ BaseQtVersion::PropertyVariant variant = BaseQtVersion::PropertyVariantGet);
+ static FilePath mkspecDirectoryFromVersionInfo(const QHash<ProKey,ProString> &versionInfo);
+ static FilePath mkspecFromVersionInfo(const QHash<ProKey,ProString> &versionInfo);
+ static FilePath sourcePath(const QHash<ProKey,ProString> &versionInfo);
+ void setId(int id); // used by the qtversionmanager for legacy restore
+ // and by the qtoptionspage to replace Qt versions
+
+ FilePathList qtCorePaths();
+
+public:
+ BaseQtVersion *q;
+ int m_id = -1;
+ bool m_isAutodetected = false;
+ QString m_type;
+
+ bool m_hasQmlDump = false; // controlled by m_versionInfoUpToDate
+ bool m_mkspecUpToDate = false;
+ bool m_mkspecReadUpToDate = false;
+ bool m_defaultConfigIsDebug = true;
+ bool m_defaultConfigIsDebugAndRelease = true;
+ bool m_frameworkBuild = false;
+ bool m_versionInfoUpToDate = false;
+ bool m_installed = true;
+ bool m_hasExamples = false;
+ bool m_hasDemos = false;
+ bool m_hasDocumentation = false;
+ bool m_qmakeIsExecutable = true;
+ bool m_hasQtAbis = false;
+
+ QStringList m_configValues;
+ QStringList m_qtConfigValues;
+
+ QString m_unexpandedDisplayName;
+ QString m_autodetectionSource;
+ QSet<Core::Id> m_overrideFeatures;
+ FilePath m_sourcePath;
+ FilePath m_qtSources;
+
+ FilePath m_mkspec;
+ FilePath m_mkspecFullPath;
+
+ QHash<QString, QString> m_mkspecValues;
+
+ QHash<ProKey, ProString> m_versionInfo;
+
+ FilePath m_qmakeCommand;
+ QString m_qtVersionString;
+ QString m_uicCommand;
+ QString m_designerCommand;
+ QString m_linguistCommand;
+ QString m_qscxmlcCommand;
+ QString m_qmlsceneCommand;
+
+ Abis m_qtAbis;
+
+ MacroExpanderWrapper m_expander;
+};
+
///////////////
// MacroExpanderWrapper
///////////////
@@ -119,6 +211,8 @@ MacroExpander *MacroExpanderWrapper::macroExpander(const BaseQtVersion *qtversio
return m_expander.get();
}
+} // Internal
+
///////////////
// QtVersionNumber
///////////////
@@ -195,16 +289,22 @@ bool QtVersionNumber::operator >=(const QtVersionNumber &b) const
// BaseQtVersion
///////////////
-BaseQtVersion::BaseQtVersion() = default;
+BaseQtVersion::BaseQtVersion()
+ : d(new BaseQtVersionPrivate(this))
+{}
+
-BaseQtVersion::~BaseQtVersion() = default;
+BaseQtVersion::~BaseQtVersion()
+{
+ delete d;
+}
-void BaseQtVersion::setupQmakePathAndId(const FilePath &qmakeCommand)
+void BaseQtVersionPrivate::setupQmakePathAndId(const FilePath &qmakeCommand)
{
m_id = QtVersionManager::getUniqueId();
QTC_CHECK(m_qmakeCommand.isEmpty()); // Should only be used once.
m_qmakeCommand = qmakeCommand;
- setUnexpandedDisplayName(defaultUnexpandedDisplayName(m_qmakeCommand, false));
+ m_unexpandedDisplayName = BaseQtVersion::defaultUnexpandedDisplayName(m_qmakeCommand, false);
}
QString BaseQtVersion::defaultUnexpandedDisplayName(const FilePath &qmakePath, bool fromPath)
@@ -452,7 +552,7 @@ FilePath BaseQtVersion::mkspecsPath() const
FilePath BaseQtVersion::qmlBinPath() const
{
- return FilePath::fromUserInput(m_mkspecValues.value("QT.qml.bins"));
+ return FilePath::fromUserInput(d->m_mkspecValues.value("QT.qml.bins"));
}
FilePath BaseQtVersion::librarySearchPath() const
@@ -480,63 +580,52 @@ FilePathList BaseQtVersion::directoriesToIgnoreInProjectTree() const
QString BaseQtVersion::qtNamespace() const
{
ensureMkSpecParsed();
- return m_mkspecValues.value(MKSPEC_VALUE_NAMESPACE);
+ return d->m_mkspecValues.value(MKSPEC_VALUE_NAMESPACE);
}
QString BaseQtVersion::qtLibInfix() const
{
ensureMkSpecParsed();
- return m_mkspecValues.value(MKSPEC_VALUE_LIBINFIX);
+ return d->m_mkspecValues.value(MKSPEC_VALUE_LIBINFIX);
}
bool BaseQtVersion::isFrameworkBuild() const
{
ensureMkSpecParsed();
- return m_frameworkBuild;
+ return d->m_frameworkBuild;
}
bool BaseQtVersion::hasDebugBuild() const
{
- return m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease;
+ return d->m_defaultConfigIsDebug || d->m_defaultConfigIsDebugAndRelease;
}
bool BaseQtVersion::hasReleaseBuild() const
{
- return !m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease;
-}
-
-void BaseQtVersion::setId(int id)
-{
- m_id = id;
-}
-
-void BaseQtVersion::setIsAutodetected(bool isAutodetected)
-{
- m_isAutodetected = isAutodetected;
+ return !d->m_defaultConfigIsDebug || d->m_defaultConfigIsDebugAndRelease;
}
void BaseQtVersion::fromMap(const QVariantMap &map)
{
- m_id = map.value(Constants::QTVERSIONID).toInt();
- if (m_id == -1) // this happens on adding from installer, see updateFromInstaller => get a new unique id
- m_id = QtVersionManager::getUniqueId();
- m_unexpandedDisplayName = map.value(Constants::QTVERSIONNAME).toString();
- m_isAutodetected = map.value(QTVERSIONAUTODETECTED).toBool();
- if (m_isAutodetected)
- m_autodetectionSource = map.value(QTVERSIONAUTODETECTIONSOURCE).toString();
- m_overrideFeatures = Core::Id::fromStringList(map.value(QTVERSION_OVERRIDE_FEATURES).toStringList());
+ d->m_id = map.value(Constants::QTVERSIONID).toInt();
+ if (d->m_id == -1) // this happens on adding from installer, see updateFromInstaller => get a new unique id
+ d->m_id = QtVersionManager::getUniqueId();
+ d->m_unexpandedDisplayName = map.value(Constants::QTVERSIONNAME).toString();
+ d->m_isAutodetected = map.value(QTVERSIONAUTODETECTED).toBool();
+ if (d->m_isAutodetected)
+ d->m_autodetectionSource = map.value(QTVERSIONAUTODETECTIONSOURCE).toString();
+ d->m_overrideFeatures = Core::Id::fromStringList(map.value(QTVERSION_OVERRIDE_FEATURES).toStringList());
QString string = map.value(QTVERSIONQMAKEPATH).toString();
if (string.startsWith('~'))
string.remove(0, 1).prepend(QDir::homePath());
- m_qtSources = Utils::FilePath::fromUserInput(
- map.value(QTVERSIONSOURCEPATH).toString());
+ d->m_qtSources = FilePath::fromUserInput(map.value(QTVERSIONSOURCEPATH).toString());
// Handle ABIs provided by the SDKTool:
// Note: Creator does not write these settings itself, so it has to come from the SDKTool!
- m_qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(), &Abi::fromString);
- m_qtAbis = Utils::filtered(m_qtAbis, &Abi::isValid);
- m_hasQtAbis = !m_qtAbis.isEmpty();
+ d->m_qtAbis = Utils::transform<Abis>(map.value(QTVERSION_ABIS).toStringList(), &Abi::fromString);
+ d->m_qtAbis = Utils::filtered(d->m_qtAbis, &Abi::isValid);
+ d->m_hasQtAbis = !d->m_qtAbis.isEmpty();
QFileInfo fi(string);
if (BuildableHelperLibrary::isQtChooser(fi)) {
@@ -546,7 +635,10 @@ void BaseQtVersion::fromMap(const QVariantMap &map)
string = BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget());
}
- m_qmakeCommand = Utils::FilePath::fromString(string);
+ d->m_qmakeCommand = FilePath::fromString(string);
+
+ // Clear the cached qmlscene command, it might not match the restored path anymore.
+ d->m_qmlsceneCommand.clear();
}
QVariantMap BaseQtVersion::toMap() const
@@ -557,8 +649,8 @@ QVariantMap BaseQtVersion::toMap() const
result.insert(QTVERSIONAUTODETECTED, isAutodetected());
if (isAutodetected())
result.insert(QTVERSIONAUTODETECTIONSOURCE, autodetectionSource());
- if (!m_overrideFeatures.isEmpty())
- result.insert(QTVERSION_OVERRIDE_FEATURES, Core::Id::toStringList(m_overrideFeatures));
+ if (!d->m_overrideFeatures.isEmpty())
+ result.insert(QTVERSION_OVERRIDE_FEATURES, Core::Id::toStringList(d->m_overrideFeatures));
result.insert(QTVERSIONQMAKEPATH, qmakeCommand().toString());
return result;
@@ -568,14 +660,14 @@ bool BaseQtVersion::isValid() const
{
if (uniqueId() == -1 || displayName().isEmpty())
return false;
- updateVersionInfo();
- updateMkspec();
+ d->updateVersionInfo();
+ d->updateMkspec();
return !qmakeCommand().isEmpty()
- && m_installed
+ && d->m_installed
&& !qmakeProperty("QT_HOST_BINS").isNull()
- && !m_mkspecFullPath.isEmpty()
- && m_qmakeIsExecutable;
+ && !d->m_mkspecFullPath.isEmpty()
+ && d->m_qmakeIsExecutable;
}
BaseQtVersion::Predicate BaseQtVersion::isValidPredicate(const BaseQtVersion::Predicate &predicate)
@@ -591,14 +683,14 @@ QString BaseQtVersion::invalidReason() const
return QCoreApplication::translate("QtVersion", "Qt version has no name");
if (qmakeCommand().isEmpty())
return QCoreApplication::translate("QtVersion", "No qmake path set");
- if (!m_qmakeIsExecutable)
+ if (!d->m_qmakeIsExecutable)
return QCoreApplication::translate("QtVersion", "qmake does not exist or is not executable");
- if (!m_installed)
+ if (!d->m_installed)
return QCoreApplication::translate("QtVersion", "Qt version is not properly installed, please run make install");
if (qmakeProperty("QT_HOST_BINS").isNull())
return QCoreApplication::translate("QtVersion",
"Could not determine the path to the binaries of the Qt installation, maybe the qmake path is wrong?");
- if (m_mkspecUpToDate && m_mkspecFullPath.isEmpty())
+ if (d->m_mkspecUpToDate && d->m_mkspecFullPath.isEmpty())
return QCoreApplication::translate("QtVersion", "The default mkspec symlink is broken.");
return QString();
}
@@ -608,8 +700,8 @@ QStringList BaseQtVersion::warningReason() const
QStringList ret;
if (qtAbis().isEmpty())
ret << QCoreApplication::translate("QtVersion", "ABI detection failed: Make sure to use a matching compiler when building.");
- if (m_versionInfo.value(ProKey("QT_INSTALL_PREFIX/get"))
- != m_versionInfo.value(ProKey("QT_INSTALL_PREFIX"))) {
+ if (d->m_versionInfo.value(ProKey("QT_INSTALL_PREFIX/get"))
+ != d->m_versionInfo.value(ProKey("QT_INSTALL_PREFIX"))) {
ret << QCoreApplication::translate("QtVersion", "Non-installed -prefix build - for internal development only.");
}
return ret;
@@ -617,26 +709,26 @@ QStringList BaseQtVersion::warningReason() const
FilePath BaseQtVersion::qmakeCommand() const
{
- return m_qmakeCommand;
+ return d->m_qmakeCommand;
}
Abis BaseQtVersion::qtAbis() const
{
- if (!m_hasQtAbis) {
- m_qtAbis = detectQtAbis();
- m_hasQtAbis = true;
+ if (!d->m_hasQtAbis) {
+ d->m_qtAbis = detectQtAbis();
+ d->m_hasQtAbis = true;
}
- return m_qtAbis;
+ return d->m_qtAbis;
}
Abis BaseQtVersion::detectQtAbis() const
{
- return qtAbisFromLibrary(qtCorePaths());
+ return qtAbisFromLibrary(d->qtCorePaths());
}
bool BaseQtVersion::equals(BaseQtVersion *other)
{
- if (m_qmakeCommand != other->m_qmakeCommand)
+ if (d->m_qmakeCommand != other->d->m_qmakeCommand)
return false;
if (type() != other->type())
return false;
@@ -652,43 +744,37 @@ bool BaseQtVersion::equals(BaseQtVersion *other)
int BaseQtVersion::uniqueId() const
{
- return m_id;
+ return d->m_id;
}
QString BaseQtVersion::type() const
{
- QTC_ASSERT(m_factory, return QString());
- return m_factory->supportedType();
+ return d->m_type;
}
bool BaseQtVersion::isAutodetected() const
{
- return m_isAutodetected;
+ return d->m_isAutodetected;
}
QString BaseQtVersion::autodetectionSource() const
{
- return m_autodetectionSource;
-}
-
-void BaseQtVersion::setAutoDetectionSource(const QString &autodetectionSource)
-{
- m_autodetectionSource = autodetectionSource;
+ return d->m_autodetectionSource;
}
QString BaseQtVersion::displayName() const
{
- return macroExpander()->expand(m_unexpandedDisplayName);
+ return macroExpander()->expand(d->m_unexpandedDisplayName);
}
QString BaseQtVersion::unexpandedDisplayName() const
{
- return m_unexpandedDisplayName;
+ return d->m_unexpandedDisplayName;
}
void BaseQtVersion::setUnexpandedDisplayName(const QString &name)
{
- m_unexpandedDisplayName = name;
+ d->m_unexpandedDisplayName = name;
}
QString BaseQtVersion::toHtml(bool verbose) const
@@ -720,13 +806,13 @@ QString BaseQtVersion::toHtml(bool verbose) const
str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "mkspec:")
<< "</b></td><td>" << QDir::toNativeSeparators(mkspec()) << "</td></tr>";
str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "qmake:")
- << "</b></td><td>" << m_qmakeCommand.toUserOutput() << "</td></tr>";
+ << "</b></td><td>" << d->m_qmakeCommand.toUserOutput() << "</td></tr>";
ensureMkSpecParsed();
if (!mkspecPath().isEmpty()) {
- if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) {
+ if (d->m_defaultConfigIsDebug || d->m_defaultConfigIsDebugAndRelease) {
str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "Default:") << "</b></td><td>"
- << (m_defaultConfigIsDebug ? "debug" : "release");
- if (m_defaultConfigIsDebugAndRelease)
+ << (d->m_defaultConfigIsDebug ? "debug" : "release");
+ if (d->m_defaultConfigIsDebugAndRelease)
str << " debug_and_release";
str << "</td></tr>";
} // default config.
@@ -734,7 +820,7 @@ QString BaseQtVersion::toHtml(bool verbose) const
str << "<tr><td><b>" << QCoreApplication::translate("BaseQtVersion", "Version:")
<< "</b></td><td>" << qtVersionString() << "</td></tr>";
if (verbose) {
- const QHash<ProKey, ProString> vInfo = versionInfo();
+ const QHash<ProKey, ProString> vInfo = d->versionInfo();
if (!vInfo.isEmpty()) {
QList<ProKey> keys = vInfo.keys();
Utils::sort(keys);
@@ -774,34 +860,34 @@ QString BaseQtVersion::toHtml(bool verbose) const
FilePath BaseQtVersion::sourcePath() const
{
- if (m_sourcePath.isEmpty()) {
- updateVersionInfo();
- m_sourcePath = sourcePath(m_versionInfo);
+ if (d->m_sourcePath.isEmpty()) {
+ d->updateVersionInfo();
+ d->m_sourcePath = d->sourcePath(d->m_versionInfo);
}
- return m_sourcePath;
+ return d->m_sourcePath;
}
FilePath BaseQtVersion::qtPackageSourcePath() const
{
- return m_qtSources;
+ return d->m_qtSources;
}
QString BaseQtVersion::designerCommand() const
{
if (!isValid())
return QString();
- if (m_designerCommand.isNull())
- m_designerCommand = findHostBinary(Designer);
- return m_designerCommand;
+ if (d->m_designerCommand.isNull())
+ d->m_designerCommand = d->findHostBinary(Designer);
+ return d->m_designerCommand;
}
QString BaseQtVersion::linguistCommand() const
{
if (!isValid())
return QString();
- if (m_linguistCommand.isNull())
- m_linguistCommand = findHostBinary(Linguist);
- return m_linguistCommand;
+ if (d->m_linguistCommand.isNull())
+ d->m_linguistCommand = d->findHostBinary(Linguist);
+ return d->m_linguistCommand;
}
QString BaseQtVersion::qscxmlcCommand() const
@@ -809,18 +895,36 @@ QString BaseQtVersion::qscxmlcCommand() const
if (!isValid())
return QString();
- if (m_qscxmlcCommand.isNull())
- m_qscxmlcCommand = findHostBinary(QScxmlc);
- return m_qscxmlcCommand;
+ if (d->m_qscxmlcCommand.isNull())
+ d->m_qscxmlcCommand = d->findHostBinary(QScxmlc);
+ return d->m_qscxmlcCommand;
}
-QString BaseQtVersion::findHostBinary(HostBinaries binary) const
+QString BaseQtVersion::qmlsceneCommand() const
+{
+ if (!isValid())
+ return QString();
+
+ if (!d->m_qmlsceneCommand.isNull())
+ return d->m_qmlsceneCommand;
+
+ ensureMkSpecParsed();
+
+ const QString path =
+ qmlBinPath().pathAppended(HostOsInfo::withExecutableSuffix("qmlscene")).toString();
+
+ d->m_qmlsceneCommand = QFileInfo(path).isFile() ? path : QString();
+
+ return d->m_qmlsceneCommand;
+}
+
+QString BaseQtVersionPrivate::findHostBinary(HostBinaries binary) const
{
QString baseDir;
- if (qtVersion() < QtVersionNumber(5, 0, 0)) {
- baseDir = qmakeProperty("QT_HOST_BINS");
+ if (q->qtVersion() < QtVersionNumber(5, 0, 0)) {
+ baseDir = q->qmakeProperty("QT_HOST_BINS");
} else {
- ensureMkSpecParsed();
+ q->ensureMkSpecParsed();
switch (binary) {
case Designer:
case Linguist:
@@ -828,7 +932,7 @@ QString BaseQtVersion::findHostBinary(HostBinaries binary) const
break;
case Uic:
case QScxmlc:
- baseDir = qmakeProperty("QT_HOST_BINS");
+ baseDir = q->qmakeProperty("QT_HOST_BINS");
break;
default:
// Can't happen
@@ -880,15 +984,15 @@ QString BaseQtVersion::uicCommand() const
{
if (!isValid())
return QString();
- if (!m_uicCommand.isNull())
- return m_uicCommand;
- m_uicCommand = findHostBinary(Uic);
- return m_uicCommand;
+ if (!d->m_uicCommand.isNull())
+ return d->m_uicCommand;
+ d->m_uicCommand = d->findHostBinary(Uic);
+ return d->m_uicCommand;
}
-void BaseQtVersion::updateMkspec() const
+void BaseQtVersionPrivate::updateMkspec()
{
- if (uniqueId() == -1 || m_mkspecUpToDate)
+ if (m_id == -1 || m_mkspecUpToDate)
return;
m_mkspecUpToDate = true;
@@ -904,7 +1008,7 @@ void BaseQtVersion::updateMkspec() const
m_mkspec = m_mkspec.relativeChildPath(baseMkspecDir);
// qDebug() << "Setting mkspec to"<<mkspec;
} else {
- const FilePath sourceMkSpecPath = sourcePath().pathAppended("mkspecs");
+ const FilePath sourceMkSpecPath = q->sourcePath().pathAppended("mkspecs");
if (m_mkspec.isChildOf(sourceMkSpecPath)) {
m_mkspec = m_mkspec.relativeChildPath(sourceMkSpecPath);
} else {
@@ -915,9 +1019,9 @@ void BaseQtVersion::updateMkspec() const
void BaseQtVersion::ensureMkSpecParsed() const
{
- if (m_mkspecReadUpToDate)
+ if (d->m_mkspecReadUpToDate)
return;
- m_mkspecReadUpToDate = true;
+ d->m_mkspecReadUpToDate = true;
if (mkspecPath().isEmpty())
return;
@@ -939,36 +1043,41 @@ void BaseQtVersion::ensureMkSpecParsed() const
void BaseQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const
{
- m_configValues = evaluator->values("CONFIG");
- m_qtConfigValues = evaluator->values("QT_CONFIG");
- m_defaultConfigIsDebugAndRelease = false;
- m_frameworkBuild = false;
- foreach (const QString &value, m_configValues) {
+ d->m_configValues = evaluator->values("CONFIG");
+ d->m_qtConfigValues = evaluator->values("QT_CONFIG");
+ d->m_defaultConfigIsDebugAndRelease = false;
+ d->m_frameworkBuild = false;
+ for (const QString &value : qAsConst(d->m_configValues)) {
if (value == "debug")
- m_defaultConfigIsDebug = true;
+ d->m_defaultConfigIsDebug = true;
else if (value == "release")
- m_defaultConfigIsDebug = false;
+ d->m_defaultConfigIsDebug = false;
else if (value == "build_all")
- m_defaultConfigIsDebugAndRelease = true;
+ d->m_defaultConfigIsDebugAndRelease = true;
else if (value == "qt_framework")
- m_frameworkBuild = true;
+ d->m_frameworkBuild = true;
}
const QString designerBins = "QT.designer.bins";
const QString qmlBins = "QT.qml.bins";
const QString declarativeBins = "QT.declarative.bins";
const QString libinfix = MKSPEC_VALUE_LIBINFIX;
const QString ns = MKSPEC_VALUE_NAMESPACE;
- m_mkspecValues.insert(designerBins, evaluator->value(designerBins));
- m_mkspecValues.insert(qmlBins, evaluator->value(qmlBins));
- m_mkspecValues.insert(declarativeBins, evaluator->value(declarativeBins));
- m_mkspecValues.insert(libinfix, evaluator->value(libinfix));
- m_mkspecValues.insert(ns, evaluator->value(ns));
+ d->m_mkspecValues.insert(designerBins, evaluator->value(designerBins));
+ d->m_mkspecValues.insert(qmlBins, evaluator->value(qmlBins));
+ d->m_mkspecValues.insert(declarativeBins, evaluator->value(declarativeBins));
+ d->m_mkspecValues.insert(libinfix, evaluator->value(libinfix));
+ d->m_mkspecValues.insert(ns, evaluator->value(ns));
+}
+
+void BaseQtVersion::setId(int id)
+{
+ d->m_id = id;
}
QString BaseQtVersion::mkspec() const
{
- updateMkspec();
- return m_mkspec.toString();
+ d->updateMkspec();
+ return d->m_mkspec.toString();
}
QString BaseQtVersion::mkspecFor(ToolChain *tc) const
@@ -991,8 +1100,8 @@ QString BaseQtVersion::mkspecFor(ToolChain *tc) const
FilePath BaseQtVersion::mkspecPath() const
{
- updateMkspec();
- return m_mkspecFullPath;
+ d->updateMkspec();
+ return d->m_mkspecFullPath;
}
bool BaseQtVersion::hasMkspec(const QString &spec) const
@@ -1017,17 +1126,17 @@ BaseQtVersion::QmakeBuildConfigs BaseQtVersion::defaultBuildConfig() const
ensureMkSpecParsed();
BaseQtVersion::QmakeBuildConfigs result = BaseQtVersion::QmakeBuildConfig(0);
- if (m_defaultConfigIsDebugAndRelease)
+ if (d->m_defaultConfigIsDebugAndRelease)
result = BaseQtVersion::BuildAll;
- if (m_defaultConfigIsDebug)
+ if (d->m_defaultConfigIsDebug)
result = result | BaseQtVersion::DebugBuild;
return result;
}
QString BaseQtVersion::qtVersionString() const
{
- updateVersionInfo();
- return m_qtVersionString;
+ d->updateVersionInfo();
+ return d->m_qtVersionString;
}
QtVersionNumber BaseQtVersion::qtVersion() const
@@ -1035,7 +1144,7 @@ QtVersionNumber BaseQtVersion::qtVersion() const
return QtVersionNumber(qtVersionString());
}
-void BaseQtVersion::updateVersionInfo() const
+void BaseQtVersionPrivate::updateVersionInfo()
{
if (m_versionInfoUpToDate)
return;
@@ -1049,10 +1158,10 @@ void BaseQtVersion::updateVersionInfo() const
m_hasDocumentation = false;
m_hasQmlDump = false;
- if (!queryQMakeVariables(qmakeCommand(), qmakeRunEnvironment(), &m_versionInfo)) {
+ if (!queryQMakeVariables(m_qmakeCommand, q->qmakeRunEnvironment(), &m_versionInfo)) {
m_qmakeIsExecutable = false;
qWarning("Cannot update Qt version information: %s cannot be run.",
- qPrintable(qmakeCommand().toString()));
+ qPrintable(m_qmakeCommand.toString()));
return;
}
m_qmakeIsExecutable = true;
@@ -1103,18 +1212,18 @@ void BaseQtVersion::updateVersionInfo() const
m_versionInfoUpToDate = true;
}
-QHash<ProKey,ProString> BaseQtVersion::versionInfo() const
+QHash<ProKey,ProString> BaseQtVersionPrivate::versionInfo()
{
updateVersionInfo();
return m_versionInfo;
}
-QString BaseQtVersion::qmakeProperty(const QHash<ProKey,ProString> &versionInfo, const QByteArray &name,
- PropertyVariant variant)
+QString BaseQtVersionPrivate::qmakeProperty(const QHash<ProKey,ProString> &versionInfo, const QByteArray &name,
+ BaseQtVersion::PropertyVariant variant)
{
QString val = versionInfo.value(ProKey(QString::fromLatin1(
- name + (variant == PropertyVariantDev ? "/dev" :
- variant == PropertyVariantGet ? "/get" : "/src")))).toQString();
+ name + (variant == BaseQtVersion::PropertyVariantDev ? "/dev" :
+ variant == BaseQtVersion::PropertyVariantGet ? "/get" : "/src")))).toQString();
if (!val.isNull())
return val;
return versionInfo.value(ProKey(name)).toQString();
@@ -1122,19 +1231,19 @@ QString BaseQtVersion::qmakeProperty(const QHash<ProKey,ProString> &versionInfo,
QString BaseQtVersion::qmakeProperty(const QByteArray &name, PropertyVariant variant) const
{
- updateVersionInfo();
- return qmakeProperty(m_versionInfo, name, variant);
+ d->updateVersionInfo();
+ return d->qmakeProperty(d->m_versionInfo, name, variant);
}
void BaseQtVersion::applyProperties(QMakeGlobals *qmakeGlobals) const
{
- qmakeGlobals->setProperties(versionInfo());
+ qmakeGlobals->setProperties(d->versionInfo());
}
bool BaseQtVersion::hasDocumentation() const
{
- updateVersionInfo();
- return m_hasDocumentation;
+ d->updateVersionInfo();
+ return d->m_hasDocumentation;
}
QString BaseQtVersion::documentationPath() const
@@ -1144,8 +1253,8 @@ QString BaseQtVersion::documentationPath() const
bool BaseQtVersion::hasDemos() const
{
- updateVersionInfo();
- return m_hasDemos;
+ d->updateVersionInfo();
+ return d->m_hasDemos;
}
QString BaseQtVersion::demosPath() const
@@ -1162,8 +1271,8 @@ QString BaseQtVersion::frameworkInstallPath() const
bool BaseQtVersion::hasExamples() const
{
- updateVersionInfo();
- return m_hasExamples;
+ d->updateVersionInfo();
+ return d->m_hasExamples;
}
QString BaseQtVersion::examplesPath() const
@@ -1171,21 +1280,44 @@ QString BaseQtVersion::examplesPath() const
return QFileInfo(qmakeProperty("QT_INSTALL_EXAMPLES")).canonicalFilePath();
}
+QStringList BaseQtVersion::qtSoPaths() const
+{
+ static const char * const qMakeVariables[] = {
+ "QT_INSTALL_LIBS",
+ "QT_INSTALL_PLUGINS",
+ "QT_INSTALL_QML",
+ "QT_INSTALL_IMPORTS"
+ };
+
+ QSet<QString> paths;
+ for (uint i = 0; i < sizeof qMakeVariables / sizeof qMakeVariables[0]; ++i) {
+ QString path = qmakeProperty(qMakeVariables[i]);
+ if (path.isNull())
+ continue;
+ QDirIterator it(path, QStringList("*.so"), QDir::Files, QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ it.next();
+ paths.insert(it.fileInfo().absolutePath());
+ }
+ }
+ return Utils::toList(paths);
+}
+
QStringList BaseQtVersion::configValues() const
{
ensureMkSpecParsed();
- return m_configValues;
+ return d->m_configValues;
}
QStringList BaseQtVersion::qtConfigValues() const
{
ensureMkSpecParsed();
- return m_qtConfigValues;
+ return d->m_qtConfigValues;
}
MacroExpander *BaseQtVersion::macroExpander() const
{
- return m_expander.macroExpander(this);
+ return d->m_expander.macroExpander(this);
}
std::unique_ptr<MacroExpander>
@@ -1198,7 +1330,7 @@ BaseQtVersion::createMacroExpander(const std::function<const BaseQtVersion *()>
return version ? property(version) : QString();
};
};
- std::unique_ptr<Utils::MacroExpander> expander(new Utils::MacroExpander);
+ std::unique_ptr<MacroExpander> expander(new MacroExpander);
expander->setDisplayName(QtKitAspect::tr("Qt version"));
expander->registerVariable(
@@ -1226,119 +1358,119 @@ BaseQtVersion::createMacroExpander(const std::function<const BaseQtVersion *()>
"Qt:QT_INSTALL_PREFIX",
QtKitAspect::tr("The installation prefix of the current Qt version."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_PREFIX");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_PREFIX");
}));
expander->registerVariable(
"Qt:QT_INSTALL_DATA",
QtKitAspect::tr("The installation location of the current Qt version's data."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_DATA");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_DATA");
}));
expander->registerVariable(
"Qt:QT_INSTALL_HEADERS",
QtKitAspect::tr("The installation location of the current Qt version's header files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_HEADERS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_HEADERS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_LIBS",
QtKitAspect::tr("The installation location of the current Qt version's library files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_LIBS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_LIBS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_DOCS",
QtKitAspect::tr("The installation location of the current Qt version's documentation files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_DOCS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_DOCS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_BINS",
QtKitAspect::tr("The installation location of the current Qt version's executable files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_BINS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_BINS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_PLUGINS",
QtKitAspect::tr("The installation location of the current Qt version's plugins."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_PLUGINS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_PLUGINS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_QML",
QtKitAspect::tr("The installation location of the current Qt version's QML files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_QML");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_QML");
}));
expander->registerVariable(
"Qt:QT_INSTALL_IMPORTS",
QtKitAspect::tr("The installation location of the current Qt version's imports."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_IMPORTS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_IMPORTS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_TRANSLATIONS",
QtKitAspect::tr("The installation location of the current Qt version's translation files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_TRANSLATIONS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_TRANSLATIONS");
}));
expander->registerVariable(
"Qt:QT_INSTALL_CONFIGURATION",
QtKitAspect::tr("The installation location of the current Qt version's translation files."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_CONFIGURATION");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_CONFIGURATION");
}));
expander->registerVariable(
"Qt:QT_INSTALL_EXAMPLES",
QtKitAspect::tr("The installation location of the current Qt version's examples."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_EXAMPLES");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_EXAMPLES");
}));
expander->registerVariable(
"Qt:QT_INSTALL_DEMOS",
QtKitAspect::tr("The installation location of the current Qt version's demos."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QT_INSTALL_DEMOS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QT_INSTALL_DEMOS");
}));
expander->registerVariable(
"Qt:QMAKE_MKSPECS",
QtKitAspect::tr("The current Qt version's default mkspecs (Qt 4)."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QMAKE_MKSPECS");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_MKSPECS");
}));
expander->registerVariable(
"Qt:QMAKE_SPEC",
QtKitAspect::tr("The current Qt version's default mkspec (Qt 5; host system)."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QMAKE_SPEC");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_SPEC");
}));
expander->registerVariable(
"Qt:QMAKE_XSPEC",
QtKitAspect::tr("The current Qt version's default mkspec (Qt 5; target system)."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QMAKE_XSPEC");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_XSPEC");
}));
expander->registerVariable(
"Qt:QMAKE_VERSION",
QtKitAspect::tr("The current Qt's qmake version."),
versionProperty([](const BaseQtVersion *version) {
- return version->qmakeProperty(version->m_versionInfo, "QMAKE_VERSION");
+ return version->d->qmakeProperty(version->d->m_versionInfo, "QMAKE_VERSION");
}));
// FIXME: Re-enable once we can detect expansion loops.
@@ -1354,29 +1486,29 @@ BaseQtVersion::createMacroExpander(const std::function<const BaseQtVersion *()>
void BaseQtVersion::populateQmlFileFinder(FileInProjectFinder *finder, const Target *target)
{
// If target given, then use the project associated with that ...
- const ProjectExplorer::Project *startupProject = target ? target->project() : nullptr;
+ const Project *startupProject = target ? target->project() : nullptr;
// ... else try the session manager's global startup project ...
if (!startupProject)
- startupProject = ProjectExplorer::SessionManager::startupProject();
+ startupProject = SessionManager::startupProject();
// ... and if that is null, use the first project available.
- const QList<ProjectExplorer::Project *> projects = ProjectExplorer::SessionManager::projects();
+ const QList<Project *> projects = SessionManager::projects();
QTC_CHECK(projects.isEmpty() || startupProject);
- Utils::FilePath projectDirectory;
- Utils::FilePathList sourceFiles;
+ FilePath projectDirectory;
+ FilePathList sourceFiles;
// Sort files from startupProject to the front of the list ...
if (startupProject) {
projectDirectory = startupProject->projectDirectory();
- sourceFiles.append(startupProject->files(ProjectExplorer::Project::SourceFiles));
+ sourceFiles.append(startupProject->files(Project::SourceFiles));
}
// ... then add all the other projects' files.
- for (const ProjectExplorer::Project *project : projects) {
+ for (const Project *project : projects) {
if (project != startupProject)
- sourceFiles.append(project->files(ProjectExplorer::Project::SourceFiles));
+ sourceFiles.append(project->files(Project::SourceFiles));
}
// If no target was given, but we've found a startupProject, then try to deduce a
@@ -1385,22 +1517,22 @@ void BaseQtVersion::populateQmlFileFinder(FileInProjectFinder *finder, const Tar
target = startupProject->activeTarget();
// ... and find the sysroot and qml directory if we have any target at all.
- const ProjectExplorer::Kit *kit = target ? target->kit() : nullptr;
- const Utils::FilePath activeSysroot = ProjectExplorer::SysRootKitAspect::sysRoot(kit);
- const QtSupport::BaseQtVersion *qtVersion = QtVersionManager::isLoaded()
- ? QtSupport::QtKitAspect::qtVersion(kit) : nullptr;
- Utils::FilePathList additionalSearchDirectories = qtVersion
- ? Utils::FilePathList({qtVersion->qmlPath()}) : Utils::FilePathList();
+ const Kit *kit = target ? target->kit() : nullptr;
+ const FilePath activeSysroot = SysRootKitAspect::sysRoot(kit);
+ const BaseQtVersion *qtVersion = QtVersionManager::isLoaded()
+ ? QtKitAspect::qtVersion(kit) : nullptr;
+ FilePathList additionalSearchDirectories = qtVersion
+ ? FilePathList({qtVersion->qmlPath()}) : FilePathList();
if (target) {
- for (const ProjectExplorer::DeployableFile &file : target->deploymentData().allFiles())
+ for (const DeployableFile &file : target->deploymentData().allFiles())
finder->addMappedPath(file.localFilePath(), file.remoteFilePath());
}
// Add resource paths to the mapping
if (startupProject) {
- if (ProjectExplorer::ProjectNode *rootNode = startupProject->rootProjectNode()) {
- rootNode->forEachNode([&](ProjectExplorer::FileNode *node) {
+ if (ProjectNode *rootNode = startupProject->rootProjectNode()) {
+ rootNode->forEachNode([&](FileNode *node) {
if (auto resourceNode = dynamic_cast<ResourceEditor::ResourceFileNode *>(node))
finder->addMappedPath(node->filePath(), ":" + resourceNode->qrcPath());
});
@@ -1418,14 +1550,14 @@ void BaseQtVersion::populateQmlFileFinder(FileInProjectFinder *finder, const Tar
QSet<Id> BaseQtVersion::features() const
{
- if (m_overrideFeatures.isEmpty())
+ if (d->m_overrideFeatures.isEmpty())
return availableFeatures();
- return m_overrideFeatures;
+ return d->m_overrideFeatures;
}
void BaseQtVersion::addToEnvironment(const Kit *k, Environment &env) const
{
- Q_UNUSED(k);
+ Q_UNUSED(k)
env.set("QTDIR", QDir::toNativeSeparators(qmakeProperty("QT_HOST_DATA")));
}
@@ -1441,8 +1573,8 @@ Environment BaseQtVersion::qmakeRunEnvironment() const
bool BaseQtVersion::hasQmlDump() const
{
- updateVersionInfo();
- return m_hasQmlDump;
+ d->updateVersionInfo();
+ return d->m_hasQmlDump;
}
bool BaseQtVersion::hasQmlDumpWithRelocatableFlag() const
@@ -1462,15 +1594,10 @@ QString BaseQtVersion::qmlDumpTool(bool debugVersion) const
return QmlDumpTool::toolForQtPaths(qtInstallBins, debugVersion);
}
-void BaseQtVersion::recheckDumper()
-{
- m_versionInfoUpToDate = false;
-}
-
Tasks BaseQtVersion::reportIssuesImpl(const QString &proFile, const QString &buildDir) const
{
- Q_UNUSED(proFile);
- Q_UNUSED(buildDir);
+ Q_UNUSED(proFile)
+ Q_UNUSED(buildDir)
Tasks results;
if (!isValid()) {
@@ -1537,8 +1664,8 @@ static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env,
return process.readAllStandardOutput();
}
-bool BaseQtVersion::queryQMakeVariables(const FilePath &binary, const Environment &env,
- QHash<ProKey, ProString> *versionInfo, QString *error)
+bool BaseQtVersionPrivate::queryQMakeVariables(const FilePath &binary, const Environment &env,
+ QHash<ProKey, ProString> *versionInfo, QString *error)
{
QString tmp;
if (!error)
@@ -1579,15 +1706,15 @@ bool BaseQtVersion::queryQMakeVariables(const FilePath &binary, const Environmen
return true;
}
-FilePath BaseQtVersion::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo)
+FilePath BaseQtVersionPrivate::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo)
{
- QString dataDir = qmakeProperty(versionInfo, "QT_HOST_DATA", PropertyVariantSrc);
+ QString dataDir = qmakeProperty(versionInfo, "QT_HOST_DATA", BaseQtVersion::PropertyVariantSrc);
if (dataDir.isEmpty())
return FilePath();
return FilePath::fromUserInput(dataDir + "/mkspecs");
}
-FilePath BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &versionInfo)
+FilePath BaseQtVersionPrivate::mkspecFromVersionInfo(const QHash<ProKey, ProString> &versionInfo)
{
FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo);
if (baseMkspecDir.isEmpty())
@@ -1666,11 +1793,11 @@ FilePath BaseQtVersion::mkspecFromVersionInfo(const QHash<ProKey, ProString> &ve
return mkspecFullPath;
}
-FilePath BaseQtVersion::sourcePath(const QHash<ProKey, ProString> &versionInfo)
+FilePath BaseQtVersionPrivate::sourcePath(const QHash<ProKey, ProString> &versionInfo)
{
const QString qt5Source = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX/src");
if (!qt5Source.isEmpty())
- return Utils::FilePath::fromString(QFileInfo(qt5Source).canonicalFilePath());
+ return FilePath::fromString(QFileInfo(qt5Source).canonicalFilePath());
const QString installData = qmakeProperty(versionInfo, "QT_INSTALL_PREFIX");
QString sourcePath = installData;
@@ -1692,9 +1819,9 @@ FilePath BaseQtVersion::sourcePath(const QHash<ProKey, ProString> &versionInfo)
return FilePath::fromUserInput(QFileInfo(sourcePath).canonicalFilePath());
}
-bool BaseQtVersion::isInSourceDirectory(const Utils::FilePath &filePath)
+bool BaseQtVersion::isInSourceDirectory(const FilePath &filePath)
{
- const Utils::FilePath &source = sourcePath();
+ const FilePath &source = sourcePath();
if (source.isEmpty())
return false;
QDir dir = QDir(source.toString());
@@ -1703,9 +1830,9 @@ bool BaseQtVersion::isInSourceDirectory(const Utils::FilePath &filePath)
return filePath.isChildOf(dir);
}
-bool BaseQtVersion::isSubProject(const Utils::FilePath &filePath) const
+bool BaseQtVersion::isSubProject(const FilePath &filePath) const
{
- const Utils::FilePath &source = sourcePath();
+ const FilePath &source = sourcePath();
if (!source.isEmpty()) {
QDir dir = QDir(source.toString());
if (dir.dirName() == "qtbase")
@@ -1791,7 +1918,7 @@ bool BaseQtVersion::isQtQuickCompilerSupported(QString *reason) const
return true;
}
-FilePathList BaseQtVersion::qtCorePaths() const
+FilePathList BaseQtVersionPrivate::qtCorePaths()
{
updateVersionInfo();
const QString &versionString = m_qtVersionString;
@@ -1820,10 +1947,9 @@ FilePathList BaseQtVersion::qtCorePaths() const
const FilePath lib = FilePath::fromFileInfo(info);
dynamicLibs.append(lib.pathAppended(file.left(file.lastIndexOf('.'))));
} else if (info.isReadable()) {
- if (file.startsWith("libQtCore")
- || file.startsWith("libQt5Core")
- || file.startsWith("QtCore")
- || file.startsWith("Qt5Core")) {
+ if (file.startsWith("libQtCore") || file.startsWith("QtCore")
+ || file.startsWith("libQt5Core") || file.startsWith("Qt5Core")
+ || file.startsWith("libQt6Core") || file.startsWith("Qt6Core")) {
if (file.endsWith(".a") || file.endsWith(".lib"))
staticLibs.append(FilePath::fromFileInfo(info));
else if (file.endsWith(".dll")
@@ -1996,7 +2122,7 @@ static Abi refineAbiFromBuildString(const QByteArray &buildString, const Abi &pr
static Abi scanQtBinaryForBuildStringAndRefineAbi(const FilePath &library,
const Abi &probableAbi)
{
- static QHash<Utils::FilePath, Abi> results;
+ static QHash<FilePath, Abi> results;
if (!results.contains(library)) {
const QByteArray buildString = scanQtBinaryForBuildString(library);
@@ -2020,12 +2146,143 @@ Abis BaseQtVersion::qtAbisFromLibrary(const FilePathList &coreLibraries)
return res;
}
+
+// QtVersionFactory
+
+static QList<QtVersionFactory *> g_qtVersionFactories;
+
+BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath
+ (const FilePath &qmakePath, bool isAutoDetected, const QString &autoDetectionSource, QString *error)
+{
+ QHash<ProKey, ProString> versionInfo;
+ if (!BaseQtVersionPrivate::queryQMakeVariables(qmakePath, Environment::systemEnvironment(), &versionInfo, error))
+ return nullptr;
+ FilePath mkspec = BaseQtVersionPrivate::mkspecFromVersionInfo(versionInfo);
+
+ QMakeVfs vfs;
+ QMakeGlobals globals;
+ globals.setProperties(versionInfo);
+ ProMessageHandler msgHandler(false);
+ ProFileCacheManager::instance()->incRefCount();
+ QMakeParser parser(ProFileCacheManager::instance()->cache(), &vfs, &msgHandler);
+ ProFileEvaluator evaluator(&globals, &parser, &vfs, &msgHandler);
+ evaluator.loadNamedSpec(mkspec.toString(), false);
+
+ QList<QtVersionFactory *> factories = g_qtVersionFactories;
+ Utils::sort(factories, [](const QtVersionFactory *l, const QtVersionFactory *r) {
+ return l->m_priority > r->m_priority;
+ });
+
+ QFileInfo fi = qmakePath.toFileInfo();
+ if (!fi.exists() || !fi.isExecutable() || !fi.isFile())
+ return nullptr;
+
+ QtVersionFactory::SetupData setup;
+ setup.config = evaluator.values("CONFIG");
+ setup.platforms = evaluator.values("QMAKE_PLATFORM"); // It's a list in general.
+ setup.isQnx = !evaluator.value("QNX_CPUDIR").isEmpty();
+
+ foreach (QtVersionFactory *factory, factories) {
+ if (!factory->m_restrictionChecker || factory->m_restrictionChecker(setup)) {
+ BaseQtVersion *ver = factory->create();
+ QTC_ASSERT(ver, continue);
+ ver->d->setupQmakePathAndId(qmakePath);
+ ver->d->m_autodetectionSource = autoDetectionSource;
+ ver->d->m_isAutodetected = isAutoDetected;
+ ProFileCacheManager::instance()->decRefCount();
+ return ver;
+ }
+ }
+ ProFileCacheManager::instance()->decRefCount();
+ if (error) {
+ *error = QCoreApplication::translate("QtSupport::QtVersionFactory",
+ "No factory found for qmake: \"%1\"").arg(qmakePath.toUserOutput());
+ }
+ return nullptr;
+}
+
+QtVersionFactory::QtVersionFactory()
+{
+ g_qtVersionFactories.append(this);
+}
+
+QtVersionFactory::~QtVersionFactory()
+{
+ g_qtVersionFactories.removeOne(this);
+}
+
+const QList<QtVersionFactory *> QtVersionFactory::allQtVersionFactories()
+{
+ return g_qtVersionFactories;
+}
+
+bool QtVersionFactory::canRestore(const QString &type)
+{
+ return type == m_supportedType;
+}
+
+BaseQtVersion *QtVersionFactory::restore(const QString &type, const QVariantMap &data)
+{
+ QTC_ASSERT(canRestore(type), return nullptr);
+ QTC_ASSERT(m_creator, return nullptr);
+ BaseQtVersion *version = create();
+ version->fromMap(data);
+ return version;
+}
+
+BaseQtVersion *QtVersionFactory::create() const
+{
+ QTC_ASSERT(m_creator, return nullptr);
+ BaseQtVersion *version = m_creator();
+ version->d->m_type = m_supportedType;
+ return version;
+}
+
+BaseQtVersion *BaseQtVersion::clone() const
+{
+ for (QtVersionFactory *factory : g_qtVersionFactories) {
+ if (factory->m_supportedType == d->m_type) {
+ BaseQtVersion *version = factory->create();
+ QTC_ASSERT(version, return nullptr);
+ version->fromMap(toMap());
+ return version;
+ }
+ }
+ QTC_CHECK(false);
+ return nullptr;
+}
+
+void QtVersionFactory::setQtVersionCreator(const std::function<BaseQtVersion *()> &creator)
+{
+ m_creator = creator;
+}
+
+void QtVersionFactory::setRestrictionChecker(const std::function<bool(const SetupData &)> &checker)
+{
+ m_restrictionChecker = checker;
+}
+
+void QtVersionFactory::setSupportedType(const QString &type)
+{
+ m_supportedType = type;
+}
+
+void QtVersionFactory::setPriority(int priority)
+{
+ m_priority = priority;
+}
+
+} // QtSupport
+
#if defined(WITH_TESTS)
#include <QTest>
#include "qtsupportplugin.h"
+namespace QtSupport {
+namespace Internal {
+
void QtSupportPlugin::testQtBuildStringParsing_data()
{
QTest::addColumn<QByteArray>("buildString");
@@ -2072,4 +2329,7 @@ void QtSupportPlugin::testQtBuildStringParsing()
QCOMPARE(expectedList, actual);
}
+} // Internal
+} // QtSupport
+
#endif // WITH_TESTS
diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h
index 34e33b1c20..48ae12e2dc 100644
--- a/src/plugins/qtsupport/baseqtversion.h
+++ b/src/plugins/qtsupport/baseqtversion.h
@@ -37,47 +37,26 @@
#include <QStringList>
#include <QVariantMap>
+QT_BEGIN_NAMESPACE
+class ProFileEvaluator;
+class QMakeGlobals;
+QT_END_NAMESPACE
+
namespace Utils {
class Environment;
class FileInProjectFinder;
-}
-namespace Core { class Id; }
+} // Utils
namespace ProjectExplorer {
-class IOutputParser;
class Kit;
class ToolChain;
-class HeaderPath;
class Target;
-} // namespace ProjectExplorer
+} // ProjectExplorer
-QT_BEGIN_NAMESPACE
-class ProKey;
-class ProString;
-class ProFileEvaluator;
-class QMakeGlobals;
-class QSettings;
-QT_END_NAMESPACE
+namespace QtSupport {
-namespace QtSupport
-{
class QtConfigWidget;
-
class BaseQtVersion;
-class QtVersionFactory;
-
-// Wrapper to make the std::unique_ptr<Utils::MacroExpander> "copyable":
-class MacroExpanderWrapper
-{
-public:
- MacroExpanderWrapper() = default;
- MacroExpanderWrapper(const MacroExpanderWrapper &other) { Q_UNUSED(other); }
- MacroExpanderWrapper(MacroExpanderWrapper &&other) = default;
-
- Utils::MacroExpander *macroExpander(const BaseQtVersion *qtversion) const;
-private:
- mutable std::unique_ptr<Utils::MacroExpander> m_expander;
-};
class QTSUPPORT_EXPORT QtVersionNumber
{
@@ -101,13 +80,13 @@ public:
bool operator ==(const QtVersionNumber &b) const;
};
-namespace Internal { class QtOptionsPageWidget; }
+namespace Internal {
+class QtOptionsPageWidget;
+class BaseQtVersionPrivate;
+}
class QTSUPPORT_EXPORT BaseQtVersion
{
- friend class QtVersionFactory;
- friend class QtVersionManager;
- friend class QtSupport::Internal::QtOptionsPageWidget;
public:
using Predicate = std::function<bool(const BaseQtVersion *)>;
@@ -159,6 +138,7 @@ public:
QString designerCommand() const;
QString linguistCommand() const;
QString qscxmlcCommand() const;
+ QString qmlsceneCommand() const;
QString qtVersionString() const;
QtVersionNumber qtVersion() const;
@@ -166,6 +146,8 @@ public:
bool hasExamples() const;
QString examplesPath() const;
+ QStringList qtSoPaths() const;
+
bool hasDocumentation() const;
QString documentationPath() const;
@@ -196,7 +178,6 @@ public:
Q_DECLARE_FLAGS(QmakeBuildConfigs, QmakeBuildConfig)
virtual QmakeBuildConfigs defaultBuildConfig() const;
- virtual void recheckDumper();
/// Check a .pro-file/Qt version combination on possible issues
/// @return a list of tasks, ordered on severity (errors first, then
@@ -253,89 +234,33 @@ public:
const ProjectExplorer::Target *target);
QSet<Core::Id> features() const;
- void setIsAutodetected(bool isAutodetected);
-protected:
- virtual QSet<Core::Id> availableFeatures() const;
+protected:
BaseQtVersion();
BaseQtVersion(const BaseQtVersion &other) = delete;
+ virtual QSet<Core::Id> availableFeatures() const;
virtual ProjectExplorer::Tasks reportIssuesImpl(const QString &proFile, const QString &buildDir) const;
// helper function for desktop and simulator to figure out the supported abis based on the libraries
- Utils::FilePathList qtCorePaths() const;
static ProjectExplorer::Abis qtAbisFromLibrary(const Utils::FilePathList &coreLibraries);
void ensureMkSpecParsed() const;
virtual void parseMkSpec(ProFileEvaluator *) const;
private:
- void setupQmakePathAndId(const Utils::FilePath &path);
- void setAutoDetectionSource(const QString &autodetectionSource);
- void updateVersionInfo() const;
- enum HostBinaries { Designer, Linguist, Uic, QScxmlc };
- QString findHostBinary(HostBinaries binary) const;
- void updateMkspec() const;
- QHash<ProKey, ProString> versionInfo() const;
- static bool queryQMakeVariables(const Utils::FilePath &binary,
- const Utils::Environment &env,
- QHash<ProKey, ProString> *versionInfo,
- QString *error = nullptr);
- static QString qmakeProperty(const QHash<ProKey, ProString> &versionInfo,
- const QByteArray &name,
- PropertyVariant variant = PropertyVariantGet);
- static Utils::FilePath mkspecDirectoryFromVersionInfo(const QHash<ProKey,ProString> &versionInfo);
- static Utils::FilePath mkspecFromVersionInfo(const QHash<ProKey,ProString> &versionInfo);
- static Utils::FilePath sourcePath(const QHash<ProKey,ProString> &versionInfo);
- void setId(int id); // used by the qtversionmanager for legacy restore
- // and by the qtoptionspage to replace Qt versions
-
- int m_id = -1;
- const QtVersionFactory *m_factory = nullptr; // The factory that created us.
-
- bool m_isAutodetected = false;
- mutable bool m_hasQmlDump = false; // controlled by m_versionInfoUpToDate
- mutable bool m_mkspecUpToDate = false;
- mutable bool m_mkspecReadUpToDate = false;
- mutable bool m_defaultConfigIsDebug = true;
- mutable bool m_defaultConfigIsDebugAndRelease = true;
- mutable bool m_frameworkBuild = false;
- mutable bool m_versionInfoUpToDate = false;
- mutable bool m_installed = true;
- mutable bool m_hasExamples = false;
- mutable bool m_hasDemos = false;
- mutable bool m_hasDocumentation = false;
- mutable bool m_qmakeIsExecutable = true;
- mutable bool m_hasQtAbis = false;
-
- mutable QStringList m_configValues;
- mutable QStringList m_qtConfigValues;
-
- QString m_unexpandedDisplayName;
- QString m_autodetectionSource;
- QSet<Core::Id> m_overrideFeatures;
- mutable Utils::FilePath m_sourcePath;
- mutable Utils::FilePath m_qtSources;
-
- mutable Utils::FilePath m_mkspec;
- mutable Utils::FilePath m_mkspecFullPath;
-
- mutable QHash<QString, QString> m_mkspecValues;
-
- mutable QHash<ProKey, ProString> m_versionInfo;
-
- Utils::FilePath m_qmakeCommand;
- mutable QString m_qtVersionString;
- mutable QString m_uicCommand;
- mutable QString m_designerCommand;
- mutable QString m_linguistCommand;
- mutable QString m_qscxmlcCommand;
-
- mutable ProjectExplorer::Abis m_qtAbis;
-
- MacroExpanderWrapper m_expander;
+ friend class QtVersionFactory;
+ friend class QtVersionManager;
+ friend class Internal::BaseQtVersionPrivate;
+ friend class Internal::QtOptionsPageWidget;
+
+ void setId(int id);
+ BaseQtVersion *clone() const;
+
+ Internal::BaseQtVersionPrivate *d = nullptr;
};
-}
+
+} // QtSupport
Q_DECLARE_OPERATORS_FOR_FLAGS(QtSupport::BaseQtVersion::QmakeBuildConfigs)
diff --git a/src/plugins/qtsupport/codegensettingspage.cpp b/src/plugins/qtsupport/codegensettingspage.cpp
index 8f45c02a14..1181b3bb3f 100644
--- a/src/plugins/qtsupport/codegensettingspage.cpp
+++ b/src/plugins/qtsupport/codegensettingspage.cpp
@@ -38,8 +38,7 @@ namespace Internal {
// ---------- CodeGenSettingsPageWidget
-CodeGenSettingsPageWidget::CodeGenSettingsPageWidget(QWidget *parent) :
- QWidget(parent)
+CodeGenSettingsPageWidget::CodeGenSettingsPageWidget()
{
m_ui.setupUi(this);
connect(m_ui.includeQtModuleCheckBox, &QAbstractButton::toggled,
@@ -89,13 +88,17 @@ void CodeGenSettingsPageWidget::setUiEmbedding(int v)
}
// ---------- CodeGenSettingsPage
-CodeGenSettingsPage::CodeGenSettingsPage(QObject *parent) :
- Core::IOptionsPage(parent)
+CodeGenSettingsPage::CodeGenSettingsPage()
{
m_parameters.fromSettings(Core::ICore::settings());
setId(Constants::CODEGEN_SETTINGS_PAGE_ID);
setDisplayName(QCoreApplication::translate("QtSupport", "Qt Class Generation"));
setCategory(CppTools::Constants::CPP_SETTINGS_CATEGORY);
+ setDisplayCategory(
+ QCoreApplication::translate("CppTools", CppTools::Constants::CPP_SETTINGS_NAME));
+ setCategoryIcon(Utils::Icon({{":/projectexplorer/images/settingscategory_cpp.png",
+ Utils::Theme::PanelTextColorDark}},
+ Utils::Icon::Tint));
}
QWidget *CodeGenSettingsPage::widget()
diff --git a/src/plugins/qtsupport/codegensettingspage.h b/src/plugins/qtsupport/codegensettingspage.h
index b6987824c8..68aee7db29 100644
--- a/src/plugins/qtsupport/codegensettingspage.h
+++ b/src/plugins/qtsupport/codegensettingspage.h
@@ -40,7 +40,7 @@ class CodeGenSettingsPageWidget : public QWidget
{
Q_OBJECT
public:
- explicit CodeGenSettingsPageWidget(QWidget *parent = nullptr);
+ CodeGenSettingsPageWidget();
CodeGenSettings parameters() const;
void setParameters(const CodeGenSettings &p);
@@ -55,7 +55,7 @@ private:
class CodeGenSettingsPage : public Core::IOptionsPage
{
public:
- explicit CodeGenSettingsPage(QObject *parent = nullptr);
+ CodeGenSettingsPage();
QWidget *widget() override;
void apply() override;
diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
index 0b34c9b809..9a9fdfe213 100644
--- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
+++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp
@@ -30,6 +30,7 @@
#include <utils/fileutils.h>
#include <utils/pathchooser.h>
+#include <utils/theme/theme.h>
#include <utils/winutils.h>
#include <coreplugin/coreconstants.h>
diff --git a/src/plugins/qtsupport/qscxmlcgenerator.cpp b/src/plugins/qtsupport/qscxmlcgenerator.cpp
index 415a6ea701..30694071bc 100644
--- a/src/plugins/qtsupport/qscxmlcgenerator.cpp
+++ b/src/plugins/qtsupport/qscxmlcgenerator.cpp
@@ -114,7 +114,7 @@ bool QScxmlcGenerator::prepareToRun(const QByteArray &sourceContents)
FileNameToContentsHash QScxmlcGenerator::handleProcessFinished(QProcess *process)
{
- Q_UNUSED(process);
+ Q_UNUSED(process)
const Utils::FilePath wd = workingDirectory();
FileNameToContentsHash result;
forEachTarget([&](const Utils::FilePath &target) {
diff --git a/src/plugins/qtsupport/qscxmlcgenerator.h b/src/plugins/qtsupport/qscxmlcgenerator.h
index 37c7617ed6..ea99d3d23d 100644
--- a/src/plugins/qtsupport/qscxmlcgenerator.h
+++ b/src/plugins/qtsupport/qscxmlcgenerator.h
@@ -38,7 +38,7 @@ class QScxmlcGenerator : public ProjectExplorer::ProcessExtraCompiler
Q_OBJECT
public:
QScxmlcGenerator(const ProjectExplorer::Project *project, const Utils::FilePath &source,
- const Utils::FilePathList &targets, QObject *parent = 0);
+ const Utils::FilePathList &targets, QObject *parent = nullptr);
protected:
Utils::FilePath command() const override;
@@ -60,7 +60,7 @@ class QScxmlcGeneratorFactory : public ProjectExplorer::ExtraCompilerFactory
{
Q_OBJECT
public:
- QScxmlcGeneratorFactory(QObject *parent = 0) : ExtraCompilerFactory(parent) {}
+ QScxmlcGeneratorFactory() = default;
ProjectExplorer::FileType sourceType() const override;
diff --git a/src/plugins/qtsupport/qtcppkitinfo.cpp b/src/plugins/qtsupport/qtcppkitinfo.cpp
index 07e404cce4..17a201dfc2 100644
--- a/src/plugins/qtsupport/qtcppkitinfo.cpp
+++ b/src/plugins/qtsupport/qtcppkitinfo.cpp
@@ -30,16 +30,14 @@
namespace QtSupport {
-using namespace CppTools;
-
CppKitInfo::CppKitInfo(ProjectExplorer::Project *project)
- : KitInfo(project)
+ : ProjectExplorer::KitInfo(project)
{
if (kit && (qtVersion = QtKitAspect::qtVersion(kit))) {
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5, 0, 0))
- projectPartQtVersion = ProjectPart::Qt4;
+ projectPartQtVersion = Utils::QtVersion::Qt4;
else
- projectPartQtVersion = ProjectPart::Qt5;
+ projectPartQtVersion = Utils::QtVersion::Qt5;
}
}
diff --git a/src/plugins/qtsupport/qtcppkitinfo.h b/src/plugins/qtsupport/qtcppkitinfo.h
index d20853a034..fe5d90e317 100644
--- a/src/plugins/qtsupport/qtcppkitinfo.h
+++ b/src/plugins/qtsupport/qtcppkitinfo.h
@@ -27,13 +27,13 @@
#include "qtsupport_global.h"
-#include <cpptools/cppkitinfo.h>
+#include <projectexplorer/rawprojectpart.h>
namespace QtSupport {
class BaseQtVersion;
-class QTSUPPORT_EXPORT CppKitInfo : public CppTools::KitInfo
+class QTSUPPORT_EXPORT CppKitInfo : public ProjectExplorer::KitInfo
{
public:
CppKitInfo(ProjectExplorer::Project *project);
diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp
index 3319aa732a..7d8ada6480 100644
--- a/src/plugins/qtsupport/qtkitinformation.cpp
+++ b/src/plugins/qtsupport/qtkitinformation.cpp
@@ -331,8 +331,8 @@ void QtKitAspect::qtVersionsChanged(const QList<int> &addedIds,
const QList<int> &removedIds,
const QList<int> &changedIds)
{
- Q_UNUSED(addedIds);
- Q_UNUSED(removedIds);
+ Q_UNUSED(addedIds)
+ Q_UNUSED(removedIds)
foreach (ProjectExplorer::Kit *k, ProjectExplorer::KitManager::kits()) {
if (changedIds.contains(qtVersionId(k))) {
k->validate(); // Qt version may have become (in)valid
diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp
index c2269ebe07..51e7a29679 100644
--- a/src/plugins/qtsupport/qtoptionspage.cpp
+++ b/src/plugins/qtsupport/qtoptionspage.cpp
@@ -142,7 +142,7 @@ public:
}
private:
- BaseQtVersion *m_version = 0;
+ BaseQtVersion *m_version = nullptr;
QIcon m_icon;
QString m_buildLog;
bool m_changed = false;
@@ -153,7 +153,7 @@ private:
///
QtOptionsPage::QtOptionsPage()
- : m_widget(0)
+ : m_widget(nullptr)
{
setId(Constants::QTVERSION_SETTINGS_PAGE_ID);
setDisplayName(QCoreApplication::translate("QtSupport", "Qt Versions"));
@@ -190,7 +190,7 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent)
, m_infoBrowser(new QTextBrowser)
, m_invalidVersionIcon(Utils::Icons::CRITICAL.icon())
, m_warningVersionIcon(Utils::Icons::WARNING.icon())
- , m_configurationWidget(0)
+ , m_configurationWidget(nullptr)
{
QWidget *versionInfoWidget = new QWidget();
m_versionUi->setupUi(versionInfoWidget);
@@ -277,7 +277,7 @@ BaseQtVersion *QtOptionsPageWidget::currentVersion() const
{
QtVersionItem *item = currentItem();
if (!item)
- return 0;
+ return nullptr;
return item->version();
}
@@ -307,7 +307,7 @@ void QtOptionsPageWidget::cleanUpQtVersions()
return;
- if (QMessageBox::warning(0, tr("Remove Invalid Qt Versions"),
+ if (QMessageBox::warning(nullptr, tr("Remove Invalid Qt Versions"),
tr("Do you want to remove all invalid Qt Versions?<br>"
"<ul><li>%1</li></ul><br>"
"will be removed.").arg(text),
@@ -468,7 +468,7 @@ void QtOptionsPageWidget::updateVersionItem(QtVersionItem *item)
// Non-modal dialog
class BuildLogDialog : public QDialog {
public:
- explicit BuildLogDialog(QWidget *parent = 0);
+ explicit BuildLogDialog(QWidget *parent = nullptr);
void setText(const QString &text);
private:
@@ -522,7 +522,7 @@ void QtOptionsPageWidget::updateQtVersions(const QList<int> &additions, const QL
// Add changed/added items:
foreach (int a, toAdd) {
- BaseQtVersion *version = QtVersionFactory::cloneQtVersion(QtVersionManager::version(a));
+ BaseQtVersion *version = QtVersionManager::version(a)->clone();
auto *item = new QtVersionItem(version);
// Insert in the right place:
@@ -674,7 +674,7 @@ void QtOptionsPageWidget::userChangedCurrentVersion()
void QtOptionsPageWidget::updateDescriptionLabel()
{
QtVersionItem *item = currentItem();
- const BaseQtVersion *version = item ? item->version() : 0;
+ const BaseQtVersion *version = item ? item->version() : nullptr;
const ValidityInfo info = validInformation(version);
if (info.message.isEmpty()) {
m_versionUi->errorLabel->setVisible(false);
@@ -699,15 +699,15 @@ void QtOptionsPageWidget::updateDescriptionLabel()
void QtOptionsPageWidget::versionChanged(const QModelIndex &current, const QModelIndex &previous)
{
- Q_UNUSED(current);
- Q_UNUSED(previous);
+ Q_UNUSED(current)
+ Q_UNUSED(previous)
userChangedCurrentVersion();
}
void QtOptionsPageWidget::updateWidgets()
{
delete m_configurationWidget;
- m_configurationWidget = 0;
+ m_configurationWidget = nullptr;
BaseQtVersion *version = currentVersion();
if (version) {
m_versionUi->nameEdit->setText(version->unexpandedDisplayName());
@@ -724,7 +724,7 @@ void QtOptionsPageWidget::updateWidgets()
m_versionUi->qmakePath->clear();
}
- const bool enabled = version != 0;
+ const bool enabled = version != nullptr;
const bool isAutodetected = enabled && version->isAutodetected();
m_ui->delButton->setEnabled(enabled && !isAutodetected);
m_versionUi->nameEdit->setEnabled(enabled);
@@ -753,7 +753,7 @@ void QtOptionsPageWidget::apply()
m_model->forItemsAtLevel<2>([&versions](QtVersionItem *item) {
item->setChanged(false);
- versions.append(QtVersionFactory::cloneQtVersion(item->version()));
+ versions.append(item->version()->clone());
});
QtVersionManager::setNewQtVersions(versions);
diff --git a/src/plugins/qtsupport/qtoptionspage.h b/src/plugins/qtsupport/qtoptionspage.h
index 04af543355..ece24c4b51 100644
--- a/src/plugins/qtsupport/qtoptionspage.h
+++ b/src/plugins/qtsupport/qtoptionspage.h
@@ -60,7 +60,7 @@ class QtOptionsPageWidget : public QWidget
Q_OBJECT
public:
- QtOptionsPageWidget(QWidget *parent = 0);
+ QtOptionsPageWidget(QWidget *parent = nullptr);
~QtOptionsPageWidget();
void apply();
diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp
index 4c9090c2d8..689ac367cd 100644
--- a/src/plugins/qtsupport/qtoutputformatter.cpp
+++ b/src/plugins/qtsupport/qtoutputformatter.cpp
@@ -25,13 +25,18 @@
#include "qtoutputformatter.h"
+#include "qtkitinformation.h"
+#include "qtsupportconstants.h"
+
#include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
#include <utils/algorithm.h>
#include <utils/ansiescapecodehandler.h>
#include <utils/fileinprojectfinder.h>
#include <utils/hostosinfo.h>
+#include <utils/outputformatter.h>
#include <utils/theme/theme.h>
#include <QPlainTextEdit>
@@ -44,13 +49,19 @@ using namespace ProjectExplorer;
using namespace Utils;
namespace QtSupport {
-
namespace Internal {
+struct LinkResult
+{
+ int start = -1;
+ int end = -1;
+ QString href;
+};
+
class QtOutputFormatterPrivate
{
public:
- QtOutputFormatterPrivate(Project *proj)
+ QtOutputFormatterPrivate()
: qmlError("(" QT_QML_URL_REGEXP // url
":\\d+" // colon, line
"(?::\\d+)?)" // colon, column (optional)
@@ -60,11 +71,6 @@ public:
, qtAssertX(QT_ASSERT_X_REGEXP)
, qtTestFailUnix(QT_TEST_FAIL_UNIX_REGEXP)
, qtTestFailWin(QT_TEST_FAIL_WIN_REGEXP)
- , project(proj)
- {
- }
-
- ~QtOutputFormatterPrivate()
{
}
@@ -80,17 +86,45 @@ public:
QTextCursor cursor;
};
-} // namespace Internal
+class QtOutputFormatter : public OutputFormatter
+{
+public:
+ explicit QtOutputFormatter(Target *target);
+ ~QtOutputFormatter() override;
+
+ void appendMessage(const QString &text, Utils::OutputFormat format) override;
+ void handleLink(const QString &href) override;
+ void setPlainTextEdit(QPlainTextEdit *plainText) override;
+
+protected:
+ void clearLastLine() override;
+ virtual void openEditor(const QString &fileName, int line, int column = -1);
+
+private:
+ void updateProjectFileList();
+ LinkResult matchLine(const QString &line) const;
+ void appendMessagePart(const QString &txt, const QTextCharFormat &fmt);
+ void appendLine(const LinkResult &lr, const QString &line, Utils::OutputFormat format);
+ void appendLine(const LinkResult &lr, const QString &line, const QTextCharFormat &format);
+ void appendMessage(const QString &text, const QTextCharFormat &format) override;
+
+ QtOutputFormatterPrivate *d;
+ friend class QtSupportPlugin; // for testing
+};
-QtOutputFormatter::QtOutputFormatter(Project *project)
- : d(new Internal::QtOutputFormatterPrivate(project))
+QtOutputFormatter::QtOutputFormatter(Target *target)
+ : d(new QtOutputFormatterPrivate)
{
- if (project) {
- d->projectFinder.setProjectFiles(project->files(Project::SourceFiles));
- d->projectFinder.setProjectDirectory(project->projectDirectory());
+ d->project = target ? target->project() : nullptr;
+ if (d->project) {
+ d->projectFinder.setProjectFiles(d->project->files(Project::SourceFiles));
+ d->projectFinder.setProjectDirectory(d->project->projectDirectory());
- connect(project, &Project::fileListChanged,
- this, &QtOutputFormatter::updateProjectFileList);
+ connect(d->project,
+ &Project::fileListChanged,
+ this,
+ &QtOutputFormatter::updateProjectFileList,
+ Qt::QueuedConnection);
}
}
@@ -305,6 +339,17 @@ void QtOutputFormatter::updateProjectFileList()
d->projectFinder.setProjectFiles(d->project->files(Project::SourceFiles));
}
+// QtOutputFormatterFactory
+
+QtOutputFormatterFactory::QtOutputFormatterFactory()
+{
+ setFormatterCreator([](Target *t) -> OutputFormatter * {
+ BaseQtVersion *qt = QtKitAspect::qtVersion(t->kit());
+ return qt ? new QtOutputFormatter(t) : nullptr;
+ });
+}
+
+} // namespace Internal
} // namespace QtSupport
// Unit tests:
diff --git a/src/plugins/qtsupport/qtoutputformatter.h b/src/plugins/qtsupport/qtoutputformatter.h
index 1d5a886b19..c2b92098c2 100644
--- a/src/plugins/qtsupport/qtoutputformatter.h
+++ b/src/plugins/qtsupport/qtoutputformatter.h
@@ -25,9 +25,7 @@
#pragma once
-#include "qtsupport_global.h"
-
-#include <utils/outputformatter.h>
+#include <projectexplorer/runcontrol.h>
// "file" or "qrc", colon, optional '//', '/' and further characters
#define QT_QML_URL_REGEXP "(?:file|qrc):(?://)?/.+?"
@@ -36,50 +34,14 @@
#define QT_TEST_FAIL_UNIX_REGEXP "^ Loc: \\[((?<file>.+)(?|\\((?<line>\\d+)\\)|:(?<line>\\d+)))\\]$"
#define QT_TEST_FAIL_WIN_REGEXP "^((?<file>.+)\\((?<line>\\d+)\\)) : failure location\\s*$"
-namespace ProjectExplorer { class Project; }
-
namespace QtSupport {
-
-struct LinkResult
-{
- int start = -1;
- int end = -1;
- QString href;
-};
-
namespace Internal {
-class QtOutputFormatterPrivate;
-class QtSupportPlugin;
-}
-class QTSUPPORT_EXPORT QtOutputFormatter : public Utils::OutputFormatter
+class QtOutputFormatterFactory : public ProjectExplorer::OutputFormatterFactory
{
- Q_OBJECT
public:
- explicit QtOutputFormatter(ProjectExplorer::Project *project);
- ~QtOutputFormatter() override;
-
- void appendMessage(const QString &text, Utils::OutputFormat format) override;
- void handleLink(const QString &href) override;
- void setPlainTextEdit(QPlainTextEdit *plainText) override;
-
-protected:
- void clearLastLine() override;
- virtual void openEditor(const QString &fileName, int line, int column = -1);
-
-private:
- void updateProjectFileList();
- LinkResult matchLine(const QString &line) const;
- void appendMessagePart(const QString &txt, const QTextCharFormat &fmt);
- void appendLine(const LinkResult &lr, const QString &line, Utils::OutputFormat format);
- void appendLine(const LinkResult &lr, const QString &line, const QTextCharFormat &format);
- void appendMessage(const QString &text, const QTextCharFormat &format) override;
-
- Internal::QtOutputFormatterPrivate *d;
-
- // for testing
- friend class Internal::QtSupportPlugin;
+ QtOutputFormatterFactory();
};
-
+} // namespace Internal
} // namespace QtSupport
diff --git a/src/plugins/qtsupport/qtprojectimporter.cpp b/src/plugins/qtsupport/qtprojectimporter.cpp
index 0e4124f7d9..1ba4de7321 100644
--- a/src/plugins/qtsupport/qtprojectimporter.cpp
+++ b/src/plugins/qtsupport/qtprojectimporter.cpp
@@ -129,7 +129,7 @@ void QtProjectImporter::persistTemporaryQt(Kit *k, const QVariantList &vl)
} // namespace QtSupport
#include "qtsupportplugin.h"
-#include "desktopqtversion.h"
+#include "qtversions.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/buildinfo.h>
@@ -243,7 +243,7 @@ Kit *TestQtProjectImporter::createKit(void *directoryData) const
const QList<BuildInfo> TestQtProjectImporter::buildInfoListForKit(const Kit *k, void *directoryData) const
{
- Q_UNUSED(directoryData);
+ Q_UNUSED(directoryData)
assert(m_testData.contains(directoryData));
assert(!m_deletedTestData.contains(directoryData));
assert(static_cast<const DirectoryData *>(directoryData)->importPath == m_path);
diff --git a/src/plugins/qtsupport/qtsupport.pro b/src/plugins/qtsupport/qtsupport.pro
index 4c5900027f..eb0c78c880 100644
--- a/src/plugins/qtsupport/qtsupport.pro
+++ b/src/plugins/qtsupport/qtsupport.pro
@@ -29,9 +29,10 @@ HEADERS += \
exampleslistmodel.h \
screenshotcropper.h \
qtconfigwidget.h \
- desktopqtversion.h \
+ qtversions.h \
uicgenerator.h \
- qscxmlcgenerator.h
+ qscxmlcgenerator.h \
+ translationwizardpage.h
SOURCES += \
codegenerator.cpp \
@@ -45,7 +46,6 @@ SOURCES += \
qtoutputformatter.cpp \
qttestparser.cpp \
qtversionmanager.cpp \
- qtversionfactory.cpp \
baseqtversion.cpp \
qmldumptool.cpp \
qtoptionspage.cpp \
@@ -54,9 +54,10 @@ SOURCES += \
exampleslistmodel.cpp \
screenshotcropper.cpp \
qtconfigwidget.cpp \
- desktopqtversion.cpp \
+ qtversions.cpp \
uicgenerator.cpp \
- qscxmlcgenerator.cpp
+ qscxmlcgenerator.cpp \
+ translationwizardpage.cpp
FORMS += \
codegensettingspagewidget.ui \
diff --git a/src/plugins/qtsupport/qtsupport.qbs b/src/plugins/qtsupport/qtsupport.qbs
index 7e2aa71e32..40ff98448c 100644
--- a/src/plugins/qtsupport/qtsupport.qbs
+++ b/src/plugins/qtsupport/qtsupport.qbs
@@ -13,7 +13,6 @@ Project {
Depends { name: "ProParser" }
Depends { name: "ProjectExplorer" }
Depends { name: "ResourceEditor" }
- Depends { name: "CppTools" }
cpp.defines: base.concat([
"QMAKE_LIBRARY",
@@ -96,7 +95,6 @@ Project {
"qtsupportplugin.h",
"qttestparser.cpp",
"qttestparser.h",
- "qtversionfactory.cpp",
"qtversionfactory.h",
"qtversioninfo.ui",
"qtversionmanager.cpp",
@@ -105,6 +103,8 @@ Project {
"screenshotcropper.cpp",
"screenshotcropper.h",
"showbuildlog.ui",
+ "translationwizardpage.cpp",
+ "translationwizardpage.h",
"uicgenerator.cpp",
"uicgenerator.h",
]
@@ -112,8 +112,8 @@ Project {
Group {
name: "QtVersion"
files: [
- "desktopqtversion.cpp",
- "desktopqtversion.h",
+ "qtversions.cpp",
+ "qtversions.h",
]
}
diff --git a/src/plugins/qtsupport/qtsupport_dependencies.pri b/src/plugins/qtsupport/qtsupport_dependencies.pri
index e5e83db8f9..c4bb6143cc 100644
--- a/src/plugins/qtsupport/qtsupport_dependencies.pri
+++ b/src/plugins/qtsupport/qtsupport_dependencies.pri
@@ -4,7 +4,6 @@ QTC_LIB_DEPENDS += \
utils
QTC_PLUGIN_DEPENDS += \
coreplugin \
- cpptools \
projectexplorer \
resourceeditor
DEFINES *= \
diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp
index 5faa9f7a1a..9b6038f5eb 100644
--- a/src/plugins/qtsupport/qtsupportplugin.cpp
+++ b/src/plugins/qtsupport/qtsupportplugin.cpp
@@ -27,24 +27,25 @@
#include "codegenerator.h"
#include "codegensettingspage.h"
-#include "desktopqtversion.h"
#include "gettingstartedwelcomepage.h"
+#include "profilereader.h"
+#include "qscxmlcgenerator.h"
#include "qtkitinformation.h"
#include "qtoptionspage.h"
+#include "qtoutputformatter.h"
#include "qtsupportconstants.h"
-#include "qtversionfactory.h"
#include "qtversionmanager.h"
+#include "qtversions.h"
+#include "translationwizardpage.h"
#include "uicgenerator.h"
-#include "qscxmlcgenerator.h"
-
-#include "desktopqtversion.h"
-#include "profilereader.h"
#include <coreplugin/icore.h>
#include <coreplugin/jsexpander.h>
+#include <projectexplorer/jsonwizard/jsonwizardfactory.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
+#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>
#include <utils/macroexpander.h>
@@ -53,6 +54,7 @@ const char kHostBins[] = "CurrentProject:QT_HOST_BINS";
const char kInstallBins[] = "CurrentProject:QT_INSTALL_BINS";
using namespace Core;
+using namespace ProjectExplorer;
namespace QtSupport {
namespace Internal {
@@ -61,7 +63,9 @@ class QtSupportPluginPrivate
{
public:
QtVersionManager qtVersionManager;
+
DesktopQtVersionFactory desktopQtVersionFactory;
+ EmbeddedLinuxQtVersionFactory embeddedLinuxQtVersionFactory;
CodeGenSettingsPage codeGenSettingsPage;
QtOptionsPage qtOptionsPage;
@@ -70,6 +74,11 @@ public:
ExamplesWelcomePage tutorialPage{false};
QtKitAspect qtKiAspect;
+
+ QtOutputFormatterFactory qtOutputFormatterFactory;
+
+ UicGeneratorFactory uicGeneratorFactory;
+ QScxmlcGeneratorFactory qscxmlcGeneratorFactory;
};
QtSupportPlugin::~QtSupportPlugin()
@@ -79,19 +88,17 @@ QtSupportPlugin::~QtSupportPlugin()
bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorMessage);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorMessage)
QMakeParser::initialize();
ProFileEvaluator::initialize();
new ProFileCacheManager(this);
JsExpander::registerGlobalObject<CodeGenerator>("QtSupport");
+ ProjectExplorer::JsonWizardFactory::registerPageFactory(new TranslationWizardPageFactory);
d = new QtSupportPluginPrivate;
- (void) new UicGeneratorFactory(this);
- (void) new QScxmlcGeneratorFactory(this);
-
QtVersionManager::initialized();
return true;
diff --git a/src/plugins/qtsupport/qtversionfactory.cpp b/src/plugins/qtsupport/qtversionfactory.cpp
deleted file mode 100644
index 4560667d8f..0000000000
--- a/src/plugins/qtsupport/qtversionfactory.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qtversionfactory.h"
-#include "profilereader.h"
-#include "baseqtversion.h"
-
-#include <proparser/qmakevfs.h>
-
-#include <extensionsystem/pluginmanager.h>
-
-#include <utils/algorithm.h>
-#include <utils/environment.h>
-#include <utils/qtcassert.h>
-
-#include <QFileInfo>
-
-using namespace QtSupport;
-using namespace QtSupport::Internal;
-
-static QList<QtVersionFactory *> g_qtVersionFactories;
-
-QtVersionFactory::QtVersionFactory()
-{
- g_qtVersionFactories.append(this);
-}
-
-QtVersionFactory::~QtVersionFactory()
-{
- g_qtVersionFactories.removeOne(this);
-}
-
-const QList<QtVersionFactory *> QtVersionFactory::allQtVersionFactories()
-{
- return g_qtVersionFactories;
-}
-
-bool QtVersionFactory::canRestore(const QString &type)
-{
- return type == m_supportedType;
-}
-
-BaseQtVersion *QtVersionFactory::restore(const QString &type, const QVariantMap &data)
-{
- QTC_ASSERT(canRestore(type), return nullptr);
- QTC_ASSERT(m_creator, return nullptr);
- BaseQtVersion *version = create();
- version->fromMap(data);
- return version;
-}
-
-BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath(const Utils::FilePath &qmakePath, bool isAutoDetected, const QString &autoDetectionSource, QString *error)
-{
- QHash<ProKey, ProString> versionInfo;
- if (!BaseQtVersion::queryQMakeVariables(qmakePath, Utils::Environment::systemEnvironment(),
- &versionInfo, error))
- return 0;
- Utils::FilePath mkspec = BaseQtVersion::mkspecFromVersionInfo(versionInfo);
-
- QMakeVfs vfs;
- QMakeGlobals globals;
- globals.setProperties(versionInfo);
- ProMessageHandler msgHandler(false);
- ProFileCacheManager::instance()->incRefCount();
- QMakeParser parser(ProFileCacheManager::instance()->cache(), &vfs, &msgHandler);
- ProFileEvaluator evaluator(&globals, &parser, &vfs, &msgHandler);
- evaluator.loadNamedSpec(mkspec.toString(), false);
-
- QList<QtVersionFactory *> factories = g_qtVersionFactories;
- Utils::sort(factories, [](const QtVersionFactory *l, const QtVersionFactory *r) {
- return l->priority() > r->priority();
- });
-
- QFileInfo fi = qmakePath.toFileInfo();
- if (!fi.exists() || !fi.isExecutable() || !fi.isFile())
- return nullptr;
-
- SetupData setup;
- setup.config = evaluator.values("CONFIG");
- setup.platforms = evaluator.values("QMAKE_PLATFORM"); // It's a list in general.
- setup.isQnx = !evaluator.value("QNX_CPUDIR").isEmpty();
-
- foreach (QtVersionFactory *factory, factories) {
- if (!factory->m_restrictionChecker || factory->m_restrictionChecker(setup)) {
- BaseQtVersion *ver = factory->create();
- QTC_ASSERT(ver, continue);
- ver->setupQmakePathAndId(qmakePath);
- ver->setAutoDetectionSource(autoDetectionSource);
- ver->setIsAutodetected(isAutoDetected);
- ProFileCacheManager::instance()->decRefCount();
- return ver;
- }
- }
- ProFileCacheManager::instance()->decRefCount();
- if (error) {
- *error = QCoreApplication::translate("QtSupport::QtVersionFactory",
- "No factory found for qmake: \"%1\"").arg(qmakePath.toUserOutput());
- }
- return 0;
-}
-
-BaseQtVersion *QtVersionFactory::create() const
-{
- QTC_ASSERT(m_creator, return nullptr);
- BaseQtVersion *version = m_creator();
- version->m_factory = this;
- return version;
-}
-
-QString QtVersionFactory::supportedType() const
-{
- return m_supportedType;
-}
-
-BaseQtVersion *QtVersionFactory::cloneQtVersion(const BaseQtVersion *source)
-{
- QTC_ASSERT(source, return nullptr);
- const QString sourceType = source->type();
- for (QtVersionFactory *factory : g_qtVersionFactories) {
- if (factory->m_supportedType == sourceType) {
- BaseQtVersion *version = factory->create();
- QTC_ASSERT(version, return nullptr);
- version->fromMap(source->toMap());
- return version;
- }
- }
- QTC_CHECK(false);
- return nullptr;
-}
-
-void QtVersionFactory::setQtVersionCreator(const std::function<BaseQtVersion *()> &creator)
-{
- m_creator = creator;
-}
-
-void QtVersionFactory::setRestrictionChecker(const std::function<bool(const SetupData &)> &checker)
-{
- m_restrictionChecker = checker;
-}
-
-void QtVersionFactory::setSupportedType(const QString &type)
-{
- m_supportedType = type;
-}
-
-void QtVersionFactory::setPriority(int priority)
-{
- m_priority = priority;
-}
diff --git a/src/plugins/qtsupport/qtversionfactory.h b/src/plugins/qtsupport/qtversionfactory.h
index 4bafe40c14..9f055ea1cc 100644
--- a/src/plugins/qtsupport/qtversionfactory.h
+++ b/src/plugins/qtsupport/qtversionfactory.h
@@ -51,14 +51,10 @@ public:
/// the desktop factory claims to handle all paths
int priority() const { return m_priority; }
- QString supportedType() const;
-
static BaseQtVersion *createQtVersionFromQMakePath(
const Utils::FilePath &qmakePath, bool isAutoDetected = false,
const QString &autoDetectionSource = QString(), QString *error = nullptr);
- static BaseQtVersion *cloneQtVersion(const BaseQtVersion *source);
-
protected:
struct SetupData
{
@@ -73,6 +69,7 @@ protected:
void setPriority(int priority);
private:
+ friend class BaseQtVersion;
BaseQtVersion *create() const;
std::function<BaseQtVersion *()> m_creator;
diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp
index 7256d33915..f8ab8f50d3 100644
--- a/src/plugins/qtsupport/qtversionmanager.cpp
+++ b/src/plugins/qtsupport/qtversionmanager.cpp
@@ -503,12 +503,6 @@ QList<BaseQtVersion *> QtVersionManager::sortVersions(const QList<BaseQtVersion
return result;
}
-bool QtVersionManager::isValidId(int id)
-{
- QTC_ASSERT(isLoaded(), return false);
- return m_versions.contains(id);
-}
-
BaseQtVersion *QtVersionManager::version(int id)
{
QTC_ASSERT(isLoaded(), return nullptr);
@@ -591,9 +585,4 @@ void QtVersionManager::setNewQtVersions(QList<BaseQtVersion *> newVersions)
emit m_instance->qtVersionsChanged(addedVersions, removedVersions, changedVersions);
}
-BaseQtVersion *QtVersionManager::qtVersionForQMakeBinary(const FilePath &qmakePath)
-{
- return version(Utils::equal(&BaseQtVersion::qmakeCommand, qmakePath));
-}
-
} // namespace QtVersion
diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h
index 4a9d077752..65695bfff0 100644
--- a/src/plugins/qtsupport/qtversionmanager.h
+++ b/src/plugins/qtsupport/qtversionmanager.h
@@ -35,6 +35,7 @@ class QTSUPPORT_EXPORT QtVersionManager : public QObject
Q_OBJECT
// for getUniqueId();
friend class BaseQtVersion;
+ friend class Internal::BaseQtVersionPrivate;
friend class Internal::QtOptionsPageWidget;
public:
static QtVersionManager *instance();
@@ -58,13 +59,9 @@ public:
// Sorting is potentially expensive since it might require qmake --query to run for each version!
static QList<BaseQtVersion *> sortVersions(const QList<BaseQtVersion *> &input);
- static BaseQtVersion *qtVersionForQMakeBinary(const Utils::FilePath &qmakePath);
-
static void addVersion(BaseQtVersion *version);
static void removeVersion(BaseQtVersion *version);
- static bool isValidId(int id);
-
signals:
// content of BaseQtVersion objects with qmake path might have changed
void qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, const QList<int> &changedIds);
diff --git a/src/plugins/qtsupport/desktopqtversion.cpp b/src/plugins/qtsupport/qtversions.cpp
index c3d23cb5bf..450f1dd848 100644
--- a/src/plugins/qtsupport/desktopqtversion.cpp
+++ b/src/plugins/qtsupport/qtversions.cpp
@@ -23,12 +23,16 @@
**
****************************************************************************/
-#include "desktopqtversion.h"
+#include "qtversions.h"
+
+#include "baseqtversion.h"
#include "qtsupportconstants.h"
#include <projectexplorer/abi.h>
#include <projectexplorer/projectexplorerconstants.h>
+
#include <remotelinux/remotelinux_constants.h>
+
#include <coreplugin/featureprovider.h>
#include <utils/algorithm.h>
@@ -39,12 +43,20 @@
#include <QFileInfo>
namespace QtSupport {
+namespace Internal {
-DesktopQtVersion::DesktopQtVersion()
- : BaseQtVersion()
+class DesktopQtVersion : public BaseQtVersion
{
+public:
+ DesktopQtVersion() = default;
-}
+ QStringList warningReason() const override;
+
+ QString description() const override;
+
+ QSet<Core::Id> availableFeatures() const override;
+ QSet<Core::Id> targetDeviceTypes() const override;
+};
QStringList DesktopQtVersion::warningReason() const
{
@@ -77,41 +89,53 @@ QSet<Core::Id> DesktopQtVersion::targetDeviceTypes() const
return result;
}
-void DesktopQtVersion::fromMap(const QVariantMap &map)
-{
- BaseQtVersion::fromMap(map);
- // Clear the cached qmlscene command, it might not match the restored path anymore.
- m_qmlsceneCommand.clear();
-}
+// Factory
-QString DesktopQtVersion::qmlsceneCommand() const
+DesktopQtVersionFactory::DesktopQtVersionFactory()
{
- if (!isValid())
- return QString();
-
- if (!m_qmlsceneCommand.isNull())
- return m_qmlsceneCommand;
+ setQtVersionCreator([] { return new DesktopQtVersion; });
+ setSupportedType(QtSupport::Constants::DESKTOPQT);
+ setPriority(0); // Lowest of all, we want to be the fallback
+ // No further restrictions. We are the fallback :) so we don't care what kind of qt it is.
+}
- ensureMkSpecParsed();
- const QString path =
- qmlBinPath().pathAppended(Utils::HostOsInfo::withExecutableSuffix("qmlscene")).toString();
+// EmbeddedLinuxQtVersion
- m_qmlsceneCommand = QFileInfo(path).isFile() ? path : QString();
+const char EMBEDDED_LINUX_QT[] = "RemoteLinux.EmbeddedLinuxQt";
- return m_qmlsceneCommand;
-}
+class EmbeddedLinuxQtVersion : public BaseQtVersion
+{
+public:
+ EmbeddedLinuxQtVersion() = default;
-namespace Internal {
+ QString description() const override
+ {
+ return QCoreApplication::translate("QtVersion", "Embedded Linux",
+ "Qt Version is used for embedded Linux development");
+ }
-// Factory
+ QSet<Core::Id> targetDeviceTypes() const override
+ {
+ return {RemoteLinux::Constants::GenericLinuxOsType};
+ }
+};
-DesktopQtVersionFactory::DesktopQtVersionFactory()
+EmbeddedLinuxQtVersionFactory::EmbeddedLinuxQtVersionFactory()
{
- setQtVersionCreator([] { return new DesktopQtVersion; });
- setSupportedType(QtSupport::Constants::DESKTOPQT);
- setPriority(0); // Lowest of all, we want to be the fallback
- // No further restrictions. We are the fallback :) so we don't care what kind of qt it is.
+ setQtVersionCreator([] { return new EmbeddedLinuxQtVersion; });
+ setSupportedType(EMBEDDED_LINUX_QT);
+ setPriority(10);
+
+ setRestrictionChecker([](const SetupData &) {
+ const EmbeddedLinuxQtVersion tempVersion;
+ const ProjectExplorer::Abis abis = tempVersion.qtAbis();
+
+ // Note: This fails for e.g. intel/meego cross builds on x86 linux machines.
+ return abis.count() == 1
+ && abis.at(0).os() == ProjectExplorer::Abi::LinuxOS
+ && !ProjectExplorer::Abi::hostAbi().isCompatibleWith(abis.at(0));
+ });
}
} // Internal
diff --git a/src/plugins/qmakeprojectmanager/qtmodulesinfo.h b/src/plugins/qtsupport/qtversions.h
index 5f3e793d3c..eb939816d4 100644
--- a/src/plugins/qmakeprojectmanager/qtmodulesinfo.h
+++ b/src/plugins/qtsupport/qtversions.h
@@ -25,19 +25,22 @@
#pragma once
-#include <QStringList>
+#include "qtversionfactory.h"
-namespace QmakeProjectManager {
+namespace QtSupport {
namespace Internal {
-class QtModulesInfo
+class DesktopQtVersionFactory : public QtVersionFactory
{
public:
- static QStringList modules();
- static QString moduleName(const QString &module);
- static QString moduleDescription(const QString &module);
- static bool moduleIsDefault(const QString &module);
+ DesktopQtVersionFactory();
};
-} // namespace Internal
-} // namespace QmakeProjectManager
+class EmbeddedLinuxQtVersionFactory : public QtSupport::QtVersionFactory
+{
+public:
+ EmbeddedLinuxQtVersionFactory();
+};
+
+} // Internal
+} // QtSupport
diff --git a/src/plugins/qtsupport/screenshotcropper.cpp b/src/plugins/qtsupport/screenshotcropper.cpp
index 79e10a8b84..4595e41143 100644
--- a/src/plugins/qtsupport/screenshotcropper.cpp
+++ b/src/plugins/qtsupport/screenshotcropper.cpp
@@ -152,9 +152,7 @@ bool ScreenshotCropper::saveAreasOfInterest(const QString &areasXmlFile, QMap<QS
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeStartElement(xmlTagAreas);
- QMapIterator<QString, QRect> i(areas);
- while (i.hasNext()) {
- i.next();
+ for (auto i = areas.cbegin(), end = areas.cend(); i != end; ++i) {
writer.writeStartElement(xmlTagArea);
writer.writeAttribute(xmlAttributeImage, i.key());
writer.writeAttribute(xmlAttributeX, QString::number(i.value().x()));
diff --git a/src/plugins/qtsupport/translationwizardpage.cpp b/src/plugins/qtsupport/translationwizardpage.cpp
new file mode 100644
index 0000000000..d90d2a9e0c
--- /dev/null
+++ b/src/plugins/qtsupport/translationwizardpage.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "translationwizardpage.h"
+
+#include <projectexplorer/jsonwizard/jsonwizard.h>
+#include <utils/algorithm.h>
+#include <utils/fileutils.h>
+#include <utils/macroexpander.h>
+#include <utils/wizardpage.h>
+
+#include <QComboBox>
+#include <QFileInfo>
+#include <QFormLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QLocale>
+#include <QPair>
+#include <QVBoxLayout>
+
+using namespace Core;
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace QtSupport {
+namespace Internal {
+
+class TranslationWizardPage : public WizardPage
+{
+ Q_OBJECT
+
+public:
+ TranslationWizardPage(const QString &enabledExpr);
+
+private:
+ void initializePage() override;
+ bool isComplete() const override;
+ bool validatePage() override;
+
+ QString tsBaseName() const { return m_fileNameLineEdit.text(); }
+ void updateLineEdit();
+
+ QComboBox m_languageComboBox;
+ QLineEdit m_fileNameLineEdit;
+ QLabel m_suffixLabel;
+ const QString m_enabledExpr;
+ bool m_lineEditEdited = false;
+};
+
+TranslationWizardPageFactory::TranslationWizardPageFactory()
+{
+ setTypeIdsSuffix("QtTranslation");
+}
+
+WizardPage *TranslationWizardPageFactory::create(JsonWizard *wizard, Id typeId,
+ const QVariant &data)
+{
+ Q_UNUSED(wizard)
+ Q_UNUSED(typeId)
+ return new TranslationWizardPage(data.toMap().value("enabled").toString());
+}
+
+TranslationWizardPage::TranslationWizardPage(const QString &enabledExpr)
+ : m_enabledExpr(enabledExpr)
+{
+ const auto mainLayout = new QVBoxLayout(this);
+ const auto descriptionLabel = new QLabel(
+ tr("If you plan to provide translations for your project's "
+ "user interface via the Qt Linguist tool, please select a language here. "
+ "A corresponding translation (.ts) file will be generated for you."));
+ descriptionLabel->setWordWrap(true);
+ mainLayout->addWidget(descriptionLabel);
+ const auto formLayout = new QFormLayout;
+ mainLayout->addLayout(formLayout);
+ m_languageComboBox.addItem(tr("<none>"));
+ QList<QLocale> allLocales = QLocale::matchingLocales(
+ QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
+ allLocales.removeOne(QLocale::C);
+ using LocalePair = QPair<QString, QString>;
+ auto localeStrings = transform<QList<LocalePair>>(allLocales,
+ [](const QLocale &l) {
+ const QString displayName = QLocale::languageToString(l.language()).append(" (")
+ .append(QLocale::countryToString(l.country())).append(')');
+ const QString tsFileBaseName = l.name();
+ return qMakePair(displayName, tsFileBaseName);
+ });
+ sort(localeStrings, [](const LocalePair &l1, const LocalePair &l2) {
+ return l1.first < l2.first; });
+ for (const LocalePair &lp : qAsConst(localeStrings))
+ m_languageComboBox.addItem(lp.first, lp.second);
+ formLayout->addRow(tr("Language:"), &m_languageComboBox);
+ const auto fileNameLayout = new QHBoxLayout;
+ fileNameLayout->addWidget(&m_fileNameLineEdit);
+ m_suffixLabel.setText(".ts");
+ fileNameLayout->addWidget(&m_suffixLabel);
+ fileNameLayout->addStretch(1);
+ formLayout->addRow(tr("Translation file:"), fileNameLayout);
+ connect(&m_fileNameLineEdit, &QLineEdit::textEdited, this, [this] {
+ emit completeChanged();
+ m_lineEditEdited = true;
+ });
+ connect(&m_languageComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, &TranslationWizardPage::updateLineEdit);
+}
+
+void TranslationWizardPage::initializePage()
+{
+ const bool isEnabled = m_enabledExpr.isEmpty()
+ || static_cast<JsonWizard *>(wizard())->expander()->expand(m_enabledExpr) == "yes";
+ setEnabled(isEnabled);
+ if (!isEnabled)
+ m_languageComboBox.setCurrentIndex(0);
+ updateLineEdit();
+}
+
+bool TranslationWizardPage::isComplete() const
+{
+ return m_languageComboBox.currentIndex() == 0 || !tsBaseName().isEmpty();
+}
+
+bool TranslationWizardPage::validatePage()
+{
+ const auto w = static_cast<JsonWizard *>(wizard());
+ w->setValue("TsFileName", tsBaseName().isEmpty() ? QString() : QString(tsBaseName() + ".ts"));
+ w->setValue("TsLanguage", m_fileNameLineEdit.text());
+ return true;
+}
+
+void TranslationWizardPage::updateLineEdit()
+{
+ m_fileNameLineEdit.setEnabled(m_languageComboBox.currentIndex() != 0);
+ m_suffixLabel.setEnabled(m_fileNameLineEdit.isEnabled());
+ if (m_fileNameLineEdit.isEnabled()) {
+ if (!m_lineEditEdited) {
+ const QString projectName
+ = static_cast<JsonWizard *>(wizard())->stringValue("ProjectName");
+ m_fileNameLineEdit.setText(projectName + '_'
+ + m_languageComboBox.currentData().toString());
+ }
+ } else {
+ m_fileNameLineEdit.clear();
+ m_fileNameLineEdit.setPlaceholderText(tr("<none>"));
+ }
+ emit completeChanged();
+}
+
+} // namespace Internal
+} // namespace QtSupport
+
+#include <translationwizardpage.moc>
diff --git a/src/plugins/qtsupport/translationwizardpage.h b/src/plugins/qtsupport/translationwizardpage.h
new file mode 100644
index 0000000000..726f64857a
--- /dev/null
+++ b/src/plugins/qtsupport/translationwizardpage.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/jsonwizard/jsonwizardpagefactory.h>
+
+namespace QtSupport {
+namespace Internal {
+
+class TranslationWizardPageFactory : public ProjectExplorer::JsonWizardPageFactory
+{
+public:
+ TranslationWizardPageFactory();
+
+private:
+ Utils::WizardPage *create(ProjectExplorer::JsonWizard *wizard, Core::Id typeId,
+ const QVariant &data) override;
+ bool validateData(Core::Id, const QVariant &, QString *) override { return true; }
+};
+
+} // namespace Internal
+} // namespace QtSupport
diff --git a/src/plugins/qtsupport/uicgenerator.h b/src/plugins/qtsupport/uicgenerator.h
index e1c7f013d0..c9ed44ddf2 100644
--- a/src/plugins/qtsupport/uicgenerator.h
+++ b/src/plugins/qtsupport/uicgenerator.h
@@ -37,7 +37,7 @@ class UicGenerator : public ProjectExplorer::ProcessExtraCompiler
Q_OBJECT
public:
UicGenerator(const ProjectExplorer::Project *project, const Utils::FilePath &source,
- const Utils::FilePathList &targets, QObject *parent = 0);
+ const Utils::FilePathList &targets, QObject *parent = nullptr);
protected:
Utils::FilePath command() const override;
@@ -50,7 +50,7 @@ class UicGeneratorFactory : public ProjectExplorer::ExtraCompilerFactory
{
Q_OBJECT
public:
- UicGeneratorFactory(QObject *parent = 0) : ExtraCompilerFactory(parent) {}
+ UicGeneratorFactory() = default;
ProjectExplorer::FileType sourceType() const override;
diff --git a/src/plugins/remotelinux/CMakeLists.txt b/src/plugins/remotelinux/CMakeLists.txt
index 63c97b1686..f5b00e5ff8 100644
--- a/src/plugins/remotelinux/CMakeLists.txt
+++ b/src/plugins/remotelinux/CMakeLists.txt
@@ -1,13 +1,12 @@
add_qtc_plugin(RemoteLinux
DEPENDS QmlDebug QtcSsh
- PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport
+ PLUGIN_DEPENDS Core Debugger ProjectExplorer
SOURCES
abstractpackagingstep.cpp abstractpackagingstep.h
abstractremotelinuxdeployservice.cpp abstractremotelinuxdeployservice.h
abstractremotelinuxdeploystep.cpp abstractremotelinuxdeploystep.h
abstractuploadandinstallpackageservice.cpp abstractuploadandinstallpackageservice.h
deploymenttimeinfo.cpp deploymenttimeinfo.h
- embeddedlinuxqtversion.cpp embeddedlinuxqtversion.h
genericdirectuploadservice.cpp genericdirectuploadservice.h
genericdirectuploadstep.cpp genericdirectuploadstep.h
genericlinuxdeviceconfigurationwidget.cpp genericlinuxdeviceconfigurationwidget.h genericlinuxdeviceconfigurationwidget.ui
diff --git a/src/plugins/remotelinux/abstractpackagingstep.cpp b/src/plugins/remotelinux/abstractpackagingstep.cpp
index c328837628..dc23580414 100644
--- a/src/plugins/remotelinux/abstractpackagingstep.cpp
+++ b/src/plugins/remotelinux/abstractpackagingstep.cpp
@@ -42,7 +42,6 @@ namespace Internal {
class AbstractPackagingStepPrivate
{
public:
- BuildConfiguration *currentBuildConfiguration = nullptr;
QString cachedPackageFilePath;
QString cachedPackageDirectory;
bool deploymentDataModified = false;
@@ -54,9 +53,6 @@ AbstractPackagingStep::AbstractPackagingStep(BuildStepList *bsl, Core::Id id)
: BuildStep(bsl, id)
{
d = new Internal::AbstractPackagingStepPrivate;
- connect(target(), &Target::activeBuildConfigurationChanged,
- this, &AbstractPackagingStep::handleBuildConfigurationChanged);
- handleBuildConfigurationChanged();
connect(target(), &Target::deploymentDataChanged,
this, &AbstractPackagingStep::setDeploymentDataModified);
@@ -71,18 +67,6 @@ AbstractPackagingStep::~AbstractPackagingStep()
delete d;
}
-void AbstractPackagingStep::handleBuildConfigurationChanged()
-{
- if (d->currentBuildConfiguration)
- disconnect(d->currentBuildConfiguration, nullptr, this, nullptr);
- d->currentBuildConfiguration = buildConfiguration();
- if (d->currentBuildConfiguration) {
- connect(d->currentBuildConfiguration, &BuildConfiguration::buildDirectoryChanged,
- this, &AbstractPackagingStep::packageFilePathChanged);
- }
- emit packageFilePathChanged();
-}
-
QString AbstractPackagingStep::cachedPackageFilePath() const
{
return d->cachedPackageFilePath;
@@ -102,8 +86,7 @@ QString AbstractPackagingStep::cachedPackageDirectory() const
QString AbstractPackagingStep::packageDirectory() const
{
- return d->currentBuildConfiguration
- ? d->currentBuildConfiguration->buildDirectory().toString() : QString();
+ return buildConfiguration()->buildDirectory().toString();
}
bool AbstractPackagingStep::isPackagingNeeded() const
diff --git a/src/plugins/remotelinux/abstractpackagingstep.h b/src/plugins/remotelinux/abstractpackagingstep.h
index d792e2e870..616c76d921 100644
--- a/src/plugins/remotelinux/abstractpackagingstep.h
+++ b/src/plugins/remotelinux/abstractpackagingstep.h
@@ -46,7 +46,6 @@ public:
bool init() override;
signals:
- void packageFilePathChanged();
void unmodifyDeploymentData();
protected:
@@ -61,7 +60,6 @@ protected:
virtual bool isPackagingNeeded() const;
private:
- void handleBuildConfigurationChanged();
void setDeploymentDataUnmodified();
void setDeploymentDataModified();
diff --git a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp
index c6d184ec12..827c72b0b7 100644
--- a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp
+++ b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp
@@ -27,12 +27,14 @@
#include "deploymenttimeinfo.h"
#include <projectexplorer/deployablefile.h>
+#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtkitinformation.h>
-#include <utils/qtcassert.h>
+
#include <ssh/sshconnection.h>
#include <ssh/sshconnectionmanager.h>
+#include <utils/qtcassert.h>
+
#include <QDateTime>
#include <QFileInfo>
#include <QPointer>
diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp
index 45e34bda29..a1a497d171 100644
--- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp
+++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp
@@ -40,6 +40,9 @@ class AbstractRemoteLinuxDeployStepPrivate
{
public:
bool hasError;
+ std::function<CheckResult()> internalInit;
+ std::function<void()> runPreparer;
+ AbstractRemoteLinuxDeployService *deployService = nullptr;
};
} // namespace Internal
@@ -49,8 +52,24 @@ AbstractRemoteLinuxDeployStep::AbstractRemoteLinuxDeployStep(BuildStepList *bsl,
{
}
+void AbstractRemoteLinuxDeployStep::setInternalInitializer(const std::function<CheckResult ()> &init)
+{
+ d->internalInit = init;
+}
+
+void AbstractRemoteLinuxDeployStep::setRunPreparer(const std::function<void ()> &prep)
+{
+ d->runPreparer = prep;
+}
+
+void AbstractRemoteLinuxDeployStep::setDeployService(AbstractRemoteLinuxDeployService *service)
+{
+ d->deployService = service;
+}
+
AbstractRemoteLinuxDeployStep::~AbstractRemoteLinuxDeployStep()
{
+ delete d->deployService;
delete d;
}
@@ -58,19 +77,21 @@ bool AbstractRemoteLinuxDeployStep::fromMap(const QVariantMap &map)
{
if (!BuildStep::fromMap(map))
return false;
- deployService()->importDeployTimes(map);
+ d->deployService->importDeployTimes(map);
return true;
}
QVariantMap AbstractRemoteLinuxDeployStep::toMap() const
{
- return BuildStep::toMap().unite(deployService()->exportDeployTimes());
+ return BuildStep::toMap().unite(d->deployService->exportDeployTimes());
}
bool AbstractRemoteLinuxDeployStep::init()
{
- deployService()->setTarget(target());
- const CheckResult canDeploy = initInternal();
+ d->deployService->setTarget(target());
+
+ QTC_ASSERT(d->internalInit, return false);
+ const CheckResult canDeploy = d->internalInit();
if (!canDeploy) {
emit addOutput(tr("Cannot deploy: %1").arg(canDeploy.errorMessage()),
OutputFormat::ErrorMessage);
@@ -80,21 +101,24 @@ bool AbstractRemoteLinuxDeployStep::init()
void AbstractRemoteLinuxDeployStep::doRun()
{
- connect(deployService(), &AbstractRemoteLinuxDeployService::errorMessage,
+ if (d->runPreparer)
+ d->runPreparer();
+
+ connect(d->deployService, &AbstractRemoteLinuxDeployService::errorMessage,
this, &AbstractRemoteLinuxDeployStep::handleErrorMessage);
- connect(deployService(), &AbstractRemoteLinuxDeployService::progressMessage,
+ connect(d->deployService, &AbstractRemoteLinuxDeployService::progressMessage,
this, &AbstractRemoteLinuxDeployStep::handleProgressMessage);
- connect(deployService(), &AbstractRemoteLinuxDeployService::warningMessage,
+ connect(d->deployService, &AbstractRemoteLinuxDeployService::warningMessage,
this, &AbstractRemoteLinuxDeployStep::handleWarningMessage);
- connect(deployService(), &AbstractRemoteLinuxDeployService::stdOutData,
+ connect(d->deployService, &AbstractRemoteLinuxDeployService::stdOutData,
this, &AbstractRemoteLinuxDeployStep::handleStdOutData);
- connect(deployService(), &AbstractRemoteLinuxDeployService::stdErrData,
+ connect(d->deployService, &AbstractRemoteLinuxDeployService::stdErrData,
this, &AbstractRemoteLinuxDeployStep::handleStdErrData);
- connect(deployService(), &AbstractRemoteLinuxDeployService::finished,
+ connect(d->deployService, &AbstractRemoteLinuxDeployService::finished,
this, &AbstractRemoteLinuxDeployStep::handleFinished);
d->hasError = false;
- deployService()->start();
+ d->deployService->start();
}
void AbstractRemoteLinuxDeployStep::doCancel()
@@ -105,7 +129,7 @@ void AbstractRemoteLinuxDeployStep::doCancel()
emit addOutput(tr("User requests deployment to stop; cleaning up."),
OutputFormat::NormalMessage);
d->hasError = true;
- deployService()->stop();
+ d->deployService->stop();
}
void AbstractRemoteLinuxDeployStep::handleProgressMessage(const QString &message)
@@ -136,7 +160,7 @@ void AbstractRemoteLinuxDeployStep::handleFinished()
emit addOutput(tr("Deploy step failed."), OutputFormat::ErrorMessage);
else
emit addOutput(tr("Deploy step finished."), OutputFormat::NormalMessage);
- disconnect(deployService(), nullptr, this, nullptr);
+ disconnect(d->deployService, nullptr, this, nullptr);
emit finished(!d->hasError);
}
diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.h b/src/plugins/remotelinux/abstractremotelinuxdeploystep.h
index e8fac039b7..e15cef3706 100644
--- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.h
+++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.h
@@ -41,19 +41,29 @@ class REMOTELINUX_EXPORT AbstractRemoteLinuxDeployStep : public ProjectExplorer:
public:
~AbstractRemoteLinuxDeployStep() override;
- virtual AbstractRemoteLinuxDeployService *deployService() const = 0;
protected:
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
bool init() override;
- void doRun() override;
+ void doRun() final;
void doCancel() override;
explicit AbstractRemoteLinuxDeployStep(ProjectExplorer::BuildStepList *bsl, Core::Id id);
- virtual CheckResult initInternal() = 0;
+
+ void setInternalInitializer(const std::function<CheckResult()> &init);
+ void setRunPreparer(const std::function<void()> &prep);
+
+ template <class T>
+ T *createDeployService()
+ {
+ T *service = new T;
+ setDeployService(service);
+ return service;
+ }
private:
+ void setDeployService(AbstractRemoteLinuxDeployService *service);
void handleProgressMessage(const QString &message);
void handleErrorMessage(const QString &message);
void handleWarningMessage(const QString &message);
diff --git a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp
index 18ac23f496..d94270eaeb 100644
--- a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp
+++ b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.cpp
@@ -60,9 +60,8 @@ public:
using namespace Internal;
-AbstractUploadAndInstallPackageService::AbstractUploadAndInstallPackageService(QObject *parent)
- : AbstractRemoteLinuxDeployService(parent),
- d(new AbstractUploadAndInstallPackageServicePrivate)
+AbstractUploadAndInstallPackageService::AbstractUploadAndInstallPackageService()
+ : d(new AbstractUploadAndInstallPackageServicePrivate)
{
}
diff --git a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h
index c970e287ea..cef3ccf6b3 100644
--- a/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h
+++ b/src/plugins/remotelinux/abstractuploadandinstallpackageservice.h
@@ -41,7 +41,7 @@ public:
void setPackageFilePath(const QString &filePath);
protected:
- explicit AbstractUploadAndInstallPackageService(QObject *parent);
+ AbstractUploadAndInstallPackageService();
~AbstractUploadAndInstallPackageService() override;
QString packageFilePath() const;
diff --git a/src/plugins/remotelinux/deploymenttimeinfo.cpp b/src/plugins/remotelinux/deploymenttimeinfo.cpp
index e43dd75ca7..59a4e3f63c 100644
--- a/src/plugins/remotelinux/deploymenttimeinfo.cpp
+++ b/src/plugins/remotelinux/deploymenttimeinfo.cpp
@@ -22,16 +22,16 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
+
#include "deploymenttimeinfo.h"
#include <projectexplorer/deployablefile.h>
+#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtkitinformation.h>
#include <ssh/sshconnection.h>
#include <ssh/sshconnectionmanager.h>
-#include <QPointer>
#include <QDateTime>
#include <QFileInfo>
@@ -51,11 +51,7 @@ const char LastDeployedRemoteTimesKey[] = "RemoteLinux.LastDeployedRemoteTimes";
class DeployParameters
{
-
public:
- DeployParameters(const DeployableFile &d, const QString &h, const QString &s)
- : file(d), host(h), sysroot(s) {}
-
bool operator==(const DeployParameters &other) const {
return file == other.file && host == other.host && sysroot == other.sysroot;
}
@@ -81,8 +77,8 @@ public:
};
QHash<DeployParameters, Timestamps> lastDeployed;
- DeployParameters parameters(const ProjectExplorer::DeployableFile &deployableFile,
- const ProjectExplorer::Kit *kit) const
+ DeployParameters parameters(const DeployableFile &deployableFile,
+ const Kit *kit) const
{
QString systemRoot;
QString host;
@@ -93,7 +89,7 @@ public:
host = deviceConfiguration->sshParameters().host();
}
- return DeployParameters(deployableFile, host, systemRoot);
+ return DeployParameters{deployableFile, host, systemRoot};
}
};
@@ -117,7 +113,7 @@ void DeploymentTimeInfo::saveDeploymentTimeStamp(const DeployableFile &deployabl
}
bool DeploymentTimeInfo::hasLocalFileChanged(const DeployableFile &deployableFile,
- const ProjectExplorer::Kit *kit) const
+ const Kit *kit) const
{
const auto &lastDeployed = d->lastDeployed.value(d->parameters(deployableFile, kit));
const QDateTime lastModified = deployableFile.localFilePath().toFileInfo().lastModified();
@@ -125,7 +121,7 @@ bool DeploymentTimeInfo::hasLocalFileChanged(const DeployableFile &deployableFil
}
bool DeploymentTimeInfo::hasRemoteFileChanged(const DeployableFile &deployableFile,
- const ProjectExplorer::Kit *kit,
+ const Kit *kit,
const QDateTime &remoteTimestamp) const
{
const auto &lastDeployed = d->lastDeployed.value(d->parameters(deployableFile, kit));
@@ -185,7 +181,7 @@ void DeploymentTimeInfo::importDeployTimes(const QVariantMap &map)
for (int i = 0; i < elemCount; ++i) {
const DeployableFile df(fileList.at(i).toString(), remotePathList.at(i).toString());
- const DeployParameters dp(df, hostList.at(i).toString(), sysrootList.at(i).toString());
+ const DeployParameters dp{df, hostList.at(i).toString(), sysrootList.at(i).toString()};
d->lastDeployed.insert(dp, { localTimesList.at(i).toDateTime(),
remoteTimesList.length() > i
? remoteTimesList.at(i).toDateTime()
diff --git a/src/plugins/remotelinux/embeddedlinuxqtversion.cpp b/src/plugins/remotelinux/embeddedlinuxqtversion.cpp
deleted file mode 100644
index e315cf066a..0000000000
--- a/src/plugins/remotelinux/embeddedlinuxqtversion.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "embeddedlinuxqtversion.h"
-
-#include "remotelinux_constants.h"
-
-#include <coreplugin/id.h>
-#include <qtsupport/qtsupportconstants.h>
-
-#include <QCoreApplication>
-
-namespace RemoteLinux {
-namespace Internal {
-
-QString EmbeddedLinuxQtVersion::description() const
-{
- return QCoreApplication::translate("QtVersion", "Embedded Linux", "Qt Version is used for embedded Linux development");
-}
-
-QSet<Core::Id> EmbeddedLinuxQtVersion::targetDeviceTypes() const
-{
- return {Constants::GenericLinuxOsType};
-}
-
-
-// Factory
-
-EmbeddedLinuxQtVersionFactory::EmbeddedLinuxQtVersionFactory()
-{
- setQtVersionCreator([] { return new EmbeddedLinuxQtVersion; });
- setSupportedType(RemoteLinux::Constants::EMBEDDED_LINUX_QT);
- setPriority(10);
-
- setRestrictionChecker([](const SetupData &) {
- const EmbeddedLinuxQtVersion tempVersion;
- const ProjectExplorer::Abis abis = tempVersion.qtAbis();
-
- // Note: This fails for e.g. intel/meego cross builds on x86 linux machines.
- return abis.count() == 1
- && abis.at(0).os() == ProjectExplorer::Abi::LinuxOS
- && !ProjectExplorer::Abi::hostAbi().isCompatibleWith(abis.at(0));
- });
-}
-
-} // namespace Internal
-} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp
index 27668c0a50..2a07c5d94a 100644
--- a/src/plugins/remotelinux/genericdirectuploadstep.cpp
+++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp
@@ -34,60 +34,37 @@
using namespace ProjectExplorer;
namespace RemoteLinux {
-namespace Internal {
-
-class GenericDirectUploadStepPrivate
-{
-public:
- GenericDirectUploadService deployService;
- BaseBoolAspect *incrementalAspect;
- BaseBoolAspect *ignoreMissingFilesAspect;
-};
-
-} // namespace Internal
GenericDirectUploadStep::GenericDirectUploadStep(BuildStepList *bsl)
: AbstractRemoteLinuxDeployStep(bsl, stepId())
{
- d = new Internal::GenericDirectUploadStepPrivate;
+ auto service = createDeployService<GenericDirectUploadService>();
- d->incrementalAspect = addAspect<BaseBoolAspect>();
- d->incrementalAspect->setSettingsKey("RemoteLinux.GenericDirectUploadStep.Incremental");
- d->incrementalAspect->setLabel(tr("Incremental deployment"));
- d->incrementalAspect->setValue(true);
- d->incrementalAspect->setDefaultValue(true);
+ auto incremental = addAspect<BaseBoolAspect>();
+ incremental->setSettingsKey("RemoteLinux.GenericDirectUploadStep.Incremental");
+ incremental->setLabel(tr("Incremental deployment"));
+ incremental->setValue(true);
+ incremental->setDefaultValue(true);
- d->ignoreMissingFilesAspect = addAspect<BaseBoolAspect>();
- d->ignoreMissingFilesAspect
- ->setSettingsKey("RemoteLinux.GenericDirectUploadStep.IgnoreMissingFiles");
- d->ignoreMissingFilesAspect->setLabel(tr("Ignore missing files"));
- d->ignoreMissingFilesAspect->setValue(false);
+ auto ignoreMissingFiles = addAspect<BaseBoolAspect>();
+ ignoreMissingFiles->setSettingsKey("RemoteLinux.GenericDirectUploadStep.IgnoreMissingFiles");
+ ignoreMissingFiles->setLabel(tr("Ignore missing files"));
+ ignoreMissingFiles->setValue(false);
- setDefaultDisplayName(displayName());
-}
-
-GenericDirectUploadStep::~GenericDirectUploadStep()
-{
- delete d;
-}
+ setInternalInitializer([incremental, ignoreMissingFiles, service] {
+ service->setIncrementalDeployment(incremental->value());
+ service->setIgnoreMissingFiles(ignoreMissingFiles->value());
+ return service->isDeploymentPossible();
+ });
-CheckResult GenericDirectUploadStep::initInternal()
-{
- d->deployService.setIncrementalDeployment(d->incrementalAspect->value());
- d->deployService.setIgnoreMissingFiles(d->ignoreMissingFilesAspect->value());
- return d->deployService.isDeploymentPossible();
-}
+ setRunPreparer([this, service] {
+ service->setDeployableFiles(target()->deploymentData().allFiles());
+ });
-GenericDirectUploadService *GenericDirectUploadStep::deployService() const
-{
- return &d->deployService;
+ setDefaultDisplayName(displayName());
}
-void GenericDirectUploadStep::doRun()
-{
- d->deployService.setDeployableFiles(target()->deploymentData().allFiles());
- AbstractRemoteLinuxDeployStep::doRun();
-}
+GenericDirectUploadStep::~GenericDirectUploadStep() = default;
Core::Id GenericDirectUploadStep::stepId()
{
diff --git a/src/plugins/remotelinux/genericdirectuploadstep.h b/src/plugins/remotelinux/genericdirectuploadstep.h
index fa9b98205c..0577366d9a 100644
--- a/src/plugins/remotelinux/genericdirectuploadstep.h
+++ b/src/plugins/remotelinux/genericdirectuploadstep.h
@@ -26,11 +26,9 @@
#pragma once
#include "abstractremotelinuxdeploystep.h"
-#include "genericdirectuploadservice.h"
#include "remotelinux_export.h"
namespace RemoteLinux {
-namespace Internal { class GenericDirectUploadStepPrivate; }
class REMOTELINUX_EXPORT GenericDirectUploadStep : public AbstractRemoteLinuxDeployStep
{
@@ -40,16 +38,8 @@ public:
explicit GenericDirectUploadStep(ProjectExplorer::BuildStepList *bsl);
~GenericDirectUploadStep() override;
- CheckResult initInternal() override;
-
static Core::Id stepId();
static QString displayName();
-
-private:
- GenericDirectUploadService *deployService() const override;
- void doRun() override;
-
- Internal::GenericDirectUploadStepPrivate *d;
};
} //namespace RemoteLinux
diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.cpp
index 4f7eaf229d..a184bb2fd3 100644
--- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.cpp
+++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.cpp
@@ -39,8 +39,8 @@ using namespace QSsh;
using namespace Utils;
GenericLinuxDeviceConfigurationWidget::GenericLinuxDeviceConfigurationWidget(
- const IDevice::Ptr &deviceConfig, QWidget *parent) :
- IDeviceWidget(deviceConfig, parent),
+ const IDevice::Ptr &deviceConfig) :
+ IDeviceWidget(deviceConfig),
m_ui(new Ui::GenericLinuxDeviceConfigurationWidget)
{
m_ui->setupUi(this);
diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.h b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.h
index 7faf3494d6..bc4383e6c9 100644
--- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.h
+++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwidget.h
@@ -40,7 +40,7 @@ class REMOTELINUX_EXPORT GenericLinuxDeviceConfigurationWidget
public:
explicit GenericLinuxDeviceConfigurationWidget(
- const ProjectExplorer::IDevice::Ptr &deviceConfig, QWidget *parent = nullptr);
+ const ProjectExplorer::IDevice::Ptr &deviceConfig);
~GenericLinuxDeviceConfigurationWidget() override;
private:
diff --git a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp
index 56cbd99ccd..913097a335 100644
--- a/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp
+++ b/src/plugins/remotelinux/genericlinuxdeviceconfigurationwizard.cpp
@@ -64,7 +64,6 @@ GenericLinuxDeviceConfigurationWizard::GenericLinuxDeviceConfigurationWizard(QWi
d->finalPage.setCommitPage(true);
d->device = LinuxDevice::create();
d->device->setupId(IDevice::ManuallyAdded, Core::Id());
- d->device->setDisplayName(tr("Generic Linux Device"));
d->device->setType(Constants::GenericLinuxOsType);
d->device->setMachineType(IDevice::Hardware);
d->device->setFreePorts(Utils::PortList::fromString(QLatin1String("10000-10100")));
diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp
index 6e05739c01..4bec21d896 100644
--- a/src/plugins/remotelinux/linuxdevice.cpp
+++ b/src/plugins/remotelinux/linuxdevice.cpp
@@ -52,6 +52,7 @@
#include <QTimer>
using namespace ProjectExplorer;
+using namespace Utils;
namespace RemoteLinux {
@@ -145,7 +146,7 @@ class LinuxPortsGatheringMethod : public PortsGatheringMethod
// /proc/net/tcp* covers /proc/net/tcp and /proc/net/tcp6
Runnable runnable;
- runnable.executable = "sed";
+ runnable.executable = FilePath::fromString("sed");
runnable.commandLineArguments
= "-e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*";
return runnable;
@@ -172,23 +173,17 @@ class LinuxPortsGatheringMethod : public PortsGatheringMethod
}
};
-QString LinuxDevice::displayType() const
-{
- return tr("Generic Linux");
-}
-
IDeviceWidget *LinuxDevice::createWidget()
{
return new GenericLinuxDeviceConfigurationWidget(sharedFromThis());
}
-Utils::OsType LinuxDevice::osType() const
-{
- return Utils::OsTypeLinux;
-}
-
LinuxDevice::LinuxDevice()
{
+ setDisplayType(tr("Generic Linux"));
+ setDefaultDisplayName(tr("Generic Linux Device"));
+ setOsType(OsTypeLinux);
+
addDeviceAction({tr("Deploy Public Key..."), [](const IDevice::Ptr &device, QWidget *parent) {
if (auto d = PublicKeyDeploymentDialog::createDialog(device, parent)) {
d->exec();
@@ -219,7 +214,7 @@ LinuxDevice::LinuxDevice()
// It seems we cannot pass an environment to OpenSSH dynamically
// without specifying an executable.
if (env.size() > 0)
- runnable.executable = "/bin/sh";
+ runnable.executable = FilePath::fromString("/bin/sh");
proc->setRunInTerminal(true);
proc->start(runnable);
diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h
index 18faf4ae05..f9a84eedb6 100644
--- a/src/plugins/remotelinux/linuxdevice.h
+++ b/src/plugins/remotelinux/linuxdevice.h
@@ -44,9 +44,7 @@ public:
static Ptr create() { return Ptr(new LinuxDevice); }
- QString displayType() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
- Utils::OsType osType() const override;
bool canCreateProcess() const override { return true; }
ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const override;
diff --git a/src/plugins/remotelinux/linuxdeviceprocess.cpp b/src/plugins/remotelinux/linuxdeviceprocess.cpp
index ca08b44ec9..c16a12baee 100644
--- a/src/plugins/remotelinux/linuxdeviceprocess.cpp
+++ b/src/plugins/remotelinux/linuxdeviceprocess.cpp
@@ -79,28 +79,28 @@ QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
for (const QString &filePath : rcFilesToSource()) {
cmd.addArgs({"test", "-f", filePath});
- cmd.addArgs("&&");
+ cmd.addArgs("&&", CommandLine::Raw);
cmd.addArgs({".", filePath});
- cmd.addArgs(";");
+ cmd.addArgs(";", CommandLine::Raw);
}
if (!runnable.workingDirectory.isEmpty()) {
cmd.addArgs({"cd", runnable.workingDirectory});
- cmd.addArgs("&&");
+ cmd.addArgs("&&", CommandLine::Raw);
}
if (!runInTerminal())
- cmd.addArgs("echo $$ && ");
+ cmd.addArgs("echo $$ && ", CommandLine::Raw);
const Environment &env = runnable.environment;
for (auto it = env.constBegin(); it != env.constEnd(); ++it)
- cmd.addArgs(env.key(it) + "='" + env.value(it) + '\'');
+ cmd.addArgs(env.key(it) + "='" + env.expandedValueForKey(env.key(it)) + '\'', CommandLine::Raw);
if (!runInTerminal())
cmd.addArg("exec");
- cmd.addArg(runnable.executable);
- cmd.addArgs(runnable.commandLineArguments);
+ cmd.addArg(runnable.executable.toString());
+ cmd.addArgs(runnable.commandLineArguments, CommandLine::Raw);
return cmd.arguments();
}
diff --git a/src/plugins/remotelinux/makeinstallstep.cpp b/src/plugins/remotelinux/makeinstallstep.cpp
index c9d3578b79..3c2b798ca5 100644
--- a/src/plugins/remotelinux/makeinstallstep.cpp
+++ b/src/plugins/remotelinux/makeinstallstep.cpp
@@ -85,7 +85,7 @@ MakeInstallStep::MakeInstallStep(BuildStepList *parent) : MakeStep(parent, stepI
commandLineAspect->setLabelText(tr("Full command line:"));
QTemporaryDir tmpDir;
- installRootAspect->setFileName(FilePath::fromString(tmpDir.path()));
+ installRootAspect->setFilePath(FilePath::fromString(tmpDir.path()));
const MakeInstallCommand cmd = target()->makeInstallCommand(tmpDir.path());
QTC_ASSERT(!cmd.command.isEmpty(), return);
makeAspect->setExecutable(cmd.command);
@@ -138,15 +138,20 @@ bool MakeInstallStep::init()
const MakeInstallCommand cmd = target()->makeInstallCommand(installRoot().toString());
if (cmd.environment.size() > 0) {
Environment env = processParameters()->environment();
- for (auto it = cmd.environment.constBegin(); it != cmd.environment.constEnd(); ++it)
- env.set(it.key(), it.value());
+ for (auto it = cmd.environment.constBegin(); it != cmd.environment.constEnd(); ++it) {
+ if (cmd.environment.isEnabled(it)) {
+ const QString key = cmd.environment.key(it);
+ env.set(key, cmd.environment.expandedValueForKey(key));
+ }
+ }
processParameters()->setEnvironment(env);
}
m_noInstallTarget = false;
const auto buildStep = buildConfiguration()
->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD)
->firstOfType<AbstractProcessStep>();
- m_isCmakeProject = buildStep && buildStep->processParameters()->command().toString()
+ m_isCmakeProject = buildStep
+ && buildStep->processParameters()->command().executable().toString()
.contains("cmake");
return true;
}
@@ -183,7 +188,7 @@ void MakeInstallStep::stdError(const QString &line)
FilePath MakeInstallStep::installRoot() const
{
- return static_cast<BaseStringAspect *>(aspect(InstallRootAspectId))->fileName();
+ return static_cast<BaseStringAspect *>(aspect(InstallRootAspectId))->filePath();
}
bool MakeInstallStep::cleanInstallRoot() const
@@ -200,16 +205,17 @@ void MakeInstallStep::updateCommandFromAspect()
void MakeInstallStep::updateArgsFromAspect()
{
setUserArguments(QtcProcess::joinArgs(target()->makeInstallCommand(
- static_cast<BaseStringAspect *>(aspect(InstallRootAspectId))->fileName().toString())
+ static_cast<BaseStringAspect *>(aspect(InstallRootAspectId))->filePath().toString())
.arguments));
updateFullCommandLine();
}
void MakeInstallStep::updateFullCommandLine()
{
+ // FIXME: Only executable?
static_cast<BaseStringAspect *>(aspect(FullCommandLineAspectId))->setValue(
QDir::toNativeSeparators(
- QtcProcess::quoteArg(effectiveMakeCommand().toString()))
+ QtcProcess::quoteArg(effectiveMakeCommand().executable().toString()))
+ ' ' + userArguments());
}
diff --git a/src/plugins/remotelinux/remotelinux.pro b/src/plugins/remotelinux/remotelinux.pro
index 5314e25d64..1e92e019cb 100644
--- a/src/plugins/remotelinux/remotelinux.pro
+++ b/src/plugins/remotelinux/remotelinux.pro
@@ -3,7 +3,6 @@ QT += network
include(../../qtcreatorplugin.pri)
HEADERS += \
- embeddedlinuxqtversion.h \
makeinstallstep.h \
remotelinuxenvironmentaspect.h \
remotelinuxenvironmentaspectwidget.h \
@@ -47,7 +46,6 @@ HEADERS += \
deploymenttimeinfo.h
SOURCES += \
- embeddedlinuxqtversion.cpp \
makeinstallstep.cpp \
remotelinuxenvironmentaspect.cpp \
remotelinuxenvironmentaspectwidget.cpp \
diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs
index e2a9551393..03d280735b 100644
--- a/src/plugins/remotelinux/remotelinux.qbs
+++ b/src/plugins/remotelinux/remotelinux.qbs
@@ -14,7 +14,6 @@ Project {
Depends { name: "Core" }
Depends { name: "Debugger" }
Depends { name: "ProjectExplorer" }
- Depends { name: "QtSupport" }
files: [
"abstractpackagingstep.cpp",
@@ -27,8 +26,6 @@ Project {
"abstractuploadandinstallpackageservice.h",
"deploymenttimeinfo.cpp",
"deploymenttimeinfo.h",
- "embeddedlinuxqtversion.cpp",
- "embeddedlinuxqtversion.h",
"genericdirectuploadservice.cpp",
"genericdirectuploadservice.h",
"genericdirectuploadstep.cpp",
diff --git a/src/plugins/remotelinux/remotelinux_constants.h b/src/plugins/remotelinux/remotelinux_constants.h
index 1b34d1d4d7..479dfda167 100644
--- a/src/plugins/remotelinux/remotelinux_constants.h
+++ b/src/plugins/remotelinux/remotelinux_constants.h
@@ -30,7 +30,5 @@ namespace Constants {
const char GenericLinuxOsType[] = "GenericLinuxOsType";
-const char EMBEDDED_LINUX_QT[] = "RemoteLinux.EmbeddedLinuxQt";
-
} // Constants
} // RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinux_dependencies.pri b/src/plugins/remotelinux/remotelinux_dependencies.pri
index 2e8344d418..51d71c5659 100644
--- a/src/plugins/remotelinux/remotelinux_dependencies.pri
+++ b/src/plugins/remotelinux/remotelinux_dependencies.pri
@@ -7,5 +7,4 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \
coreplugin \
debugger \
- projectexplorer \
- qtsupport
+ projectexplorer
diff --git a/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.cpp b/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.cpp
index 1070083eeb..0db981e144 100644
--- a/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.cpp
+++ b/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.cpp
@@ -34,65 +34,36 @@
using namespace ProjectExplorer;
namespace RemoteLinux {
-namespace Internal {
-
-const char PathToCheckAspectId[] = "PathToCheckAspectId";
-const char PathToCheckKey[] = "RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck";
-
-const char RequiredSpaceAspectId[] = "RequiredSpaceAspectId";
-const char RequiredSpaceKey[] = "RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace";
-
-class RemoteLinuxCheckForFreeDiskSpaceStepPrivate
-{
-public:
- RemoteLinuxCheckForFreeDiskSpaceService deployService;
-};
-
-} // namespace Internal
-
-using namespace Internal;
RemoteLinuxCheckForFreeDiskSpaceStep::RemoteLinuxCheckForFreeDiskSpaceStep(BuildStepList *bsl)
: AbstractRemoteLinuxDeployStep(bsl, stepId())
{
- d = new Internal::RemoteLinuxCheckForFreeDiskSpaceStepPrivate;
setDefaultDisplayName(displayName());
+ auto service = createDeployService<RemoteLinuxCheckForFreeDiskSpaceService>();
+
auto pathToCheckAspect = addAspect<BaseStringAspect>();
- pathToCheckAspect->setId(PathToCheckAspectId);
- pathToCheckAspect->setSettingsKey(PathToCheckKey);
+ pathToCheckAspect->setSettingsKey("RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck");
pathToCheckAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
pathToCheckAspect->setValue("/");
pathToCheckAspect->setLabelText(tr("Remote path to check for free space:"));
auto requiredSpaceAspect = addAspect<BaseIntegerAspect>();
- requiredSpaceAspect->setId(RequiredSpaceAspectId);
- requiredSpaceAspect->setSettingsKey(RequiredSpaceKey);
+ requiredSpaceAspect->setSettingsKey("RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace");
requiredSpaceAspect->setLabel(tr("Required disk space:"));
requiredSpaceAspect->setDisplayScaleFactor(1024*1024);
requiredSpaceAspect->setValue(5*1024*1024);
requiredSpaceAspect->setSuffix(tr("MB"));
requiredSpaceAspect->setRange(1, std::numeric_limits<int>::max());
-}
-RemoteLinuxCheckForFreeDiskSpaceStep::~RemoteLinuxCheckForFreeDiskSpaceStep()
-{
- delete d;
+ setInternalInitializer([service, pathToCheckAspect, requiredSpaceAspect] {
+ service->setPathToCheck(pathToCheckAspect->value());
+ service->setRequiredSpaceInBytes(requiredSpaceAspect->value());
+ return CheckResult::success();
+ });
}
-CheckResult RemoteLinuxCheckForFreeDiskSpaceStep::initInternal()
-{
- d->deployService.setPathToCheck(
- static_cast<BaseStringAspect *>(aspect(PathToCheckAspectId))->value());
- d->deployService.setRequiredSpaceInBytes(
- static_cast<BaseIntegerAspect *>(aspect(RequiredSpaceAspectId))->value());
- return CheckResult::success();
-}
-
-AbstractRemoteLinuxDeployService *RemoteLinuxCheckForFreeDiskSpaceStep::deployService() const
-{
- return &d->deployService;
-}
+RemoteLinuxCheckForFreeDiskSpaceStep::~RemoteLinuxCheckForFreeDiskSpaceStep() = default;
Core::Id RemoteLinuxCheckForFreeDiskSpaceStep::stepId()
{
diff --git a/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.h b/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.h
index afd5887f33..5dd2cdcc94 100644
--- a/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.h
+++ b/src/plugins/remotelinux/remotelinuxcheckforfreediskspacestep.h
@@ -28,24 +28,17 @@
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
-namespace Internal { class RemoteLinuxCheckForFreeDiskSpaceStepPrivate; }
class REMOTELINUX_EXPORT RemoteLinuxCheckForFreeDiskSpaceStep : public AbstractRemoteLinuxDeployStep
{
Q_OBJECT
+
public:
explicit RemoteLinuxCheckForFreeDiskSpaceStep(ProjectExplorer::BuildStepList *bsl);
~RemoteLinuxCheckForFreeDiskSpaceStep() override;
static Core::Id stepId();
static QString displayName();
-
-protected:
- CheckResult initInternal() override;
- AbstractRemoteLinuxDeployService *deployService() const override;
-
-private:
- Internal::RemoteLinuxCheckForFreeDiskSpaceStepPrivate *d;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.cpp b/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.cpp
index 87c82e52f8..61aebbe893 100644
--- a/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.cpp
+++ b/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.cpp
@@ -31,44 +31,27 @@
using namespace ProjectExplorer;
namespace RemoteLinux {
-namespace Internal {
-
-class RemoteLinuxCustomCommandDeploymentStepPrivate
-{
-public:
- BaseStringAspect *commandLineAspect;
- RemoteLinuxCustomCommandDeployService service;
-};
-
-} // namespace Internal
RemoteLinuxCustomCommandDeploymentStep::RemoteLinuxCustomCommandDeploymentStep(BuildStepList *bsl)
: AbstractRemoteLinuxDeployStep(bsl, stepId())
{
- d = new Internal::RemoteLinuxCustomCommandDeploymentStepPrivate;
- d->commandLineAspect = addAspect<BaseStringAspect>();
- d->commandLineAspect->setSettingsKey("RemoteLinuxCustomCommandDeploymentStep.CommandLine");
- d->commandLineAspect->setLabelText(tr("Command line:"));
- d->commandLineAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
- setDefaultDisplayName(displayName());
-}
+ auto service = createDeployService<RemoteLinuxCustomCommandDeployService>();
-RemoteLinuxCustomCommandDeploymentStep::~RemoteLinuxCustomCommandDeploymentStep()
-{
- delete d;
-}
+ auto commandLine = addAspect<BaseStringAspect>();
+ commandLine->setSettingsKey("RemoteLinuxCustomCommandDeploymentStep.CommandLine");
+ commandLine->setLabelText(tr("Command line:"));
+ commandLine->setDisplayStyle(BaseStringAspect::LineEditDisplay);
-CheckResult RemoteLinuxCustomCommandDeploymentStep::initInternal()
-{
- d->service.setCommandLine(d->commandLineAspect->value().trimmed());
- return d->service.isDeploymentPossible();
-}
+ setDefaultDisplayName(displayName());
-AbstractRemoteLinuxDeployService *RemoteLinuxCustomCommandDeploymentStep::deployService() const
-{
- return &d->service;
+ setInternalInitializer([service, commandLine] {
+ service->setCommandLine(commandLine->value().trimmed());
+ return service->isDeploymentPossible();
+ });
}
+RemoteLinuxCustomCommandDeploymentStep::~RemoteLinuxCustomCommandDeploymentStep() = default;
+
Core::Id RemoteLinuxCustomCommandDeploymentStep::stepId()
{
return "RemoteLinux.GenericRemoteLinuxCustomCommandDeploymentStep";
diff --git a/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.h b/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.h
index 325ceb0ebd..56f3ecac29 100644
--- a/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.h
+++ b/src/plugins/remotelinux/remotelinuxcustomcommanddeploymentstep.h
@@ -28,24 +28,18 @@
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
-namespace Internal { class RemoteLinuxCustomCommandDeploymentStepPrivate; }
class REMOTELINUX_EXPORT RemoteLinuxCustomCommandDeploymentStep
: public AbstractRemoteLinuxDeployStep
{
Q_OBJECT
+
public:
explicit RemoteLinuxCustomCommandDeploymentStep(ProjectExplorer::BuildStepList *bsl);
~RemoteLinuxCustomCommandDeploymentStep() override;
static Core::Id stepId();
static QString displayName();
-
-private:
- CheckResult initInternal() override;
- AbstractRemoteLinuxDeployService *deployService() const override;
-
- Internal::RemoteLinuxCustomCommandDeploymentStepPrivate *d;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp
index a375716aab..d43cc7a9f1 100644
--- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp
@@ -33,8 +33,6 @@
#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtoutputformatter.h>
-
#include <utils/hostosinfo.h>
using namespace ProjectExplorer;
@@ -68,7 +66,6 @@ RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *tar
addAspect<X11ForwardingAspect>();
setDefaultDisplayName(runConfigDefaultDisplayName());
- setOutputFormatter<QtSupport::QtOutputFormatter>();
}
bool RemoteLinuxCustomRunConfiguration::isConfigured() const
diff --git a/src/plugins/remotelinux/remotelinuxenvironmentaspect.cpp b/src/plugins/remotelinux/remotelinuxenvironmentaspect.cpp
index 36d2d03e2d..4b8c4a5ad8 100644
--- a/src/plugins/remotelinux/remotelinuxenvironmentaspect.cpp
+++ b/src/plugins/remotelinux/remotelinuxenvironmentaspect.cpp
@@ -34,7 +34,7 @@ const char DISPLAY_KEY[] = "DISPLAY";
const char VERSION_KEY[] = "RemoteLinux.EnvironmentAspect.Version";
const int ENVIRONMENTASPECT_VERSION = 1; // Version was introduced in 4.3 with the value 1
-static bool displayAlreadySet(const QList<Utils::EnvironmentItem> &changes)
+static bool displayAlreadySet(const Utils::EnvironmentItems &changes)
{
return Utils::contains(changes, [](const Utils::EnvironmentItem &item) {
return item.name == DISPLAY_KEY;
diff --git a/src/plugins/remotelinux/remotelinuxenvironmentreader.cpp b/src/plugins/remotelinux/remotelinuxenvironmentreader.cpp
index 33543f6ee1..45edb51a1a 100644
--- a/src/plugins/remotelinux/remotelinuxenvironmentreader.cpp
+++ b/src/plugins/remotelinux/remotelinuxenvironmentreader.cpp
@@ -30,6 +30,7 @@
#include <projectexplorer/runcontrol.h>
using namespace ProjectExplorer;
+using namespace Utils;
namespace RemoteLinux {
namespace Internal {
@@ -56,7 +57,7 @@ void RemoteLinuxEnvironmentReader::start()
connect(m_deviceProcess, &DeviceProcess::finished,
this, &RemoteLinuxEnvironmentReader::remoteProcessFinished);
Runnable runnable;
- runnable.executable = QLatin1String("env");
+ runnable.executable = FilePath::fromString("env");
m_deviceProcess->start(runnable);
}
diff --git a/src/plugins/remotelinux/remotelinuxkillappservice.cpp b/src/plugins/remotelinux/remotelinuxkillappservice.cpp
index f033635444..c3ce06c254 100644
--- a/src/plugins/remotelinux/remotelinuxkillappservice.cpp
+++ b/src/plugins/remotelinux/remotelinuxkillappservice.cpp
@@ -35,9 +35,8 @@ public:
};
} // namespace Internal
-RemoteLinuxKillAppService::RemoteLinuxKillAppService(QObject *parent)
- : AbstractRemoteLinuxDeployService(parent),
- d(new Internal::RemoteLinuxKillAppServicePrivate)
+RemoteLinuxKillAppService::RemoteLinuxKillAppService()
+ : d(new Internal::RemoteLinuxKillAppServicePrivate)
{
}
diff --git a/src/plugins/remotelinux/remotelinuxkillappservice.h b/src/plugins/remotelinux/remotelinuxkillappservice.h
index 16dd33908e..c3ff4f5e0e 100644
--- a/src/plugins/remotelinux/remotelinuxkillappservice.h
+++ b/src/plugins/remotelinux/remotelinuxkillappservice.h
@@ -34,7 +34,7 @@ class REMOTELINUX_EXPORT RemoteLinuxKillAppService : public AbstractRemoteLinuxD
{
Q_OBJECT
public:
- RemoteLinuxKillAppService(QObject *parent = nullptr);
+ RemoteLinuxKillAppService();
~RemoteLinuxKillAppService() override;
void setRemoteExecutable(const QString &filePath);
diff --git a/src/plugins/remotelinux/remotelinuxkillappstep.cpp b/src/plugins/remotelinux/remotelinuxkillappstep.cpp
index f6dd121e7c..c9a9025979 100644
--- a/src/plugins/remotelinux/remotelinuxkillappstep.cpp
+++ b/src/plugins/remotelinux/remotelinuxkillappstep.cpp
@@ -31,32 +31,26 @@
#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
-#include <QString>
-
using namespace ProjectExplorer;
namespace RemoteLinux {
RemoteLinuxKillAppStep::RemoteLinuxKillAppStep(BuildStepList *bsl, Core::Id id)
- : AbstractRemoteLinuxDeployStep(bsl, id), m_service(new RemoteLinuxKillAppService(this))
+ : AbstractRemoteLinuxDeployStep(bsl, id)
{
+ auto service = createDeployService<RemoteLinuxKillAppService>();
+
setDefaultDisplayName(displayName());
setWidgetExpandedByDefault(false);
-}
-CheckResult RemoteLinuxKillAppStep::initInternal()
-{
- Target * const theTarget = target();
- QTC_ASSERT(theTarget, return CheckResult::failure());
- RunConfiguration * const rc = theTarget->activeRunConfiguration();
- const QString remoteExe = rc ? rc->runnable().executable : QString();
- m_service->setRemoteExecutable(remoteExe);
- return CheckResult::success();
-}
-
-AbstractRemoteLinuxDeployService *RemoteLinuxKillAppStep::deployService() const
-{
- return m_service;
+ setInternalInitializer([this, service] {
+ Target * const theTarget = target();
+ QTC_ASSERT(theTarget, return CheckResult::failure());
+ RunConfiguration * const rc = theTarget->activeRunConfiguration();
+ const QString remoteExe = rc ? rc->runnable().executable.toString() : QString();
+ service->setRemoteExecutable(remoteExe);
+ return CheckResult::success();
+ });
}
Core::Id RemoteLinuxKillAppStep::stepId()
diff --git a/src/plugins/remotelinux/remotelinuxkillappstep.h b/src/plugins/remotelinux/remotelinuxkillappstep.h
index 183db57b2a..7aec59acd9 100644
--- a/src/plugins/remotelinux/remotelinuxkillappstep.h
+++ b/src/plugins/remotelinux/remotelinuxkillappstep.h
@@ -28,7 +28,6 @@
#include "abstractremotelinuxdeploystep.h"
namespace RemoteLinux {
-class RemoteLinuxKillAppService;
class REMOTELINUX_EXPORT RemoteLinuxKillAppStep : public AbstractRemoteLinuxDeployStep
{
@@ -39,12 +38,6 @@ public:
static Core::Id stepId();
static QString displayName();
-
-private:
- CheckResult initInternal() override;
- AbstractRemoteLinuxDeployService *deployService() const override;
-
- RemoteLinuxKillAppService * const m_service;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp
index 1f25666cbf..036750f466 100644
--- a/src/plugins/remotelinux/remotelinuxplugin.cpp
+++ b/src/plugins/remotelinux/remotelinuxplugin.cpp
@@ -25,7 +25,6 @@
#include "remotelinuxplugin.h"
-#include "embeddedlinuxqtversion.h"
#include "linuxdevice.h"
#include "remotelinux_constants.h"
#include "remotelinuxqmltoolingsupport.h"
@@ -82,7 +81,32 @@ public:
checkForFreeDiskSpaceStepFactory;
GenericDeployStepFactory<RemoteLinuxKillAppStep> remoteLinuxKillAppStepFactory;
GenericDeployStepFactory<MakeInstallStep> makeInstallStepFactory;
- EmbeddedLinuxQtVersionFactory embeddedLinuxQtVersionFactory;
+
+ const QList<Core::Id> supportedRunConfigs {
+ runConfigurationFactory.id(),
+ customRunConfigurationFactory.id(),
+ "QmlProjectManager.QmlRunConfiguration"
+ };
+
+ RunWorkerFactory runnerFactory{
+ RunWorkerFactory::make<SimpleTargetRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ supportedRunConfigs,
+ {Constants::GenericLinuxOsType}
+ };
+ RunWorkerFactory debuggerFactory{
+ RunWorkerFactory::make<LinuxDeviceDebugSupport>(),
+ {ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ supportedRunConfigs,
+ {Constants::GenericLinuxOsType}
+ };
+ RunWorkerFactory qmlToolingFactory{
+ RunWorkerFactory::make<RemoteLinuxQmlToolingSupport>(),
+ {ProjectExplorer::Constants::QML_PROFILER_RUN_MODE,
+ ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE},
+ supportedRunConfigs,
+ {Constants::GenericLinuxOsType}
+ };
};
static RemoteLinuxPluginPrivate *dd = nullptr;
@@ -104,25 +128,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments, QString *errorM
dd = new RemoteLinuxPluginPrivate;
- auto constraint = [](RunConfiguration *runConfig) {
- const Core::Id devType = ProjectExplorer::DeviceTypeKitAspect::deviceTypeId(
- runConfig->target()->kit());
-
- if (devType != Constants::GenericLinuxOsType)
- return false;
-
- const Core::Id id = runConfig->id();
- return id == RemoteLinuxCustomRunConfiguration::runConfigId()
- || id.name().startsWith(RemoteLinuxRunConfiguration::IdPrefix)
- || id.name().startsWith("QmlProjectManager.QmlRunConfiguration");
- };
-
- using namespace ProjectExplorer::Constants;
- RunControl::registerWorker<SimpleTargetRunner>(NORMAL_RUN_MODE, constraint);
- RunControl::registerWorker<LinuxDeviceDebugSupport>(DEBUG_RUN_MODE, constraint);
- RunControl::registerWorker<RemoteLinuxQmlProfilerSupport>(QML_PROFILER_RUN_MODE, constraint);
- RunControl::registerWorker<RemoteLinuxQmlPreviewSupport>(QML_PREVIEW_RUN_MODE, constraint);
-
return true;
}
diff --git a/src/plugins/remotelinux/remotelinuxqmltoolingsupport.cpp b/src/plugins/remotelinux/remotelinuxqmltoolingsupport.cpp
index 49f6851068..2dd5214617 100644
--- a/src/plugins/remotelinux/remotelinuxqmltoolingsupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxqmltoolingsupport.cpp
@@ -25,9 +25,9 @@
#include "remotelinuxqmltoolingsupport.h"
-#include <ssh/sshconnection.h>
-#include <utils/qtcprocess.h>
-#include <utils/url.h>
+#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
+
+#include <qmldebug/qmldebugcommandlinearguments.h>
using namespace ProjectExplorer;
using namespace Utils;
@@ -35,43 +35,35 @@ using namespace Utils;
namespace RemoteLinux {
namespace Internal {
-// RemoteLinuxQmlProfilerSupport
-
-RemoteLinuxQmlToolingSupport::RemoteLinuxQmlToolingSupport(
- RunControl *runControl, QmlDebug::QmlDebugServicesPreset services)
- : SimpleTargetRunner(runControl), m_services(services)
+RemoteLinuxQmlToolingSupport::RemoteLinuxQmlToolingSupport(RunControl *runControl)
+ : SimpleTargetRunner(runControl)
{
setId("RemoteLinuxQmlToolingSupport");
- m_portsGatherer = new PortsGatherer(runControl);
- addStartDependency(m_portsGatherer);
+ auto portsGatherer = new PortsGatherer(runControl);
+ addStartDependency(portsGatherer);
// The ports gatherer can safely be stopped once the process is running, even though it has to
// be started before.
- addStopDependency(m_portsGatherer);
+ addStopDependency(portsGatherer);
- m_runworker = runControl->createWorker(runControl->runMode());
- m_runworker->addStartDependency(this);
- addStopDependency(m_runworker);
-}
-
-void RemoteLinuxQmlToolingSupport::start()
-{
- Port qmlPort = m_portsGatherer->findPort();
+ auto runworker = runControl->createWorker(QmlDebug::runnerIdForRunMode(runControl->runMode()));
+ runworker->addStartDependency(this);
+ addStopDependency(runworker);
- QUrl serverUrl;
- serverUrl.setScheme(urlTcpScheme());
- serverUrl.setHost(device()->sshParameters().host());
- serverUrl.setPort(qmlPort.number());
- m_runworker->recordData("QmlServerUrl", serverUrl);
+ setStarter([this, runControl, portsGatherer, runworker] {
+ const QUrl serverUrl = portsGatherer->findEndPoint();
+ runworker->recordData("QmlServerUrl", serverUrl);
- Runnable r = runnable();
- QtcProcess::addArg(&r.commandLineArguments, QmlDebug::qmlDebugTcpArguments(m_services, qmlPort),
- device()->osType());
+ QmlDebug::QmlDebugServicesPreset services = QmlDebug::servicesForRunMode(runControl->runMode());
- setRunnable(r);
+ Runnable r = runControl->runnable();
+ QtcProcess::addArg(&r.commandLineArguments,
+ QmlDebug::qmlDebugTcpArguments(services, serverUrl),
+ OsTypeLinux);
- SimpleTargetRunner::start();
+ doStart(r, runControl->device());
+ });
}
} // namespace Internal
diff --git a/src/plugins/remotelinux/remotelinuxqmltoolingsupport.h b/src/plugins/remotelinux/remotelinuxqmltoolingsupport.h
index 0677b425fc..9cfa927a0a 100644
--- a/src/plugins/remotelinux/remotelinuxqmltoolingsupport.h
+++ b/src/plugins/remotelinux/remotelinuxqmltoolingsupport.h
@@ -25,9 +25,7 @@
#pragma once
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-#include <projectexplorer/runconfiguration.h>
-#include <qmldebug/qmldebugcommandlinearguments.h>
+#include <projectexplorer/runcontrol.h>
namespace RemoteLinux {
namespace Internal {
@@ -35,31 +33,7 @@ namespace Internal {
class RemoteLinuxQmlToolingSupport : public ProjectExplorer::SimpleTargetRunner
{
public:
- RemoteLinuxQmlToolingSupport(ProjectExplorer::RunControl *runControl,
- QmlDebug::QmlDebugServicesPreset services);
-
-private:
- void start() override;
-
- ProjectExplorer::PortsGatherer *m_portsGatherer;
- ProjectExplorer::RunWorker *m_runworker;
- QmlDebug::QmlDebugServicesPreset m_services;
-};
-
-class RemoteLinuxQmlProfilerSupport : public RemoteLinuxQmlToolingSupport
-{
-public:
- RemoteLinuxQmlProfilerSupport(ProjectExplorer::RunControl *runControl) :
- RemoteLinuxQmlToolingSupport(runControl, QmlDebug::QmlProfilerServices)
- {}
-};
-
-class RemoteLinuxQmlPreviewSupport : public RemoteLinuxQmlToolingSupport
-{
-public:
- RemoteLinuxQmlPreviewSupport(ProjectExplorer::RunControl *runControl) :
- RemoteLinuxQmlToolingSupport(runControl, QmlDebug::QmlPreviewServices)
- {}
+ explicit RemoteLinuxQmlToolingSupport(ProjectExplorer::RunControl *runControl);
};
} // namespace Internal
diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
index f636799af8..745858dd41 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp
@@ -37,14 +37,13 @@
#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtoutputformatter.h>
-
#include <utils/hostosinfo.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
+namespace Internal {
RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::Id id)
: RunConfiguration(target, id)
@@ -66,11 +65,9 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::I
if (HostOsInfo::isAnyUnixHost())
addAspect<TerminalAspect>();
addAspect<RemoteLinuxEnvironmentAspect>(target);
- if (id == IdPrefix && Utils::HostOsInfo::isAnyUnixHost())
+ if (HostOsInfo::isAnyUnixHost())
addAspect<X11ForwardingAspect>();
- setOutputFormatter<QtSupport::QtOutputFormatter>();
-
connect(target, &Target::deploymentDataChanged,
this, &RemoteLinuxRunConfiguration::updateTargetInformation);
connect(target, &Target::applicationTargetsChanged,
@@ -93,11 +90,11 @@ Runnable RemoteLinuxRunConfiguration::runnable() const
void RemoteLinuxRunConfiguration::updateTargetInformation()
{
BuildTargetInfo bti = buildTargetInfo();
- QString localExecutable = bti.targetFilePath.toString();
+ const FilePath localExecutable = bti.targetFilePath;
DeployableFile depFile = target()->deploymentData().deployableForLocalFile(localExecutable);
aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(depFile.remoteFilePath()));
- aspect<SymbolFileAspect>()->setValue(localExecutable);
+ aspect<SymbolFileAspect>()->setFilePath(localExecutable);
emit enabledChanged();
}
@@ -114,4 +111,5 @@ RemoteLinuxRunConfigurationFactory::RemoteLinuxRunConfigurationFactory()
addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType);
}
+} // namespace Internal
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.h b/src/plugins/remotelinux/remotelinuxrunconfiguration.h
index 1990660d76..d685d19ea8 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfiguration.h
+++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.h
@@ -30,8 +30,9 @@
#include <projectexplorer/runconfiguration.h>
namespace RemoteLinux {
+namespace Internal {
-class REMOTELINUX_EXPORT RemoteLinuxRunConfiguration : public ProjectExplorer::RunConfiguration
+class RemoteLinuxRunConfiguration final : public ProjectExplorer::RunConfiguration
{
Q_OBJECT
@@ -46,10 +47,11 @@ private:
void updateTargetInformation();
};
-class RemoteLinuxRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
+class RemoteLinuxRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory
{
public:
RemoteLinuxRunConfigurationFactory();
};
+} // namespace Internal
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/rsyncdeploystep.cpp b/src/plugins/remotelinux/rsyncdeploystep.cpp
index 25dc0b28d5..19429e7778 100644
--- a/src/plugins/remotelinux/rsyncdeploystep.cpp
+++ b/src/plugins/remotelinux/rsyncdeploystep.cpp
@@ -177,55 +177,37 @@ void RsyncDeployService::setFinished()
} // namespace Internal
-class RsyncDeployStep::RsyncDeployStepPrivate
-{
-public:
- Internal::RsyncDeployService deployService;
- BaseBoolAspect *ignoreMissingFilesAspect;
- BaseStringAspect *flagsAspect;
-};
-
RsyncDeployStep::RsyncDeployStep(BuildStepList *bsl)
- : AbstractRemoteLinuxDeployStep(bsl, stepId()), d(new RsyncDeployStepPrivate)
+ : AbstractRemoteLinuxDeployStep(bsl, stepId())
{
- d->flagsAspect = addAspect<BaseStringAspect>();
- d->flagsAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
- d->flagsAspect->setSettingsKey("RemoteLinux.RsyncDeployStep.Flags");
- d->flagsAspect->setLabelText(tr("Flags:"));
- d->flagsAspect->setValue(defaultFlags());
-
- d->ignoreMissingFilesAspect = addAspect<BaseBoolAspect>();
- d->ignoreMissingFilesAspect
- ->setSettingsKey("RemoteLinux.RsyncDeployStep.IgnoreMissingFiles");
- d->ignoreMissingFilesAspect->setLabel(tr("Ignore missing files"));
- d->ignoreMissingFilesAspect->setValue(false);
+ auto service = createDeployService<Internal::RsyncDeployService>();
- setDefaultDisplayName(displayName());
-}
+ auto flags = addAspect<BaseStringAspect>();
+ flags->setDisplayStyle(BaseStringAspect::LineEditDisplay);
+ flags->setSettingsKey("RemoteLinux.RsyncDeployStep.Flags");
+ flags->setLabelText(tr("Flags:"));
+ flags->setValue(defaultFlags());
-RsyncDeployStep::~RsyncDeployStep()
-{
- delete d;
-}
+ auto ignoreMissingFiles = addAspect<BaseBoolAspect>();
+ ignoreMissingFiles->setSettingsKey("RemoteLinux.RsyncDeployStep.IgnoreMissingFiles");
+ ignoreMissingFiles->setLabel(tr("Ignore missing files"));
+ ignoreMissingFiles->setValue(false);
-CheckResult RsyncDeployStep::initInternal()
-{
- d->deployService.setIgnoreMissingFiles(d->ignoreMissingFilesAspect->value());
- d->deployService.setFlags(d->flagsAspect->value());
- return d->deployService.isDeploymentPossible();
-}
+ setDefaultDisplayName(displayName());
-AbstractRemoteLinuxDeployService *RsyncDeployStep::deployService() const
-{
- return &d->deployService;
-}
+ setInternalInitializer([service, flags, ignoreMissingFiles] {
+ service->setIgnoreMissingFiles(ignoreMissingFiles->value());
+ service->setFlags(flags->value());
+ return service->isDeploymentPossible();
+ });
-void RsyncDeployStep::doRun()
-{
- d->deployService.setDeployableFiles(target()->deploymentData().allFiles());
- AbstractRemoteLinuxDeployStep::doRun();
+ setRunPreparer([this, service] {
+ service->setDeployableFiles(target()->deploymentData().allFiles());
+ });
}
+RsyncDeployStep::~RsyncDeployStep() = default;
+
Core::Id RsyncDeployStep::stepId()
{
return "RemoteLinux.RsyncDeployStep";
diff --git a/src/plugins/remotelinux/rsyncdeploystep.h b/src/plugins/remotelinux/rsyncdeploystep.h
index e71a57a11d..746715d5e3 100644
--- a/src/plugins/remotelinux/rsyncdeploystep.h
+++ b/src/plugins/remotelinux/rsyncdeploystep.h
@@ -54,15 +54,6 @@ public:
static QString defaultFlags();
static RsyncCommandLine rsyncCommand(const QSsh::SshConnection &sshConnection,
const QString &flags);
-
-private:
- AbstractRemoteLinuxDeployService *deployService() const override;
- void doRun() override;
-
- CheckResult initInternal() override;
-
- class RsyncDeployStepPrivate;
- RsyncDeployStepPrivate * const d;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp
index 67302cf3c6..e8165bee7c 100644
--- a/src/plugins/remotelinux/tarpackagecreationstep.cpp
+++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp
@@ -29,7 +29,7 @@
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
-#include <qtsupport/qtkitinformation.h>
+
#include <ssh/sshconnection.h>
#include <ssh/sshconnectionmanager.h>
@@ -82,6 +82,14 @@ TarPackageCreationStep::TarPackageCreationStep(BuildStepList *bsl)
m_incrementalDeploymentAspect = addAspect<BaseBoolAspect>();
m_incrementalDeploymentAspect->setLabel(tr("Package modified files only"));
m_incrementalDeploymentAspect->setSettingsKey(IncrementalDeploymentKey);
+
+ setSummaryUpdater([this] {
+ QString path = packageFilePath();
+ if (path.isEmpty())
+ return QString("<font color=\"red\">" + tr("Tarball creation not possible.")
+ + "</font>");
+ return QString("<b>" + tr("Create tarball:") + "</b> " + path);
+ });
}
bool TarPackageCreationStep::init()
@@ -355,29 +363,6 @@ bool TarPackageCreationStep::runImpl()
return success;
}
-BuildStepConfigWidget *TarPackageCreationStep::createConfigWidget()
-{
- auto widget = BuildStep::createConfigWidget();
-
- auto updateSummary = [this, widget] {
- QString path = packageFilePath();
- if (path.isEmpty()) {
- widget->setSummaryText("<font color=\"red\">"
- + tr("Tarball creation not possible.")
- + "</font>");
- } else {
- widget->setSummaryText("<b>" + tr("Create tarball:") + "</b> " + path);
- }
- };
-
- connect(this, &AbstractPackagingStep::packageFilePathChanged,
- this, updateSummary);
-
- updateSummary();
-
- return widget;
-}
-
bool TarPackageCreationStep::fromMap(const QVariantMap &map)
{
if (!AbstractPackagingStep::fromMap(map))
diff --git a/src/plugins/remotelinux/tarpackagecreationstep.h b/src/plugins/remotelinux/tarpackagecreationstep.h
index 1d359032bd..fca28eae67 100644
--- a/src/plugins/remotelinux/tarpackagecreationstep.h
+++ b/src/plugins/remotelinux/tarpackagecreationstep.h
@@ -63,7 +63,6 @@ private:
void addNeededDeploymentFiles(const ProjectExplorer::DeployableFile &deployable,
const ProjectExplorer::Kit *kit);
- ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
diff --git a/src/plugins/remotelinux/uploadandinstalltarpackagestep.cpp b/src/plugins/remotelinux/uploadandinstalltarpackagestep.cpp
index cf1c2face6..585f28da59 100644
--- a/src/plugins/remotelinux/uploadandinstalltarpackagestep.cpp
+++ b/src/plugins/remotelinux/uploadandinstalltarpackagestep.cpp
@@ -44,9 +44,8 @@ public:
using namespace Internal;
-UploadAndInstallTarPackageService::UploadAndInstallTarPackageService(QObject *parent)
- : AbstractUploadAndInstallPackageService(parent),
- d(new UploadAndInstallTarPackageServicePrivate)
+UploadAndInstallTarPackageService::UploadAndInstallTarPackageService()
+ : d(new UploadAndInstallTarPackageServicePrivate)
{
}
@@ -64,26 +63,26 @@ AbstractRemoteLinuxPackageInstaller *UploadAndInstallTarPackageService::packageI
UploadAndInstallTarPackageStep::UploadAndInstallTarPackageStep(BuildStepList *bsl)
: AbstractRemoteLinuxDeployStep(bsl, stepId())
{
- m_deployService = new UploadAndInstallTarPackageService(this);
+ auto service = createDeployService<UploadAndInstallTarPackageService>();
+
setDefaultDisplayName(displayName());
setWidgetExpandedByDefault(false);
-}
-CheckResult UploadAndInstallTarPackageStep::initInternal()
-{
- const TarPackageCreationStep *pStep = nullptr;
-
- for (BuildStep *step : deployConfiguration()->stepList()->steps()) {
- if (step == this)
- break;
- if ((pStep = dynamic_cast<TarPackageCreationStep *>(step)))
- break;
- }
- if (!pStep)
- return CheckResult::failure(tr("No tarball creation step found."));
-
- m_deployService->setPackageFilePath(pStep->packageFilePath());
- return m_deployService->isDeploymentPossible();
+ setInternalInitializer([this, service] {
+ const TarPackageCreationStep *pStep = nullptr;
+
+ for (BuildStep *step : deployConfiguration()->stepList()->steps()) {
+ if (step == this)
+ break;
+ if ((pStep = dynamic_cast<TarPackageCreationStep *>(step)))
+ break;
+ }
+ if (!pStep)
+ return CheckResult::failure(tr("No tarball creation step found."));
+
+ service->setPackageFilePath(pStep->packageFilePath());
+ return service->isDeploymentPossible();
+ });
}
Core::Id UploadAndInstallTarPackageStep::stepId()
diff --git a/src/plugins/remotelinux/uploadandinstalltarpackagestep.h b/src/plugins/remotelinux/uploadandinstalltarpackagestep.h
index a613e7426f..d4566470ee 100644
--- a/src/plugins/remotelinux/uploadandinstalltarpackagestep.h
+++ b/src/plugins/remotelinux/uploadandinstalltarpackagestep.h
@@ -38,7 +38,7 @@ class REMOTELINUX_EXPORT UploadAndInstallTarPackageService : public AbstractUplo
Q_OBJECT
public:
- explicit UploadAndInstallTarPackageService(QObject *parent);
+ UploadAndInstallTarPackageService();
~UploadAndInstallTarPackageService() override;
private:
@@ -55,15 +55,8 @@ class REMOTELINUX_EXPORT UploadAndInstallTarPackageStep : public AbstractRemoteL
public:
explicit UploadAndInstallTarPackageStep(ProjectExplorer::BuildStepList *bsl);
- CheckResult initInternal() override;
-
static Core::Id stepId();
static QString displayName();
-
-private:
- AbstractRemoteLinuxDeployService *deployService() const override { return m_deployService; }
-
- UploadAndInstallTarPackageService *m_deployService;
};
} //namespace RemoteLinux
diff --git a/src/plugins/resourceeditor/qrceditor/qrceditor.cpp b/src/plugins/resourceeditor/qrceditor/qrceditor.cpp
index 3c0041be83..8384ab0a34 100644
--- a/src/plugins/resourceeditor/qrceditor/qrceditor.cpp
+++ b/src/plugins/resourceeditor/qrceditor/qrceditor.cpp
@@ -39,29 +39,21 @@ using namespace ResourceEditor;
using namespace ResourceEditor::Internal;
QrcEditor::QrcEditor(RelativeResourceModel *model, QWidget *parent)
- : QWidget(parent),
+ : Core::MiniSplitter(Qt::Vertical, parent),
m_treeview(new ResourceView(model, &m_history))
{
- m_ui.setupUi(this);
- auto layout = new QHBoxLayout;
- layout->setSpacing(0);
- layout->setMargin(0);
- m_ui.centralWidget->setLayout(layout);
+ addWidget(m_treeview);
+ auto widget = new QWidget;
+ m_ui.setupUi(widget);
+ addWidget(widget);
m_treeview->setFrameStyle(QFrame::NoFrame);
- layout->addWidget(m_treeview);
+ connect(m_ui.addPrefixButton, &QAbstractButton::clicked, this, &QrcEditor::onAddPrefix);
+ connect(m_ui.addFilesButton, &QAbstractButton::clicked, this, &QrcEditor::onAddFiles);
connect(m_ui.removeButton, &QAbstractButton::clicked, this, &QrcEditor::onRemove);
connect(m_ui.removeNonExistingButton, &QPushButton::clicked,
this, &QrcEditor::onRemoveNonExisting);
- // 'Add' button with menu
- auto addMenu = new QMenu(this);
- m_addFileAction = addMenu->addAction(tr("Add Files"));
- connect(m_addFileAction, &QAction::triggered, this, &QrcEditor::onAddFiles);
- connect(addMenu->addAction(tr("Add Prefix")), &QAction::triggered,
- this, &QrcEditor::onAddPrefix);
- m_ui.addButton->setMenu(addMenu);
-
connect(m_treeview, &ResourceView::removeItem, this, &QrcEditor::onRemove);
connect(m_treeview->selectionModel(), &QItemSelectionModel::currentChanged,
this, &QrcEditor::updateCurrent);
@@ -139,8 +131,7 @@ void QrcEditor::updateCurrent()
m_currentLanguage = m_treeview->currentLanguage();
m_ui.languageText->setText(m_currentLanguage);
- m_ui.addButton->setEnabled(true);
- m_addFileAction->setEnabled(isValid);
+ m_ui.addFilesButton->setEnabled(isValid);
m_ui.removeButton->setEnabled(isValid);
}
diff --git a/src/plugins/resourceeditor/qrceditor/qrceditor.h b/src/plugins/resourceeditor/qrceditor/qrceditor.h
index e6f7c1cf8a..9273f8c6cf 100644
--- a/src/plugins/resourceeditor/qrceditor/qrceditor.h
+++ b/src/plugins/resourceeditor/qrceditor/qrceditor.h
@@ -28,13 +28,13 @@
#include "ui_qrceditor.h"
#include "resourceview.h"
-#include <QWidget>
+#include <coreplugin/minisplitter.h>
#include <QUndoStack>
namespace ResourceEditor {
namespace Internal {
-class QrcEditor : public QWidget
+class QrcEditor : public Core::MiniSplitter
{
Q_OBJECT
@@ -79,7 +79,6 @@ private:
Ui::QrcEditor m_ui;
QUndoStack m_history;
ResourceView *m_treeview;
- QAction *m_addFileAction = nullptr;
QString m_currentAlias;
QString m_currentPrefix;
diff --git a/src/plugins/resourceeditor/qrceditor/qrceditor.ui b/src/plugins/resourceeditor/qrceditor/qrceditor.ui
index 5bac2230ce..98035b4382 100644
--- a/src/plugins/resourceeditor/qrceditor/qrceditor.ui
+++ b/src/plugins/resourceeditor/qrceditor/qrceditor.ui
@@ -6,14 +6,17 @@
<rect>
<x>0</x>
<y>0</y>
- <width>491</width>
- <height>381</height>
+ <width>521</width>
+ <height>180</height>
</rect>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
<property name="leftMargin">
<number>0</number>
</property>
@@ -27,138 +30,114 @@
<number>0</number>
</property>
<item>
- <widget class="QWidget" name="centralWidget" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="addPrefixButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Add Prefix</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addFilesButton">
+ <property name="text">
+ <string>Add Files</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeNonExistingButton">
+ <property name="text">
+ <string>Remove Missing Files</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
<item>
- <widget class="Line" name="line">
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>1</height>
- </size>
- </property>
- <property name="styleSheet">
- <string notr="true">color: #666666</string>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Properties</string>
</property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="widget" native="true">
- <layout class="QGridLayout" name="gridLayout">
- <property name="leftMargin">
- <number>6</number>
- </property>
- <property name="topMargin">
- <number>6</number>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinAndMaxSize</enum>
</property>
- <property name="rightMargin">
- <number>6</number>
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QPushButton" name="addButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Add</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="removeButton">
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="removeNonExistingButton">
- <property name="text">
- <string>Remove Missing Files</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ <widget class="QLabel" name="aliasLabel">
+ <property name="text">
+ <string>Alias:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="aliasText"/>
</item>
<item row="1" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Properties</string>
+ <widget class="QLabel" name="prefixLabel">
+ <property name="text">
+ <string>Prefix:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="prefixText"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="languageLabel">
+ <property name="text">
+ <string>Language:</string>
</property>
- <layout class="QFormLayout" name="formLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinAndMaxSize</enum>
- </property>
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="aliasLabel">
- <property name="text">
- <string>Alias:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="aliasText"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="prefixLabel">
- <property name="text">
- <string>Prefix:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="prefixText"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="languageLabel">
- <property name="text">
- <string>Language:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="languageText"/>
- </item>
- </layout>
</widget>
</item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="languageText"/>
+ </item>
</layout>
</widget>
</item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
<resources/>
diff --git a/src/plugins/resourceeditor/qrceditor/resourceview.cpp b/src/plugins/resourceeditor/qrceditor/resourceview.cpp
index 081bf4bf5d..8e2c70ad79 100644
--- a/src/plugins/resourceeditor/qrceditor/resourceview.cpp
+++ b/src/plugins/resourceeditor/qrceditor/resourceview.cpp
@@ -197,7 +197,7 @@ void ResourceView::refresh()
{
m_qrcModel->refresh();
QModelIndex idx = currentIndex();
- setModel(0);
+ setModel(nullptr);
setModel(m_qrcModel);
setCurrentIndex(idx);
expandAll();
diff --git a/src/plugins/resourceeditor/resourceeditorplugin.cpp b/src/plugins/resourceeditor/resourceeditorplugin.cpp
index 7a5aedc434..1af724504b 100644
--- a/src/plugins/resourceeditor/resourceeditorplugin.cpp
+++ b/src/plugins/resourceeditor/resourceeditorplugin.cpp
@@ -284,7 +284,7 @@ void ResourceEditorPlugin::removeFileContextMenu()
QString path = rfn->filePath().toString();
FolderNode *parent = rfn->parentFolderNode();
QTC_ASSERT(parent, return);
- if (!parent->removeFiles(QStringList() << path))
+ if (parent->removeFiles(QStringList() << path) != RemovedFilesFromProject::Ok)
QMessageBox::warning(Core::ICore::mainWindow(),
tr("File Removal Failed"),
tr("Removing file %1 from the project failed.").arg(path));
diff --git a/src/plugins/resourceeditor/resourceeditorw.cpp b/src/plugins/resourceeditor/resourceeditorw.cpp
index 1dff313993..2255810bb9 100644
--- a/src/plugins/resourceeditor/resourceeditorw.cpp
+++ b/src/plugins/resourceeditor/resourceeditorw.cpp
@@ -229,6 +229,24 @@ void ResourceEditorDocument::setShouldAutoSave(bool save)
m_shouldAutoSave = save;
}
+QByteArray ResourceEditorW::saveState() const
+{
+ QByteArray bytes;
+ QDataStream stream(&bytes, QIODevice::WriteOnly);
+ stream << m_resourceEditor->saveState();
+ return bytes;
+}
+
+bool ResourceEditorW::restoreState(const QByteArray &state)
+{
+ QDataStream stream(state);
+ QByteArray splitterState;
+ stream >> splitterState;
+ if (!m_resourceEditor->restoreState(splitterState))
+ return false;
+ return true;
+}
+
QWidget *ResourceEditorW::toolBar()
{
return m_toolBar;
diff --git a/src/plugins/resourceeditor/resourceeditorw.h b/src/plugins/resourceeditor/resourceeditorw.h
index 14c9c12394..8ac4e8d9b2 100644
--- a/src/plugins/resourceeditor/resourceeditorw.h
+++ b/src/plugins/resourceeditor/resourceeditorw.h
@@ -90,6 +90,8 @@ public:
// IEditor
Core::IDocument *document() const override { return m_resourceDocument; }
+ QByteArray saveState() const override;
+ bool restoreState(const QByteArray &state) override;
QWidget *toolBar() override;
private:
diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp
index c3eb7c24b1..13d23eee23 100644
--- a/src/plugins/resourceeditor/resourcenode.cpp
+++ b/src/plugins/resourceeditor/resourcenode.cpp
@@ -162,7 +162,8 @@ public:
bool supportsAction(ProjectAction, const Node *node) const final;
bool addFiles(const QStringList &filePaths, QStringList *notAdded) final;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) final;
+ RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved) final;
bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
bool renameFile(const QString &filePath, const QString &newFilePath) final;
@@ -197,7 +198,6 @@ bool SimpleResourceFolderNode::supportsAction(ProjectAction action, const Node *
|| action == AddExistingFile
|| action == AddExistingDirectory
|| action == RemoveFile
- || action == DuplicateFile
|| action == Rename // Note: only works for the filename, works akwardly for relative file paths
|| action == InheritedFromParent; // Do not add to list of projects when adding new file
}
@@ -207,7 +207,8 @@ bool SimpleResourceFolderNode::addFiles(const QStringList &filePaths, QStringLis
return addFilesToResource(m_topLevelNode->filePath(), filePaths, notAdded, m_prefix, m_lang);
}
-bool SimpleResourceFolderNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject SimpleResourceFolderNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
return prefixNode()->removeFiles(filePaths, notRemoved);
}
@@ -375,7 +376,8 @@ bool ResourceTopLevelNode::addFiles(const QStringList &filePaths, QStringList *n
return addFilesToResource(filePath(), filePaths, notAdded, QLatin1String("/"), QString());
}
-bool ResourceTopLevelNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject ResourceTopLevelNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
return parentFolderNode()->removeFiles(filePaths, notRemoved);
}
@@ -487,7 +489,6 @@ bool ResourceFolderNode::supportsAction(ProjectAction action, const Node *node)
|| action == AddExistingFile
|| action == AddExistingDirectory
|| action == RemoveFile
- || action == DuplicateFile
|| action == Rename // Note: only works for the filename, works akwardly for relative file paths
|| action == HidePathActions; // hides open terminal etc.
}
@@ -497,16 +498,17 @@ bool ResourceFolderNode::addFiles(const QStringList &filePaths, QStringList *not
return addFilesToResource(m_topLevelNode->filePath(), filePaths, notAdded, m_prefix, m_lang);
}
-bool ResourceFolderNode::removeFiles(const QStringList &filePaths, QStringList *notRemoved)
+RemovedFilesFromProject ResourceFolderNode::removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved)
{
if (notRemoved)
*notRemoved = filePaths;
ResourceFile file(m_topLevelNode->filePath().toString());
if (file.load() != IDocument::OpenResult::Success)
- return false;
+ return RemovedFilesFromProject::Error;
int index = file.indexOfPrefix(m_prefix, m_lang);
if (index == -1)
- return false;
+ return RemovedFilesFromProject::Error;
for (int j = 0; j < file.fileCount(index); ++j) {
QString fileName = file.file(index, j);
if (!filePaths.contains(fileName))
@@ -519,7 +521,7 @@ bool ResourceFolderNode::removeFiles(const QStringList &filePaths, QStringList *
FileChangeBlocker changeGuard(m_topLevelNode->filePath().toString());
file.save();
- return true;
+ return RemovedFilesFromProject::Ok;
}
// QTCREATORBUG-15280
diff --git a/src/plugins/resourceeditor/resourcenode.h b/src/plugins/resourceeditor/resourcenode.h
index 181172a7fe..daa0442bd9 100644
--- a/src/plugins/resourceeditor/resourcenode.h
+++ b/src/plugins/resourceeditor/resourcenode.h
@@ -43,7 +43,8 @@ public:
bool supportsAction(ProjectExplorer::ProjectAction action, const Node *node) const override;
bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved) override;
bool addPrefix(const QString &prefix, const QString &lang);
bool removePrefix(const QString &prefix, const QString &lang);
@@ -70,7 +71,8 @@ public:
QString displayName() const override;
bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
- bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) override;
+ ProjectExplorer::RemovedFilesFromProject removeFiles(const QStringList &filePaths,
+ QStringList *notRemoved) override;
bool canRenameFile(const QString &filePath, const QString &newFilePath) override;
bool renameFile(const QString &filePath, const QString &newFilePath) override;
diff --git a/src/plugins/scxmleditor/common/colorpicker.cpp b/src/plugins/scxmleditor/common/colorpicker.cpp
index fc99976596..bd9e86f0e3 100644
--- a/src/plugins/scxmleditor/common/colorpicker.cpp
+++ b/src/plugins/scxmleditor/common/colorpicker.cpp
@@ -49,7 +49,6 @@ ColorPicker::ColorPicker(const QString &key, QWidget *parent)
auto vBoxLayout = new QVBoxLayout;
vBoxLayout->setContentsMargins(0, 0, 0, 0);
- vBoxLayout->setMargin(0);
vBoxLayout->setSpacing(0);
const int buttonRowsCount = 4;
@@ -58,7 +57,6 @@ ColorPicker::ColorPicker(const QString &key, QWidget *parent)
for (int r = 0; r < buttonRowsCount; ++r) {
auto hBoxLayout = new QHBoxLayout;
hBoxLayout->setContentsMargins(0, 0, 0, 0);
- hBoxLayout->setMargin(0);
hBoxLayout->setSpacing(0);
for (int c = 0; c < buttonColumnsCount; ++c)
diff --git a/src/plugins/scxmleditor/common/graphicsview.cpp b/src/plugins/scxmleditor/common/graphicsview.cpp
index ec50c43a8d..d1ac25cd60 100644
--- a/src/plugins/scxmleditor/common/graphicsview.cpp
+++ b/src/plugins/scxmleditor/common/graphicsview.cpp
@@ -138,7 +138,7 @@ void GraphicsView::zoomOut()
void GraphicsView::wheelEvent(QWheelEvent *event)
{
if (Qt::ControlModifier & event->modifiers()) {
- if (event->delta() > 0)
+ if (event->angleDelta().y() > 0)
zoomIn();
else
zoomOut();
diff --git a/src/plugins/scxmleditor/common/magnifier.cpp b/src/plugins/scxmleditor/common/magnifier.cpp
index 1ffedd2d92..7b92176ada 100644
--- a/src/plugins/scxmleditor/common/magnifier.cpp
+++ b/src/plugins/scxmleditor/common/magnifier.cpp
@@ -89,7 +89,7 @@ void Magnifier::wheelEvent(QWheelEvent *e)
{
QWidget::wheelEvent(e);
- if (e->delta() > 0)
+ if (e->angleDelta().y() > 0)
m_ui.m_graphicsView->scale(1.1, 1.1);
else
m_ui.m_graphicsView->scale(1.0 / 1.1, 1.0 / 1.1);
diff --git a/src/plugins/scxmleditor/common/mainwidget.cpp b/src/plugins/scxmleditor/common/mainwidget.cpp
index d2c880d0d6..298d021910 100644
--- a/src/plugins/scxmleditor/common/mainwidget.cpp
+++ b/src/plugins/scxmleditor/common/mainwidget.cpp
@@ -672,7 +672,7 @@ void MainWidget::createUi()
m_mainContentWidget = new QWidget;
m_mainContentWidget->setLayout(new QVBoxLayout);
- m_mainContentWidget->layout()->setMargin(0);
+ m_mainContentWidget->layout()->setContentsMargins(0, 0, 0, 0);
m_mainContentWidget->layout()->addWidget(m_stackedWidget);
m_mainContentWidget->layout()->addWidget(m_outputPaneWindow);
@@ -692,7 +692,7 @@ void MainWidget::createUi()
setLayout(new QVBoxLayout);
layout()->addWidget(m_horizontalSplitter);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
}
void MainWidget::showEvent(QShowEvent *e)
diff --git a/src/plugins/scxmleditor/common/navigator.cpp b/src/plugins/scxmleditor/common/navigator.cpp
index b907021434..f8624230f9 100644
--- a/src/plugins/scxmleditor/common/navigator.cpp
+++ b/src/plugins/scxmleditor/common/navigator.cpp
@@ -96,7 +96,7 @@ void Navigator::createUi()
setLayout(new QVBoxLayout);
layout()->setSpacing(0);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
layout()->addWidget(titleToolBar);
layout()->addWidget(m_navigatorView);
layout()->addWidget(m_navigatorSlider);
diff --git a/src/plugins/scxmleditor/common/navigatorgraphicsview.cpp b/src/plugins/scxmleditor/common/navigatorgraphicsview.cpp
index 9334aa824c..e49aaaefca 100644
--- a/src/plugins/scxmleditor/common/navigatorgraphicsview.cpp
+++ b/src/plugins/scxmleditor/common/navigatorgraphicsview.cpp
@@ -75,12 +75,16 @@ void NavigatorGraphicsView::paintEvent(QPaintEvent *e)
void NavigatorGraphicsView::wheelEvent(QWheelEvent *event)
{
if (Qt::ControlModifier & event->modifiers()) {
- if (event->delta() > 0)
+ if (event->angleDelta().y() > 0)
emit zoomIn();
else
emit zoomOut();
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
emit moveMainViewTo(mapToScene(event->pos()));
+#else
+ emit moveMainViewTo(mapToScene(event->position().toPoint()));
+#endif
} else
QGraphicsView::wheelEvent(event);
}
diff --git a/src/plugins/scxmleditor/common/shapegroupwidget.cpp b/src/plugins/scxmleditor/common/shapegroupwidget.cpp
index 17edf2fb87..5fe0c15805 100644
--- a/src/plugins/scxmleditor/common/shapegroupwidget.cpp
+++ b/src/plugins/scxmleditor/common/shapegroupwidget.cpp
@@ -76,7 +76,7 @@ void ShapeGroupWidget::createUi()
m_content->setLayout(new Utils::FlowLayout);
setLayout(new QVBoxLayout);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
layout()->addWidget(toolBar);
layout()->addWidget(m_content);
diff --git a/src/plugins/scxmleditor/common/stateproperties.cpp b/src/plugins/scxmleditor/common/stateproperties.cpp
index b9797aeed3..2c181ab8aa 100644
--- a/src/plugins/scxmleditor/common/stateproperties.cpp
+++ b/src/plugins/scxmleditor/common/stateproperties.cpp
@@ -154,7 +154,7 @@ void StateProperties::createUi()
splitter->addWidget(m_contentFrame);
setLayout(new QVBoxLayout);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
layout()->addWidget(propertiesToolBar);
layout()->addWidget(splitter);
diff --git a/src/plugins/scxmleditor/common/structure.cpp b/src/plugins/scxmleditor/common/structure.cpp
index ea5fe972e9..be49e9711d 100644
--- a/src/plugins/scxmleditor/common/structure.cpp
+++ b/src/plugins/scxmleditor/common/structure.cpp
@@ -270,7 +270,7 @@ void Structure::createUi()
m_checkboxFrame = new QWidget;
m_checkboxFrame->setLayout(new QVBoxLayout);
- m_checkboxFrame->layout()->setMargin(0);
+ m_checkboxFrame->layout()->setContentsMargins(0, 0, 0, 0);
auto spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
@@ -279,18 +279,18 @@ void Structure::createUi()
m_tagVisibilityFrame->layout()->addWidget(m_visibleTagsTitle);
m_tagVisibilityFrame->layout()->addWidget(m_checkboxFrame);
m_tagVisibilityFrame->layout()->addWidget(spacer);
- m_tagVisibilityFrame->layout()->setMargin(0);
+ m_tagVisibilityFrame->layout()->setContentsMargins(0, 0, 0, 0);
auto paneInnerFrame = new QWidget;
paneInnerFrame->setLayout(new QHBoxLayout);
paneInnerFrame->layout()->addWidget(m_structureView);
paneInnerFrame->layout()->addWidget(m_tagVisibilityFrame);
- paneInnerFrame->layout()->setMargin(0);
+ paneInnerFrame->layout()->setContentsMargins(0, 0, 0, 0);
setLayout(new QVBoxLayout);
layout()->addWidget(toolBar);
layout()->addWidget(paneInnerFrame);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
}
diff --git a/src/plugins/scxmleditor/outputpane/errorwidget.cpp b/src/plugins/scxmleditor/outputpane/errorwidget.cpp
index 455bd88e7b..bd53724e7f 100644
--- a/src/plugins/scxmleditor/outputpane/errorwidget.cpp
+++ b/src/plugins/scxmleditor/outputpane/errorwidget.cpp
@@ -151,7 +151,7 @@ void ErrorWidget::createUi()
setLayout(new QVBoxLayout);
layout()->addWidget(toolBar);
layout()->addWidget(m_errorsTable);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
layout()->setSpacing(0);
}
diff --git a/src/plugins/scxmleditor/outputpane/outputtabwidget.cpp b/src/plugins/scxmleditor/outputpane/outputtabwidget.cpp
index 678b017be6..be8af10f42 100644
--- a/src/plugins/scxmleditor/outputpane/outputtabwidget.cpp
+++ b/src/plugins/scxmleditor/outputpane/outputtabwidget.cpp
@@ -178,7 +178,7 @@ void OutputTabWidget::createUi()
setLayout(new QVBoxLayout);
layout()->setSpacing(0);
- layout()->setMargin(0);
+ layout()->setContentsMargins(0, 0, 0, 0);
layout()->addWidget(m_toolBar);
layout()->addWidget(m_stackedWidget);
}
diff --git a/src/plugins/scxmleditor/plugin_interface/sceneutils.cpp b/src/plugins/scxmleditor/plugin_interface/sceneutils.cpp
index 016749d221..04456168d6 100644
--- a/src/plugins/scxmleditor/plugin_interface/sceneutils.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/sceneutils.cpp
@@ -224,7 +224,11 @@ void layout(const QList<QGraphicsItem*> &items)
firstItem = initialItem->outputTransitions().constFirst()->connectedItem(initialItem);
int index = childItems.indexOf(firstItem);
if (index > 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
childItems.swap(index, 0);
+#else
+ childItems.swapItemsAt(index, 0);
+#endif
}
// Search final-item
diff --git a/src/plugins/scxmleditor/plugin_interface/scxmldocument.cpp b/src/plugins/scxmleditor/plugin_interface/scxmldocument.cpp
index 4b7d61175c..033a6fbe1f 100644
--- a/src/plugins/scxmleditor/plugin_interface/scxmldocument.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/scxmldocument.cpp
@@ -133,17 +133,15 @@ void ScxmlDocument::addNamespace(ScxmlNamespace *ns)
ScxmlTag *scxmlTag = scxmlRootTag();
if (scxmlTag) {
- QMapIterator<QString, ScxmlNamespace*> i(m_namespaces);
- while (i.hasNext()) {
- i.next();
- QString prefix = i.value()->prefix();
+ for (ScxmlNamespace *ns : qAsConst(m_namespaces)) {
+ QString prefix = ns->prefix();
if (prefix.isEmpty())
prefix = "xmlns";
if (prefix.startsWith("xmlns"))
- scxmlTag->setAttribute(prefix, i.value()->name());
+ scxmlTag->setAttribute(prefix, ns->name());
else
- scxmlTag->setAttribute(QString::fromLatin1("xmlns:%1").arg(prefix), i.value()->name());
+ scxmlTag->setAttribute(QString::fromLatin1("xmlns:%1").arg(prefix), ns->name());
}
}
}
@@ -172,17 +170,15 @@ bool ScxmlDocument::generateSCXML(QIODevice *io, ScxmlTag *tag) const
ScxmlTag *ScxmlDocument::createScxmlTag()
{
auto tag = new ScxmlTag(Scxml, this);
- QMapIterator<QString, ScxmlNamespace*> i(m_namespaces);
- while (i.hasNext()) {
- i.next();
- QString prefix = i.value()->prefix();
+ for (ScxmlNamespace *ns : m_namespaces) {
+ QString prefix = ns->prefix();
if (prefix.isEmpty())
prefix = "xmlns";
if (prefix.startsWith("xmlns"))
- tag->setAttribute(prefix, i.value()->name());
+ tag->setAttribute(prefix, ns->name());
else
- tag->setAttribute(QString::fromLatin1("xmlns:%1").arg(prefix), i.value()->name());
+ tag->setAttribute(QString::fromLatin1("xmlns:%1").arg(prefix), ns->name());
}
return tag;
}
diff --git a/src/plugins/scxmleditor/plugin_interface/scxmltag.cpp b/src/plugins/scxmleditor/plugin_interface/scxmltag.cpp
index f44ca314b6..b037fb9bb9 100644
--- a/src/plugins/scxmleditor/plugin_interface/scxmltag.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/scxmltag.cpp
@@ -552,11 +552,8 @@ void ScxmlTag::writeXml(QXmlStreamWriter &xml)
// Write editorinfo if necessary
if (!m_editorInfo.isEmpty()) {
xml.writeStartElement("qt:editorinfo");
- QHashIterator<QString, QString> i(m_editorInfo);
- while (i.hasNext()) {
- i.next();
+ for (auto i = m_editorInfo.cbegin(), end = m_editorInfo.cend(); i != end; ++i)
xml.writeAttribute(i.key(), i.value());
- }
xml.writeEndElement();
}
diff --git a/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp b/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp
index eb05ca403f..fefa5c3e56 100644
--- a/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp
+++ b/src/plugins/scxmleditor/plugin_interface/transitionitem.cpp
@@ -306,11 +306,19 @@ void TransitionItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
QPointF intersPoint;
QLineF line2(p, p + QPointF(SELECTION_DISTANCE, SELECTION_DISTANCE));
line2.setAngle(line.angle() + 90);
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
if (line.intersect(line2, &intersPoint) == QLineF::BoundedIntersection)
+#else
+ if (line.intersects(line2, &intersPoint) == QLineF::BoundedIntersection)
+#endif
sel = true;
else {
line2.setAngle(line.angle() - 90);
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
sel = line.intersect(line2, &intersPoint) == QLineF::BoundedIntersection;
+#else
+ sel = line.intersects(line2, &intersPoint) == QLineF::BoundedIntersection;
+#endif
}
if (sel)
@@ -797,7 +805,11 @@ QPointF TransitionItem::findIntersectionPoint(ConnectableItem *item, const QLine
for (int i = 1; i < itemPolygon.count(); ++i) {
p2 = itemPolygon.at(i) + item->scenePos();
checkLine = QLineF(p1, p2);
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
if (checkLine.intersect(line, &intersectPoint) == QLineF::BoundedIntersection)
+#else
+ if (checkLine.intersects(line, &intersectPoint) == QLineF::BoundedIntersection)
+#endif
return intersectPoint;
p1 = p2;
}
@@ -1083,11 +1095,19 @@ bool TransitionItem::containsScenePoint(const QPointF &p) const
QPointF intersPoint;
QLineF line2(pp, pp + QPointF(SELECTION_DISTANCE, SELECTION_DISTANCE));
line2.setAngle(line.angle() + 90);
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
if (line.intersect(line2, &intersPoint) == QLineF::BoundedIntersection) {
+#else
+ if (line.intersects(line2, &intersPoint) == QLineF::BoundedIntersection) {
+#endif
return true;
} else {
line2.setAngle(line.angle() - 90);
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
if (line.intersect(line2, &intersPoint) == QLineF::BoundedIntersection)
+#else
+ if (line.intersects(line2, &intersPoint) == QLineF::BoundedIntersection)
+#endif
return true;
}
}
diff --git a/src/plugins/scxmleditor/scxmleditordata.cpp b/src/plugins/scxmleditor/scxmleditordata.cpp
index 205eaa8b90..394b00533c 100644
--- a/src/plugins/scxmleditor/scxmleditordata.cpp
+++ b/src/plugins/scxmleditor/scxmleditordata.cpp
@@ -222,7 +222,7 @@ QWidget *ScxmlEditorData::createModeWidget()
widget->setObjectName("ScxmlEditorDesignModeWidget");
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_mainToolBar);
// Avoid mode switch to 'Edit' mode when the application started by
diff --git a/src/plugins/serialterminal/serialoutputpane.cpp b/src/plugins/serialterminal/serialoutputpane.cpp
index e1eca5aec1..191aa93180 100644
--- a/src/plugins/serialterminal/serialoutputpane.cpp
+++ b/src/plugins/serialterminal/serialoutputpane.cpp
@@ -142,7 +142,7 @@ SerialOutputPane::SerialOutputPane(Settings &settings) :
createToolButtons();
auto layout = new QVBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
m_tabWidget->setDocumentMode(true);
@@ -157,7 +157,7 @@ SerialOutputPane::SerialOutputPane(Settings &settings) :
this, &SerialOutputPane::contextMenuRequested);
auto inputLayout = new QHBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(2);
m_inputLine->setPlaceholderText(tr("Type text and hit Enter to send."));
@@ -302,10 +302,10 @@ void SerialOutputPane::createNewOutputWindow(SerialControl *rc)
Utils::OutputFormatter *formatter = rc->outputFormatter();
// Create new
- static uint counter = 0;
+ static int counter = 0;
Core::Id contextId = Core::Id(Constants::C_SERIAL_OUTPUT).withSuffix(counter++);
Core::Context context(contextId);
- Core::OutputWindow *ow = new Core::OutputWindow(context, QString(), m_tabWidget);
+ auto ow = new Core::OutputWindow(context, QString(), m_tabWidget);
using TextEditor::TextEditorSettings;
auto fontSettingsChanged = [ow] {
ow->setBaseFont(TextEditorSettings::fontSettings().font());
@@ -694,7 +694,7 @@ void SerialOutputPane::connectControl()
current->setBaudRate(m_devicesModel->baudRate(m_baudRateSelection->currentIndex()));
// Gray out old and connect
if (index != -1) {
- auto& tab = m_serialControlTabs[index];
+ auto &tab = m_serialControlTabs[index];
handleOldOutput(tab.window);
tab.window->scrollToBottom();
}
diff --git a/src/plugins/serialterminal/serialoutputpane.h b/src/plugins/serialterminal/serialoutputpane.h
index 56577d4613..944b008ab1 100644
--- a/src/plugins/serialterminal/serialoutputpane.h
+++ b/src/plugins/serialterminal/serialoutputpane.h
@@ -36,10 +36,10 @@
#include <memory>
QT_BEGIN_NAMESPACE
-class QToolButton;
-class QButtonGroup;
class QAbstractButton;
+class QButtonGroup;
class QComboBox;
+class QToolButton;
QT_END_NAMESPACE
namespace Core { class OutputWindow; }
@@ -47,10 +47,10 @@ namespace Core { class OutputWindow; }
namespace SerialTerminal {
namespace Internal {
-class SerialControl;
-class TabWidget;
class ComboBox;
class ConsoleLineEdit;
+class SerialControl;
+class TabWidget;
class SerialOutputPane : public Core::IOutputPane
{
@@ -146,7 +146,6 @@ private:
void updateCloseActions();
-
std::unique_ptr<QWidget> m_mainWidget;
ConsoleLineEdit *m_inputLine = nullptr;
QComboBox *m_lineEndingsSelection = nullptr;
diff --git a/src/plugins/silversearcher/findinfilessilversearcher.cpp b/src/plugins/silversearcher/findinfilessilversearcher.cpp
index f0d6fa7eae..c7794f89ac 100644
--- a/src/plugins/silversearcher/findinfilessilversearcher.cpp
+++ b/src/plugins/silversearcher/findinfilessilversearcher.cpp
@@ -165,7 +165,7 @@ FindInFilesSilverSearcher::FindInFilesSilverSearcher(QObject *parent)
{
m_widget = new QWidget;
auto layout = new QHBoxLayout(m_widget);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
m_searchOptionsLineEdit = new QLineEdit;
m_searchOptionsLineEdit->setPlaceholderText(tr("Search Options (optional)"));
layout->addWidget(m_searchOptionsLineEdit);
diff --git a/src/plugins/studiowelcome/CMakeLists.txt b/src/plugins/studiowelcome/CMakeLists.txt
index 30e5cc62af..217e5f7de4 100644
--- a/src/plugins/studiowelcome/CMakeLists.txt
+++ b/src/plugins/studiowelcome/CMakeLists.txt
@@ -7,4 +7,6 @@ add_qtc_plugin(StudioWelcome
studiowelcome_global.h
studiowelcome.qrc
"${PROJECT_SOURCE_DIR}/src/share/3rdparty/studiofonts/studiofonts.qrc"
+ EXTRA_TRANSLATIONS
+ qml
)
diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp
index 4cd6d35701..abdecb1180 100644
--- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp
+++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp
@@ -206,8 +206,8 @@ StudioWelcomePlugin::~StudioWelcomePlugin()
bool StudioWelcomePlugin::initialize(const QStringList &arguments, QString *errorString)
{
- Q_UNUSED(arguments);
- Q_UNUSED(errorString);
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
qmlRegisterType<ProjectModel>("projectmodel", 1, 0, "ProjectModel");
diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp
index 6982bb854b..aa03bdb917 100644
--- a/src/plugins/subversion/subversionclient.cpp
+++ b/src/plugins/subversion/subversionclient.cpp
@@ -150,7 +150,7 @@ QString SubversionClient::synchronousTopic(const QString &repository)
svnVersionBinary = svnVersionBinary.left(pos + 1);
svnVersionBinary.append(HostOsInfo::withExecutableSuffix("svnversion"));
const SynchronousProcessResponse result
- = vcsFullySynchronousExec(repository, FilePath::fromString(svnVersionBinary), args);
+ = vcsFullySynchronousExec(repository, {svnVersionBinary, args});
if (result.result != SynchronousProcessResponse::Finished)
return QString();
@@ -285,7 +285,7 @@ SubversionDiffEditorController *SubversionClient::findOrCreateDiffEditor(const Q
void SubversionClient::diff(const QString &workingDirectory, const QStringList &files, const QStringList &extraOptions)
{
- Q_UNUSED(extraOptions);
+ Q_UNUSED(extraOptions)
const QString vcsCmdString = vcsCommandString(DiffCommand);
const QString documentId = QLatin1String(Constants::SUBVERSION_PLUGIN)
diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp
index 0d4a024271..70604a5650 100644
--- a/src/plugins/subversion/subversioncontrol.cpp
+++ b/src/plugins/subversion/subversioncontrol.cpp
@@ -171,7 +171,7 @@ Core::ShellCommand *SubversionControl::createInitialCheckoutCommand(const QStrin
args << extraArgs << url << localName;
auto command = new VcsBase::VcsCommand(baseDirectory.toString(), client->processEnvironment());
- command->addJob(client->vcsBinary(), args, -1);
+ command->addJob({client->vcsBinary(), args}, -1);
return command;
}
diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp
index 21b30d878d..bde71f4422 100644
--- a/src/plugins/subversion/subversionplugin.cpp
+++ b/src/plugins/subversion/subversionplugin.cpp
@@ -393,8 +393,7 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e
bool SubversionPlugin::isVcsDirectory(const FilePath &fileName)
{
const QString baseName = fileName.fileName();
- return fileName.toFileInfo().isDir()
- && contains(m_svnDirectories, [baseName](const QString &s) {
+ return fileName.isDir() && contains(m_svnDirectories, [baseName](const QString &s) {
return !baseName.compare(s, HostOsInfo::fileNameCaseSensitivity());
});
}
diff --git a/src/plugins/tasklist/stopmonitoringhandler.cpp b/src/plugins/tasklist/stopmonitoringhandler.cpp
index 56ca7c78f5..0ca105a719 100644
--- a/src/plugins/tasklist/stopmonitoringhandler.cpp
+++ b/src/plugins/tasklist/stopmonitoringhandler.cpp
@@ -49,7 +49,7 @@ bool StopMonitoringHandler::canHandle(const ProjectExplorer::Task &task) const
void StopMonitoringHandler::handle(const ProjectExplorer::Task &task)
{
QTC_ASSERT(canHandle(task), return);
- Q_UNUSED(task);
+ Q_UNUSED(task)
TaskListPlugin::stopMonitoring();
}
diff --git a/src/plugins/tasklist/taskfile.cpp b/src/plugins/tasklist/taskfile.cpp
index 871cefe1ab..ad9b9d18b7 100644
--- a/src/plugins/tasklist/taskfile.cpp
+++ b/src/plugins/tasklist/taskfile.cpp
@@ -43,14 +43,14 @@ TaskFile::TaskFile(QObject *parent) : Core::IDocument(parent)
Core::IDocument::ReloadBehavior TaskFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
{
- Q_UNUSED(state);
- Q_UNUSED(type);
+ Q_UNUSED(state)
+ Q_UNUSED(type)
return BehaviorSilent;
}
bool TaskFile::reload(QString *errorString, ReloadFlag flag, ChangeType type)
{
- Q_UNUSED(flag);
+ Q_UNUSED(flag)
if (type == TypePermissions)
return true;
diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp
index ea50725639..799efdef67 100644
--- a/src/plugins/texteditor/autocompleter.cpp
+++ b/src/plugins/texteditor/autocompleter.cpp
@@ -342,15 +342,15 @@ int AutoCompleter::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor)
bool AutoCompleter::contextAllowsAutoBrackets(const QTextCursor &cursor,
const QString &textToInsert) const
{
- Q_UNUSED(cursor);
- Q_UNUSED(textToInsert);
+ Q_UNUSED(cursor)
+ Q_UNUSED(textToInsert)
return false;
}
bool AutoCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor, const QString &textToInsert) const
{
- Q_UNUSED(cursor);
- Q_UNUSED(textToInsert);
+ Q_UNUSED(cursor)
+ Q_UNUSED(textToInsert)
return false;
}
@@ -361,13 +361,13 @@ bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) c
bool AutoCompleter::isInComment(const QTextCursor &cursor) const
{
- Q_UNUSED(cursor);
+ Q_UNUSED(cursor)
return false;
}
bool AutoCompleter::isInString(const QTextCursor &cursor) const
{
- Q_UNUSED(cursor);
+ Q_UNUSED(cursor)
return false;
}
@@ -377,11 +377,11 @@ QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor,
bool skipChars,
int *skippedChars) const
{
- Q_UNUSED(cursor);
- Q_UNUSED(text);
- Q_UNUSED(lookAhead);
- Q_UNUSED(skipChars);
- Q_UNUSED(skippedChars);
+ Q_UNUSED(cursor)
+ Q_UNUSED(text)
+ Q_UNUSED(lookAhead)
+ Q_UNUSED(skipChars)
+ Q_UNUSED(skippedChars)
return QString();
}
@@ -391,16 +391,16 @@ QString AutoCompleter::insertMatchingQuote(const QTextCursor &cursor,
bool skipChars,
int *skippedChars) const
{
- Q_UNUSED(cursor);
- Q_UNUSED(text);
- Q_UNUSED(lookAhead);
- Q_UNUSED(skipChars);
- Q_UNUSED(skippedChars);
+ Q_UNUSED(cursor)
+ Q_UNUSED(text)
+ Q_UNUSED(lookAhead)
+ Q_UNUSED(skipChars)
+ Q_UNUSED(skippedChars)
return QString();
}
QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
{
- Q_UNUSED(cursor);
+ Q_UNUSED(cursor)
return QString();
}
diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp
index 79c7d60d9b..8354e83f50 100644
--- a/src/plugins/texteditor/basefilefind.cpp
+++ b/src/plugins/texteditor/basefilefind.cpp
@@ -496,10 +496,8 @@ QStringList BaseFileFind::replaceAll(const QString &text,
changes[QDir::fromNativeSeparators(item.path.first())].append(item);
// Checking for files without write permissions
- QHashIterator<QString, QList<SearchResultItem> > it(changes);
QSet<FilePath> roFiles;
- while (it.hasNext()) {
- it.next();
+ for (auto it = changes.cbegin(), end = changes.cend(); it != end; ++it) {
const QFileInfo fileInfo(it.key());
if (!fileInfo.isWritable())
roFiles.insert(FilePath::fromString(it.key()));
@@ -513,9 +511,7 @@ QStringList BaseFileFind::replaceAll(const QString &text,
return QStringList();
}
- it.toFront();
- while (it.hasNext()) {
- it.next();
+ for (auto it = changes.cbegin(), end = changes.cend(); it != end; ++it) {
const QString fileName = it.key();
const QList<SearchResultItem> changeItems = it.value();
diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp
index dfe390d68f..136fa30e76 100644
--- a/src/plugins/texteditor/basehoverhandler.cpp
+++ b/src/plugins/texteditor/basehoverhandler.cpp
@@ -142,15 +142,12 @@ void BaseHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, Re
void BaseHoverHandler::decorateToolTip()
{
- if (Qt::mightBeRichText(toolTip()))
- setToolTip(toolTip().toHtmlEscaped());
+ m_toolTip = m_toolTip.toHtmlEscaped();
if (lastHelpItemIdentified().isValid() && !lastHelpItemIdentified().isFuzzyMatch()) {
const QString &helpContents = lastHelpItemIdentified().extractContent(false);
- if (!helpContents.isEmpty()) {
- m_toolTip = toolTip().toHtmlEscaped();
+ if (!helpContents.isEmpty())
m_toolTip = m_toolTip.isEmpty() ? helpContents : ("<p>" + m_toolTip + "</p><hr/><p>" + helpContents + "</p>");
- }
}
}
diff --git a/src/plugins/texteditor/basehoverhandler.h b/src/plugins/texteditor/basehoverhandler.h
index 3850c98564..d7ff52aa9a 100644
--- a/src/plugins/texteditor/basehoverhandler.h
+++ b/src/plugins/texteditor/basehoverhandler.h
@@ -80,11 +80,11 @@ protected:
// Utils::ExecuteOnDestruction reportPriority([this, report](){ report(priority()); });
// at the beginning of an implementation to ensure this in any case.
virtual void identifyMatch(TextEditorWidget *editorWidget, int pos, ReportPriority report);
- virtual void decorateToolTip();
virtual void operateTooltip(TextEditorWidget *editorWidget, const QPoint &point);
private:
void process(TextEditorWidget *widget, int pos, ReportPriority report);
+ void decorateToolTip();
QString m_toolTip;
Core::HelpItem m_lastHelpItemIdentified;
diff --git a/src/plugins/texteditor/codeassist/assistproposalitem.cpp b/src/plugins/texteditor/codeassist/assistproposalitem.cpp
index 05222ed107..cf9cbe6e38 100644
--- a/src/plugins/texteditor/codeassist/assistproposalitem.cpp
+++ b/src/plugins/texteditor/codeassist/assistproposalitem.cpp
@@ -122,7 +122,7 @@ bool AssistProposalItem::implicitlyApplies() const
bool AssistProposalItem::prematurelyApplies(const QChar &c) const
{
- Q_UNUSED(c);
+ Q_UNUSED(c)
return false;
}
diff --git a/src/plugins/texteditor/codeassist/assistproposaliteminterface.h b/src/plugins/texteditor/codeassist/assistproposaliteminterface.h
index 893dc4aa0d..d4b7f3268e 100644
--- a/src/plugins/texteditor/codeassist/assistproposaliteminterface.h
+++ b/src/plugins/texteditor/codeassist/assistproposaliteminterface.h
@@ -42,12 +42,13 @@ class TEXTEDITOR_EXPORT AssistProposalItemInterface
{
public:
// We compare proposals by enum values, be careful changing their values
- enum class PrefixMatch
+ enum class ProposalMatch
{
Full = 0,
Exact = 1,
- Lower = 2,
- None = 3
+ Prefix = 2,
+ Infix = 3,
+ None = 4
};
AssistProposalItemInterface() = default;
@@ -70,12 +71,12 @@ public:
inline int order() const { return m_order; }
inline void setOrder(int order) { m_order = order; }
- inline PrefixMatch prefixMatch() { return m_prefixMatch; }
- inline void setPrefixMatch(PrefixMatch match) { m_prefixMatch = match; }
+ inline ProposalMatch proposalMatch() { return m_proposalMatch; }
+ inline void setProposalMatch(ProposalMatch match) { m_proposalMatch = match; }
private:
int m_order = 0;
- PrefixMatch m_prefixMatch = PrefixMatch::None;
+ ProposalMatch m_proposalMatch = ProposalMatch::None;
};
} // namespace TextEditor
diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp
index 4f9605d1e3..a29019a245 100644
--- a/src/plugins/texteditor/codeassist/codeassistant.cpp
+++ b/src/plugins/texteditor/codeassist/codeassistant.cpp
@@ -554,7 +554,7 @@ bool CodeAssistantPrivate::isDestroyEvent(int key, const QString &keyText)
bool CodeAssistantPrivate::eventFilter(QObject *o, QEvent *e)
{
- Q_UNUSED(o);
+ Q_UNUSED(o)
if (isWaitingForProposal()) {
QEvent::Type type = e->type();
diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
index 4e72e4449b..292c46cccc 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
@@ -141,14 +141,14 @@ FunctionHintProposalWidget::FunctionHintProposalWidget()
upArrow->setAutoRaise(true);
auto pagerLayout = new QHBoxLayout(d->m_pager);
- pagerLayout->setMargin(0);
+ pagerLayout->setContentsMargins(0, 0, 0, 0);
pagerLayout->setSpacing(0);
pagerLayout->addWidget(upArrow);
pagerLayout->addWidget(d->m_numberLabel);
pagerLayout->addWidget(downArrow);
auto popupLayout = new QHBoxLayout(d->m_popupFrame);
- popupLayout->setMargin(0);
+ popupLayout->setContentsMargins(0, 0, 0, 0);
popupLayout->setSpacing(0);
popupLayout->addWidget(d->m_pager);
popupLayout->addWidget(d->m_hintLabel);
@@ -310,7 +310,7 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e)
if (d->m_popupFrame && !d->m_popupFrame->isAncestorOf(widget)) {
abort();
} else if (e->type() == QEvent::Wheel) {
- if (static_cast<QWheelEvent*>(e)->delta() > 0)
+ if (static_cast<QWheelEvent*>(e)->angleDelta().y() > 0)
previousPage();
else
nextPage();
diff --git a/src/plugins/texteditor/codeassist/genericproposalmodel.cpp b/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
index b5d9b00340..75dcf2d540 100644
--- a/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
+++ b/src/plugins/texteditor/codeassist/genericproposalmodel.cpp
@@ -116,12 +116,11 @@ struct ContentLessThan
{
bool operator()(const QChar &a, const QChar &b)
{
- if (a == QLatin1Char('_'))
+ if (a == '_')
return false;
- else if (b == QLatin1Char('_'))
+ if (b == '_')
return true;
- else
- return a < b;
+ return a < b;
}
};
@@ -158,7 +157,7 @@ static QString cleanText(const QString &original)
int ignore = 0;
for (int i = clean.length() - 1; i >= 0; --i, ++ignore) {
const QChar &c = clean.at(i);
- if (c.isLetterOrNumber() || c == QLatin1Char('_')
+ if (c.isLetterOrNumber() || c == '_'
|| c.isHighSurrogate() || c.isLowSurrogate()) {
break;
}
@@ -218,8 +217,7 @@ bool GenericProposalModel::isPerfectMatch(const QString &prefix) const
if (proposalItem(i)->isKeyword())
return true;
- if (!hasFullMatch)
- hasFullMatch = true;
+ hasFullMatch = true;
}
}
@@ -300,20 +298,25 @@ void GenericProposalModel::filter(const QString &prefix)
m_currentItems.clear();
const QString lowerPrefix = prefix.toLower();
- foreach (const auto &item, m_originalItems) {
+ for (const auto &item : qAsConst(m_originalItems)) {
const QString &text = item->text();
- if (regExp.match(text).capturedStart() == 0) {
+ const QRegularExpressionMatch match = regExp.match(text);
+ const bool hasPrefixMatch = match.capturedStart() == 0;
+ const bool hasInfixMatch = prefix.size() >= 3 && match.hasMatch();
+ if (hasPrefixMatch || hasInfixMatch) {
m_currentItems.append(item);
if (text.startsWith(prefix)) {
// Direct match
- item->setPrefixMatch(text.length() == prefix.length()
- ? AssistProposalItemInterface::PrefixMatch::Full
- : AssistProposalItemInterface::PrefixMatch::Exact);
+ item->setProposalMatch(text.length() == prefix.length()
+ ? AssistProposalItemInterface::ProposalMatch::Full
+ : AssistProposalItemInterface::ProposalMatch::Exact);
continue;
}
if (text.startsWith(lowerPrefix, Qt::CaseInsensitive))
- item->setPrefixMatch(AssistProposalItemInterface::PrefixMatch::Lower);
+ item->setProposalMatch(AssistProposalItemInterface::ProposalMatch::Prefix);
+ else if (text.contains(lowerPrefix, Qt::CaseInsensitive))
+ item->setProposalMatch(AssistProposalItemInterface::ProposalMatch::Infix);
}
}
}
@@ -333,7 +336,7 @@ FuzzyMatcher::CaseSensitivity
bool GenericProposalModel::isSortable(const QString &prefix) const
{
- Q_UNUSED(prefix);
+ Q_UNUSED(prefix)
if (m_currentItems.size() < kMaxSort)
return true;
diff --git a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp
index aad4096f81..92f3e9a3b9 100644
--- a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp
@@ -119,7 +119,7 @@ public:
: FakeToolTip(parent), m_label(new QLabel(this))
{
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_label);
@@ -361,7 +361,7 @@ GenericProposalWidget::GenericProposalWidget()
this, &GenericProposalWidget::turnOnAutoWidth);
auto layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(d->m_completionListView);
d->m_completionListView->installEventFilter(this);
@@ -476,7 +476,7 @@ bool GenericProposalWidget::updateAndCheck(const QString &prefix)
d->m_model->sort(prefix);
d->m_completionListView->reset();
- // Try to find the previosly explicit selection (if any). If we can find the item set it
+ // Try to find the previously explicit selection (if any). If we can find the item set it
// as the current. Otherwise (it might have been filtered out) select the first row.
if (d->m_explicitlySelected) {
Q_ASSERT(preferredItemId != -1);
diff --git a/src/plugins/texteditor/codeassist/iassistproposal.cpp b/src/plugins/texteditor/codeassist/iassistproposal.cpp
index 84beac910f..a5576ae620 100644
--- a/src/plugins/texteditor/codeassist/iassistproposal.cpp
+++ b/src/plugins/texteditor/codeassist/iassistproposal.cpp
@@ -104,7 +104,7 @@ bool IAssistProposal::supportsPrefix() const
bool IAssistProposal::isCorrective(TextEditorWidget *editorWidget) const
{
- Q_UNUSED(editorWidget);
+ Q_UNUSED(editorWidget)
return false;
}
@@ -116,7 +116,7 @@ bool IAssistProposal::isCorrective(TextEditorWidget *editorWidget) const
void IAssistProposal::makeCorrection(TextEditorWidget *editorWidget)
{
- Q_UNUSED(editorWidget);
+ Q_UNUSED(editorWidget)
}
void IAssistProposal::setFragile(bool fragile)
diff --git a/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp b/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp
index b5458e0aa3..b08fdc558f 100644
--- a/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp
+++ b/src/plugins/texteditor/codeassist/keywordscompletionassist.cpp
@@ -158,7 +158,7 @@ QString KeywordsFunctionHintModel::text(int index) const
int KeywordsFunctionHintModel::activeArgument(const QString &prefix) const
{
- Q_UNUSED(prefix);
+ Q_UNUSED(prefix)
return 1;
}
diff --git a/src/plugins/texteditor/colorscheme.cpp b/src/plugins/texteditor/colorscheme.cpp
index ad756be2c7..80733e7ee1 100644
--- a/src/plugins/texteditor/colorscheme.cpp
+++ b/src/plugins/texteditor/colorscheme.cpp
@@ -251,9 +251,8 @@ bool ColorScheme::save(const QString &fileName, QWidget *parent) const
if (!m_displayName.isEmpty())
w.writeAttribute(QLatin1String("name"), m_displayName);
- QMapIterator<TextStyle, Format> i(m_formats);
- while (i.hasNext()) {
- const Format &format = i.next().value();
+ for (auto i = m_formats.cbegin(), end = m_formats.cend(); i != end; ++i) {
+ const Format &format = i.value();
w.writeStartElement(QLatin1String("style"));
w.writeAttribute(QLatin1String("name"), QString::fromLatin1(Constants::nameForStyle(i.key())));
if (format.foreground().isValid())
diff --git a/src/plugins/texteditor/extraencodingsettings.cpp b/src/plugins/texteditor/extraencodingsettings.cpp
index daa8257cd5..898840e3d5 100644
--- a/src/plugins/texteditor/extraencodingsettings.cpp
+++ b/src/plugins/texteditor/extraencodingsettings.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "extraencodingsettings.h"
+#include "behaviorsettingswidget.h"
#include <utils/settingsutils.h>
@@ -71,3 +72,9 @@ bool ExtraEncodingSettings::equals(const ExtraEncodingSettings &s) const
{
return m_utf8BomSetting == s.m_utf8BomSetting;
}
+
+QStringList ExtraEncodingSettings::lineTerminationModeNames()
+{
+ return {BehaviorSettingsWidget::tr("Unix (LF)"),
+ BehaviorSettingsWidget::tr("Windows (CRLF)")};
+}
diff --git a/src/plugins/texteditor/extraencodingsettings.h b/src/plugins/texteditor/extraencodingsettings.h
index 1361760b05..dd2d96c9ec 100644
--- a/src/plugins/texteditor/extraencodingsettings.h
+++ b/src/plugins/texteditor/extraencodingsettings.h
@@ -49,6 +49,8 @@ public:
bool equals(const ExtraEncodingSettings &s) const;
+ static QStringList lineTerminationModeNames();
+
enum Utf8BomSetting {
AlwaysAdd = 0,
OnlyKeep = 1,
diff --git a/src/plugins/texteditor/findinfiles.cpp b/src/plugins/texteditor/findinfiles.cpp
index 4372dd0394..e753ad79a1 100644
--- a/src/plugins/texteditor/findinfiles.cpp
+++ b/src/plugins/texteditor/findinfiles.cpp
@@ -144,7 +144,7 @@ QWidget *FindInFiles::createConfigWidget()
if (!m_configWidget) {
m_configWidget = new QWidget;
auto gridLayout = new QGridLayout(m_configWidget);
- gridLayout->setMargin(0);
+ gridLayout->setContentsMargins(0, 0, 0, 0);
m_configWidget->setLayout(gridLayout);
int row = 0;
diff --git a/src/plugins/texteditor/formattexteditor.cpp b/src/plugins/texteditor/formattexteditor.cpp
index 096eca6bf8..7b4bb4265c 100644
--- a/src/plugins/texteditor/formattexteditor.cpp
+++ b/src/plugins/texteditor/formattexteditor.cpp
@@ -90,7 +90,7 @@ static FormatTask format(FormatTask task)
options.replaceInStrings(QLatin1String("%file"), sourceFile.fileName());
Utils::SynchronousProcess process;
process.setTimeoutS(5);
- Utils::SynchronousProcessResponse response = process.runBlocking(executable, options);
+ Utils::SynchronousProcessResponse response = process.runBlocking({executable, options});
if (response.result != Utils::SynchronousProcessResponse::Finished) {
task.error = QString(QT_TRANSLATE_NOOP("TextEditor", "Failed to format: %1."))
.arg(response.exitMessage(executable, 5));
diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp
index bbeff2a484..1a12d96882 100644
--- a/src/plugins/texteditor/highlighter.cpp
+++ b/src/plugins/texteditor/highlighter.cpp
@@ -44,6 +44,8 @@
#include <QDir>
#include <QMetaEnum>
+#include <cmath>
+
using namespace TextEditor;
static const char kDefinitionForMimeType[] = "definitionForMimeType";
@@ -322,9 +324,77 @@ void Highlighter::highlightBlock(const QString &text)
formatSpaces(text);
}
+static double luminance(const QColor &color)
+{
+ // calculate the luminance based on
+ // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ auto val = [](const double &colorVal) {
+ return colorVal < 0.03928 ? colorVal / 12.92 : std::pow((colorVal + 0.055) / 1.055, 2.4);
+ };
+
+ static QHash<QRgb, double> cache;
+ QHash<QRgb, double>::iterator it = cache.find(color.rgb());
+ if (it == cache.end()) {
+ it = cache.insert(color.rgb(), 0.2126 * val(color.redF())
+ + 0.7152 * val(color.greenF())
+ + 0.0722 * val(color.blueF()));
+ }
+ return it.value();
+}
+
+static double contrastRatio(const QColor &color1, const QColor &color2)
+{
+ // calculate the contrast ratio based on
+ // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+ auto contrast = (luminance(color1) + 0.05) / (luminance(color2) + 0.05);
+ if (contrast < 1)
+ return 1 / contrast;
+ return contrast;
+}
+
+static bool isReadableOn(const QColor &background, const QColor &foreground)
+{
+ // following the W3C Recommendation on contrast for large Text
+ // https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+ return contrastRatio(background, foreground) > 3;
+}
+
void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
{
- setFormat(offset, length, formatForCategory(format.textStyle()));
+ const KSyntaxHighlighting::Theme defaultTheme;
+ QTextCharFormat qformat = formatForCategory(format.textStyle());
+
+ if (format.hasTextColor(defaultTheme)) {
+ const QColor textColor = format.textColor(defaultTheme);
+ if (format.hasBackgroundColor(defaultTheme)) {
+ const QColor backgroundColor = format.hasBackgroundColor(defaultTheme);
+ if (isReadableOn(backgroundColor, textColor)) {
+ qformat.setForeground(textColor);
+ qformat.setBackground(backgroundColor);
+ } else if (isReadableOn(qformat.background().color(), textColor)) {
+ qformat.setForeground(textColor);
+ }
+ } else if (isReadableOn(qformat.background().color(), textColor)) {
+ qformat.setForeground(textColor);
+ }
+ } else if (format.hasBackgroundColor(defaultTheme)) {
+ const QColor backgroundColor = format.hasBackgroundColor(defaultTheme);
+ if (isReadableOn(backgroundColor, qformat.foreground().color()))
+ qformat.setBackground(backgroundColor);
+ }
+
+ if (format.isBold(defaultTheme))
+ qformat.setFontWeight(QFont::Bold);
+
+ if (format.isItalic(defaultTheme))
+ qformat.setFontItalic(true);
+
+ if (format.isUnderline(defaultTheme))
+ qformat.setFontUnderline(true);
+
+ if (format.isStrikeThrough(defaultTheme))
+ qformat.setFontStrikeOut(true);
+ setFormat(offset, length, qformat);
}
void Highlighter::applyFolding(int offset,
diff --git a/src/plugins/texteditor/highlightersettings.cpp b/src/plugins/texteditor/highlightersettings.cpp
index 84afbd79de..9fe4744cf7 100644
--- a/src/plugins/texteditor/highlightersettings.cpp
+++ b/src/plugins/texteditor/highlightersettings.cpp
@@ -28,6 +28,8 @@
#include "texteditorconstants.h"
#include <coreplugin/icore.h>
+
+#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h>
@@ -67,12 +69,12 @@ QString findFallbackDefinitionsLocation()
}
// Try kde-config.
- const QStringList programs = {QLatin1String("kde-config"), QLatin1String("kde4-config")};
+ const QStringList programs = {"kde-config", "kde4-config"};
for (auto &program : programs) {
Utils::SynchronousProcess process;
process.setTimeoutS(5);
Utils::SynchronousProcessResponse response
- = process.runBlocking(program, QStringList(QLatin1String("--prefix")));
+ = process.runBlocking({program, {"--prefix"}});
if (response.result == Utils::SynchronousProcessResponse::Finished) {
QString output = response.stdOut();
output.remove(QLatin1Char('\n'));
diff --git a/src/plugins/texteditor/normalindenter.cpp b/src/plugins/texteditor/normalindenter.cpp
index c6cb0febd1..e4a8ef4d10 100644
--- a/src/plugins/texteditor/normalindenter.cpp
+++ b/src/plugins/texteditor/normalindenter.cpp
@@ -58,8 +58,8 @@ int NormalIndenter::indentFor(const QTextBlock &block,
const TabSettings &tabSettings,
int cursorPositionInEditor)
{
- Q_UNUSED(tabSettings);
- Q_UNUSED(cursorPositionInEditor);
+ Q_UNUSED(tabSettings)
+ Q_UNUSED(cursorPositionInEditor)
QTextBlock previous = block.previous();
if (!previous.isValid())
diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp
index 76029cc6fd..01c61f10f8 100644
--- a/src/plugins/texteditor/refactoringchanges.cpp
+++ b/src/plugins/texteditor/refactoringchanges.cpp
@@ -232,7 +232,7 @@ TextEditorWidget *RefactoringFile::editor() const
return m_editor;
}
-int RefactoringFile::position(unsigned line, unsigned column) const
+int RefactoringFile::position(int line, int column) const
{
QTC_ASSERT(line != 0, return -1);
QTC_ASSERT(column != 0, return -1);
@@ -241,7 +241,7 @@ int RefactoringFile::position(unsigned line, unsigned column) const
return -1;
}
-void RefactoringFile::lineAndColumn(int offset, unsigned *line, unsigned *column) const
+void RefactoringFile::lineAndColumn(int offset, int *line, int *column) const
{
QTC_ASSERT(line, return);
QTC_ASSERT(column, return);
@@ -322,7 +322,7 @@ bool RefactoringFile::apply()
// open / activate / goto position
if (m_openEditor && !m_fileName.isEmpty()) {
- auto line = unsigned(-1), column = unsigned(-1);
+ int line = -1, column = -1;
if (m_editorCursorPosition != -1)
lineAndColumn(m_editorCursorPosition, &line, &column);
m_editor = RefactoringChanges::openEditor(m_fileName, m_activateEditor, line, column);
diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h
index d7e6cdd2fe..807f536242 100644
--- a/src/plugins/texteditor/refactoringchanges.h
+++ b/src/plugins/texteditor/refactoringchanges.h
@@ -66,9 +66,9 @@ public:
TextEditorWidget *editor() const;
// converts 1-based line and column into 0-based source offset
- int position(unsigned line, unsigned column) const;
+ int position(int line, int column) const;
// converts 0-based source offset into 1-based line and column
- void lineAndColumn(int offset, unsigned *line, unsigned *column) const;
+ void lineAndColumn(int offset, int *line, int *column) const;
QChar charAt(int pos) const;
QString textOf(int start, int end) const;
diff --git a/src/plugins/texteditor/refactoroverlay.cpp b/src/plugins/texteditor/refactoroverlay.cpp
index 33a18f818f..b0747d7874 100644
--- a/src/plugins/texteditor/refactoroverlay.cpp
+++ b/src/plugins/texteditor/refactoroverlay.cpp
@@ -67,6 +67,9 @@ RefactorMarker RefactorOverlay::markerAt(const QPoint &pos) const
void RefactorOverlay::paintMarker(const RefactorMarker& marker, QPainter *painter, const QRect &clip)
{
+ if (!marker.cursor.block().isVisible())
+ return; // block containing marker not visible
+
const QPointF offset = m_editor->contentOffset();
const QRectF geometry = m_editor->blockBoundingGeometry(marker.cursor.block()).translated(offset);
diff --git a/src/plugins/texteditor/semantichighlighter.cpp b/src/plugins/texteditor/semantichighlighter.cpp
index fa388ac40e..858f8bb8cd 100644
--- a/src/plugins/texteditor/semantichighlighter.cpp
+++ b/src/plugins/texteditor/semantichighlighter.cpp
@@ -38,13 +38,17 @@ using namespace TextEditor::SemanticHighlighter;
namespace {
-QTextCharFormat textCharFormatForResult(const HighlightingResult &result,
+QTextLayout::FormatRange rangeForResult(const HighlightingResult &result,
const QHash<int, QTextCharFormat> &kindToFormat)
{
- if (result.useTextSyles)
- return TextEditorSettings::fontSettings().toTextCharFormat(result.textStyles);
- else
- return kindToFormat.value(result.kind);
+ QTextLayout::FormatRange formatRange;
+
+ formatRange.start = int(result.column) - 1;
+ formatRange.length = int(result.length);
+ formatRange.format = result.useTextSyles
+ ? TextEditorSettings::fontSettings().toTextCharFormat(result.textStyles)
+ : kindToFormat.value(result.kind);
+ return formatRange;
}
}
@@ -58,14 +62,14 @@ void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
if (to <= from)
return;
- const int firstResultBlockNumber = future.resultAt(from).line - 1;
+ const int firstResultBlockNumber = int(future.resultAt(from).line) - 1;
// blocks between currentBlockNumber and the last block with results will
// be cleaned of additional extra formats if they have no results
int currentBlockNumber = 0;
for (int i = from - 1; i >= 0; --i) {
const HighlightingResult &result = future.resultAt(i);
- const int blockNumber = result.line - 1;
+ const int blockNumber = int(result.line) - 1;
if (blockNumber < firstResultBlockNumber) {
// stop! found where last format stopped
currentBlockNumber = blockNumber + 1;
@@ -81,13 +85,12 @@ void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
HighlightingResult result = future.resultAt(from);
for (int i = from; i < to && b.isValid(); ) {
- const int blockNumber = result.line - 1;
+ const int blockNumber = int(result.line) - 1;
QTC_ASSERT(blockNumber < doc->blockCount(), return);
// clear formats of blocks until blockNumber
while (currentBlockNumber < blockNumber) {
- QVector<QTextLayout::FormatRange> noFormats;
- highlighter->setExtraFormats(b, noFormats);
+ highlighter->clearExtraFormats(b);
b = b.next();
++currentBlockNumber;
}
@@ -96,29 +99,52 @@ void SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
QVector<QTextLayout::FormatRange> formats;
formats.reserve(to - from);
forever {
- QTextLayout::FormatRange formatRange;
-
- formatRange.format = textCharFormatForResult(result, kindToFormat);
- if (formatRange.format.isValid()) {
- formatRange.start = result.column - 1;
- formatRange.length = result.length;
+ const QTextLayout::FormatRange formatRange = rangeForResult(result, kindToFormat);
+ if (formatRange.format.isValid())
formats.append(formatRange);
- }
++i;
if (i >= to)
break;
result = future.resultAt(i);
- const int nextBlockNumber = result.line - 1;
+ const int nextBlockNumber = int(result.line) - 1;
if (nextBlockNumber != blockNumber)
break;
}
- highlighter->setExtraFormats(b, formats);
+ highlighter->setExtraFormats(b, std::move(formats));
b = b.next();
++currentBlockNumber;
}
}
+void SemanticHighlighter::setExtraAdditionalFormats(SyntaxHighlighter *highlighter,
+ const QList<HighlightingResult> &results,
+ const QHash<int, QTextCharFormat> &kindToFormat)
+{
+ if (!highlighter)
+ return;
+ highlighter->clearAllExtraFormats();
+
+ QTextDocument *doc = highlighter->document();
+ QTC_ASSERT(doc, return );
+
+ QVector<QVector<QTextLayout::FormatRange>> ranges(doc->blockCount());
+
+ for (auto result : results) {
+ const QTextLayout::FormatRange formatRange = rangeForResult(result, kindToFormat);
+ if (formatRange.format.isValid())
+ ranges[int(result.line) - 1].append(formatRange);
+ }
+
+ for (int blockNumber = 0; blockNumber < ranges.count(); ++blockNumber) {
+ if (!ranges[blockNumber].isEmpty()) {
+ QTextBlock b = doc->findBlockByNumber(blockNumber);
+ QTC_ASSERT(b.isValid(), return );
+ highlighter->setExtraFormats(b, std::move(ranges[blockNumber]));
+ }
+ }
+}
+
void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
SyntaxHighlighter *highlighter,
const QFuture<HighlightingResult> &future)
@@ -128,7 +154,7 @@ void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
for (int i = future.resultCount() - 1; i >= 0; --i) {
const HighlightingResult &result = future.resultAt(i);
if (result.line) {
- lastBlockNumber = result.line - 1;
+ lastBlockNumber = int(result.line) - 1;
break;
}
}
@@ -142,8 +168,7 @@ void SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
QTextBlock b = doc->findBlockByNumber(firstBlockToClear);
while (b.isValid()) {
- QVector<QTextLayout::FormatRange> noFormats;
- highlighter->setExtraFormats(b, noFormats);
+ highlighter->clearExtraFormats(b);
b = b.next();
}
}
diff --git a/src/plugins/texteditor/semantichighlighter.h b/src/plugins/texteditor/semantichighlighter.h
index f57b037957..330f9c8f05 100644
--- a/src/plugins/texteditor/semantichighlighter.h
+++ b/src/plugins/texteditor/semantichighlighter.h
@@ -37,11 +37,12 @@ namespace TextEditor {
class SyntaxHighlighter;
-class TEXTEDITOR_EXPORT HighlightingResult {
+class TEXTEDITOR_EXPORT HighlightingResult
+{
public:
- unsigned line = 0; // 1-based
- unsigned column = 0; // 1-based
- unsigned length = 0;
+ int line = 0; // 1-based
+ int column = 0; // 1-based
+ int length = 0;
TextStyles textStyles;
int kind = 0; /// The various highlighters can define their own kind of results.
bool useTextSyles = false;
@@ -54,11 +55,11 @@ public:
HighlightingResult() = default;
- HighlightingResult(unsigned line, unsigned column, unsigned length, int kind)
+ HighlightingResult(int line, int column, int length, int kind)
: line(line), column(column), length(length), kind(kind), useTextSyles(false)
{}
- HighlightingResult(unsigned line, unsigned column, unsigned length, TextStyles textStyles)
+ HighlightingResult(int line, int column, int length, TextStyles textStyles)
: line(line), column(column), length(length), textStyles(textStyles), useTextSyles(true)
{}
@@ -71,6 +72,8 @@ public:
}
};
+using HighlightingResults = QList<HighlightingResult>;
+
namespace SemanticHighlighter {
// Applies the future results [from, to) and applies the extra formats
@@ -86,6 +89,15 @@ void TEXTEDITOR_EXPORT incrementalApplyExtraAdditionalFormats(
int from, int to,
const QHash<int, QTextCharFormat> &kindToFormat);
+// Clears all extra highlights and applies the extra formats
+// indicated by Result::kind and kindToFormat to the correct location using
+// SyntaxHighlighter::setExtraFormats. In contrast to
+// incrementalApplyExtraAdditionalFormats the results do not have to be ordered by line.
+void TEXTEDITOR_EXPORT setExtraAdditionalFormats(
+ SyntaxHighlighter *highlighter,
+ const HighlightingResults &results,
+ const QHash<int, QTextCharFormat> &kindToFormat);
+
// Cleans the extra additional formats after the last result of the Future
// until the end of the document.
// Requires that results of the Future are ordered by line.
diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp
index 791b2e4a68..b28ac1ee18 100644
--- a/src/plugins/texteditor/syntaxhighlighter.cpp
+++ b/src/plugins/texteditor/syntaxhighlighter.cpp
@@ -662,20 +662,11 @@ static bool byStartOfRange(const QTextLayout::FormatRange &range, const QTextLay
return range.start < other.start;
}
-// The formats is passed in by reference in order to prevent unnecessary copying of its items.
+// The formats is passed in by rvalue reference in order to prevent unnecessary copying of its items.
// After this function returns, the list is modified, and should be considered invalidated!
void SyntaxHighlighter::setExtraFormats(const QTextBlock &block,
- QVector<QTextLayout::FormatRange> &formats)
+ QVector<QTextLayout::FormatRange> &&formats)
{
-// qDebug() << "setFormats() on block" << block.blockNumber();
-// qDebug() << " is valid:" << (block.isValid() ? "Yes" : "No");
-// qDebug() << " has layout:" << (block.layout() ? "Yes" : "No");
-// if (block.layout()) qDebug() << " has text:" << (block.text().isEmpty() ? "No" : "Yes");
-
-// for (int i = 0; i < overrides.count(); ++i)
-// qDebug() << " from " << overrides.at(i).start << "length"
-// << overrides.at(i).length
-// << "color:" << overrides.at(i).format.foreground().color();
Q_D(SyntaxHighlighter);
const int blockLength = block.length();
@@ -687,34 +678,17 @@ void SyntaxHighlighter::setExtraFormats(const QTextBlock &block,
const QVector<QTextLayout::FormatRange> all = block.layout()->formats();
QVector<QTextLayout::FormatRange> previousSemanticFormats;
QVector<QTextLayout::FormatRange> formatsToApply;
- previousSemanticFormats.reserve(all.size());
- formatsToApply.reserve(all.size() + formats.size());
+ std::tie(previousSemanticFormats, formatsToApply)
+ = Utils::partition(all, [](const QTextLayout::FormatRange &r) {
+ return r.format.hasProperty(QTextFormat::UserProperty);
+ });
for (auto &format : formats)
format.format.setProperty(QTextFormat::UserProperty, true);
- foreach (const QTextLayout::FormatRange &r, all) {
- if (r.format.hasProperty(QTextFormat::UserProperty))
- previousSemanticFormats.append(r);
- else
- formatsToApply.append(r);
- }
-
if (formats.size() == previousSemanticFormats.size()) {
Utils::sort(previousSemanticFormats, byStartOfRange);
-
- int index = 0;
- for (; index != formats.size(); ++index) {
- const QTextLayout::FormatRange &range = formats.at(index);
- const QTextLayout::FormatRange &previousRange = previousSemanticFormats.at(index);
-
- if (range.start != previousRange.start ||
- range.length != previousRange.length ||
- range.format != previousRange.format)
- break;
- }
-
- if (index == formats.size())
+ if (formats == previousSemanticFormats)
return;
}
@@ -727,6 +701,35 @@ void SyntaxHighlighter::setExtraFormats(const QTextBlock &block,
d->inReformatBlocks = wasInReformatBlocks;
}
+void SyntaxHighlighter::clearExtraFormats(const QTextBlock &block)
+{
+ Q_D(SyntaxHighlighter);
+
+ const int blockLength = block.length();
+ if (block.layout() == nullptr || blockLength == 0)
+ return;
+
+ const QVector<QTextLayout::FormatRange> formatsToApply
+ = Utils::filtered(block.layout()->formats(), [](const QTextLayout::FormatRange &r) {
+ return !r.format.hasProperty(QTextFormat::UserProperty);
+ });
+
+ bool wasInReformatBlocks = d->inReformatBlocks;
+ d->inReformatBlocks = true;
+ block.layout()->setFormats(formatsToApply);
+ document()->markContentsDirty(block.position(), blockLength - 1);
+ d->inReformatBlocks = wasInReformatBlocks;
+}
+
+void SyntaxHighlighter::clearAllExtraFormats()
+{
+ QTextBlock b = document()->firstBlock();
+ while (b.isValid()) {
+ clearExtraFormats(b);
+ b = b.next();
+ }
+}
+
/* Generate at least n different colors for highlighting, excluding background
* color. */
diff --git a/src/plugins/texteditor/syntaxhighlighter.h b/src/plugins/texteditor/syntaxhighlighter.h
index 38d7501065..05ff38908f 100644
--- a/src/plugins/texteditor/syntaxhighlighter.h
+++ b/src/plugins/texteditor/syntaxhighlighter.h
@@ -63,7 +63,9 @@ public:
void setDocument(QTextDocument *doc);
QTextDocument *document() const;
- void setExtraFormats(const QTextBlock &block, QVector<QTextLayout::FormatRange> &formats);
+ void setExtraFormats(const QTextBlock &block, QVector<QTextLayout::FormatRange> &&formats);
+ void clearExtraFormats(const QTextBlock &block);
+ void clearAllExtraFormats();
static QList<QColor> generateColors(int n, const QColor &background);
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 2250b6fb5b..1419b045c2 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -71,6 +71,7 @@
#include <coreplugin/find/highlightscrollbarcontroller.h>
#include <utils/algorithm.h>
#include <utils/textutils.h>
+#include <utils/camelcasecursor.h>
#include <utils/fixedsizeclicklabel.h>
#include <utils/fileutils.h>
#include <utils/dropsupport.h>
@@ -89,6 +90,7 @@
#include <QApplication>
#include <QClipboard>
#include <QCoreApplication>
+#include <QComboBox>
#include <QDebug>
#include <QFutureWatcher>
#include <QGridLayout>
@@ -559,8 +561,6 @@ public:
void universalHelper(); // test function for development
bool cursorMoveKeyEvent(QKeyEvent *e);
- bool camelCaseRight(QTextCursor &cursor, QTextCursor::MoveMode mode);
- bool camelCaseLeft(QTextCursor &cursor, QTextCursor::MoveMode mode);
void processTooltipRequest(const QTextCursor &c);
bool processAnnotaionTooltipRequest(const QTextBlock &block, const QPoint &pos) const;
@@ -625,6 +625,9 @@ public:
FixedSizeClickLabel *m_fileEncodingLabel = nullptr;
QAction *m_fileEncodingLabelAction = nullptr;
+ QComboBox *m_fileLineEnding = nullptr;
+ QAction *m_fileLineEndingAction = nullptr;
+
bool m_contentsChanged = false;
bool m_lastCursorChangeWasInteresting = false;
@@ -826,6 +829,11 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
m_cursorPositionLabel->setContentsMargins(spacing, 0, spacing, 0);
m_toolBarWidget->layout()->addWidget(m_cursorPositionLabel);
+ m_fileLineEnding = new QComboBox();
+ m_fileLineEnding->addItems(ExtraEncodingSettings::lineTerminationModeNames());
+ m_fileLineEnding->setContentsMargins(spacing, 0, spacing, 0);
+ m_fileLineEndingAction = m_toolBar->addWidget(m_fileLineEnding);
+
m_fileEncodingLabel = new FixedSizeClickLabel;
m_fileEncodingLabel->setContentsMargins(spacing, 0, spacing, 0);
m_fileEncodingLabelAction = m_toolBar->addWidget(m_fileEncodingLabel);
@@ -1064,6 +1072,13 @@ void TextEditorWidgetPrivate::ctor(const QSharedPointer<TextDocument> &doc)
connect(m_document->document(), &QTextDocument::modificationChanged,
q, &TextEditorWidget::updateTextCodecLabel);
q->updateTextCodecLabel();
+
+ connect(m_fileLineEnding, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ q, &TextEditorWidget::selectLineEnding);
+ connect(m_document->document(), &QTextDocument::modificationChanged,
+ q, &TextEditorWidget::updateTextLineEndingLabel);
+ q->updateTextLineEndingLabel();
+
}
TextEditorWidget::~TextEditorWidget()
@@ -1319,6 +1334,21 @@ void TextEditorWidget::selectEncoding()
}
}
+void TextEditorWidget::selectLineEnding(int index)
+{
+ QTC_CHECK(index >= 0);
+ const auto newMode = Utils::TextFileFormat::LineTerminationMode(index);
+ if (d->m_document->lineTerminationMode() != newMode) {
+ d->m_document->setLineTerminationMode(newMode);
+ d->q->document()->setModified(true);
+ }
+}
+
+void TextEditorWidget::updateTextLineEndingLabel()
+{
+ d->m_fileLineEnding->setCurrentIndex(d->m_document->lineTerminationMode());
+}
+
void TextEditorWidget::updateTextCodecLabel()
{
QString text = QString::fromLatin1(d->m_document->codec()->name());
@@ -1628,28 +1658,28 @@ void TextEditorWidget::gotoNextWordWithSelection()
void TextEditorWidget::gotoPreviousWordCamelCase()
{
QTextCursor c = textCursor();
- d->camelCaseLeft(c, QTextCursor::MoveAnchor);
+ CamelCaseCursor::left(&c, this, QTextCursor::MoveAnchor);
setTextCursor(c);
}
void TextEditorWidget::gotoPreviousWordCamelCaseWithSelection()
{
QTextCursor c = textCursor();
- d->camelCaseLeft(c, QTextCursor::KeepAnchor);
+ CamelCaseCursor::left(&c, this, QTextCursor::KeepAnchor);
setTextCursor(c);
}
void TextEditorWidget::gotoNextWordCamelCase()
{
QTextCursor c = textCursor();
- d->camelCaseRight(c, QTextCursor::MoveAnchor);
+ CamelCaseCursor::right(&c, this, QTextCursor::MoveAnchor);
setTextCursor(c);
}
void TextEditorWidget::gotoNextWordCamelCaseWithSelection()
{
QTextCursor c = textCursor();
- d->camelCaseRight(c, QTextCursor::KeepAnchor);
+ CamelCaseCursor::right(&c, this, QTextCursor::KeepAnchor);
setTextCursor(c);
}
@@ -2061,232 +2091,6 @@ static QTextLine currentTextLine(const QTextCursor &cursor)
return layout->lineForTextPosition(relativePos);
}
-bool TextEditorWidgetPrivate::camelCaseLeft(QTextCursor &cursor, QTextCursor::MoveMode mode)
-{
- int state = 0;
- enum Input {
- Input_U,
- Input_l,
- Input_underscore,
- Input_space,
- Input_other
- };
-
- if (!cursor.movePosition(QTextCursor::Left, mode))
- return false;
-
- forever {
- QChar c = q->document()->characterAt(cursor.position());
- Input input = Input_other;
- if (c.isUpper())
- input = Input_U;
- else if (c.isLower() || c.isDigit())
- input = Input_l;
- else if (c == QLatin1Char('_'))
- input = Input_underscore;
- else if (c.isSpace() && c != QChar::ParagraphSeparator)
- input = Input_space;
- else
- input = Input_other;
-
- switch (state) {
- case 0:
- switch (input) {
- case Input_U:
- state = 1;
- break;
- case Input_l:
- state = 2;
- break;
- case Input_underscore:
- state = 3;
- break;
- case Input_space:
- state = 4;
- break;
- default:
- cursor.movePosition(QTextCursor::Right, mode);
- return cursor.movePosition(QTextCursor::WordLeft, mode);
- }
- break;
- case 1:
- switch (input) {
- case Input_U:
- break;
- default:
- cursor.movePosition(QTextCursor::Right, mode);
- return true;
- }
- break;
-
- case 2:
- switch (input) {
- case Input_U:
- return true;
- case Input_l:
- break;
- default:
- cursor.movePosition(QTextCursor::Right, mode);
- return true;
- }
- break;
- case 3:
- switch (input) {
- case Input_underscore:
- break;
- case Input_U:
- state = 1;
- break;
- case Input_l:
- state = 2;
- break;
- default:
- cursor.movePosition(QTextCursor::Right, mode);
- return true;
- }
- break;
- case 4:
- switch (input) {
- case Input_space:
- break;
- case Input_U:
- state = 1;
- break;
- case Input_l:
- state = 2;
- break;
- case Input_underscore:
- state = 3;
- break;
- default:
- cursor.movePosition(QTextCursor::Right, mode);
- if (cursor.positionInBlock() == 0)
- return true;
- return cursor.movePosition(QTextCursor::WordLeft, mode);
- }
- }
-
- if (!cursor.movePosition(QTextCursor::Left, mode))
- return true;
- }
-}
-
-bool TextEditorWidgetPrivate::camelCaseRight(QTextCursor &cursor, QTextCursor::MoveMode mode)
-{
- int state = 0;
- enum Input {
- Input_U,
- Input_l,
- Input_underscore,
- Input_space,
- Input_other
- };
-
- forever {
- QChar c = q->document()->characterAt(cursor.position());
- Input input = Input_other;
- if (c.isUpper())
- input = Input_U;
- else if (c.isLower() || c.isDigit())
- input = Input_l;
- else if (c == QLatin1Char('_'))
- input = Input_underscore;
- else if (c.isSpace() && c != QChar::ParagraphSeparator)
- input = Input_space;
- else
- input = Input_other;
-
- switch (state) {
- case 0:
- switch (input) {
- case Input_U:
- state = 4;
- break;
- case Input_l:
- state = 1;
- break;
- case Input_underscore:
- state = 6;
- break;
- default:
- return cursor.movePosition(QTextCursor::WordRight, mode);
- }
- break;
- case 1:
- switch (input) {
- case Input_U:
- return true;
- case Input_l:
- break;
- case Input_underscore:
- state = 6;
- break;
- case Input_space:
- state = 7;
- break;
- default:
- return true;
- }
- break;
- case 2:
- switch (input) {
- case Input_U:
- break;
- case Input_l:
- cursor.movePosition(QTextCursor::Left, mode);
- return true;
- case Input_underscore:
- state = 6;
- break;
- case Input_space:
- state = 7;
- break;
- default:
- return true;
- }
- break;
- case 4:
- switch (input) {
- case Input_U:
- state = 2;
- break;
- case Input_l:
- state = 1;
- break;
- case Input_underscore:
- state = 6;
- break;
- case Input_space:
- state = 7;
- break;
- default:
- return true;
- }
- break;
- case 6:
- switch (input) {
- case Input_underscore:
- break;
- case Input_space:
- state = 7;
- break;
- default:
- return true;
- }
- break;
- case 7:
- switch (input) {
- case Input_space:
- break;
- default:
- return true;
- }
- break;
- }
- cursor.movePosition(QTextCursor::Right, mode);
- }
-}
-
bool TextEditorWidgetPrivate::cursorMoveKeyEvent(QKeyEvent *e)
{
QTextCursor cursor = q->textCursor();
@@ -2381,9 +2185,9 @@ bool TextEditorWidgetPrivate::cursorMoveKeyEvent(QKeyEvent *e)
cursor.setVisualNavigation(true);
if (q->camelCaseNavigationEnabled() && op == QTextCursor::WordRight)
- camelCaseRight(cursor, mode);
+ CamelCaseCursor::right(&cursor, q, mode);
else if (q->camelCaseNavigationEnabled() && op == QTextCursor::WordLeft)
- camelCaseLeft(cursor, mode);
+ CamelCaseCursor::left(&cursor, q, mode);
else if (!cursor.movePosition(op, mode) && mode == QTextCursor::MoveAnchor)
cursor.clearSelection();
cursor.setVisualNavigation(visualNavigation);
@@ -2586,7 +2390,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
QTextCursor c = textCursor();
int pos = c.position();
if (camelCaseNavigationEnabled())
- d->camelCaseLeft(c, QTextCursor::MoveAnchor);
+ CamelCaseCursor::left(&c, this, QTextCursor::MoveAnchor);
else
c.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
int targetpos = c.position();
@@ -2602,7 +2406,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
e->accept();
QTextCursor c = textCursor();
if (camelCaseNavigationEnabled())
- d->camelCaseLeft(c, QTextCursor::KeepAnchor);
+ CamelCaseCursor::left(&c, this, QTextCursor::KeepAnchor);
else
c.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
c.removeSelectedText();
@@ -2611,7 +2415,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
e->accept();
QTextCursor c = textCursor();
if (camelCaseNavigationEnabled())
- d->camelCaseRight(c, QTextCursor::KeepAnchor);
+ CamelCaseCursor::right(&c, this, QTextCursor::KeepAnchor);
else
c.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
c.removeSelectedText();
@@ -3045,14 +2849,20 @@ bool TextEditorWidget::event(QEvent *e)
if (e->type() != QEvent::InputMethodQuery)
d->m_contentsChanged = false;
switch (e->type()) {
- case QEvent::ShortcutOverride:
- if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape && d->m_snippetOverlay->isVisible()) {
+ case QEvent::ShortcutOverride: {
+ auto ke = static_cast<QKeyEvent *>(e);
+ if (ke->key() == Qt::Key_Escape && d->m_snippetOverlay->isVisible()) {
e->accept();
} else {
- e->ignore(); // we are a really nice citizen
+ // hack copied from QInputControl::isCommonTextEditShortcut
+ // Fixes: QTCREATORBUG-22854
+ e->setAccepted((ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
+ || ke->modifiers() == Qt::KeypadModifier)
+ && (ke->key() < Qt::Key_Escape));
d->m_maybeFakeTooltipEvent = false;
}
return true;
+ }
case QEvent::ApplicationPaletteChange: {
// slight hack: ignore palette changes
// at this point the palette has changed already,
@@ -3291,7 +3101,7 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions
InfoBarEntry info(missing,
BaseTextEditor::tr("A highlight definition was not found for this file. "
"Would you like to update highlight definition files?"),
- InfoBarEntry::GlobalSuppressionEnabled);
+ InfoBarEntry::GlobalSuppression::Enabled);
info.setCustomButtonInfo(BaseTextEditor::tr("Update Definitions"), [missing, this]() {
m_document->infoBar()->removeInfo(missing);
Highlighter::updateDefinitions([widget = QPointer<TextEditorWidget>(q)]() {
@@ -4282,7 +4092,8 @@ void TextEditorWidgetPrivate::paintRightMarginArea(PaintEventData &data, QPainte
return;
// Don't use QFontMetricsF::averageCharWidth here, due to it returning
// a fractional size even when this is not supported by the platform.
- data.rightMargin = QFontMetricsF(q->font()).width(QLatin1Char('x')) * m_visibleWrapColumn
+ data.rightMargin = QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char('x'))
+ * m_visibleWrapColumn
+ data.offset.x() + 4;
const QRect viewportRect = q->viewport()->rect();
if (data.rightMargin < viewportRect.width()) {
@@ -4458,7 +4269,7 @@ void TextEditorWidgetPrivate::paintFindScope(const PaintEventData &data, QPainte
QTextLayout *layout = block.layout();
QString text = block.text();
const TabSettings ts = m_document->tabSettings();
- qreal spacew = QFontMetricsF(q->font()).width(QLatin1Char(' '));
+ qreal spacew = QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char(' '));
int offset = 0;
int relativePos = ts.positionAtColumn(text,
@@ -4548,7 +4359,7 @@ void TextEditorWidgetPrivate::paintBlockSelection(const PaintEventData &data, QP
QRectF blockBoundingRect = q->blockBoundingRect(data.block).translated(data.offset);
QString text = data.block.text();
const TabSettings tabSettings = m_document->tabSettings();
- const qreal spacew = QFontMetricsF(q->font()).width(QLatin1Char(' '));
+ const qreal spacew = QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char(' '));
const int cursorw = q->overwriteMode() ? QFontMetrics(q->font()).horizontalAdvance(QLatin1Char(' '))
: q->cursorWidth();
@@ -4623,14 +4434,14 @@ void TextEditorWidgetPrivate::paintCursorAsBlock(const PaintEventData &data, QPa
w = line.cursorToX(relativePos + 1) - x;
if (data.doc->characterAt(data.context.cursorPosition) == QLatin1Char('\t')) {
doSelection = false;
- qreal space = fontMetrics.width(QLatin1Char(' '));
+ qreal space = fontMetrics.horizontalAdvance(QLatin1Char(' '));
if (w > space) {
x += w-space;
w = space;
}
}
} else
- w = fontMetrics.width(QLatin1Char(' ')); // in sync with QTextLine::draw()
+ w = fontMetrics.horizontalAdvance(QLatin1Char(' ')); // in sync with QTextLine::draw()
QRectF lineRect = line.rect();
lineRect.moveTop(lineRect.top() + blockData.boundingRect.top());
@@ -5312,7 +5123,7 @@ void TextEditorWidget::extraAreaPaintEvent(QPaintEvent *e)
QPainter painter(d->m_extraArea);
- painter.fillRect(e->rect(), data.palette.color(QPalette::Background));
+ painter.fillRect(e->rect(), data.palette.color(QPalette::Window));
data.block = firstVisibleBlock();
QPointF offset = contentOffset();
@@ -5638,7 +5449,7 @@ void TextEditorWidget::mouseMoveEvent(QMouseEvent *e)
int column = tabSettings.columnAt(
cursor.block().text(), cursor.positionInBlock());
if (cursor.positionInBlock() == cursor.block().length()-1)
- column += (e->pos().x() - cursorRect().center().x()) / QFontMetricsF(font()).width(QLatin1Char(' '));
+ column += (e->pos().x() - cursorRect().center().x()) / QFontMetricsF(font()).horizontalAdvance(QLatin1Char(' '));
int block = cursor.blockNumber();
if (block == blockCount() - 1)
block += (e->pos().y() - cursorRect().center().y()) / QFontMetricsF(font()).lineSpacing();
@@ -5651,7 +5462,7 @@ void TextEditorWidget::mouseMoveEvent(QMouseEvent *e)
int column = tabSettings.columnAt(
cursor.block().text(), cursor.positionInBlock());
if (cursor.positionInBlock() == cursor.block().length()-1)
- column += (e->pos().x() - cursorRect().center().x()) / QFontMetricsF(font()).width(QLatin1Char(' '));
+ column += (e->pos().x() - cursorRect().center().x()) / QFontMetricsF(font()).horizontalAdvance(QLatin1Char(' '));
d->m_blockSelection.positionBlock = cursor.blockNumber();
d->m_blockSelection.positionColumn = column;
@@ -5689,7 +5500,7 @@ void TextEditorWidget::mousePressEvent(QMouseEvent *e)
int column = d->m_document->tabSettings().columnAt(
cursor.block().text(), cursor.positionInBlock());
if (cursor.positionInBlock() == cursor.block().length()-1)
- column += (e->pos().x() - cursorRect(cursor).center().x()) / QFontMetricsF(font()).width(QLatin1Char(' '));
+ column += (e->pos().x() - cursorRect(cursor).center().x()) / QFontMetricsF(font()).horizontalAdvance(QLatin1Char(' '));
int block = cursor.blockNumber();
if (block == blockCount() - 1)
block += (e->pos().y() - cursorRect(cursor).center().y()) / QFontMetricsF(font()).lineSpacing();
@@ -7111,7 +6922,7 @@ void TextEditorWidget::deleteEndOfWord()
void TextEditorWidget::deleteEndOfWordCamelCase()
{
QTextCursor c = textCursor();
- d->camelCaseRight(c, QTextCursor::KeepAnchor);
+ CamelCaseCursor::right(&c, this, QTextCursor::KeepAnchor);
c.removeSelectedText();
setTextCursor(c);
}
@@ -7133,7 +6944,7 @@ void TextEditorWidget::deleteStartOfWord()
void TextEditorWidget::deleteStartOfWordCamelCase()
{
QTextCursor c = textCursor();
- d->camelCaseLeft(c, QTextCursor::KeepAnchor);
+ CamelCaseCursor::left(&c, this, QTextCursor::KeepAnchor);
c.removeSelectedText();
setTextCursor(c);
}
@@ -7444,7 +7255,7 @@ void TextEditorWidget::applyFontSettings()
const QColor background = textFormat.background().color();
QPalette p = palette();
p.setColor(QPalette::Text, foreground);
- p.setColor(QPalette::Foreground, foreground);
+ p.setColor(QPalette::WindowText, foreground);
p.setColor(QPalette::Base, background);
p.setColor(QPalette::Highlight, (selectionFormat.background().style() != Qt::NoBrush) ?
selectionFormat.background().color() :
@@ -7461,7 +7272,7 @@ void TextEditorWidget::applyFontSettings()
// Line numbers
QPalette ep;
ep.setColor(QPalette::Dark, lineNumberFormat.foreground().color());
- ep.setColor(QPalette::Background, lineNumberFormat.background().style() != Qt::NoBrush ?
+ ep.setColor(QPalette::Window, lineNumberFormat.background().style() != Qt::NoBrush ?
lineNumberFormat.background().color() : background);
d->m_extraArea->setPalette(ep);
@@ -7900,7 +7711,7 @@ int TextEditorWidget::lineNumberDigits() const
bool TextEditorWidget::selectionVisible(int blockNumber) const
{
- Q_UNUSED(blockNumber);
+ Q_UNUSED(blockNumber)
return true;
}
@@ -8297,7 +8108,7 @@ void TextEditorWidgetPrivate::updateTabStops()
{
// Although the tab stop is stored as qreal the API from QPlainTextEdit only allows it
// to be set as an int. A work around is to access directly the QTextOption.
- qreal charWidth = QFontMetricsF(q->font()).width(QLatin1Char(' '));
+ qreal charWidth = QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char(' '));
QTextOption option = q->document()->defaultTextOption();
option.setTabStopDistance(charWidth * m_document->tabSettings().m_tabSize);
q->document()->setDefaultTextOption(option);
@@ -8306,7 +8117,7 @@ void TextEditorWidgetPrivate::updateTabStops()
int TextEditorWidget::columnCount() const
{
QFontMetricsF fm(font());
- return int(viewport()->rect().width() / fm.width(QLatin1Char('x')));
+ return int(viewport()->rect().width() / fm.horizontalAdvance(QLatin1Char('x')));
}
int TextEditorWidget::rowCount() const
@@ -8506,7 +8317,7 @@ void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider)
AssistInterface *TextEditorWidget::createAssistInterface(AssistKind kind,
AssistReason reason) const
{
- Q_UNUSED(kind);
+ Q_UNUSED(kind)
return new AssistInterface(document(), position(), d->m_document->filePath().toString(), reason);
}
diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h
index 08b6738a5e..d5a9a68ead 100644
--- a/src/plugins/texteditor/texteditor.h
+++ b/src/plugins/texteditor/texteditor.h
@@ -381,6 +381,8 @@ public:
void unfold();
void selectEncoding();
void updateTextCodecLabel();
+ void selectLineEnding(int index);
+ void updateTextLineEndingLabel();
void gotoBlockStart();
void gotoBlockEnd();
diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h
index 78c9c1cb71..b3905b5192 100644
--- a/src/plugins/texteditor/texteditorconstants.h
+++ b/src/plugins/texteditor/texteditorconstants.h
@@ -25,6 +25,8 @@
#pragma once
+#include "texteditor_global.h"
+
#include <QtGlobal>
namespace TextEditor {
@@ -204,7 +206,7 @@ const char JUMP_TO_FILE_UNDER_CURSOR_IN_NEXT_SPLIT[] = "TextEditor.JumpToFileUnd
const char SCROLL_BAR_SEARCH_RESULT[] = "TextEditor.ScrollBarSearchResult";
const char SCROLL_BAR_CURRENT_LINE[] = "TextEditor.ScrollBarCurrentLine";
-const char *nameForStyle(TextStyle style);
+const TEXTEDITOR_EXPORT char *nameForStyle(TextStyle style);
TextStyle styleFromName(const char *name);
const char TEXT_EDITOR_SETTINGS_CATEGORY[] = "C.TextEditor";
diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp
index a33ca13810..735869082f 100644
--- a/src/plugins/texteditor/texteditoroverlay.cpp
+++ b/src/plugins/texteditor/texteditoroverlay.cpp
@@ -393,7 +393,7 @@ void TextEditorOverlay::fillSelection(QPainter *painter,
void TextEditorOverlay::paint(QPainter *painter, const QRect &clip)
{
- Q_UNUSED(clip);
+ Q_UNUSED(clip)
for (int i = m_selections.size()-1; i >= 0; --i) {
const OverlaySelection &selection = m_selections.at(i);
if (selection.m_dropShadow)
@@ -420,7 +420,7 @@ void TextEditorOverlay::paint(QPainter *painter, const QRect &clip)
void TextEditorOverlay::fill(QPainter *painter, const QColor &color, const QRect &clip)
{
- Q_UNUSED(clip);
+ Q_UNUSED(clip)
for (int i = m_selections.size()-1; i >= 0; --i) {
const OverlaySelection &selection = m_selections.at(i);
if (selection.m_dropShadow)
diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp
index e08ecbe75d..676ce18b45 100644
--- a/src/plugins/texteditor/texteditorplugin.cpp
+++ b/src/plugins/texteditor/texteditorplugin.cpp
@@ -48,6 +48,7 @@
#include <texteditor/icodestylepreferences.h>
#include <texteditor/tabsettings.h>
+#include <utils/fancylineedit.h>
#include <utils/qtcassert.h>
#include <utils/macroexpander.h>
@@ -125,6 +126,10 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
if (BaseTextEditor *editor = BaseTextEditor::currentTextEditor())
editor->editorWidget()->invokeAssist(Completion);
});
+ connect(command, &Command::keySequenceChanged, [command] {
+ Utils::FancyLineEdit::setCompletionShortcut(command->keySequence());
+ });
+ Utils::FancyLineEdit::setCompletionShortcut(command->keySequence());
// Add shortcut for invoking quick fix options
QAction *quickFixAction = new QAction(tr("Trigger Refactoring Action"), this);
diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp
index bdc7e7a583..650959c73d 100644
--- a/src/plugins/texteditor/texteditorsettings.cpp
+++ b/src/plugins/texteditor/texteditorsettings.cpp
@@ -48,6 +48,7 @@
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
+#include <utils/fancylineedit.h>
#include <utils/qtcassert.h>
#include <QApplication>
@@ -399,6 +400,13 @@ TextEditorSettings::TextEditorSettings()
this, &TextEditorSettings::completionSettingsChanged);
connect(d->m_completionSettingsPage, &CompletionSettingsPage::commentsSettingsChanged,
this, &TextEditorSettings::commentsSettingsChanged);
+
+ auto updateCamelCaseNavigation = [] {
+ Utils::FancyLineEdit::setCamelCaseNavigationEnabled(behaviorSettings().m_camelCaseNavigation);
+ };
+ connect(d->m_behaviorSettingsPage, &BehaviorSettingsPage::behaviorSettingsChanged,
+ this, updateCamelCaseNavigation);
+ updateCamelCaseNavigation();
}
TextEditorSettings::~TextEditorSettings()
@@ -473,7 +481,7 @@ void TextEditorSettings::unregisterCodeStyleFactory(Core::Id languageId)
d->m_languageToFactory.remove(languageId);
}
-QMap<Core::Id, ICodeStylePreferencesFactory *> TextEditorSettings::codeStyleFactories()
+const QMap<Core::Id, ICodeStylePreferencesFactory *> &TextEditorSettings::codeStyleFactories()
{
return d->m_languageToFactory;
}
diff --git a/src/plugins/texteditor/texteditorsettings.h b/src/plugins/texteditor/texteditorsettings.h
index 013ed790ae..675c459d2e 100644
--- a/src/plugins/texteditor/texteditorsettings.h
+++ b/src/plugins/texteditor/texteditorsettings.h
@@ -79,7 +79,7 @@ public:
static const CommentsSettings &commentsSettings();
static ICodeStylePreferencesFactory *codeStyleFactory(Core::Id languageId);
- static QMap<Core::Id, ICodeStylePreferencesFactory *> codeStyleFactories();
+ static const QMap<Core::Id, ICodeStylePreferencesFactory *> &codeStyleFactories();
static void registerCodeStyleFactory(ICodeStylePreferencesFactory *codeStyleFactory);
static void unregisterCodeStyleFactory(Core::Id languageId);
diff --git a/src/plugins/texteditor/textindenter.cpp b/src/plugins/texteditor/textindenter.cpp
index 3dab3e2c48..c2d328d3fe 100644
--- a/src/plugins/texteditor/textindenter.cpp
+++ b/src/plugins/texteditor/textindenter.cpp
@@ -51,7 +51,7 @@ void TextIndenter::indentBlock(const QTextBlock &block,
const TabSettings &tabSettings,
int /*cursorPositionInEditor*/)
{
- Q_UNUSED(typedChar);
+ Q_UNUSED(typedChar)
const int indent = indentFor(block, tabSettings);
if (indent < 0)
return;
diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp
index 3493570487..63d6c17844 100644
--- a/src/plugins/texteditor/textmark.cpp
+++ b/src/plugins/texteditor/textmark.cpp
@@ -267,7 +267,7 @@ bool TextMark::isDraggable() const
void TextMark::dragToLine(int lineNumber)
{
- Q_UNUSED(lineNumber);
+ Q_UNUSED(lineNumber)
}
void TextMark::addToToolTipLayout(QGridLayout *target) const
diff --git a/src/plugins/todo/cpptodoitemsscanner.cpp b/src/plugins/todo/cpptodoitemsscanner.cpp
index 2c6f8f0e1c..8fa9972274 100644
--- a/src/plugins/todo/cpptodoitemsscanner.cpp
+++ b/src/plugins/todo/cpptodoitemsscanner.cpp
@@ -77,7 +77,7 @@ void CppTodoItemsScanner::processDocument(CPlusPlus::Document::Ptr doc)
QList<TodoItem> itemList;
CPlusPlus::TranslationUnit *translationUnit = doc->translationUnit();
- for (unsigned i = 0; i < translationUnit->commentCount(); ++i) {
+ for (int i = 0; i < translationUnit->commentCount(); ++i) {
// Get comment source
CPlusPlus::Token token = doc->translationUnit()->commentAt(i);
@@ -89,7 +89,7 @@ void CppTodoItemsScanner::processDocument(CPlusPlus::Document::Ptr doc)
}
// Process every line of the comment
- unsigned lineNumber = 0;
+ int lineNumber = 0;
translationUnit->getPosition(token.utf16charsBegin(), &lineNumber);
for (int from = 0, sz = source.size(); from < sz; ++lineNumber) {
diff --git a/src/plugins/todo/lineparser.cpp b/src/plugins/todo/lineparser.cpp
index a81e65b938..161ca71c32 100644
--- a/src/plugins/todo/lineparser.cpp
+++ b/src/plugins/todo/lineparser.cpp
@@ -104,17 +104,13 @@ QList<LineParser::KeywordEntry> LineParser::keywordEntriesFromCandidates(
return QList<KeywordEntry>();
// Convert candidates to entries
- QList<KeywordEntry> entries;
- QMapIterator<int, int> i(candidates);
- i.toBack();
-
- while (i.hasPrevious()) {
- i.previous();
+ std::vector<KeywordEntry> tmp;
+ for (auto it = candidates.cbegin(), end = candidates.cend(); it != end; ++it)
+ tmp.emplace_back(KeywordEntry{it.value(), it.key(), QString()});
- KeywordEntry entry;
-
- entry.keywordStart = i.key();
- entry.keywordIndex = i.value();
+ QList<KeywordEntry> entries;
+ for (auto it = tmp.crbegin(), end = tmp.crend(); it != end; ++it) {
+ KeywordEntry entry = *it;
int keywordLength = m_keywords.at(entry.keywordIndex).name.length();
diff --git a/src/plugins/todo/optionsdialog.cpp b/src/plugins/todo/optionsdialog.cpp
index 706f67cd18..d4b1860c8d 100644
--- a/src/plugins/todo/optionsdialog.cpp
+++ b/src/plugins/todo/optionsdialog.cpp
@@ -34,8 +34,7 @@
namespace Todo {
namespace Internal {
-OptionsDialog::OptionsDialog(QWidget *parent) :
- QWidget(parent),
+OptionsDialog::OptionsDialog() :
ui(new Ui::OptionsDialog)
{
ui->setupUi(this);
diff --git a/src/plugins/todo/optionsdialog.h b/src/plugins/todo/optionsdialog.h
index 716bdd5fd2..7f48ff2616 100644
--- a/src/plugins/todo/optionsdialog.h
+++ b/src/plugins/todo/optionsdialog.h
@@ -43,7 +43,7 @@ class Keyword;
class OptionsDialog : public QWidget
{
public:
- explicit OptionsDialog(QWidget *parent = nullptr);
+ OptionsDialog();
~OptionsDialog() override;
void setSettings(const Settings &settings);
diff --git a/src/plugins/todo/todoitemsmodel.cpp b/src/plugins/todo/todoitemsmodel.cpp
index 03d48a1352..7776ec169c 100644
--- a/src/plugins/todo/todoitemsmodel.cpp
+++ b/src/plugins/todo/todoitemsmodel.cpp
@@ -78,7 +78,7 @@ QVariant TodoItemsModel::data(const QModelIndex &index, int role) const
TodoItem item = m_todoItemsList->at(index.row());
- if (role == Qt::TextColorRole)
+ if (role == Qt::ForegroundRole)
return item.color;
switch (index.column()) {
diff --git a/src/plugins/todo/todoitemsprovider.cpp b/src/plugins/todo/todoitemsprovider.cpp
index 9c8d921567..de83d31d4e 100644
--- a/src/plugins/todo/todoitemsprovider.cpp
+++ b/src/plugins/todo/todoitemsprovider.cpp
@@ -80,7 +80,7 @@ void TodoItemsProvider::settingsChanged(const Settings &newSettings)
void TodoItemsProvider::projectSettingsChanged(Project *project)
{
- Q_UNUSED(project);
+ Q_UNUSED(project)
updateList();
}
@@ -122,13 +122,11 @@ void TodoItemsProvider::createScanners()
void TodoItemsProvider::setItemsListWithinStartupProject()
{
- QHashIterator<FilePath, QList<TodoItem> > it(m_itemsHash);
const auto filePaths = Utils::toSet(m_startupProject->files(Project::SourceFiles));
QVariantMap settings = m_startupProject->namedSettings(Constants::SETTINGS_NAME_KEY).toMap();
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_itemsHash.cbegin(), end = m_itemsHash.cend(); it != end; ++it) {
const FilePath filePath = it.key();
if (filePaths.contains(filePath)) {
bool skip = false;
@@ -160,9 +158,7 @@ void TodoItemsProvider::setItemsListWithinSubproject()
// files must be both in the current subproject and the startup-project.
const auto fileNames = Utils::toSet(m_startupProject->files(Project::SourceFiles));
- QHashIterator<FilePath, QList<TodoItem> > it(m_itemsHash);
- while (it.hasNext()) {
- it.next();
+ for (auto it = m_itemsHash.cbegin(), end = m_itemsHash.cend(); it != end; ++it) {
if (subprojectFileNames.contains(it.key()) && fileNames.contains(it.key()))
m_itemsList << it.value();
}
diff --git a/src/plugins/todo/todooutputpane.cpp b/src/plugins/todo/todooutputpane.cpp
index 9f8a528124..940f6e97f2 100644
--- a/src/plugins/todo/todooutputpane.cpp
+++ b/src/plugins/todo/todooutputpane.cpp
@@ -178,7 +178,7 @@ void TodoOutputPane::todoTreeViewClicked(const QModelIndex &index)
item.text = index.sibling(row, Constants::OUTPUT_COLUMN_TEXT).data().toString();
item.file = Utils::FilePath::fromUserInput(index.sibling(row, Constants::OUTPUT_COLUMN_FILE).data().toString());
item.line = index.sibling(row, Constants::OUTPUT_COLUMN_LINE).data().toInt();
- item.color = index.data(Qt::TextColorRole).value<QColor>();
+ item.color = index.data(Qt::ForegroundRole).value<QColor>();
item.iconType = static_cast<IconType>(index.sibling(row, Constants::OUTPUT_COLUMN_TEXT)
.data(Qt::UserRole).toInt());
diff --git a/src/plugins/todo/todooutputtreeview.cpp b/src/plugins/todo/todooutputtreeview.cpp
index 9db3800089..d75b5c140a 100644
--- a/src/plugins/todo/todooutputtreeview.cpp
+++ b/src/plugins/todo/todooutputtreeview.cpp
@@ -101,7 +101,7 @@ void TodoOutputTreeView::resizeEvent(QResizeEvent *event)
void TodoOutputTreeView::todoColumnResized(int column, int oldSize, int newSize)
{
- Q_UNUSED(oldSize);
+ Q_UNUSED(oldSize)
if (column == Constants::OUTPUT_COLUMN_TEXT)
m_textColumnDefaultWidth = newSize;
else if (column == Constants::OUTPUT_COLUMN_FILE)
diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp
index b59e50ee44..e16e11e063 100644
--- a/src/plugins/todo/todoplugin.cpp
+++ b/src/plugins/todo/todoplugin.cpp
@@ -54,8 +54,8 @@ TodoPlugin::~TodoPlugin() = default;
bool TodoPlugin::initialize(const QStringList& args, QString *errMsg)
{
- Q_UNUSED(args);
- Q_UNUSED(errMsg);
+ Q_UNUSED(args)
+ Q_UNUSED(errMsg)
m_settings.load(Core::ICore::settings());
diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp
index 08e644bc5e..4644823ed5 100644
--- a/src/plugins/updateinfo/updateinfoplugin.cpp
+++ b/src/plugins/updateinfo/updateinfoplugin.cpp
@@ -30,6 +30,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
+#include <coreplugin/infobar.h>
#include <coreplugin/settingsdatabase.h>
#include <coreplugin/shellcommand.h>
#include <utils/fileutils.h>
@@ -40,7 +41,6 @@
#include <QFile>
#include <QFileInfo>
#include <QMenu>
-#include <QMessageBox>
#include <QMetaEnum>
#include <QPointer>
#include <QProcessEnvironment>
@@ -55,6 +55,7 @@ namespace {
static const char LastCheckDateKey[] = "LastCheckDate";
static const quint32 OneMinute = 60000;
static const quint32 OneHour = 3600000;
+ static const char InstallUpdates[] = "UpdateInfo.InstallUpdates";
}
using namespace Core;
@@ -128,7 +129,7 @@ void UpdateInfoPlugin::startCheckForUpdates()
d->m_checkUpdatesCommand->setDisplayName(tr("Checking for Updates"));
connect(d->m_checkUpdatesCommand, &ShellCommand::stdOutText, this, &UpdateInfoPlugin::collectCheckForUpdatesOutput);
connect(d->m_checkUpdatesCommand, &ShellCommand::finished, this, &UpdateInfoPlugin::checkForUpdatesFinished);
- d->m_checkUpdatesCommand->addJob(Utils::FilePath::fromFileInfo(d->m_maintenanceTool), {"--checkupdates"},
+ d->m_checkUpdatesCommand->addJob({Utils::FilePath::fromFileInfo(d->m_maintenanceTool), {"--checkupdates"}},
60 * 3, // 3 minutes timeout
/*workingDirectory=*/QString(),
[](int /*exitCode*/) { return Utils::SynchronousProcessResponse::Finished; });
@@ -158,6 +159,23 @@ void UpdateInfoPlugin::collectCheckForUpdatesOutput(const QString &contents)
d->m_collectedOutput += contents;
}
+static QStringList availableUpdates(const QDomDocument &document)
+{
+ if (document.isNull() || !document.firstChildElement().hasChildNodes())
+ return {};
+ QStringList result;
+ const QDomNodeList updates = document.firstChildElement().elementsByTagName("update");
+ for (int i = 0; i < updates.size(); ++i) {
+ const QDomNode node = updates.item(i);
+ if (node.isElement()) {
+ const QDomElement element = node.toElement();
+ if (element.hasAttribute("name"))
+ result.append(element.attribute("name"));
+ }
+ }
+ return result;
+}
+
void UpdateInfoPlugin::checkForUpdatesFinished()
{
setLastCheckDate(QDate::currentDate());
@@ -168,11 +186,29 @@ void UpdateInfoPlugin::checkForUpdatesFinished()
stopCheckForUpdates();
if (!document.isNull() && document.firstChildElement().hasChildNodes()) {
+ // progress details are shown until user interaction for the "no updates" case,
+ // so we can show the "No updates found" text, but if we have updates we don't
+ // want to keep it around
+ if (d->m_progress)
+ d->m_progress->setKeepOnFinish(FutureProgress::HideOnFinish);
emit newUpdatesAvailable(true);
- if (QMessageBox::question(ICore::dialogParent(), tr("Qt Updater"),
- tr("New updates are available. Do you want to start the update?"))
- == QMessageBox::Yes)
+ Core::InfoBarEntry info(InstallUpdates,
+ tr("New updates are available. Do you want to start the update?"));
+ info.setCustomButtonInfo(tr("Start Update"), [this] {
+ Core::ICore::infoBar()->removeInfo(InstallUpdates);
startUpdater();
+ });
+ const QStringList updates = availableUpdates(document);
+ info.setDetailsWidgetCreator([updates]() -> QWidget * {
+ const QString updateText = updates.join("</li><li>");
+ auto label = new QLabel;
+ label->setText("<qt><p>" + tr("Available Updates:") + "<ul><li>" + updateText
+ + "</li></ul></p></qt>");
+ label->setContentsMargins(0, 0, 0, 8);
+ return label;
+ });
+ Core::ICore::infoBar()->unsuppressInfo(InstallUpdates);
+ Core::ICore::infoBar()->addInfo(info);
} else {
emit newUpdatesAvailable(false);
if (d->m_progress)
diff --git a/src/plugins/valgrind/callgrind/callgrindcontroller.cpp b/src/plugins/valgrind/callgrind/callgrindcontroller.cpp
index 1974ced68f..f195d2e374 100644
--- a/src/plugins/valgrind/callgrind/callgrindcontroller.cpp
+++ b/src/plugins/valgrind/callgrind/callgrindcontroller.cpp
@@ -125,7 +125,7 @@ void CallgrindController::run(Option option)
this, &CallgrindController::controllerProcessClosed);
Runnable controller = m_valgrindRunnable;
- controller.executable = CALLGRIND_CONTROL_BINARY;
+ controller.executable = FilePath::fromString(CALLGRIND_CONTROL_BINARY);
controller.commandLineArguments = QString("%1 %2").arg(toOptionString(option)).arg(m_pid);
if (!m_valgrindRunnable.device
@@ -187,7 +187,7 @@ void CallgrindController::controllerProcessFinished(int rc, QProcess::ExitStatus
void CallgrindController::controllerProcessClosed(bool success)
{
- Q_UNUSED(success);
+ Q_UNUSED(success)
// QTC_ASSERT(m_remote.m_process, return);
// m_remote.m_errorString = m_remote.m_process->errorString();
diff --git a/src/plugins/valgrind/callgrind/callgrinddatamodel.cpp b/src/plugins/valgrind/callgrind/callgrinddatamodel.cpp
index 611c1634af..b64ee8764d 100644
--- a/src/plugins/valgrind/callgrind/callgrinddatamodel.cpp
+++ b/src/plugins/valgrind/callgrind/callgrinddatamodel.cpp
@@ -240,7 +240,7 @@ QVariant DataModel::data(const QModelIndex &index, int role) const
}
}
ret += entry.arg(tr("Object:")).arg(func->object());
- ret += entry.arg(tr("Called:")).arg(tr("%n time(s)", 0, func->called()));
+ ret += entry.arg(tr("Called:")).arg(tr("%n time(s)", nullptr, func->called()));
ret += "</dl><p/>";
// self/inclusive costs
diff --git a/src/plugins/valgrind/callgrind/callgrindparser.cpp b/src/plugins/valgrind/callgrind/callgrindparser.cpp
index c80a30b99b..e966452d47 100644
--- a/src/plugins/valgrind/callgrind/callgrindparser.cpp
+++ b/src/plugins/valgrind/callgrind/callgrindparser.cpp
@@ -224,7 +224,7 @@ void Parser::Private::parse(QIODevice *device)
// functions that need to accumulate their calees
QSet<Function *> pendingFunctions;
foreach (const CallData &callData, pendingCallees) {
- Function *calledFunction = 0;
+ Function *calledFunction = nullptr;
QTC_ASSERT(callData.call, continue);
QTC_ASSERT(callData.call->caller(), continue);
foreach (const Function *function, functionLookup.value(callData.calledFunction)) {
diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp
index 698d47479c..22512b7438 100644
--- a/src/plugins/valgrind/callgrindengine.cpp
+++ b/src/plugins/valgrind/callgrindengine.cpp
@@ -77,18 +77,16 @@ QStringList CallgrindToolRunner::toolArguments() const
{
QStringList arguments = {"--tool=callgrind"};
- QTC_ASSERT(m_settings, return arguments);
-
- if (m_settings->enableCacheSim())
+ if (m_settings.enableCacheSim())
arguments << "--cache-sim=yes";
- if (m_settings->enableBranchSim())
+ if (m_settings.enableBranchSim())
arguments << "--branch-sim=yes";
- if (m_settings->collectBusEvents())
+ if (m_settings.collectBusEvents())
arguments << "--collect-bus=yes";
- if (m_settings->collectSystime())
+ if (m_settings.collectSystime())
arguments << "--collect-systime=yes";
if (m_markAsPaused)
@@ -108,7 +106,7 @@ QString CallgrindToolRunner::progressTitle() const
void CallgrindToolRunner::start()
{
- appendMessage(tr("Profiling %1").arg(executable()), Utils::NormalMessageFormat);
+ appendMessage(tr("Profiling %1").arg(executable().toUserOutput()), Utils::NormalMessageFormat);
return ValgrindToolRunner::start();
}
diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp
index 0bf4b2661e..0d8cc15109 100644
--- a/src/plugins/valgrind/callgrindtool.cpp
+++ b/src/plugins/valgrind/callgrindtool.cpp
@@ -219,6 +219,11 @@ public:
bool m_toolBusy = false;
Perspective m_perspective{"Callgrind.Perspective", CallgrindTool::tr("Callgrind")};
+
+ RunWorkerFactory callgrindRunWorkerFactory{
+ RunWorkerFactory::make<CallgrindToolRunner>(),
+ {CALLGRIND_RUN_MODE}
+ };
};
CallgrindToolPrivate::CallgrindToolPrivate()
@@ -285,7 +290,7 @@ CallgrindToolPrivate::CallgrindToolPrivate()
runControl->createMainWorker();
const auto runnable = dlg.runnable();
runControl->setRunnable(runnable);
- runControl->setDisplayName(runnable.executable);
+ runControl->setDisplayName(runnable.executable.toUserOutput());
ProjectExplorerPlugin::startRunControl(runControl);
});
@@ -781,13 +786,11 @@ void CallgrindToolPrivate::setupRunner(CallgrindToolRunner *toolRunner)
QTC_ASSERT(m_visualization, return);
// apply project settings
- auto settings
- = qobject_cast<ValgrindBaseSettings *>(runControl->settings(ANALYZER_VALGRIND_SETTINGS));
- if (settings) {
- m_visualization->setMinimumInclusiveCostRatio(settings->visualisationMinimumInclusiveCostRatio() / 100.0);
- m_proxyModel.setMinimumInclusiveCostRatio(settings->minimumInclusiveCostRatio() / 100.0);
- m_dataModel.setVerboseToolTipsEnabled(settings->enableEventToolTips());
- }
+ ValgrindProjectSettings settings;
+ settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS));
+ m_visualization->setMinimumInclusiveCostRatio(settings.visualisationMinimumInclusiveCostRatio() / 100.0);
+ m_proxyModel.setMinimumInclusiveCostRatio(settings.minimumInclusiveCostRatio() / 100.0);
+ m_dataModel.setVerboseToolTipsEnabled(settings.enableEventToolTips());
m_toolBusy = true;
updateRunActions();
@@ -999,7 +1002,6 @@ void setupCallgrindRunner(CallgrindToolRunner *toolRunner)
CallgrindTool::CallgrindTool()
{
dd = new CallgrindToolPrivate;
- RunControl::registerWorker<CallgrindToolRunner>(CALLGRIND_RUN_MODE, {});
}
CallgrindTool::~CallgrindTool()
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index d83cb16afa..72d33d719b 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -191,16 +191,14 @@ QStringList MemcheckToolRunner::toolArguments() const
{
QStringList arguments = {"--tool=memcheck", "--gen-suppressions=all"};
- QTC_ASSERT(m_settings, return arguments);
-
- if (m_settings->trackOrigins())
+ if (m_settings.trackOrigins())
arguments << "--track-origins=yes";
- if (m_settings->showReachable())
+ if (m_settings.showReachable())
arguments << "--show-reachable=yes";
QString leakCheckValue;
- switch (m_settings->leakCheckOnFinish()) {
+ switch (m_settings.leakCheckOnFinish()) {
case ValgrindBaseSettings::LeakCheckOnFinishNo:
leakCheckValue = "no";
break;
@@ -214,10 +212,10 @@ QStringList MemcheckToolRunner::toolArguments() const
}
arguments << "--leak-check=" + leakCheckValue;
- foreach (const QString &file, m_settings->suppressionFiles())
+ foreach (const QString &file, m_settings.suppressionFiles())
arguments << QString("--suppressions=%1").arg(file);
- arguments << QString("--num-callers=%1").arg(m_settings->numCallers());
+ arguments << QString("--num-callers=%1").arg(m_settings.numCallers());
if (m_withGdb)
arguments << "--vgdb=yes" << "--vgdb-error=0";
@@ -227,7 +225,7 @@ QStringList MemcheckToolRunner::toolArguments() const
QStringList MemcheckToolRunner::suppressionFiles() const
{
- return m_settings->suppressionFiles();
+ return m_settings.suppressionFiles();
}
void MemcheckToolRunner::startDebugger(qint64 valgrindPid)
@@ -437,6 +435,11 @@ private:
QString m_exitMsg;
Perspective m_perspective{"Memcheck.Perspective", MemcheckTool::tr("Memcheck")};
+
+ RunWorkerFactory memcheckToolRunnerFactory{
+ RunWorkerFactory::make<MemcheckToolRunner>(),
+ {MEMCHECK_RUN_MODE, MEMCHECK_WITH_GDB_RUN_MODE}
+ };
};
static MemcheckToolPrivate *dd = nullptr;
@@ -679,7 +682,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
rc->createMainWorker();
const auto runnable = dlg.runnable();
rc->setRunnable(runnable);
- rc->setDisplayName(runnable.executable);
+ rc->setDisplayName(runnable.executable.toUserOutput());
ProjectExplorerPlugin::startRunControl(rc);
});
@@ -739,7 +742,7 @@ void MemcheckToolPrivate::heobAction()
return;
}
- QString executable = sr.executable;
+ QString executable = sr.executable.toString();
const QString workingDirectory = Utils::FileUtils::normalizePathName(sr.workingDirectory);
const QString commandLineArguments = sr.commandLineArguments;
const QStringList envStrings = sr.environment.toStringList();
@@ -818,7 +821,7 @@ void MemcheckToolPrivate::heobAction()
// process environment
QByteArray env;
void *envPtr = nullptr;
- Q_UNUSED(envPtr);
+ Q_UNUSED(envPtr)
if (!envStrings.isEmpty()) {
uint pos = 0;
for (const QString &par : envStrings) {
@@ -976,7 +979,7 @@ void MemcheckToolPrivate::setupRunner(MemcheckToolRunner *runTool)
m_loadExternalLogFile->setDisabled(true);
QString dir = runControl->project()->projectDirectory().toString() + '/';
- const QString name = FilePath::fromString(runTool->executable()).fileName();
+ const QString name = runTool->executable().fileName();
m_errorView->setDefaultSuppressionFile(dir + name + ".supp");
@@ -1522,7 +1525,7 @@ void HeobData::processFinished()
debugger->setStartMode(AttachExternal);
debugger->setCloseMode(DetachAtClose);
debugger->setContinueAfterAttach(true);
- debugger->setInferiorExecutable(Utils::imageName(m_data[1]));
+ debugger->setInferiorExecutable(FilePath::fromString(Utils::imageName(m_data[1])));
connect(m_runControl, &RunControl::started, this, &HeobData::debugStarted);
connect(m_runControl, &RunControl::stopped, this, &HeobData::debugStopped);
@@ -1644,9 +1647,6 @@ void HeobData::debugStopped()
MemcheckTool::MemcheckTool()
{
dd = new MemcheckToolPrivate;
-
- RunControl::registerWorker<MemcheckToolRunner>(MEMCHECK_RUN_MODE, {});
- RunControl::registerWorker<MemcheckToolRunner>(MEMCHECK_WITH_GDB_RUN_MODE, {});
}
MemcheckTool::~MemcheckTool()
diff --git a/src/plugins/valgrind/suppressiondialog.cpp b/src/plugins/valgrind/suppressiondialog.cpp
index fbd2b21726..e853791f8c 100644
--- a/src/plugins/valgrind/suppressiondialog.cpp
+++ b/src/plugins/valgrind/suppressiondialog.cpp
@@ -227,7 +227,7 @@ void SuppressionDialog::accept()
foreach (const QModelIndex &index, indices) {
bool removed = model->removeRow(index.row());
QTC_ASSERT(removed, qt_noop());
- Q_UNUSED(removed);
+ Q_UNUSED(removed)
}
// One suppression might hide multiple rows, care for that.
diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp
index 547fa4a946..486bbae244 100644
--- a/src/plugins/valgrind/valgrindengine.cpp
+++ b/src/plugins/valgrind/valgrindengine.cpp
@@ -58,11 +58,7 @@ ValgrindToolRunner::ValgrindToolRunner(RunControl *runControl)
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
setSupportsReRunning(false);
- m_settings =
- qobject_cast<ValgrindBaseSettings *>(runControl->settings(ANALYZER_VALGRIND_SETTINGS));
-
- if (!m_settings)
- m_settings = ValgrindGlobalSettings::instance();
+ m_settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS));
}
void ValgrindToolRunner::start()
@@ -81,8 +77,11 @@ void ValgrindToolRunner::start()
emit outputReceived(tr("Command line arguments: %1").arg(runnable().debuggeeArgs), DebugFormat);
#endif
- m_runner.setValgrindExecutable(m_settings->valgrindExecutable());
- m_runner.setValgrindArguments(genericToolArguments() + toolArguments());
+ CommandLine valgrind{m_settings.valgrindExecutable()};
+ valgrind.addArgs(genericToolArguments());
+ valgrind.addArgs(toolArguments());
+
+ m_runner.setValgrindCommand(valgrind);
m_runner.setDevice(device());
m_runner.setDebuggee(runnable());
@@ -115,16 +114,16 @@ void ValgrindToolRunner::stop()
m_runner.stop();
}
-QString ValgrindToolRunner::executable() const
+FilePath ValgrindToolRunner::executable() const
{
return runnable().executable;
}
QStringList ValgrindToolRunner::genericToolArguments() const
{
- QTC_ASSERT(m_settings, return QStringList());
QString smcCheckValue;
- switch (m_settings->selfModifyingCodeDetection()) {
+
+ switch (m_settings.selfModifyingCodeDetection()) {
case ValgrindBaseSettings::DetectSmcNo:
smcCheckValue = "none";
break;
@@ -175,7 +174,7 @@ void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputForma
void ValgrindToolRunner::receiveProcessError(const QString &message, QProcess::ProcessError error)
{
if (error == QProcess::FailedToStart) {
- const QString valgrind = m_settings->valgrindExecutable();
+ const QString valgrind = m_settings.valgrindExecutable();
if (!valgrind.isEmpty())
appendMessage(tr("Error: \"%1\" could not be started: %2").arg(valgrind, message), ErrorMessageFormat);
else
diff --git a/src/plugins/valgrind/valgrindengine.h b/src/plugins/valgrind/valgrindengine.h
index 06c51583e7..30ffbdb22f 100644
--- a/src/plugins/valgrind/valgrindengine.h
+++ b/src/plugins/valgrind/valgrindengine.h
@@ -26,10 +26,11 @@
#pragma once
+#include "valgrindsettings.h"
+
#include <projectexplorer/runcontrol.h>
#include <utils/environment.h>
#include <valgrind/valgrindrunner.h>
-#include <valgrind/valgrindsettings.h>
#include <QFutureInterface>
#include <QFutureWatcher>
@@ -47,13 +48,13 @@ public:
void start() override;
void stop() override;
- QString executable() const;
+ Utils::FilePath executable() const;
protected:
virtual QString progressTitle() const = 0;
virtual QStringList toolArguments() const = 0;
- ValgrindBaseSettings *m_settings = nullptr;
+ ValgrindProjectSettings m_settings;
QFutureInterface<void> m_progress;
ValgrindRunner m_runner;
diff --git a/src/plugins/valgrind/valgrindmemcheckparsertest.cpp b/src/plugins/valgrind/valgrindmemcheckparsertest.cpp
index 3bb2ba4ebf..f381650b8e 100644
--- a/src/plugins/valgrind/valgrindmemcheckparsertest.cpp
+++ b/src/plugins/valgrind/valgrindmemcheckparsertest.cpp
@@ -44,6 +44,7 @@
#include <QTcpSocket>
#include <QSignalSpy>
+using namespace Utils;
using namespace Valgrind::XmlProtocol;
QT_BEGIN_NAMESPACE
@@ -476,9 +477,9 @@ void ValgrindMemcheckParserTest::testValgrindGarbage()
void ValgrindMemcheckParserTest::testParserStop()
{
ValgrindRunner runner;
- runner.setValgrindExecutable(fakeValgrindExecutable());
- runner.setValgrindArguments({QString("--xml-socket=127.0.0.1:%1").arg(m_server->serverPort()),
- "-i", dataFile("memcheck-output-sample1.xml"), "--wait", "5" });
+ runner.setValgrindCommand({fakeValgrindExecutable(),
+ {QString("--xml-socket=127.0.0.1:%1").arg(m_server->serverPort()),
+ "-i", dataFile("memcheck-output-sample1.xml"), "--wait", "5" }});
runner.setProcessChannelMode(QProcess::ForwardedChannels);
runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
@@ -498,10 +499,10 @@ void ValgrindMemcheckParserTest::testRealValgrind()
qDebug() << "running exe:" << executable << " HINT: set VALGRIND_TEST_BIN to change this";
ProjectExplorer::Runnable debuggee;
- debuggee.executable = executable;
+ debuggee.executable = FilePath::fromString(executable);
debuggee.environment = sysEnv;
ValgrindRunner runner;
- runner.setValgrindExecutable("valgrind");
+ runner.setValgrindCommand({"valgrind", {}});
runner.setDebuggee(debuggee);
runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE));
@@ -535,13 +536,12 @@ void ValgrindMemcheckParserTest::testValgrindStartError()
QFETCH(QString, debuggeeArgs);
ProjectExplorer::Runnable debuggeeExecutable;
- debuggeeExecutable.executable = debuggee;
+ debuggeeExecutable.executable = FilePath::fromString(debuggee);
debuggeeExecutable.environment = Utils::Environment::systemEnvironment();
debuggeeExecutable.commandLineArguments = debuggeeArgs;
ValgrindRunner runner;
- runner.setValgrindExecutable(valgrindExe);
- runner.setValgrindArguments(valgrindArgs);
+ runner.setValgrindCommand({valgrindExe, valgrindArgs});
runner.setDebuggee(debuggeeExecutable);
runner.setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE));
diff --git a/src/plugins/valgrind/valgrindmemcheckparsertest.h b/src/plugins/valgrind/valgrindmemcheckparsertest.h
index 71da4cc302..6dff0aef57 100644
--- a/src/plugins/valgrind/valgrindmemcheckparsertest.h
+++ b/src/plugins/valgrind/valgrindmemcheckparsertest.h
@@ -123,7 +123,7 @@ public:
}
void processErrorReceived(const QString &s)
{
- Q_UNUSED(s);
+ Q_UNUSED(s)
// qDebug() << "error received:" << s; // this can be a lot of text
m_errorReceived = true;
}
diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp
index 827e2c2b4e..2bf5fefde4 100644
--- a/src/plugins/valgrind/valgrindrunner.cpp
+++ b/src/plugins/valgrind/valgrindrunner.cpp
@@ -63,8 +63,7 @@ public:
ApplicationLauncher m_findPID;
- QString m_valgrindExecutable;
- QStringList m_valgrindArguments;
+ CommandLine m_valgrindCommand;
QHostAddress localServerAddress;
QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels;
@@ -82,17 +81,17 @@ public:
bool ValgrindRunner::Private::run()
{
- QStringList arguments;
+ CommandLine cmd{m_valgrindCommand.executable(), {}};
if (!localServerAddress.isNull()) {
if (!q->startServers())
return false;
- arguments.append("--child-silent-after-fork=yes");
+ cmd.addArg("--child-silent-after-fork=yes");
bool enableXml = !disableXml;
- auto handleSocketParameter = [&enableXml, &arguments](const QString &prefix, const QTcpServer &tcpServer)
+ auto handleSocketParameter = [&enableXml, &cmd](const QString &prefix, const QTcpServer &tcpServer)
{
QHostAddress serverAddress = tcpServer.serverAddress();
if (serverAddress.protocol() != QAbstractSocket::IPv4Protocol) {
@@ -101,8 +100,8 @@ bool ValgrindRunner::Private::run()
qWarning("Need IPv4 for valgrind");
enableXml = false;
} else {
- arguments << QString("%1=%2:%3").arg(prefix).arg(serverAddress.toString())
- .arg(tcpServer.serverPort());
+ cmd.addArg(QString("%1=%2:%3").arg(prefix).arg(serverAddress.toString())
+ .arg(tcpServer.serverPort()));
}
};
@@ -110,9 +109,9 @@ bool ValgrindRunner::Private::run()
handleSocketParameter("--log-socket", logServer);
if (enableXml)
- arguments << "--xml=yes";
+ cmd.addArg("--xml=yes");
}
- arguments += m_valgrindArguments;
+ cmd.addArgs(m_valgrindCommand.arguments(), CommandLine::Raw);
m_valgrindProcess.setProcessChannelMode(channelMode);
// consider appending our options last so they override any interfering user-supplied options
@@ -138,18 +137,17 @@ bool ValgrindRunner::Private::run()
if (HostOsInfo::isMacHost())
// May be slower to start but without it we get no filenames for symbols.
- arguments << "--dsymutil=yes";
- arguments << m_debuggee.executable;
+ cmd.addArg("--dsymutil=yes");
+ cmd.addArg(m_debuggee.executable.toString());
+ cmd.addArgs(m_debuggee.commandLineArguments, CommandLine::Raw);
+
+ emit q->valgrindExecuted(cmd.toUserOutput());
Runnable valgrind;
- valgrind.executable = m_valgrindExecutable;
+ valgrind.setCommandLine(cmd);
valgrind.workingDirectory = m_debuggee.workingDirectory;
valgrind.environment = m_debuggee.environment;
valgrind.device = m_device;
- valgrind.commandLineArguments = QtcProcess::joinArgs(arguments, m_device->osType());
- Utils::QtcProcess::addArgs(&valgrind.commandLineArguments, m_debuggee.commandLineArguments);
- emit q->valgrindExecuted(QtcProcess::quoteArg(valgrind.executable) + ' '
- + valgrind.commandLineArguments);
if (m_device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
m_valgrindProcess.start(valgrind);
@@ -188,10 +186,11 @@ void ValgrindRunner::Private::remoteProcessStarted()
// hence we need to do something more complex...
// plain path to exe, m_valgrindExe contains e.g. env vars etc. pp.
- const QString proc = m_valgrindExecutable.split(' ').last();
+ // FIXME: Really?
+ const QString proc = m_valgrindCommand.executable().toString().split(' ').last();
Runnable findPid;
- findPid.executable = "/bin/sh";
+ findPid.executable = FilePath::fromString("/bin/sh");
// sleep required since otherwise we might only match "bash -c..."
// and not the actual valgrind run
findPid.commandLineArguments = QString("-c \""
@@ -201,7 +200,7 @@ void ValgrindRunner::Private::remoteProcessStarted()
// we pick the last one, first would be "bash -c ..."
" | awk '{print $1;}'" // get pid
"\""
- ).arg(proc, Utils::FilePath::fromString(m_debuggee.executable).fileName());
+ ).arg(proc, m_debuggee.executable.fileName());
// m_remote.m_findPID = m_remote.m_connection->createRemoteProcess(cmd.toUtf8());
connect(&m_findPID, &ApplicationLauncher::remoteStderr,
@@ -228,7 +227,7 @@ void ValgrindRunner::Private::findPidOutputReceived(const QString &out)
void ValgrindRunner::Private::closed(bool success)
{
- Q_UNUSED(success);
+ Q_UNUSED(success)
// QTC_ASSERT(m_remote.m_process, return);
// m_remote.m_errorString = m_remote.m_process->errorString();
@@ -264,14 +263,9 @@ ValgrindRunner::~ValgrindRunner()
d = nullptr;
}
-void ValgrindRunner::setValgrindExecutable(const QString &executable)
-{
- d->m_valgrindExecutable = executable;
-}
-
-void ValgrindRunner::setValgrindArguments(const QStringList &toolArguments)
+void ValgrindRunner::setValgrindCommand(const Utils::CommandLine &command)
{
- d->m_valgrindArguments = toolArguments;
+ d->m_valgrindCommand = command;
}
void ValgrindRunner::setDebuggee(const Runnable &debuggee)
diff --git a/src/plugins/valgrind/valgrindrunner.h b/src/plugins/valgrind/valgrindrunner.h
index 8278c94291..647cac8bae 100644
--- a/src/plugins/valgrind/valgrindrunner.h
+++ b/src/plugins/valgrind/valgrindrunner.h
@@ -44,8 +44,7 @@ public:
explicit ValgrindRunner(QObject *parent = nullptr);
~ValgrindRunner() override;
- void setValgrindExecutable(const QString &executable);
- void setValgrindArguments(const QStringList &toolArguments);
+ void setValgrindCommand(const Utils::CommandLine &command);
void setDebuggee(const ProjectExplorer::Runnable &debuggee);
void setProcessChannelMode(QProcess::ProcessChannelMode mode);
void setLocalServerAddress(const QHostAddress &localServerAddress);
diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp
index 0d63b23ea8..d4585d73b1 100644
--- a/src/plugins/valgrind/valgrindsettings.cpp
+++ b/src/plugins/valgrind/valgrindsettings.cpp
@@ -82,9 +82,7 @@ template <typename T> void setIfPresent(const QVariantMap &map, const QString &k
*val = map.value(key).template value<T>();
}
-ValgrindBaseSettings::ValgrindBaseSettings(const ConfigWidgetCreator &creator)
- : ISettingsAspect(creator)
-{}
+ValgrindBaseSettings::ValgrindBaseSettings() = default;
void ValgrindBaseSettings::fromMap(const QVariantMap &map)
{
@@ -304,9 +302,10 @@ void ValgrindBaseSettings::setVisualisationMinimumInclusiveCostRatio(
static ValgrindGlobalSettings *theGlobalSettings = nullptr;
ValgrindGlobalSettings::ValgrindGlobalSettings()
- : ValgrindBaseSettings([this] { return new ValgrindConfigWidget(this, true); })
{
theGlobalSettings = this;
+
+ setConfigWidgetCreator([this] { return new ValgrindConfigWidget(this, true); });
readSettings();
}
@@ -494,8 +493,9 @@ void ValgrindGlobalSettings::setShortenTemplates(bool on)
//////////////////////////////////////////////////////////////////
ValgrindProjectSettings::ValgrindProjectSettings()
- : ValgrindBaseSettings([this] { return new ValgrindConfigWidget(this, false); })
-{}
+{
+ setConfigWidgetCreator([this] { return new ValgrindConfigWidget(this, false); });
+}
void ValgrindProjectSettings::fromMap(const QVariantMap &map)
{
diff --git a/src/plugins/valgrind/valgrindsettings.h b/src/plugins/valgrind/valgrindsettings.h
index eaeda4190f..eb7311cb12 100644
--- a/src/plugins/valgrind/valgrindsettings.h
+++ b/src/plugins/valgrind/valgrindsettings.h
@@ -59,7 +59,7 @@ public:
LeakCheckOnFinishYes
};
- ValgrindBaseSettings(const ConfigWidgetCreator &creator);
+ ValgrindBaseSettings();
void toMap(QVariantMap &map) const override;
void fromMap(const QVariantMap &map) override;
diff --git a/src/plugins/valgrind/valgrindtestrunnertest.cpp b/src/plugins/valgrind/valgrindtestrunnertest.cpp
index 4a3414060e..d5a9cdf479 100644
--- a/src/plugins/valgrind/valgrindtestrunnertest.cpp
+++ b/src/plugins/valgrind/valgrindtestrunnertest.cpp
@@ -46,7 +46,9 @@
#define HEADER_LENGTH 25
+using namespace ProjectExplorer;
using namespace Valgrind::XmlProtocol;
+using namespace Utils;
namespace Valgrind {
namespace Test {
@@ -77,15 +79,20 @@ QString ValgrindTestRunnerTest::runTestBinary(const QString &binary, const QStri
const QFileInfo binPathFileInfo(appBinDir, binary);
if (!binPathFileInfo.isExecutable())
return QString();
- ProjectExplorer::Runnable debuggee;
+
+ Runnable debuggee;
const QString &binPath = binPathFileInfo.canonicalFilePath();
- debuggee.executable = binPath;
+ debuggee.executable = Utils::FilePath::fromString(binPath);
debuggee.environment = Utils::Environment::systemEnvironment();
+
+ CommandLine valgrind{"valgrind", {"--num-callers=50", "--track-origins=yes"}};
+ valgrind.addArgs(vArgs);
+
m_runner->setLocalServerAddress(QHostAddress::LocalHost);
- m_runner->setValgrindArguments(QStringList() << "--num-callers=50" << "--track-origins=yes" << vArgs);
+ m_runner->setValgrindCommand(valgrind);
m_runner->setDebuggee(debuggee);
- m_runner->setDevice(ProjectExplorer::DeviceManager::instance()->defaultDevice(
- Core::Id(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)));
+ m_runner->setDevice(DeviceManager::instance()->defaultDevice(
+ ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE));
m_runner->start();
m_runner->waitForFinished();
return binPath;
@@ -131,7 +138,6 @@ void ValgrindTestRunnerTest::init()
Q_ASSERT(!m_runner);
m_runner = new ValgrindRunner;
- m_runner->setValgrindExecutable("valgrind");
m_runner->setProcessChannelMode(QProcess::ForwardedChannels);
connect(m_runner, &ValgrindRunner::logMessageReceived,
this, &ValgrindTestRunnerTest::logMessageReceived);
diff --git a/src/plugins/vcsbase/CMakeLists.txt b/src/plugins/vcsbase/CMakeLists.txt
index b6d234b4f2..1cffe26be0 100644
--- a/src/plugins/vcsbase/CMakeLists.txt
+++ b/src/plugins/vcsbase/CMakeLists.txt
@@ -1,6 +1,6 @@
add_qtc_plugin(VcsBase
- PLUGIN_DEPENDS Core CppTools DiffEditor ProjectExplorer TextEditor
- PLUGIN_RECOMMENDS CodePaster
+ PLUGIN_DEPENDS Core DiffEditor ProjectExplorer TextEditor
+ PLUGIN_RECOMMENDS CodePaster CppTools
SOURCES
baseannotationhighlighter.cpp baseannotationhighlighter.h
basevcseditorfactory.cpp basevcseditorfactory.h
diff --git a/src/plugins/vcsbase/submitfieldwidget.cpp b/src/plugins/vcsbase/submitfieldwidget.cpp
index b92579be43..df3513e59f 100644
--- a/src/plugins/vcsbase/submitfieldwidget.cpp
+++ b/src/plugins/vcsbase/submitfieldwidget.cpp
@@ -80,7 +80,7 @@ struct FieldEntry {
void FieldEntry::createGui(const QIcon &removeIcon)
{
layout = new QHBoxLayout;
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout ->setSpacing(spacing);
combo = new QComboBox;
layout->addWidget(combo);
@@ -174,7 +174,7 @@ SubmitFieldWidget::SubmitFieldWidget(QWidget *parent) :
d(new SubmitFieldWidgetPrivate)
{
d->layout = new QVBoxLayout;
- d->layout->setMargin(0);
+ d->layout->setContentsMargins(0, 0, 0, 0);
d->layout->setSpacing(spacing);
setLayout(d->layout);
}
diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs
index 036c99adce..df5686db5c 100644
--- a/src/plugins/vcsbase/vcsbase.qbs
+++ b/src/plugins/vcsbase/vcsbase.qbs
@@ -11,11 +11,11 @@ QtcPlugin {
Depends { name: "Core" }
Depends { name: "TextEditor" }
Depends { name: "ProjectExplorer" }
- Depends { name: "CppTools" }
Depends { name: "DiffEditor" }
pluginRecommends: [
- "CodePaster"
+ "CodePaster",
+ "CppTools"
]
files: [
diff --git a/src/plugins/vcsbase/vcsbase_dependencies.pri b/src/plugins/vcsbase/vcsbase_dependencies.pri
index f398e2926b..2606ce19c8 100644
--- a/src/plugins/vcsbase/vcsbase_dependencies.pri
+++ b/src/plugins/vcsbase/vcsbase_dependencies.pri
@@ -8,7 +8,7 @@ QTC_PLUGIN_DEPENDS += \
coreplugin \
texteditor \
projectexplorer \
- cpptools \
diffeditor
QTC_PLUGIN_RECOMMENDS += \
- cpaster
+ cpaster \
+ cpptools
diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp
index 4e772f3b2c..c359060d7c 100644
--- a/src/plugins/vcsbase/vcsbaseclient.cpp
+++ b/src/plugins/vcsbase/vcsbaseclient.cpp
@@ -138,7 +138,7 @@ void VcsBaseClientImpl::enqueueJob(VcsCommand *cmd, const QStringList &args,
const QString &workingDirectory,
const ExitCodeInterpreter &interpreter) const
{
- cmd->addJob(vcsBinary(), args, vcsTimeoutS(), workingDirectory, interpreter);
+ cmd->addJob({vcsBinary(), args}, vcsTimeoutS(), workingDirectory, interpreter);
cmd->execute();
}
@@ -178,15 +178,14 @@ QString VcsBaseClientImpl::stripLastNewline(const QString &in)
}
SynchronousProcessResponse
-VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const FilePath &binary,
- const QStringList &args, unsigned flags,
- int timeoutS, QTextCodec *codec) const
+VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const CommandLine &cmdLine,
+ unsigned flags, int timeoutS, QTextCodec *codec) const
{
VcsCommand command(workingDir, processEnvironment());
command.addFlags(flags);
if (codec)
command.setCodec(codec);
- return command.runCommand(binary, args, (timeoutS > 0) ? timeoutS : vcsTimeoutS());
+ return command.runCommand(cmdLine, (timeoutS > 0) ? timeoutS : vcsTimeoutS());
}
void VcsBaseClientImpl::resetCachedVcsInfo(const QString &workingDir)
@@ -211,7 +210,7 @@ SynchronousProcessResponse
VcsBaseClientImpl::vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
unsigned flags, int timeoutS, QTextCodec *codec) const
{
- return vcsFullySynchronousExec(workingDir, vcsBinary(), args, flags, timeoutS, codec);
+ return vcsFullySynchronousExec(workingDir, {vcsBinary(), args}, flags, timeoutS, codec);
}
VcsCommand *VcsBaseClientImpl::vcsExec(const QString &workingDirectory, const QStringList &arguments,
@@ -233,7 +232,7 @@ SynchronousProcessResponse VcsBaseClientImpl::vcsSynchronousExec(const QString &
unsigned flags,
QTextCodec *outputCodec) const
{
- return VcsBasePlugin::runVcs(workingDir, vcsBinary(), args, vcsTimeoutS(), flags,
+ return VcsBasePlugin::runVcs(workingDir, {vcsBinary(), args}, vcsTimeoutS(), flags,
outputCodec, processEnvironment());
}
diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h
index 0706d53861..96e9ca5e40 100644
--- a/src/plugins/vcsbase/vcsbaseclient.h
+++ b/src/plugins/vcsbase/vcsbaseclient.h
@@ -105,7 +105,7 @@ public:
vcsFullySynchronousExec(const QString &workingDir, const QStringList &args,
unsigned flags = 0, int timeoutS = -1, QTextCodec *codec = nullptr) const;
Utils::SynchronousProcessResponse
- vcsFullySynchronousExec(const QString &workingDir, const Utils::FilePath &binary, const QStringList &args,
+ vcsFullySynchronousExec(const QString &workingDir, const Utils::CommandLine &cmdLine,
unsigned flags = 0, int timeoutS = -1, QTextCodec *codec = nullptr) const;
diff --git a/src/plugins/vcsbase/vcsbaseclientsettings.cpp b/src/plugins/vcsbase/vcsbaseclientsettings.cpp
index 96571e5782..60bd754825 100644
--- a/src/plugins/vcsbase/vcsbaseclientsettings.cpp
+++ b/src/plugins/vcsbase/vcsbaseclientsettings.cpp
@@ -354,8 +354,7 @@ QVariant::Type VcsBaseClientSettings::valueType(const QString &key) const
FilePath VcsBaseClientSettings::binaryPath() const
{
if (d->m_binaryFullPath.isEmpty()) {
- const FilePathList searchPaths
- = Utils::transform(searchPathList(), [](const QString &s) { return FilePath::fromString(s); });
+ const FilePathList searchPaths = Utils::transform(searchPathList(), &FilePath::fromString);
d->m_binaryFullPath = Environment::systemEnvironment().searchInPath(
stringValue(binaryPathKey), searchPaths);
}
@@ -394,7 +393,7 @@ QVariant VcsBaseClientSettings::keyDefaultValue(const QString &key) const
void VcsBaseClientSettings::readLegacySettings(const QSettings *settings)
{
- Q_UNUSED(settings);
+ Q_UNUSED(settings)
}
} // namespace VcsBase
diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
index e72d68ef72..30946aee13 100644
--- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
+++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
@@ -261,7 +261,7 @@ void VcsBaseDiffEditorController::runCommand(const QList<QStringList> &args, uns
for (const QStringList &arg : args) {
QTC_ASSERT(!arg.isEmpty(), continue);
- d->m_command->addJob(d->m_client->vcsBinary(), arg, d->m_client->vcsTimeoutS());
+ d->m_command->addJob({d->m_client->vcsBinary(), arg}, d->m_client->vcsTimeoutS());
}
d->m_command->execute();
diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp
index 885b0c7cd1..aaf677063b 100644
--- a/src/plugins/vcsbase/vcsbaseeditor.cpp
+++ b/src/plugins/vcsbase/vcsbaseeditor.cpp
@@ -460,7 +460,7 @@ void UrlTextCursorHandler::handleCurrentContents()
void UrlTextCursorHandler::fillContextMenu(QMenu *menu, EditorContentType type) const
{
- Q_UNUSED(type);
+ Q_UNUSED(type)
menu->addSeparator();
menu->addAction(createOpenUrlAction(tr("Open URL in Browser...")));
menu->addAction(createCopyUrlAction(tr("Copy URL Location")));
@@ -527,7 +527,7 @@ EmailTextCursorHandler::EmailTextCursorHandler(VcsBaseEditorWidget *editorWidget
void EmailTextCursorHandler::fillContextMenu(QMenu *menu, EditorContentType type) const
{
- Q_UNUSED(type);
+ Q_UNUSED(type)
menu->addSeparator();
menu->addAction(createOpenUrlAction(tr("Send Email To...")));
menu->addAction(createCopyUrlAction(tr("Copy Email Address")));
@@ -673,7 +673,7 @@ bool VcsBaseEditorWidget::supportChangeLinks() const
QString VcsBaseEditorWidget::fileNameForLine(int line) const
{
- Q_UNUSED(line);
+ Q_UNUSED(line)
return source();
}
@@ -1212,7 +1212,7 @@ DiffChunk VcsBaseEditorWidget::diffChunk(QTextCursor cursor) const
void VcsBaseEditorWidget::reportCommandFinished(bool ok, int exitCode, const QVariant &data)
{
- Q_UNUSED(exitCode);
+ Q_UNUSED(exitCode)
hideProgressIndicator();
if (!ok) {
@@ -1246,19 +1246,13 @@ static QTextCodec *findFileCodec(const QString &source)
// Find the codec by checking the projects (root dir of project file)
static QTextCodec *findProjectCodec(const QString &dir)
{
+ const FilePath dirPath = FilePath::fromString(dir);
typedef QList<ProjectExplorer::Project*> ProjectList;
// Try to find a project under which file tree the file is.
const ProjectList projects = ProjectExplorer::SessionManager::projects();
- if (!projects.empty()) {
- const ProjectList::const_iterator pcend = projects.constEnd();
- for (ProjectList::const_iterator it = projects.constBegin(); it != pcend; ++it)
- if (const Core::IDocument *document = (*it)->document())
- if (document->filePath().toString().startsWith(dir)) {
- QTextCodec *codec = (*it)->editorConfiguration()->textCodec();
- return codec;
- }
- }
- return nullptr;
+ const ProjectExplorer::Project *p
+ = findOrDefault(projects, equal(&ProjectExplorer::Project::projectDirectory, dirPath));
+ return p ? p->editorConfiguration()->textCodec() : nullptr;
}
QTextCodec *VcsBaseEditor::getCodec(const QString &source)
@@ -1549,13 +1543,13 @@ QString VcsBaseEditorWidget::decorateVersion(const QString &revision) const
bool VcsBaseEditorWidget::isValidRevision(const QString &revision) const
{
- Q_UNUSED(revision);
+ Q_UNUSED(revision)
return true;
}
QString VcsBaseEditorWidget::revisionSubject(const QTextBlock &inBlock) const
{
- Q_UNUSED(inBlock);
+ Q_UNUSED(inBlock)
return QString();
}
diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp
index 298fdf61b3..9ae4e93486 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.cpp
+++ b/src/plugins/vcsbase/vcsbaseplugin.cpp
@@ -791,8 +791,7 @@ void VcsBasePlugin::setProcessEnvironment(QProcessEnvironment *e,
// Run a process synchronously, returning Utils::SynchronousProcessResponse
// response struct and using the VcsBasePlugin flags as applicable
SynchronousProcessResponse VcsBasePlugin::runVcs(const QString &workingDir,
- const FilePath &binary,
- const QStringList &arguments,
+ const CommandLine &cmd,
int timeOutS,
unsigned flags,
QTextCodec *outputCodec,
@@ -801,7 +800,7 @@ SynchronousProcessResponse VcsBasePlugin::runVcs(const QString &workingDir,
VcsCommand command(workingDir, env.isEmpty() ? QProcessEnvironment::systemEnvironment() : env);
command.addFlags(flags);
command.setCodec(outputCodec);
- return command.runCommand(binary, arguments, timeOutS);
+ return command.runCommand(cmd, timeOutS);
}
} // namespace VcsBase
diff --git a/src/plugins/vcsbase/vcsbaseplugin.h b/src/plugins/vcsbase/vcsbaseplugin.h
index e1bfa15ded..779092e185 100644
--- a/src/plugins/vcsbase/vcsbaseplugin.h
+++ b/src/plugins/vcsbase/vcsbaseplugin.h
@@ -41,7 +41,7 @@ class QTextCodec;
QT_END_NAMESPACE
namespace Utils {
-class FilePath;
+class CommandLine;
class SynchronousProcessResponse;
} // namespace Utils
@@ -170,8 +170,7 @@ public:
static QString source(Core::IDocument *document);
static Utils::SynchronousProcessResponse runVcs(const QString &workingDir,
- const Utils::FilePath &binary,
- const QStringList &arguments,
+ const Utils::CommandLine &cmd,
int timeOutS,
unsigned flags = 0,
QTextCodec *outputCodec = nullptr,
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
index 3d07ced719..4c36057945 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
@@ -36,12 +36,14 @@
#include "vcsplugin.h"
#include <aggregation/aggregate.h>
-#include <cpptools/cppmodelmanager.h>
#include <coreplugin/find/basetextfind.h>
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
+#include <extensionsystem/invoker.h>
+#include <extensionsystem/pluginmanager.h>
+
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
#include <utils/completingtextedit.h>
@@ -78,30 +80,9 @@ enum { debug = 0 };
enum { wantToolBar = 0 };
// Return true if word is meaningful and can be added to a completion model
-static bool acceptsWordForCompletion(const char *word)
-{
- if (!word)
- return false;
- static const std::size_t minWordLength = 7;
- return std::strlen(word) >= minWordLength;
-}
-
-// Return the class name which function belongs to
-static const char *belongingClassName(const CPlusPlus::Function *function)
+static bool acceptsWordForCompletion(const QString &word)
{
- if (!function)
- return nullptr;
-
- if (auto funcName = function->name()) {
- if (auto qualifiedNameId = funcName->asQualifiedNameId()) {
- if (const CPlusPlus::Name *funcBaseName = qualifiedNameId->base()) {
- if (auto identifier = funcBaseName->identifier())
- return identifier->chars();
- }
- }
- }
-
- return nullptr;
+ return word.size() >= 7;
}
/*!
@@ -200,7 +181,7 @@ VcsBaseSubmitEditor::VcsBaseSubmitEditor(const VcsBaseSubmitEditorParameters *pa
QPalette pal;
pal.setColor(QPalette::Base, tf.background().color());
pal.setColor(QPalette::Text, tf.foreground().color());
- pal.setColor(QPalette::Foreground, tf.foreground().color());
+ pal.setColor(QPalette::WindowText, tf.foreground().color());
if (selectionFormat.background().style() != Qt::NoBrush)
pal.setColor(QPalette::Highlight, selectionFormat.background().color());
pal.setBrush(QPalette::HighlightedText, selectionFormat.foreground());
@@ -407,6 +388,17 @@ QStringList VcsBaseSubmitEditor::checkedFiles() const
return d->m_widget->checkedFiles();
}
+static QSet<FilePath> filesFromModel(SubmitFileModel *model)
+{
+ QSet<FilePath> result;
+ result.reserve(model->rowCount());
+ for (int row = 0; row < model->rowCount(); ++row) {
+ result.insert(FilePath::fromString(
+ QFileInfo(model->repositoryRoot(), model->file(row)).absoluteFilePath()));
+ }
+ return result;
+}
+
void VcsBaseSubmitEditor::setFileModel(SubmitFileModel *model)
{
QTC_ASSERT(model, return);
@@ -421,49 +413,21 @@ void VcsBaseSubmitEditor::setFileModel(SubmitFileModel *model)
if (!selected.isEmpty())
d->m_widget->setSelectedRows(selected);
- QSet<QString> uniqueSymbols;
- const CPlusPlus::Snapshot cppSnapShot = CppTools::CppModelManager::instance()->snapshot();
-
- // Iterate over the files and get interesting symbols
- for (int row = 0; row < model->rowCount(); ++row) {
- const QFileInfo fileInfo(model->repositoryRoot(), model->file(row));
-
- // Add file name
- uniqueSymbols.insert(fileInfo.fileName());
-
- const QString filePath = fileInfo.absoluteFilePath();
- // Add symbols from the C++ code model
- const CPlusPlus::Document::Ptr doc = cppSnapShot.document(filePath);
- if (!doc.isNull() && doc->control()) {
- const CPlusPlus::Control *ctrl = doc->control();
- CPlusPlus::Symbol **symPtr = ctrl->firstSymbol(); // Read-only
- while (symPtr != ctrl->lastSymbol()) {
- const CPlusPlus::Symbol *sym = *symPtr;
-
- const CPlusPlus::Identifier *symId = sym->identifier();
- // Add any class, function or namespace identifiers
- if ((sym->isClass() || sym->isFunction() || sym->isNamespace())
- && (symId && acceptsWordForCompletion(symId->chars())))
- {
- uniqueSymbols.insert(QString::fromUtf8(symId->chars()));
- }
-
- // Handle specific case : get "Foo" in "void Foo::function() {}"
- if (sym->isFunction() && !sym->asFunction()->isDeclaration()) {
- const char *className = belongingClassName(sym->asFunction());
- if (acceptsWordForCompletion(className))
- uniqueSymbols.insert(QString::fromUtf8(className));
- }
-
- ++symPtr;
- }
- }
+ const QSet<FilePath> files = filesFromModel(model);
+ // add file names to completion
+ QSet<QString> completionItems = Utils::transform(files, &FilePath::fileName);
+ QObject *cppModelManager = ExtensionSystem::PluginManager::getObjectByName("CppModelManager");
+ if (cppModelManager) {
+ const auto symbols = ExtensionSystem::invoke<QSet<QString>>(cppModelManager,
+ "symbolsInFiles",
+ files);
+ completionItems += Utils::filtered(symbols, acceptsWordForCompletion);
}
// Populate completer with symbols
- if (!uniqueSymbols.isEmpty()) {
+ if (!completionItems.isEmpty()) {
QCompleter *completer = d->m_widget->descriptionEdit()->completer();
- QStringList symbolsList = Utils::toList(uniqueSymbols);
+ QStringList symbolsList = Utils::toList(completionItems);
symbolsList.sort();
completer->setModel(new QStringListModel(symbolsList, completer));
}
diff --git a/src/plugins/vcsbase/vcscommand.cpp b/src/plugins/vcsbase/vcscommand.cpp
index a659b13fec..1a5c3c27f5 100644
--- a/src/plugins/vcsbase/vcscommand.cpp
+++ b/src/plugins/vcsbase/vcscommand.cpp
@@ -77,14 +77,12 @@ const QProcessEnvironment VcsCommand::processEnvironment() const
return env;
}
-SynchronousProcessResponse VcsCommand::runCommand(const FilePath &binary,
- const QStringList &arguments, int timeoutS,
- const QString &workingDirectory,
- const ExitCodeInterpreter &interpreter)
+SynchronousProcessResponse VcsCommand::runCommand(const CommandLine &command, int timeoutS,
+ const QString &workingDirectory,
+ const ExitCodeInterpreter &interpreter)
{
SynchronousProcessResponse response
- = Core::ShellCommand::runCommand(binary, arguments, timeoutS, workingDirectory,
- interpreter);
+ = Core::ShellCommand::runCommand(command, timeoutS, workingDirectory, interpreter);
emitRepositoryChanged(workingDirectory);
return response;
}
diff --git a/src/plugins/vcsbase/vcscommand.h b/src/plugins/vcsbase/vcscommand.h
index 191b72b980..e092b25177 100644
--- a/src/plugins/vcsbase/vcscommand.h
+++ b/src/plugins/vcsbase/vcscommand.h
@@ -45,8 +45,8 @@ public:
const QProcessEnvironment processEnvironment() const override;
- Utils::SynchronousProcessResponse runCommand(const Utils::FilePath &binary,
- const QStringList &arguments, int timeoutS,
+ Utils::SynchronousProcessResponse runCommand(const Utils::CommandLine &command,
+ int timeoutS,
const QString &workDirectory = QString(),
const Utils::ExitCodeInterpreter &interpreter = Utils::defaultExitCodeInterpreter) override;
diff --git a/src/plugins/vcsbase/vcsoutputwindow.cpp b/src/plugins/vcsbase/vcsoutputwindow.cpp
index f27715ed0c..da3cb8fa29 100644
--- a/src/plugins/vcsbase/vcsoutputwindow.cpp
+++ b/src/plugins/vcsbase/vcsoutputwindow.cpp
@@ -451,12 +451,10 @@ static inline QString formatArguments(const QStringList &args)
return rc;
}
-QString VcsOutputWindow::msgExecutionLogEntry(const QString &workingDir,
- const FilePath &executable,
- const QStringList &arguments)
+QString VcsOutputWindow::msgExecutionLogEntry(const QString &workingDir, const CommandLine &command)
{
- const QString args = formatArguments(arguments);
- const QString nativeExecutable = QtcProcess::quoteArg(executable.toUserOutput());
+ const QString args = formatArguments(command.splitArguments());
+ const QString nativeExecutable = QtcProcess::quoteArg(command.executable().toUserOutput());
if (workingDir.isEmpty())
return tr("Running: %1 %2").arg(nativeExecutable, args) + '\n';
return tr("Running in %1: %2 %3").
@@ -468,11 +466,9 @@ void VcsOutputWindow::appendShellCommandLine(const QString &text)
append(filterPasswordFromUrls(text), Command, true);
}
-void VcsOutputWindow::appendCommand(const QString &workingDirectory,
- const FilePath &binary,
- const QStringList &args)
+void VcsOutputWindow::appendCommand(const QString &workingDirectory, const CommandLine &command)
{
- appendShellCommandLine(msgExecutionLogEntry(workingDirectory, binary, args));
+ appendShellCommandLine(msgExecutionLogEntry(workingDirectory, command));
}
void VcsOutputWindow::appendMessage(const QString &text)
diff --git a/src/plugins/vcsbase/vcsoutputwindow.h b/src/plugins/vcsbase/vcsoutputwindow.h
index d54b4e6306..749e824c38 100644
--- a/src/plugins/vcsbase/vcsoutputwindow.h
+++ b/src/plugins/vcsbase/vcsoutputwindow.h
@@ -29,7 +29,7 @@
#include <coreplugin/ioutputpane.h>
-namespace Utils { class FilePath; }
+namespace Utils { class CommandLine; }
namespace VcsBase {
namespace Internal { class VcsPlugin; }
@@ -66,8 +66,7 @@ public:
// 'Executing <dir>: <cmd> <args>'. Hides well-known password option
// arguments.
static QString msgExecutionLogEntry(const QString &workingDir,
- const Utils::FilePath &executable,
- const QStringList &arguments);
+ const Utils::CommandLine &command);
enum MessageStyle {
None,
@@ -107,8 +106,7 @@ public slots:
// Append a standard-formatted entry for command execution
// (see msgExecutionLogEntry).
static void appendCommand(const QString &workingDirectory,
- const Utils::FilePath &binary,
- const QStringList &args);
+ const Utils::CommandLine &command);
// Append a blue message text and pop up.
static void appendMessage(const QString &text);
diff --git a/src/plugins/vcsbase/wizard/vcscommandpage.cpp b/src/plugins/vcsbase/wizard/vcscommandpage.cpp
index f40138c1a3..0e725e6ef2 100644
--- a/src/plugins/vcsbase/wizard/vcscommandpage.cpp
+++ b/src/plugins/vcsbase/wizard/vcscommandpage.cpp
@@ -71,9 +71,9 @@ VcsCommandPageFactory::VcsCommandPageFactory()
WizardPage *VcsCommandPageFactory::create(JsonWizard *wizard, Id typeId, const QVariant &data)
{
- Q_UNUSED(wizard);
+ Q_UNUSED(wizard)
- QTC_ASSERT(canCreate(typeId), return 0);
+ QTC_ASSERT(canCreate(typeId), return nullptr);
QVariantMap tmp = data.toMap();
@@ -89,7 +89,7 @@ WizardPage *VcsCommandPageFactory::create(JsonWizard *wizard, Id typeId, const Q
} else if (argsVar.type() == QVariant::List) {
args = Utils::transform(argsVar.toList(), &QVariant::toString);
} else {
- return 0;
+ return nullptr;
}
}
@@ -310,7 +310,7 @@ void VcsCommandPage::delayedInitialize()
const QString dir = wiz->expander()->expand(job.workDirectory);
const int timeoutS = command->defaultTimeoutS() * job.timeOutFactor;
- command->addJob(FilePath::fromUserInput(commandString), args, timeoutS, dir);
+ command->addJob({FilePath::fromUserInput(commandString), args}, timeoutS, dir);
}
start(command);
diff --git a/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp b/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp
index 22b69ac591..2f6c1c3598 100644
--- a/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp
+++ b/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp
@@ -78,13 +78,13 @@ VcsConfigurationPageFactory::VcsConfigurationPageFactory()
Utils::WizardPage *VcsConfigurationPageFactory::create(JsonWizard *wizard, Id typeId,
const QVariant &data)
{
- Q_UNUSED(wizard);
+ Q_UNUSED(wizard)
- QTC_ASSERT(canCreate(typeId), return 0);
+ QTC_ASSERT(canCreate(typeId), return nullptr);
QVariantMap tmp = data.toMap();
const QString vcsId = tmp.value(QLatin1String("vcsId")).toString();
- QTC_ASSERT(!vcsId.isEmpty(), return 0);
+ QTC_ASSERT(!vcsId.isEmpty(), return nullptr);
auto page = new VcsConfigurationPage;
page->setVersionControlId(vcsId);
@@ -129,7 +129,7 @@ VcsConfigurationPage::VcsConfigurationPage() : d(new Internal::VcsConfigurationP
{
setTitle(tr("Configuration"));
- d->m_versionControl = 0;
+ d->m_versionControl = nullptr;
d->m_configureButton = new QPushButton(ICore::msgShowOptionsDialog(), this);
d->m_configureButton->setEnabled(false);
@@ -151,7 +151,7 @@ void VcsConfigurationPage::setVersionControl(const IVersionControl *vc)
d->m_versionControlId = vc->id().toString();
else
d->m_versionControlId.clear();
- d->m_versionControl = 0;
+ d->m_versionControl = nullptr;
}
void VcsConfigurationPage::setVersionControlId(const QString &id)
diff --git a/src/plugins/vcsbase/wizard/vcsjsextension.cpp b/src/plugins/vcsbase/wizard/vcsjsextension.cpp
index bb781a32ad..35f73ae8a1 100644
--- a/src/plugins/vcsbase/wizard/vcsjsextension.cpp
+++ b/src/plugins/vcsbase/wizard/vcsjsextension.cpp
@@ -45,5 +45,11 @@ QString VcsJsExtension::displayName(const QString &vcsId) const
return vc ? vc->displayName() : QString();
}
+bool VcsJsExtension::isValidRepoUrl(const QString &vcsId, const QString &location) const
+{
+ const IVersionControl * const vc = VcsManager::versionControl(Id::fromString(vcsId));
+ return vc && vc->getRepoUrl(location).isValid;
+}
+
} // namespace Internal
} // namespace VcsBase
diff --git a/src/plugins/vcsbase/wizard/vcsjsextension.h b/src/plugins/vcsbase/wizard/vcsjsextension.h
index 4882a198d7..e1b5198cd9 100644
--- a/src/plugins/vcsbase/wizard/vcsjsextension.h
+++ b/src/plugins/vcsbase/wizard/vcsjsextension.h
@@ -37,6 +37,7 @@ class VcsJsExtension : public QObject
public:
Q_INVOKABLE bool isConfigured(const QString &vcsId) const;
Q_INVOKABLE QString displayName(const QString &vcsId) const;
+ Q_INVOKABLE bool isValidRepoUrl(const QString &vcsId, const QString &location) const;
};
} // namespace Internal
diff --git a/src/plugins/webassembly/CMakeLists.txt b/src/plugins/webassembly/CMakeLists.txt
new file mode 100644
index 0000000000..f56c506731
--- /dev/null
+++ b/src/plugins/webassembly/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_qtc_plugin(WebAssembly
+ DEPENDS Qt5::Core
+ PLUGIN_DEPENDS Core ProjectExplorer QtSupport
+ SOURCES
+ webassembly.qrc
+ webassembly_global.h
+ webassemblyconstants.h
+ webassemblydevice.cpp webassemblydevice.h
+ webassemblyplugin.cpp webassemblyplugin.h
+ webassemblyqtversion.cpp webassemblyqtversion.h
+ webassemblyrunconfigurationaspects.cpp webassemblyrunconfigurationaspects.h
+ webassemblyrunconfiguration.cpp webassemblyrunconfiguration.h
+ webassemblytoolchain.cpp webassemblytoolchain.h
+)
diff --git a/src/plugins/webassembly/WebAssembly.json.in b/src/plugins/webassembly/WebAssembly.json.in
new file mode 100644
index 0000000000..1601a707b7
--- /dev/null
+++ b/src/plugins/webassembly/WebAssembly.json.in
@@ -0,0 +1,20 @@
+{
+ \"Name\" : \"WebAssembly\",
+ \"Version\" : \"$$QTCREATOR_VERSION\",
+ \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
+ \"Experimental\" : true,
+ \"Vendor\" : \"The Qt Company Ltd\",
+ \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
+ \"License\" : [ \"Commercial Usage\",
+ \"\",
+ \"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt 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.\",
+ \"\",
+ \"GNU General Public License Usage\",
+ \"\",
+ \"Alternatively, this plugin 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 plugin. 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.\"
+ ],
+ \"Category\" : \"Device Support\",
+ \"Description\" : \"Helper for WebAssembly projects.\",
+ \"Url\" : \"http://www.qt.io\",
+ $$dependencyList
+}
diff --git a/src/plugins/webassembly/images/webassemblydevice.png b/src/plugins/webassembly/images/webassemblydevice.png
new file mode 100644
index 0000000000..b61a040680
--- /dev/null
+++ b/src/plugins/webassembly/images/webassemblydevice.png
Binary files differ
diff --git a/src/plugins/webassembly/images/webassemblydevice@2x.png b/src/plugins/webassembly/images/webassemblydevice@2x.png
new file mode 100644
index 0000000000..9c7a248f65
--- /dev/null
+++ b/src/plugins/webassembly/images/webassemblydevice@2x.png
Binary files differ
diff --git a/src/plugins/webassembly/images/webassemblydevicesmall.png b/src/plugins/webassembly/images/webassemblydevicesmall.png
new file mode 100644
index 0000000000..f9a367285a
--- /dev/null
+++ b/src/plugins/webassembly/images/webassemblydevicesmall.png
Binary files differ
diff --git a/src/plugins/webassembly/images/webassemblydevicesmall@2x.png b/src/plugins/webassembly/images/webassemblydevicesmall@2x.png
new file mode 100644
index 0000000000..fd51087c11
--- /dev/null
+++ b/src/plugins/webassembly/images/webassemblydevicesmall@2x.png
Binary files differ
diff --git a/src/plugins/webassembly/webassembly.pro b/src/plugins/webassembly/webassembly.pro
new file mode 100644
index 0000000000..84b9d7f6b2
--- /dev/null
+++ b/src/plugins/webassembly/webassembly.pro
@@ -0,0 +1,22 @@
+include(../../qtcreatorplugin.pri)
+
+HEADERS += \
+ webassembly_global.h \
+ webassemblyconstants.h \
+ webassemblydevice.h \
+ webassemblyplugin.h \
+ webassemblyqtversion.h \
+ webassemblyrunconfigurationaspects.h \
+ webassemblyrunconfiguration.h \
+ webassemblytoolchain.h
+
+SOURCES += \
+ webassemblydevice.cpp \
+ webassemblyplugin.cpp \
+ webassemblyqtversion.cpp \
+ webassemblyrunconfigurationaspects.cpp \
+ webassemblyrunconfiguration.cpp \
+ webassemblytoolchain.cpp
+
+RESOURCES += \
+ webassembly.qrc
diff --git a/src/plugins/webassembly/webassembly.qbs b/src/plugins/webassembly/webassembly.qbs
new file mode 100644
index 0000000000..2fa5a67725
--- /dev/null
+++ b/src/plugins/webassembly/webassembly.qbs
@@ -0,0 +1,31 @@
+import qbs 1.0
+
+QtcPlugin {
+ name: "WebAssembly"
+
+ Depends { name: "Qt.core" }
+ Depends { name: "Qt.widgets" }
+ Depends { name: "Utils" }
+
+ Depends { name: "Core" }
+ Depends { name: "ProjectExplorer" }
+ Depends { name: "QtSupport" }
+
+ files: [
+ "webassembly.qrc",
+ "webassembly_global.h",
+ "webassemblyconstants.h",
+ "webassemblydevice.cpp",
+ "webassemblydevice.h",
+ "webassemblyplugin.cpp",
+ "webassemblyplugin.h",
+ "webassemblyqtversion.cpp",
+ "webassemblyqtversion.h",
+ "webassemblyrunconfigurationaspects.cpp",
+ "webassemblyrunconfigurationaspects.h",
+ "webassemblyrunconfiguration.cpp",
+ "webassemblyrunconfiguration.h",
+ "webassemblytoolchain.cpp",
+ "webassemblytoolchain.h",
+ ]
+}
diff --git a/src/plugins/webassembly/webassembly.qrc b/src/plugins/webassembly/webassembly.qrc
new file mode 100644
index 0000000000..6b6ac54a4b
--- /dev/null
+++ b/src/plugins/webassembly/webassembly.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/webassembly">
+ <file>images/webassemblydevice.png</file>
+ <file>images/webassemblydevice@2x.png</file>
+ <file>images/webassemblydevicesmall.png</file>
+ <file>images/webassemblydevicesmall@2x.png</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/webassembly/webassembly_dependencies.pri b/src/plugins/webassembly/webassembly_dependencies.pri
new file mode 100644
index 0000000000..0a3e35ca6e
--- /dev/null
+++ b/src/plugins/webassembly/webassembly_dependencies.pri
@@ -0,0 +1,10 @@
+QTC_PLUGIN_NAME = WebAssembly
+
+QTC_LIB_DEPENDS += \
+ extensionsystem \
+ utils
+
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ projectexplorer \
+ qtsupport
diff --git a/src/plugins/webassembly/webassembly_global.h b/src/plugins/webassembly/webassembly_global.h
new file mode 100644
index 0000000000..de5a9375b3
--- /dev/null
+++ b/src/plugins/webassembly/webassembly_global.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtGlobal>
+
+#if defined(WEBASSEMBLY_LIBRARY)
+# define WEBASSEMBLYSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define WEBASSEMBLYSHARED_EXPORT Q_DECL_IMPORT
+#endif
diff --git a/src/plugins/webassembly/webassemblyconstants.h b/src/plugins/webassembly/webassemblyconstants.h
new file mode 100644
index 0000000000..0da7195222
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyconstants.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+namespace WebAssembly {
+namespace Constants {
+
+const char WEBASSEMBLY_TOOLCHAIN_TYPEID[] = "WebAssembly.ToolChain.Emscripten";
+const char WEBASSEMBLY_DEVICE_TYPE[] = "WebAssemblyDeviceType";
+const char WEBASSEMBLY_DEVICE_DEVICE_ID[] = "WebAssembly Device";
+const char WEBASSEMBLY_QT_VERSION[] = "Qt4ProjectManager.QtVersion.WebAssembly";
+const char WEBASSEMBLY_RUNCONFIGURATION_EMRUN[] = "WebAssembly.RunConfiguration.Emrun";
+
+} // namespace WebAssembly
+} // namespace Constants
diff --git a/src/plugins/webassembly/webassemblydevice.cpp b/src/plugins/webassembly/webassemblydevice.cpp
new file mode 100644
index 0000000000..d49ebc1c37
--- /dev/null
+++ b/src/plugins/webassembly/webassemblydevice.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "webassemblyconstants.h"
+#include "webassemblydevice.h"
+
+#include <projectexplorer/devicesupport/deviceprocess.h>
+#include <projectexplorer/runcontrol.h>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace WebAssembly {
+namespace Internal {
+
+WebAssemblyDevice::WebAssemblyDevice()
+{
+ setupId(IDevice::AutoDetected, Constants::WEBASSEMBLY_DEVICE_DEVICE_ID);
+ setType(Constants::WEBASSEMBLY_DEVICE_TYPE);
+ const QString displayNameAndType = tr("Web Browser");
+ setDefaultDisplayName(displayNameAndType);
+ setDisplayType(displayNameAndType);
+ setDeviceState(IDevice::DeviceStateUnknown);
+ setMachineType(IDevice::Hardware);
+ setOsType(OsTypeOther);
+}
+
+ProjectExplorer::IDevice::Ptr WebAssemblyDevice::create()
+{
+ auto device = new WebAssemblyDevice;
+ return ProjectExplorer::IDevice::Ptr(device);
+}
+
+WebAssemblyDeviceFactory::WebAssemblyDeviceFactory()
+ : ProjectExplorer::IDeviceFactory(Constants::WEBASSEMBLY_DEVICE_TYPE)
+{
+ setDisplayName(tr("WebAssembly Runtime"));
+ setCombinedIcon(":/webassembly/images/webassemblydevicesmall.png",
+ ":/webassembly/images/webassemblydevice.png");
+ setCanCreate(true);
+ setConstructionFunction(&WebAssemblyDevice::create);
+}
+
+ProjectExplorer::IDevice::Ptr WebAssemblyDeviceFactory::create() const
+{
+ return WebAssemblyDevice::create();
+}
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/webassembly/webassemblydevice.h b/src/plugins/webassembly/webassemblydevice.h
new file mode 100644
index 0000000000..12759b22f5
--- /dev/null
+++ b/src/plugins/webassembly/webassemblydevice.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/devicesupport/desktopdevice.h>
+
+#include <QCoreApplication>
+
+namespace WebAssembly {
+namespace Internal {
+
+class WebAssemblyDevice : public ProjectExplorer::DesktopDevice
+{
+ Q_DECLARE_TR_FUNCTIONS(WebAssembly::Internal::WebAssemblyDevice)
+
+public:
+ static ProjectExplorer::IDevice::Ptr create();
+
+private:
+ WebAssemblyDevice();
+};
+
+class WebAssemblyDeviceFactory : public ProjectExplorer::IDeviceFactory
+{
+ Q_OBJECT
+
+public:
+ WebAssemblyDeviceFactory();
+
+ ProjectExplorer::IDevice::Ptr create() const override;
+};
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/webassembly/webassemblyplugin.cpp b/src/plugins/webassembly/webassemblyplugin.cpp
new file mode 100644
index 0000000000..97b4ca4ebc
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyplugin.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "webassemblyplugin.h"
+#include "webassemblyconstants.h"
+#include "webassemblydevice.h"
+#include "webassemblyqtversion.h"
+#include "webassemblyrunconfiguration.h"
+#include "webassemblytoolchain.h"
+
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/icore.h>
+
+#include <projectexplorer/devicesupport/devicemanager.h>
+
+using namespace ProjectExplorer;
+
+namespace WebAssembly {
+namespace Internal {
+
+class WebAssemblyPluginPrivate
+{
+public:
+ WebAssemblyToolChainFactory toolChainFactory;
+ WebAssemblyDeviceFactory deviceFactory;
+ WebAssemblyQtVersionFactory qtVersionFactory;
+ EmrunRunConfigurationFactory emrunRunConfigurationFactory;
+ RunWorkerFactory emrunRunWorkerFactory{
+ makeEmrunWorker(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {Constants::WEBASSEMBLY_RUNCONFIGURATION_EMRUN}
+ };
+};
+
+static WebAssemblyPluginPrivate *dd = nullptr;
+
+WebAssemblyPlugin::WebAssemblyPlugin()
+{
+ setObjectName("WebAssemblyPlugin");
+}
+
+WebAssemblyPlugin::~WebAssemblyPlugin()
+{
+ delete dd;
+ dd = nullptr;
+}
+
+bool WebAssemblyPlugin::initialize(const QStringList& arguments, QString* errorString)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ dd = new WebAssemblyPluginPrivate;
+
+ return true;
+}
+
+void WebAssemblyPlugin::extensionsInitialized()
+{
+ ProjectExplorer::DeviceManager::instance()->addDevice(WebAssemblyDevice::create());
+}
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/webassembly/webassemblyplugin.h b/src/plugins/webassembly/webassemblyplugin.h
new file mode 100644
index 0000000000..a6bbf1ce5c
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyplugin.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "webassembly_global.h"
+
+#include <extensionsystem/iplugin.h>
+
+namespace WebAssembly {
+namespace Internal {
+
+class WebAssemblyPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "WebAssembly.json")
+
+public:
+ WebAssemblyPlugin();
+ ~WebAssemblyPlugin() override;
+
+ bool initialize(const QStringList &arguments, QString *errorString) override;
+ void extensionsInitialized() override;
+};
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/webassembly/webassemblyqtversion.cpp b/src/plugins/webassembly/webassemblyqtversion.cpp
new file mode 100644
index 0000000000..54f51be4bb
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyqtversion.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "webassemblyconstants.h"
+#include "webassemblyqtversion.h"
+
+#include <projectexplorer/abi.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <remotelinux/remotelinux_constants.h>
+#include <coreplugin/featureprovider.h>
+
+#include <utils/algorithm.h>
+#include <utils/hostosinfo.h>
+#include <utils/qtcassert.h>
+
+#include <QCoreApplication>
+#include <QFileInfo>
+
+namespace WebAssembly {
+namespace Internal {
+
+WebAssemblyQtVersion::WebAssemblyQtVersion() = default;
+
+QString WebAssemblyQtVersion::description() const
+{
+ return QCoreApplication::translate("WebAssemblyPlugin", "WebAssembly",
+ "Qt Version is meant for WebAssembly");
+}
+
+QSet<Core::Id> WebAssemblyQtVersion::targetDeviceTypes() const
+{
+ return {Constants::WEBASSEMBLY_DEVICE_TYPE};
+}
+
+WebAssemblyQtVersionFactory::WebAssemblyQtVersionFactory()
+{
+ setQtVersionCreator([] { return new WebAssemblyQtVersion; });
+ setSupportedType(Constants::WEBASSEMBLY_QT_VERSION);
+ setPriority(1);
+}
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/remotelinux/embeddedlinuxqtversion.h b/src/plugins/webassembly/webassemblyqtversion.h
index e70eea1df3..0b590e7f1c 100644
--- a/src/plugins/remotelinux/embeddedlinuxqtversion.h
+++ b/src/plugins/webassembly/webassemblyqtversion.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,27 +25,27 @@
#pragma once
-#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtversionfactory.h>
+#include <qtsupport/baseqtversion.h>
-namespace RemoteLinux {
+namespace WebAssembly {
namespace Internal {
-class EmbeddedLinuxQtVersion : public QtSupport::BaseQtVersion
+class WebAssemblyQtVersion : public QtSupport::BaseQtVersion
{
public:
- EmbeddedLinuxQtVersion() = default;
+ WebAssemblyQtVersion();
QString description() const override;
QSet<Core::Id> targetDeviceTypes() const override;
};
-class EmbeddedLinuxQtVersionFactory : public QtSupport::QtVersionFactory
+class WebAssemblyQtVersionFactory : public QtSupport::QtVersionFactory
{
public:
- EmbeddedLinuxQtVersionFactory();
+ WebAssemblyQtVersionFactory();
};
} // namespace Internal
-} // namespace RemoteLinux
+} // namespace WebAssembly
diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp
new file mode 100644
index 0000000000..b8f3610ccc
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "webassemblyrunconfigurationaspects.h"
+#include "webassemblyrunconfiguration.h"
+#include "webassemblyconstants.h"
+
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/devicesupport/devicemanager.h>
+#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/target.h>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace WebAssembly {
+namespace Internal {
+
+static CommandLine emrunCommand(Target *target, const QString &browser, const QString &port)
+{
+ BuildConfiguration *bc = target->activeBuildConfiguration();
+ const QFileInfo emrunScript = bc->environment().searchInPath("emrun").toFileInfo();
+ auto html = bc->buildDirectory().pathAppended(target->project()->displayName() + ".html");
+
+ return CommandLine(bc->environment().searchInPath("python"), {
+ emrunScript.absolutePath() + "/" + emrunScript.baseName() + ".py",
+ "--browser", browser,
+ "--port", port,
+ "--no_emrun_detect",
+ html.toString()
+ });
+}
+
+// Runs a webassembly application via emscripten's "emrun" tool
+// https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html
+class EmrunRunConfiguration : public ProjectExplorer::RunConfiguration
+{
+public:
+ EmrunRunConfiguration(Target *target, Core::Id id)
+ : RunConfiguration(target, id)
+ {
+ auto webBrowserAspect = addAspect<WebBrowserSelectionAspect>(target);
+
+ auto effectiveEmrunCall = addAspect<BaseStringAspect>();
+ effectiveEmrunCall->setLabelText(tr("Effective emrun call:"));
+ effectiveEmrunCall->setDisplayStyle(BaseStringAspect::TextEditDisplay);
+ effectiveEmrunCall->setReadOnly(true);
+
+ auto updateConfiguration = [target, effectiveEmrunCall, webBrowserAspect] {
+ effectiveEmrunCall->setValue(emrunCommand(target,
+ webBrowserAspect->currentBrowser(),
+ "<port>").toUserOutput());
+ };
+
+ updateConfiguration();
+
+ connect(webBrowserAspect, &WebBrowserSelectionAspect::changed,
+ this, updateConfiguration);
+ connect(target->activeBuildConfiguration(), &BuildConfiguration::buildDirectoryChanged,
+ this, updateConfiguration);
+ }
+};
+
+class EmrunRunWorker : public SimpleTargetRunner
+{
+public:
+ EmrunRunWorker(RunControl *runControl)
+ : SimpleTargetRunner(runControl)
+ {
+ auto portsGatherer = new PortsGatherer(runControl);
+ addStartDependency(portsGatherer);
+
+ setStarter([this, runControl, portsGatherer] {
+ CommandLine cmd = emrunCommand(runControl->target(),
+ runControl->aspect<WebBrowserSelectionAspect>()->currentBrowser(),
+ QString::number(portsGatherer->findEndPoint().port()));
+ Runnable r;
+ r.setCommandLine(cmd);
+ SimpleTargetRunner::doStart(r, {});
+ });
+ }
+};
+
+RunWorkerFactory::WorkerCreator makeEmrunWorker()
+{
+ return RunWorkerFactory::make<EmrunRunWorker>();
+}
+
+// Factories
+
+EmrunRunConfigurationFactory::EmrunRunConfigurationFactory()
+ : FixedRunConfigurationFactory(EmrunRunConfiguration::tr("Launch with emrun"))
+{
+ registerRunConfiguration<EmrunRunConfiguration>(Constants::WEBASSEMBLY_RUNCONFIGURATION_EMRUN);
+ addSupportedTargetDeviceType(Constants::WEBASSEMBLY_DEVICE_TYPE);
+}
+
+} // namespace Internal
+} // namespace Webassembly
diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.h b/src/plugins/webassembly/webassemblyrunconfiguration.h
new file mode 100644
index 0000000000..af6af51e81
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyrunconfiguration.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/runcontrol.h>
+
+namespace WebAssembly {
+namespace Internal {
+
+class EmrunRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory
+{
+public:
+ EmrunRunConfigurationFactory();
+};
+
+ProjectExplorer::RunWorkerFactory::WorkerCreator makeEmrunWorker();
+
+} // namespace Internal
+} // namespace Webassembly
diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp
new file mode 100644
index 0000000000..aacbc67750
--- /dev/null
+++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "webassemblyrunconfigurationaspects.h"
+
+#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/target.h>
+
+#include <QComboBox>
+#include <QFormLayout>
+
+namespace WebAssembly {
+namespace Internal {
+
+static const char BROWSER_KEY[] = "WASM.WebBrowserSelectionAspect.Browser";
+
+static QStringList detectedBrowsers(ProjectExplorer::Target *target)
+{
+ static QStringList result;
+ if (result.isEmpty()) {
+ const Utils::Environment environment = target->activeBuildConfiguration()->environment();
+ const Utils::FilePath emrunPath = environment.searchInPath("emrun");
+
+ QProcess browserLister;
+ browserLister.setProcessEnvironment(environment.toProcessEnvironment());
+ browserLister.setProgram(emrunPath.toString());
+ browserLister.setArguments({"--list_browsers"});
+ browserLister.start(QIODevice::ReadOnly);
+
+ if (browserLister.waitForFinished()) {
+ const QByteArray output = browserLister.readAllStandardOutput();
+ QTextStream ts(output);
+ QString line;
+ const QRegularExpression regExp(" - (.*):.*");
+ while (ts.readLineInto(&line)) {
+ const QRegularExpressionMatch match = regExp.match(line);
+ if (match.hasMatch())
+ result << match.captured(1);
+ }
+ }
+ }
+ return result;
+}
+
+WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *target)
+ : m_availableBrowsers(detectedBrowsers(target))
+{
+ m_currentBrowser = m_availableBrowsers.first();
+ setDisplayName(tr("Web browser"));
+ setId("WebBrowserAspect");
+ setSettingsKey("RunConfiguration.WebBrowser");
+}
+
+void WebBrowserSelectionAspect::addToConfigurationLayout(QFormLayout *layout)
+{
+ QTC_CHECK(!m_webBrowserComboBox);
+ m_webBrowserComboBox = new QComboBox(layout->parentWidget());
+ m_webBrowserComboBox->addItems(m_availableBrowsers);
+ m_webBrowserComboBox->setCurrentText(m_currentBrowser);
+ connect(m_webBrowserComboBox, &QComboBox::currentTextChanged,
+ [this](const QString &selectedBrowser){
+ m_currentBrowser = selectedBrowser;
+ emit changed();
+ });
+ layout->addRow(tr("Web browser:"), m_webBrowserComboBox);
+}
+
+void WebBrowserSelectionAspect::fromMap(const QVariantMap &map)
+{
+ m_currentBrowser = map.value(BROWSER_KEY, m_availableBrowsers.first()).toString();
+}
+
+void WebBrowserSelectionAspect::toMap(QVariantMap &map) const
+{
+ map.insert(BROWSER_KEY, m_currentBrowser);
+}
+
+QString WebBrowserSelectionAspect::currentBrowser() const
+{
+ return m_currentBrowser;
+}
+
+} // namespace Internal
+} // namespace Webassembly
diff --git a/src/plugins/qtsupport/desktopqtversion.h b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h
index 01e304e23e..16b2d842ee 100644
--- a/src/plugins/qtsupport/desktopqtversion.h
+++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,39 +25,32 @@
#pragma once
-#include <qtsupport/qtversionfactory.h>
+#include <projectexplorer/runconfigurationaspects.h>
-#include "baseqtversion.h"
+QT_FORWARD_DECLARE_CLASS(QComboBox)
-namespace QtSupport {
+namespace WebAssembly {
+namespace Internal {
-class QTSUPPORT_EXPORT DesktopQtVersion : public BaseQtVersion
+class WebBrowserSelectionAspect : public ProjectExplorer::ProjectConfigurationAspect
{
-public:
- DesktopQtVersion();
-
- QStringList warningReason() const override;
+ Q_OBJECT
- QString description() const override;
+public:
+ WebBrowserSelectionAspect(ProjectExplorer::Target *target);
- QSet<Core::Id> availableFeatures() const override;
- QSet<Core::Id> targetDeviceTypes() const override;
+ void addToConfigurationLayout(QFormLayout *layout) override;
void fromMap(const QVariantMap &map) override;
+ void toMap(QVariantMap &map) const override;
- QString qmlsceneCommand() const;
+ QString currentBrowser() const;
private:
- mutable QString m_qmlsceneCommand;
-};
-
-namespace Internal {
-
-class DesktopQtVersionFactory : public QtVersionFactory
-{
-public:
- DesktopQtVersionFactory();
+ QComboBox *m_webBrowserComboBox = nullptr;
+ QString m_currentBrowser;
+ QStringList m_availableBrowsers;
};
-} // Internal
-} // QtSupport
+} // namespace Internal
+} // namespace Webassembly
diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp
new file mode 100644
index 0000000000..ec4726aa6f
--- /dev/null
+++ b/src/plugins/webassembly/webassemblytoolchain.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "webassemblytoolchain.h"
+#include "webassemblyconstants.h"
+
+#include <utils/environment.h>
+#include <utils/fileutils.h>
+#include <utils/hostosinfo.h>
+
+#include <projectexplorer/abiwidget.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/projectmacro.h>
+#include <projectexplorer/toolchainmanager.h>
+
+#include <QDir>
+#include <QSettings>
+
+namespace WebAssembly {
+namespace Internal {
+
+// See https://emscripten.org/docs/tools_reference/emsdk.html#compiler-configuration-file
+struct CompilerConfiguration
+{
+ Utils::FilePath emSdk;
+ Utils::FilePath llvmRoot;
+ Utils::FilePath emConfig;
+ Utils::FilePath emscriptenNativeOptimizer;
+ Utils::FilePath binaryEnRoot;
+ Utils::FilePath emSdkNode;
+ Utils::FilePath emSdkPython;
+ Utils::FilePath javaHome;
+ Utils::FilePath emScripten;
+};
+
+static Utils::FilePath compilerConfigurationFile()
+{
+ return Utils::FilePath::fromString(QDir::homePath() + "/.emscripten");
+}
+
+static CompilerConfiguration compilerConfiguration()
+{
+ const QSettings configuration(compilerConfigurationFile().toString(), QSettings::IniFormat);
+ auto configPath = [&configuration](const QString &key){
+ return Utils::FilePath::fromString(configuration.value(key).toString().remove('\''));
+ };
+ const Utils::FilePath llvmRoot = configPath("LLVM_ROOT");
+ return {
+ llvmRoot.parentDir().parentDir(),
+ llvmRoot,
+ compilerConfigurationFile(),
+ configPath("EMSCRIPTEN_NATIVE_OPTIMIZER"),
+ configPath("BINARYEN_ROOT"),
+ configPath("NODE_JS"),
+ configPath("PYTHON"),
+ configPath("JAVA").parentDir().parentDir(),
+ configPath("EMSCRIPTEN_ROOT")
+ };
+}
+
+static ProjectExplorer::Abi toolChainAbi()
+{
+ return {
+ ProjectExplorer::Abi::AsmJsArchitecture,
+ ProjectExplorer::Abi::UnknownOS,
+ ProjectExplorer::Abi::UnknownFlavor,
+ ProjectExplorer::Abi::EmscriptenFormat,
+ 32
+ };
+}
+
+void WebAssemblyToolChain::addToEnvironment(Utils::Environment &env) const
+{
+ const CompilerConfiguration configuration = compilerConfiguration();
+
+ env.prependOrSetPath(configuration.emScripten.toUserOutput());
+ env.prependOrSetPath(configuration.javaHome.toUserOutput() + "/bin");
+ env.prependOrSetPath(configuration.emSdkPython.parentDir().toUserOutput());
+ env.prependOrSetPath(configuration.emSdkNode.parentDir().toUserOutput());
+ env.prependOrSetPath(configuration.llvmRoot.toUserOutput());
+ env.prependOrSetPath(configuration.emSdk.toUserOutput());
+
+ env.set("EMSDK", configuration.emSdk.toUserOutput());
+ env.set("EM_CONFIG", configuration.emConfig.toUserOutput());
+ env.set("LLVM_ROOT", configuration.llvmRoot.toUserOutput());
+ env.set("EMSCRIPTEN_NATIVE_OPTIMIZER", configuration.emscriptenNativeOptimizer.toUserOutput());
+ env.set("BINARYEN_ROOT", configuration.binaryEnRoot.toUserOutput());
+ env.set("EMSDK_NODE", configuration.emSdkNode.toUserOutput());
+ env.set("EMSDK_PYTHON", configuration.emSdkPython.toUserOutput());
+ env.set("JAVA_HOME", configuration.javaHome.toUserOutput());
+ env.set("EMSCRIPTEN", configuration.emScripten.toUserOutput());
+}
+
+WebAssemblyToolChain::WebAssemblyToolChain() :
+ ClangToolChain(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID)
+{
+ const CompilerConfiguration configuration = compilerConfiguration();
+ const QString command = configuration.llvmRoot.toString()
+ + Utils::HostOsInfo::withExecutableSuffix("/clang");
+ setLanguage(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
+ setCompilerCommand(Utils::FilePath::fromString(command));
+ setSupportedAbis({toolChainAbi()});
+ setTargetAbi(toolChainAbi());
+ const QString typeAndDisplayName = WebAssemblyToolChainFactory::tr("Emscripten Compiler");
+ setDisplayName(typeAndDisplayName);
+ setTypeDisplayName(typeAndDisplayName);
+}
+
+WebAssemblyToolChainFactory::WebAssemblyToolChainFactory()
+{
+ setDisplayName(tr("WebAssembly"));
+ setSupportedToolChainType(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID);
+ setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID,
+ ProjectExplorer::Constants::CXX_LANGUAGE_ID});
+ setToolchainConstructor([] { return new WebAssemblyToolChain; });
+ setUserCreatable(true);
+}
+
+QList<ProjectExplorer::ToolChain *> WebAssemblyToolChainFactory::autoDetect(
+ const QList<ProjectExplorer::ToolChain *> &alreadyKnown)
+{
+ Q_UNUSED(alreadyKnown)
+
+ auto cToolChain = new WebAssemblyToolChain;
+ cToolChain->setLanguage(ProjectExplorer::Constants::C_LANGUAGE_ID);
+ cToolChain->setDetection(ProjectExplorer::ToolChain::AutoDetection);
+
+ auto cxxToolChain = new WebAssemblyToolChain;
+ cxxToolChain->setLanguage(ProjectExplorer::Constants::CXX_LANGUAGE_ID);
+ cxxToolChain->setDetection(ProjectExplorer::ToolChain::AutoDetection);
+
+ return {cToolChain, cxxToolChain};
+}
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/webassembly/webassemblytoolchain.h b/src/plugins/webassembly/webassemblytoolchain.h
new file mode 100644
index 0000000000..4693bc7a10
--- /dev/null
+++ b/src/plugins/webassembly/webassemblytoolchain.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/gcctoolchain.h>
+
+namespace WebAssembly {
+namespace Internal {
+
+class WebAssemblyToolChain final : public ProjectExplorer::ClangToolChain
+{
+public:
+ void addToEnvironment(Utils::Environment &env) const override;
+
+private:
+ WebAssemblyToolChain();
+
+ friend class WebAssemblyToolChainFactory;
+};
+
+class WebAssemblyToolChainFactory : public ProjectExplorer::ToolChainFactory
+{
+ Q_OBJECT
+
+public:
+ WebAssemblyToolChainFactory();
+
+ QList<ProjectExplorer::ToolChain *> autoDetect(
+ const QList<ProjectExplorer::ToolChain *> &alreadyKnown) override;
+};
+
+} // namespace Internal
+} // namespace WebAssembly
diff --git a/src/plugins/welcome/introductionwidget.cpp b/src/plugins/welcome/introductionwidget.cpp
index 82539fd996..a29b5e4f57 100644
--- a/src/plugins/welcome/introductionwidget.cpp
+++ b/src/plugins/welcome/introductionwidget.cpp
@@ -25,6 +25,8 @@
#include "introductionwidget.h"
+#include <coreplugin/icore.h>
+#include <coreplugin/infobar.h>
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
#include <utils/qtcassert.h>
@@ -47,29 +49,24 @@ namespace Internal {
void IntroductionWidget::askUserAboutIntroduction(QWidget *parent, QSettings *settings)
{
- if (!CheckableMessageBox::shouldAskAgain(settings, kTakeTourSetting))
+ // CheckableMessageBox for compatibility with Qt Creator < 4.11
+ if (!CheckableMessageBox::shouldAskAgain(settings, kTakeTourSetting)
+ || !Core::ICore::infoBar()->canInfoBeAdded(kTakeTourSetting))
return;
- auto messageBox = new CheckableMessageBox(parent);
- messageBox->setWindowTitle(tr("Take a UI Tour"));
- messageBox->setText(
- tr("Would you like to take a quick UI tour? This tour highlights important user "
- "interface elements and shows how they are used. To take the tour later, "
- "select Help > UI Tour."));
- messageBox->setCheckBoxVisible(true);
- messageBox->setCheckBoxText(CheckableMessageBox::msgDoNotAskAgain());
- messageBox->setChecked(true);
- messageBox->setStandardButtons(QDialogButtonBox::Cancel);
- QPushButton *tourButton = messageBox->addButton(tr("Take UI Tour"), QDialogButtonBox::AcceptRole);
- connect(messageBox, &QDialog::finished, parent, [parent, settings, messageBox, tourButton]() {
- if (messageBox->isChecked())
- CheckableMessageBox::doNotAskAgain(settings, kTakeTourSetting);
- if (messageBox->clickedButton() == tourButton) {
- auto intro = new IntroductionWidget(parent);
- intro->show();
- }
- messageBox->deleteLater();
+
+ Core::InfoBarEntry
+ info(kTakeTourSetting,
+ tr("Would you like to take a quick UI tour? This tour highlights important user "
+ "interface elements and shows how they are used. To take the tour later, "
+ "select Help > UI Tour."),
+ Core::InfoBarEntry::GlobalSuppression::Enabled);
+ info.setCustomButtonInfo(tr("Take UI Tour"), [parent] {
+ Core::ICore::infoBar()->removeInfo(kTakeTourSetting);
+ Core::ICore::infoBar()->globallySuppressInfo(kTakeTourSetting);
+ auto intro = new IntroductionWidget(parent);
+ intro->show();
});
- messageBox->show();
+ Core::ICore::infoBar()->addInfo(info);
}
IntroductionWidget::IntroductionWidget(QWidget *parent)
@@ -81,7 +78,7 @@ IntroductionWidget::IntroductionWidget(QWidget *parent)
parent->installEventFilter(this);
QPalette p = palette();
- p.setColor(QPalette::Foreground, QColor(220, 220, 220));
+ p.setColor(QPalette::WindowText, QColor(220, 220, 220));
setPalette(p);
m_textWidget = new QWidget(this);
diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp
index 88a8a1ace4..08e763ab09 100644
--- a/src/plugins/welcome/welcomeplugin.cpp
+++ b/src/plugins/welcome/welcomeplugin.cpp
@@ -88,7 +88,6 @@ static QFont sizedFont(int size, const QWidget *widget, bool underline = false)
static QPalette lightText()
{
QPalette pal;
- pal.setColor(QPalette::Foreground, themeColor(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::WindowText, themeColor(Theme::Welcome_ForegroundPrimaryColor));
return pal;
}
@@ -199,7 +198,7 @@ public:
void enterEvent(QEvent *) override
{
QPalette pal;
- pal.setColor(QPalette::Background, themeColor(Theme::Welcome_HoverColor));
+ pal.setColor(QPalette::Window, themeColor(Theme::Welcome_HoverColor));
setPalette(pal);
m_label->setFont(sizedFont(11, m_label, true));
update();
@@ -208,7 +207,7 @@ public:
void leaveEvent(QEvent *) override
{
QPalette pal;
- pal.setColor(QPalette::Background, themeColor(Theme::Welcome_BackgroundColor));
+ pal.setColor(QPalette::Window, themeColor(Theme::Welcome_BackgroundColor));
setPalette(pal);
m_label->setFont(sizedFont(11, m_label, false));
update();
@@ -319,7 +318,7 @@ WelcomeMode::WelcomeMode()
setContext(Context(Constants::C_WELCOME_MODE));
QPalette palette = creatorTheme()->palette();
- palette.setColor(QPalette::Background, themeColor(Theme::Welcome_BackgroundColor));
+ palette.setColor(QPalette::Window, themeColor(Theme::Welcome_BackgroundColor));
m_modeWidget = new QWidget;
m_modeWidget->setPalette(palette);
@@ -348,7 +347,7 @@ WelcomeMode::WelcomeMode()
hbox->setStretchFactor(m_pageStack, 10);
auto layout = new QVBoxLayout(m_modeWidget);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(new StyledBar(m_modeWidget));
layout->addItem(hbox);
diff --git a/src/plugins/winrt/winrtdebugsupport.cpp b/src/plugins/winrt/winrtdebugsupport.cpp
index d7f3e9a59b..d409b0cdb0 100644
--- a/src/plugins/winrt/winrtdebugsupport.cpp
+++ b/src/plugins/winrt/winrtdebugsupport.cpp
@@ -75,7 +75,7 @@ WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl)
setQmlServer(qmlServer);
}
- setSymbolFile(runControl->buildTargetInfo().targetFilePath.toString());
+ setSymbolFile(runControl->targetFilePath());
QString errorMessage;
m_runner = new WinRtRunnerHelper(this, &errorMessage);
if (!errorMessage.isEmpty()) {
diff --git a/src/plugins/winrt/winrtdevice.cpp b/src/plugins/winrt/winrtdevice.cpp
index 9ceba3b323..953756c79f 100644
--- a/src/plugins/winrt/winrtdevice.cpp
+++ b/src/plugins/winrt/winrtdevice.cpp
@@ -60,17 +60,15 @@ Q_LOGGING_CATEGORY(winrtDeviceLog, "qtc.winrt.deviceParser", QtWarningMsg)
WinRtDevice::WinRtDevice()
{
+ setDisplayType(displayNameForType(type()));
+ setOsType(OsTypeWindows);
+
Utils::PortList portList;
portList.addRange(Utils::Port(ProjectExplorer::Constants::DESKTOP_PORT_START),
Utils::Port(ProjectExplorer::Constants::DESKTOP_PORT_END));
setFreePorts(portList);
}
-QString WinRtDevice::displayType() const
-{
- return displayNameForType(type());
-}
-
IDeviceWidget *WinRtDevice::createWidget()
{
return nullptr;
@@ -101,11 +99,6 @@ QVariantMap WinRtDevice::toMap() const
return map;
}
-Utils::OsType WinRtDevice::osType() const
-{
- return Utils::OsTypeWindows;
-}
-
QString WinRtDevice::displayNameForType(Core::Id type)
{
if (type == Constants::WINRT_DEVICE_TYPE_LOCAL)
@@ -159,11 +152,10 @@ void WinRtDeviceFactory::autoDetect()
this, &WinRtDeviceFactory::onProcessFinished);
}
- const QString args = QStringLiteral("--list-devices");
- m_process->setCommand(CommandLine(FilePath::fromString(runnerFilePath), args));
- qCDebug(winrtDeviceLog) << __FUNCTION__ << "Starting process" << runnerFilePath
- << "with arguments" << args;
- MessageManager::write(runnerFilePath + QLatin1Char(' ') + args);
+ const CommandLine cmd{runnerFilePath, {"--list-devices"}};
+ m_process->setCommand(cmd);
+ qCDebug(winrtDeviceLog) << __FUNCTION__ << "Starting process" << cmd.toUserOutput();
+ MessageManager::write(cmd.toUserOutput());
m_process->start();
qCDebug(winrtDeviceLog) << __FUNCTION__ << "Process started";
}
@@ -358,16 +350,16 @@ void WinRtDeviceFactory::parseRunnerOutput(const QByteArray &output) const
device->setDeviceId(deviceId);
device->setType(deviceType);
device->setMachineType(machineType);
- device->setDisplayName(name);
+ device->setDefaultDisplayName(name);
deviceManager->addDevice(ProjectExplorer::IDevice::ConstPtr(device));
qCDebug(winrtDeviceLog) << __FUNCTION__ << "Added device" << name << "(internal name:"
<< internalName << ")";
}
}
- QString message = tr("Found %n Windows Runtime devices.", 0, numFound);
+ QString message = tr("Found %n Windows Runtime devices.", nullptr, numFound);
if (const int numNew = numFound - numSkipped) {
message += QLatin1Char(' ');
- message += tr("%n of them are new.", 0, numNew);
+ message += tr("%n of them are new.", nullptr, numNew);
}
MessageManager::write(message);
}
diff --git a/src/plugins/winrt/winrtdevice.h b/src/plugins/winrt/winrtdevice.h
index f66c6c31ab..6b077d4747 100644
--- a/src/plugins/winrt/winrtdevice.h
+++ b/src/plugins/winrt/winrtdevice.h
@@ -41,12 +41,10 @@ public:
static Ptr create() { return Ptr(new WinRtDevice); }
- QString displayType() const override;
ProjectExplorer::IDeviceWidget *createWidget() override;
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const override;
void fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
- Utils::OsType osType() const override;
static QString displayNameForType(Core::Id type);
int deviceId() const { return m_deviceId; }
diff --git a/src/plugins/winrt/winrtpackagedeploymentstep.cpp b/src/plugins/winrt/winrtpackagedeploymentstep.cpp
index 357a306177..b1b7cf76ca 100644
--- a/src/plugins/winrt/winrtpackagedeploymentstep.cpp
+++ b/src/plugins/winrt/winrtpackagedeploymentstep.cpp
@@ -47,7 +47,7 @@
#include <QToolButton>
using namespace ProjectExplorer;
-using Utils::QtcProcess;
+using namespace Utils;
namespace WinRt {
namespace Internal {
@@ -91,24 +91,24 @@ bool WinRtPackageDeploymentStep::init()
if (!qt)
return false;
- QString args = QtcProcess::quoteArg(QDir::toNativeSeparators(m_targetFilePath));
- args += ' ' + m_argsAspect->value();
+ const QString windeployqtPath = FileUtils::resolvePath(qt->binPath().toString(), "windeployqt.exe");
- if (qt->type() == QLatin1String(Constants::WINRT_WINPHONEQT)) {
+ CommandLine windeployqt{windeployqtPath};
+ windeployqt.addArg(QDir::toNativeSeparators(m_targetFilePath));
+ windeployqt.addArgs(m_argsAspect->value(), CommandLine::Raw);
+
+ if (qt->type() == Constants::WINRT_WINPHONEQT) {
m_createMappingFile = true;
- args += QLatin1String(" -list mapping");
+ windeployqt.addArgs({"-list", "mapping"});
}
ProcessParameters *params = processParameters();
- const QString windeployqtPath
- = Utils::FileUtils::resolvePath(qt->binPath().toString(), "windeployqt.exe");
if (!QFile::exists(windeployqtPath)) {
raiseError(tr("Cannot find windeployqt.exe in \"%1\".").arg(
QDir::toNativeSeparators(qt->binPath().toString())));
return false;
}
- params->setCommand(Utils::FilePath::fromString(windeployqtPath));
- params->setArguments(args);
+ params->setCommandLine(windeployqt);
params->setEnvironment(buildConfiguration()->environment());
return AbstractProcessStep::init();
diff --git a/src/plugins/winrt/winrtplugin.cpp b/src/plugins/winrt/winrtplugin.cpp
index 18293783dd..c42cde7c17 100644
--- a/src/plugins/winrt/winrtplugin.cpp
+++ b/src/plugins/winrt/winrtplugin.cpp
@@ -56,6 +56,19 @@ public:
WinRtDeviceFactory localDeviceFactory{Constants::WINRT_DEVICE_TYPE_LOCAL};
WinRtDeviceFactory phoneDeviceFactory{Constants::WINRT_DEVICE_TYPE_PHONE};
WinRtDeviceFactory emulatorDeviceFactory{Constants::WINRT_DEVICE_TYPE_EMULATOR};
+
+ RunWorkerFactory runWorkerFactory{
+ RunWorkerFactory::make<WinRtRunner>(),
+ {ProjectExplorer::Constants::NORMAL_RUN_MODE},
+ {runConfigFactory.id()}
+ };
+
+ RunWorkerFactory debugWorkerFactory{
+ RunWorkerFactory::make<WinRtDebugSupport>(),
+ {ProjectExplorer::Constants::DEBUG_RUN_MODE},
+ {runConfigFactory.id()},
+ {Internal::Constants::WINRT_DEVICE_TYPE_LOCAL}
+ };
};
WinRtPlugin::~WinRtPlugin()
@@ -70,27 +83,6 @@ bool WinRtPlugin::initialize(const QStringList &arguments, QString *errorMessage
d = new WinRtPluginPrivate;
- auto runConstraint = [](RunConfiguration *runConfig) {
- IDevice::ConstPtr device = DeviceKitAspect::device(runConfig->target()->kit());
- if (!device)
- return false;
- return qobject_cast<WinRtRunConfiguration *>(runConfig) != nullptr;
- };
-
- auto debugConstraint = [](RunConfiguration *runConfig) {
- IDevice::ConstPtr device = DeviceKitAspect::device(runConfig->target()->kit());
- if (!device)
- return false;
- if (device->type() != Internal::Constants::WINRT_DEVICE_TYPE_LOCAL)
- return false;
- return qobject_cast<WinRtRunConfiguration *>(runConfig) != nullptr;
- };
-
- RunControl::registerWorker<WinRtRunner>
- (ProjectExplorer::Constants::NORMAL_RUN_MODE, runConstraint);
- RunControl::registerWorker<WinRtDebugSupport>
- (ProjectExplorer::Constants::DEBUG_RUN_MODE, debugConstraint);
-
return true;
}
diff --git a/src/plugins/winrt/winrtrunnerhelper.cpp b/src/plugins/winrt/winrtrunnerhelper.cpp
index 3ab8461f32..69d718e575 100644
--- a/src/plugins/winrt/winrtrunnerhelper.cpp
+++ b/src/plugins/winrt/winrtrunnerhelper.cpp
@@ -69,12 +69,11 @@ WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunWorker *runWorker, QStr
return;
}
- const BuildTargetInfo bti = runControl->buildTargetInfo();
- m_executableFilePath = bti.targetFilePath.toString();
+ m_executableFilePath = runControl->targetFilePath().toString();
if (m_executableFilePath.isEmpty()) {
- *errorMessage = tr("Cannot determine the executable file path for \"%1\".").arg(
- QDir::toNativeSeparators(bti.projectFilePath.toString()));
+ *errorMessage = tr("Cannot determine the executable file path for \"%1\".")
+ .arg(runControl->projectFilePath().toUserOutput());
return;
}
@@ -94,11 +93,11 @@ WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunWorker *runWorker, QStr
if (auto aspect = runControl->aspect<LoopbackExemptServerAspect>())
loopbackExemptServer = aspect->value();
if (loopbackExemptClient && loopbackExemptServer)
- m_loopbackArguments = "--loopbackexempt clientserver";
+ m_loopbackArguments = QStringList{"--loopbackexempt", "clientserver"};
else if (loopbackExemptClient)
- m_loopbackArguments = "--loopbackexempt client";
+ m_loopbackArguments = QStringList{"--loopbackexempt", "client"};
else if (loopbackExemptServer)
- m_loopbackArguments = "--loopbackexempt server";
+ m_loopbackArguments = QStringList{"--loopbackexempt", "server"};
if (BuildConfiguration *bc = runControl->target()->activeBuildConfiguration())
m_environment = bc->environment();
@@ -190,29 +189,29 @@ void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
}
Q_FALLTHROUGH();
case Start:
- cmdLine.addArgs("--start --stop --wait 0");
+ cmdLine.addArgs({"--start", "--stop", "--wait", "0"});
connectProcess = true;
QTC_ASSERT(!m_process, m_process->deleteLater());
m_process = new QtcProcess(this);
process = m_process;
break;
case Stop:
- cmdLine.addArgs("--stop");
+ cmdLine.addArg("--stop");
process = new QtcProcess(this);
break;
}
if (m_device->type() == Constants::WINRT_DEVICE_TYPE_LOCAL)
- cmdLine.addArgs("--profile appx");
+ cmdLine.addArgs({"--profile", "appx"});
else if (m_device->type() == Constants::WINRT_DEVICE_TYPE_PHONE ||
m_device->type() == Constants::WINRT_DEVICE_TYPE_EMULATOR)
- cmdLine.addArgs("--profile appxphone");
+ cmdLine.addArgs({"--profile", "appxphone"});
cmdLine.addArgs(m_loopbackArguments);
cmdLine.addArg(m_executableFilePath);
- cmdLine.addArgs(m_arguments);
+ cmdLine.addArgs(m_arguments, CommandLine::Raw);
- appendMessage("winrtrunner " + cmdLine.arguments() + '\n', NormalMessageFormat);
+ appendMessage(cmdLine.toUserOutput(), NormalMessageFormat);
if (connectProcess) {
connect(process, &QProcess::started, this, &WinRtRunnerHelper::started);
diff --git a/src/plugins/winrt/winrtrunnerhelper.h b/src/plugins/winrt/winrtrunnerhelper.h
index f900dd1772..785946e985 100644
--- a/src/plugins/winrt/winrtrunnerhelper.h
+++ b/src/plugins/winrt/winrtrunnerhelper.h
@@ -77,7 +77,7 @@ private:
QString m_debuggerExecutable;
QString m_debuggerArguments;
QString m_arguments;
- QString m_loopbackArguments;
+ QStringList m_loopbackArguments;
bool m_uninstallAfterStop = false;
Utils::QtcProcess *m_process = nullptr;
};
diff --git a/src/shared/designerintegrationv2/CMakeLists.txt b/src/shared/designerintegrationv2/CMakeLists.txt
index a3bdb4c50a..0298277a16 100644
--- a/src/shared/designerintegrationv2/CMakeLists.txt
+++ b/src/shared/designerintegrationv2/CMakeLists.txt
@@ -1,8 +1,12 @@
-add_library(designerintegrationv2 STATIC
+if (NOT TARGET Qt5::Designer)
+ return()
+endif()
+
+add_qtc_library(designerintegrationv2 STATIC
+ DEPENDS Qt5::Designer
+ SOURCES
formresizer.cpp formresizer.h
sizehandlerect.cpp sizehandlerect.h
widgethostconstants.h
widgethost.cpp widgethost.h
)
-target_link_libraries(designerintegrationv2 PUBLIC Qt5::Designer)
-target_include_directories(designerintegrationv2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
diff --git a/src/shared/designerintegrationv2/formresizer.cpp b/src/shared/designerintegrationv2/formresizer.cpp
index a88f0ac6e3..34de90a477 100644
--- a/src/shared/designerintegrationv2/formresizer.cpp
+++ b/src/shared/designerintegrationv2/formresizer.cpp
@@ -50,12 +50,13 @@ FormResizer::FormResizer(QWidget *parent) :
setBackgroundRole(QPalette::Base);
QVBoxLayout *handleLayout = new QVBoxLayout(this);
- handleLayout->setMargin(SELECTION_MARGIN);
+ handleLayout->setContentsMargins(SELECTION_MARGIN, SELECTION_MARGIN,
+ SELECTION_MARGIN, SELECTION_MARGIN);
handleLayout->addWidget(m_frame);
m_frame->setFrameStyle(QFrame::Panel | QFrame::Raised);
QVBoxLayout *layout = new QVBoxLayout(m_frame);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
// handles
m_handles.reserve(SizeHandleRect::Left);
for (int i = SizeHandleRect::LeftTop; i <= SizeHandleRect::Left; ++i) {
diff --git a/src/shared/designerintegrationv2/widgethost.cpp b/src/shared/designerintegrationv2/widgethost.cpp
index d4f18d30e2..ed7f2fb91d 100644
--- a/src/shared/designerintegrationv2/widgethost.cpp
+++ b/src/shared/designerintegrationv2/widgethost.cpp
@@ -66,7 +66,7 @@ void WidgetHost::setFormWindow(QDesignerFormWindowInterface *fw)
setBackgroundRole(QPalette::Base);
m_formWindow->setAutoFillBackground(true);
- m_formWindow->setBackgroundRole(QPalette::Background);
+ m_formWindow->setBackgroundRole(QPalette::Window);
connect(m_formResizer, &Internal::FormResizer::formWindowSizeChanged,
this, &WidgetHost::fwSizeWasChanged);
diff --git a/src/shared/help/CMakeLists.txt b/src/shared/help/CMakeLists.txt
index 6953123bee..442911b4b8 100644
--- a/src/shared/help/CMakeLists.txt
+++ b/src/shared/help/CMakeLists.txt
@@ -5,12 +5,18 @@ endif()
set(PLUGIN_SOURCE_DIR "${PROJECT_SOURCE_DIR}/src/plugins")
+get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+unset(autogen_suffix)
+if (isMultiConfig)
+ set(autogen_suffix "_$<CONFIG>")
+endif()
+
add_qtc_library(shared_help STATIC
DEPENDS Utils PUBLIC Qt5::Help Qt5::PrintSupport Qt5::Widgets
PUBLIC_INCLUDES
"${PLUGIN_SOURCE_DIR}/help"
"${PLUGIN_SOURCE_DIR}"
- "${CMAKE_CURRENT_BINARY_DIR}/shared_help_autogen/include"
+ "${CMAKE_CURRENT_BINARY_DIR}/shared_help_autogen/include${autogen_suffix}"
"${CMAKE_CURRENT_BINARY_DIR}/"
SOURCES
bookmarkdialog.ui
diff --git a/src/shared/help/bookmarkmanager.cpp b/src/shared/help/bookmarkmanager.cpp
index dc19b8e92a..7f652b41cf 100644
--- a/src/shared/help/bookmarkmanager.cpp
+++ b/src/shared/help/bookmarkmanager.cpp
@@ -411,7 +411,7 @@ void BookmarkWidget::setup()
regExp.setCaseSensitivity(Qt::CaseInsensitive);
QLayout *vlayout = new QVBoxLayout(this);
- vlayout->setMargin(0);
+ vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setSpacing(0);
searchField = new Utils::FancyLineEdit(this);
@@ -421,7 +421,7 @@ void BookmarkWidget::setup()
Utils::StyledBar *toolbar = new Utils::StyledBar(this);
toolbar->setSingleRow(false);
QLayout *tbLayout = new QHBoxLayout();
- tbLayout->setMargin(4);
+ tbLayout->setContentsMargins(4, 4, 4, 4);
tbLayout->addWidget(searchField);
toolbar->setLayout(tbLayout);
diff --git a/src/shared/help/contentwindow.cpp b/src/shared/help/contentwindow.cpp
index e50a47c25d..16f7aaccbd 100644
--- a/src/shared/help/contentwindow.cpp
+++ b/src/shared/help/contentwindow.cpp
@@ -56,7 +56,7 @@ ContentWindow::ContentWindow()
setFocusProxy(m_contentWidget);
QVBoxLayout *layout = new QVBoxLayout(this);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_contentWidget);
connect(m_contentWidget, &QWidget::customContextMenuRequested,
diff --git a/src/shared/help/indexwindow.cpp b/src/shared/help/indexwindow.cpp
index 5139c8574d..324a071ab6 100644
--- a/src/shared/help/indexwindow.cpp
+++ b/src/shared/help/indexwindow.cpp
@@ -69,14 +69,14 @@ IndexWindow::IndexWindow()
QLabel *l = new QLabel(tr("&Look for:"));
l->setBuddy(m_searchLineEdit);
layout->addWidget(l);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
Utils::StyledBar *toolbar = new Utils::StyledBar(this);
toolbar->setSingleRow(false);
QLayout *tbLayout = new QHBoxLayout();
tbLayout->setSpacing(6);
- tbLayout->setMargin(4);
+ tbLayout->setContentsMargins(4, 4, 4, 4);
tbLayout->addWidget(l);
tbLayout->addWidget(m_searchLineEdit);
toolbar->setLayout(tbLayout);
diff --git a/src/shared/modeltest/modeltest.cpp b/src/shared/modeltest/modeltest.cpp
index 2dfb296b46..75000e9f3b 100644
--- a/src/shared/modeltest/modeltest.cpp
+++ b/src/shared/modeltest/modeltest.cpp
@@ -458,7 +458,7 @@ void ModelTest::data()
*/
void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
{
- Q_UNUSED(end);
+ Q_UNUSED(end)
Changing c;
c.parent = parent;
c.oldSize = model->rowCount(parent);
diff --git a/src/shared/proparser/registry.cpp b/src/shared/proparser/registry.cpp
index 12c268ae2b..8320cd3e59 100644
--- a/src/shared/proparser/registry.cpp
+++ b/src/shared/proparser/registry.cpp
@@ -148,9 +148,9 @@ QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned l
RegCloseKey(handle);
#else
- Q_UNUSED(parentHandle);
+ Q_UNUSED(parentHandle)
Q_UNUSED(rSubkey)
- Q_UNUSED(options);
+ Q_UNUSED(options)
#endif
return result;
diff --git a/src/shared/qtcreator_gui_pch.h b/src/shared/qtcreator_gui_pch.h
index d6f5ec4383..b25dbf67b7 100644
--- a/src/shared/qtcreator_gui_pch.h
+++ b/src/shared/qtcreator_gui_pch.h
@@ -37,7 +37,6 @@
#include <QApplication>
#include <QBitmap>
#include <QCursor>
-#include <QDesktopWidget>
#include <QImage>
#include <QLayout>
#include <QPainter>
diff --git a/src/shared/registryaccess/registryaccess.cpp b/src/shared/registryaccess/registryaccess.cpp
index 728aa41d7e..d98d6ed0e3 100644
--- a/src/shared/registryaccess/registryaccess.cpp
+++ b/src/shared/registryaccess/registryaccess.cpp
@@ -101,7 +101,7 @@ bool openRegistryKey(HKEY category, // HKEY_LOCAL_MACHINE, etc.
AccessMode mode,
QString *errorMessage)
{
- Q_UNUSED(debuggerRegistryKeyC); // avoid warning from MinGW
+ Q_UNUSED(debuggerRegistryKeyC) // avoid warning from MinGW
REGSAM accessRights = KEY_READ;
if (readWrite)
diff --git a/src/shared/yaml-cpp/yaml-cpp_installation.pri b/src/shared/yaml-cpp/yaml-cpp_installation.pri
new file mode 100644
index 0000000000..acd9c9e080
--- /dev/null
+++ b/src/shared/yaml-cpp/yaml-cpp_installation.pri
@@ -0,0 +1,7 @@
+unix {
+ system(pkg-config yaml-cpp --atleast-version=0.5) {
+ EXTERNAL_YAML_CPP_FOUND = 1
+ EXTERNAL_YAML_CPP_LIBS = $$system(pkg-config yaml-cpp --libs)
+ EXTERNAL_YAML_CPP_CXXFLAGS = $$system(pkg-config yaml-cpp --cflags)
+ }
+}
diff --git a/src/tools/clangbackend/clangbackendmain.cpp b/src/tools/clangbackend/clangbackendmain.cpp
index 1e95db3ef3..76aff06d3b 100644
--- a/src/tools/clangbackend/clangbackendmain.cpp
+++ b/src/tools/clangbackend/clangbackendmain.cpp
@@ -57,25 +57,11 @@ QString processArguments(QCoreApplication &application)
}
#ifdef Q_OS_WIN
-struct MessageHandler {
- MessageHandler(QtMessageHandler handler)
- {
- defaultHandler = qInstallMessageHandler(handler);
- }
-
- ~MessageHandler()
- {
- qInstallMessageHandler(defaultHandler);
- }
-
- static QtMessageHandler defaultHandler;
-};
-
-QtMessageHandler MessageHandler::defaultHandler = nullptr;
-
-static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+extern "C" void OutputDebugStringW(const wchar_t* msg);
+static void messageOutput(QtMsgType type, const QMessageLogContext &/*context*/,
+ const QString &msg)
{
- MessageHandler::defaultHandler(type, context, msg);
+ OutputDebugStringW(msg.toStdWString().c_str());
std::wcout << msg.toStdWString() << std::endl;
if (type == QtFatalMsg)
abort();
@@ -85,7 +71,7 @@ static void messageOutput(QtMsgType type, const QMessageLogContext &context, con
int main(int argc, char *argv[])
{
#ifdef Q_OS_WIN
- MessageHandler messageHandler(&messageOutput);
+ qInstallMessageHandler(&messageOutput);
#endif
QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org"));
diff --git a/src/tools/clangbackend/source/clangfollowsymbol.cpp b/src/tools/clangbackend/source/clangfollowsymbol.cpp
index 27e8fb61e9..7ad610d41b 100644
--- a/src/tools/clangbackend/source/clangfollowsymbol.cpp
+++ b/src/tools/clangbackend/source/clangfollowsymbol.cpp
@@ -74,7 +74,7 @@ static SourceRangeContainer extractMatchingTokenRange(const Cursor &cursor,
static int getTokenIndex(CXTranslationUnit tu, const Tokens &tokens, uint line, uint column)
{
int tokenIndex = -1;
- for (int i = static_cast<int>(tokens.size() - 1); i >= 0; --i) {
+ for (int i = tokens.size() - 1; i >= 0; --i) {
const SourceRange range(tu, tokens[i].extent());
if (range.contains(line, column)) {
tokenIndex = i;
diff --git a/src/tools/clangbackend/source/clangjobqueue.cpp b/src/tools/clangbackend/source/clangjobqueue.cpp
index fab939c588..1be56b3b6c 100644
--- a/src/tools/clangbackend/source/clangjobqueue.cpp
+++ b/src/tools/clangbackend/source/clangjobqueue.cpp
@@ -239,9 +239,8 @@ JobRequests JobQueue::takeJobRequestsToRunNow()
using TranslationUnitIds = QSet<Utf8String>;
TranslationUnitIds translationUnitsScheduledForThisRun;
- QMutableVectorIterator<JobRequest> i(m_queue);
- while (i.hasNext()) {
- const JobRequest &request = i.next();
+ for (int pos = 0; pos < m_queue.size(); ++pos) {
+ const JobRequest &request = m_queue.at(pos);
try {
const Document &document = m_documents.document(request.filePath);
@@ -258,7 +257,7 @@ JobRequests JobQueue::takeJobRequestsToRunNow()
translationUnitsScheduledForThisRun.insert(id);
jobsToRun += request;
- i.remove();
+ m_queue.removeAt(pos--);
} catch (const std::exception &exception) {
qWarning() << "Error in Jobs::takeJobRequestsToRunNow for"
<< request << ":" << exception.what();
diff --git a/src/tools/clangbackend/source/clangreferencescollector.cpp b/src/tools/clangbackend/source/clangreferencescollector.cpp
index c5b39aa2cf..a750beac03 100644
--- a/src/tools/clangbackend/source/clangreferencescollector.cpp
+++ b/src/tools/clangbackend/source/clangreferencescollector.cpp
@@ -124,7 +124,7 @@ public:
ReferencesResult collect(uint line, uint column, bool localReferences = false) const;
private:
- bool pointsToIdentifier(uint line, uint column, unsigned *tokenIndex) const;
+ bool pointsToIdentifier(int line, int column, unsigned *tokenIndex) const;
bool matchesIdentifier(const Token &token, const Utf8String &identifier) const;
bool checkToken(unsigned index, const Utf8String &identifier, const Utf8String &usr) const;
@@ -141,9 +141,9 @@ ReferencesCollector::ReferencesCollector(CXTranslationUnit cxTranslationUnit)
{
}
-bool ReferencesCollector::pointsToIdentifier(uint line, uint column, unsigned *tokenIndex) const
+bool ReferencesCollector::pointsToIdentifier(int line, int column, unsigned *tokenIndex) const
{
- for (uint i = 0; i < m_tokens.size(); ++i) {
+ for (int i = 0; i < m_tokens.size(); ++i) {
const Token &token = m_tokens[i];
if (token.kind() == CXToken_Identifier && token.extent().contains(line, column)) {
*tokenIndex = i;
@@ -202,7 +202,7 @@ ReferencesResult ReferencesCollector::collect(uint line, uint column, bool local
const Token &token = m_tokens[index];
const Utf8String identifier = token.spelling();
- for (uint i = 0; i < m_tokens.size(); ++i) {
+ for (int i = 0; i < m_tokens.size(); ++i) {
if (checkToken(i, identifier, usr))
result.references.append(m_tokens[i].extent());
}
diff --git a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp
index 0d001ca3d4..36281674f7 100644
--- a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp
+++ b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp
@@ -269,7 +269,7 @@ Utf8String ToolTipInfoCollector::textForNamespaceAlias(const Cursor &cursor) con
Utf8String aliasedName;
// Start at 3 in order to skip these tokens: namespace X =
- for (uint i = 3; i < tokens.size(); ++i)
+ for (int i = 3; i < tokens.size(); ++i)
aliasedName += tokens[i].spelling();
return aliasedName;
diff --git a/src/tools/clangbackend/source/clangtranslationunitupdater.cpp b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp
index fdad057089..b70f828d8f 100644
--- a/src/tools/clangbackend/source/clangtranslationunitupdater.cpp
+++ b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp
@@ -113,7 +113,7 @@ void TranslationUnitUpdater::createTranslationUnitIfNeeded()
UnsavedFilesShallowArguments unsaved = m_in.unsavedFiles.shallowArguments();
m_parseErrorCode = clang_parseTranslationUnit2(m_cxIndex,
- NULL,
+ nullptr,
args.data(),
args.count(),
unsaved.data(),
diff --git a/src/tools/clangbackend/source/codecompleter.cpp b/src/tools/clangbackend/source/codecompleter.cpp
index 2db3fbe0f1..91a9ad69ba 100644
--- a/src/tools/clangbackend/source/codecompleter.cpp
+++ b/src/tools/clangbackend/source/codecompleter.cpp
@@ -94,7 +94,7 @@ static void replaceWithOpeningParen(UnsavedFile &file, uint line, uint column)
file.replaceAt(pos, 1, Utf8String("(", 1));
}
-CodeCompletions CodeCompleter::complete(uint line, uint column,
+CodeCompletions CodeCompleter::complete(int line, int column,
int funcNameStartLine,
int funcNameStartColumn)
{
diff --git a/src/tools/clangbackend/source/codecompleter.h b/src/tools/clangbackend/source/codecompleter.h
index 473404f03e..3fdab36b57 100644
--- a/src/tools/clangbackend/source/codecompleter.h
+++ b/src/tools/clangbackend/source/codecompleter.h
@@ -42,7 +42,7 @@ public:
CodeCompleter(const TranslationUnit &translationUnit,
const UnsavedFiles &unsavedFiles);
- CodeCompletions complete(uint line, uint column,
+ CodeCompletions complete(int line, int column,
int funcNameStartLine = -1,
int funcNameStartColumn = -1);
diff --git a/src/tools/clangbackend/source/sourcelocation.cpp b/src/tools/clangbackend/source/sourcelocation.cpp
index 70bb0e16aa..108173bf94 100644
--- a/src/tools/clangbackend/source/sourcelocation.cpp
+++ b/src/tools/clangbackend/source/sourcelocation.cpp
@@ -58,21 +58,21 @@ const Utf8String &SourceLocation::filePath() const
return m_filePath;
}
-uint SourceLocation::line() const
+int SourceLocation::line() const
{
if (!m_isEvaluated)
evaluate();
return m_line;
}
-uint SourceLocation::column() const
+int SourceLocation::column() const
{
if (!m_isEvaluated)
evaluate();
return m_column;
}
-uint SourceLocation::offset() const
+int SourceLocation::offset() const
{
if (!m_isEvaluated)
evaluate();
@@ -92,11 +92,15 @@ void SourceLocation::evaluate() const
CXFile cxFile;
+ unsigned line, column, offset;
clang_getFileLocation(m_cxSourceLocation,
&cxFile,
- &m_line,
- &m_column,
- &m_offset);
+ &line,
+ &column,
+ &offset);
+ m_line = line;
+ m_column = column;
+ m_offset = offset;
m_isFilePathNormalized = false;
if (!cxFile)
@@ -104,15 +108,14 @@ void SourceLocation::evaluate() const
m_filePath = ClangString(clang_getFileName(cxFile));
if (m_column > 1) {
- const uint lineStart = m_offset + 1 - m_column;
+ const int lineStart = m_offset + 1 - m_column;
const char *contents = clang_getFileContents(m_cxTranslationUnit, cxFile, nullptr);
if (!contents)
return;
// (1) column in SourceLocation is the actual column shown by CppEditor.
// (2) column in Clang is the utf8 byte offset from the beginning of the line.
// Here we convert column from (2) to (1).
- m_column = static_cast<uint>(QString::fromUtf8(&contents[lineStart],
- static_cast<int>(m_column) - 1).size()) + 1;
+ m_column = QString::fromUtf8(&contents[lineStart], m_column - 1).size() + 1;
}
}
diff --git a/src/tools/clangbackend/source/sourcelocation.h b/src/tools/clangbackend/source/sourcelocation.h
index 63a600a2a6..0c668c38de 100644
--- a/src/tools/clangbackend/source/sourcelocation.h
+++ b/src/tools/clangbackend/source/sourcelocation.h
@@ -54,9 +54,9 @@ public:
CXSourceLocation cxSourceLocation);
const Utf8String &filePath() const;
- uint line() const;
- uint column() const;
- uint offset() const;
+ int line() const;
+ int column() const;
+ int offset() const;
SourceLocationContainer toSourceLocationContainer() const;
@@ -71,9 +71,9 @@ private:
CXSourceLocation m_cxSourceLocation;
CXTranslationUnit m_cxTranslationUnit;
mutable Utf8String m_filePath;
- mutable uint m_line = 0;
- mutable uint m_column = 0;
- mutable uint m_offset = 0;
+ mutable int m_line = 0;
+ mutable int m_column = 0;
+ mutable int m_offset = 0;
mutable bool m_isFilePathNormalized = true;
mutable bool m_isEvaluated = false;
};
diff --git a/src/tools/clangbackend/source/sourcerange.cpp b/src/tools/clangbackend/source/sourcerange.cpp
index 413ddd77fa..7100122669 100644
--- a/src/tools/clangbackend/source/sourcerange.cpp
+++ b/src/tools/clangbackend/source/sourcerange.cpp
@@ -64,7 +64,7 @@ SourceLocation SourceRange::end() const
return {cxTranslationUnit, clang_getRangeEnd(cxSourceRange)};
}
-bool SourceRange::contains(unsigned line, unsigned column) const
+bool SourceRange::contains(int line, int column) const
{
const SourceLocation start_ = start();
const SourceLocation end_ = end();
diff --git a/src/tools/clangbackend/source/sourcerange.h b/src/tools/clangbackend/source/sourcerange.h
index d4887aee32..e21f32e9a6 100644
--- a/src/tools/clangbackend/source/sourcerange.h
+++ b/src/tools/clangbackend/source/sourcerange.h
@@ -49,7 +49,7 @@ public:
SourceLocation start() const;
SourceLocation end() const;
- bool contains(unsigned line, unsigned column) const;
+ bool contains(int line, int column) const;
SourceRangeContainer toSourceRangeContainer() const;
diff --git a/src/tools/clangbackend/source/token.cpp b/src/tools/clangbackend/source/token.cpp
index 0754f84317..f69497b989 100644
--- a/src/tools/clangbackend/source/token.cpp
+++ b/src/tools/clangbackend/source/token.cpp
@@ -99,12 +99,12 @@ std::vector<Cursor> Tokens::annotate() const
return cursors;
}
-const Token &Tokens::operator[](size_t index) const
+const Token &Tokens::operator[](int index) const
{
return m_tokens[index];
}
-Token &Tokens::operator[](size_t index)
+Token &Tokens::operator[](int index)
{
return m_tokens[index];
}
diff --git a/src/tools/clangbackend/source/token.h b/src/tools/clangbackend/source/token.h
index a2e3941061..ecfb42f6f4 100644
--- a/src/tools/clangbackend/source/token.h
+++ b/src/tools/clangbackend/source/token.h
@@ -72,9 +72,9 @@ public:
std::vector<Cursor> annotate() const;
- size_t size() const { return m_tokens.size(); }
- const Token &operator[](size_t index) const;
- Token &operator[](size_t index);
+ int size() const { return static_cast<int>(m_tokens.size()); }
+ const Token &operator[](int index) const;
+ Token &operator[](int index);
std::vector<Token>::const_iterator cbegin() const;
std::vector<Token>::const_iterator cend() const;
diff --git a/src/tools/clangbackend/source/unsavedfile.cpp b/src/tools/clangbackend/source/unsavedfile.cpp
index 25925ea308..df667a3630 100644
--- a/src/tools/clangbackend/source/unsavedfile.cpp
+++ b/src/tools/clangbackend/source/unsavedfile.cpp
@@ -61,7 +61,7 @@ Utf8String UnsavedFile::fileContent() const
return m_fileContent;
}
-uint UnsavedFile::toUtf8Position(uint line, uint column, bool *ok) const
+uint UnsavedFile::toUtf8Position(int line, int column, bool *ok) const
{
Utf8PositionFromLineColumn converter(m_fileContent.constData());
if (converter.find(line, column)) {
@@ -73,7 +73,7 @@ uint UnsavedFile::toUtf8Position(uint line, uint column, bool *ok) const
return 0;
}
-bool UnsavedFile::hasCharacterAt(uint line, uint column, char character) const
+bool UnsavedFile::hasCharacterAt(int line, int column, char character) const
{
bool positionIsOk = false;
const uint utf8Position = toUtf8Position(line, column, &positionIsOk);
@@ -81,7 +81,7 @@ bool UnsavedFile::hasCharacterAt(uint line, uint column, char character) const
return positionIsOk && hasCharacterAt(utf8Position, character);
}
-Utf8String UnsavedFile::lineRange(uint fromLine, uint toLine) const
+Utf8String UnsavedFile::lineRange(int fromLine, int toLine) const
{
if (fromLine > toLine)
return Utf8String();
diff --git a/src/tools/clangbackend/source/unsavedfile.h b/src/tools/clangbackend/source/unsavedfile.h
index 325139d240..58966dd9bb 100644
--- a/src/tools/clangbackend/source/unsavedfile.h
+++ b/src/tools/clangbackend/source/unsavedfile.h
@@ -44,9 +44,9 @@ public:
Utf8String fileContent() const;
// 1-based line and column
- uint toUtf8Position(uint line, uint column, bool *ok) const;
- bool hasCharacterAt(uint line, uint column, char character) const;
- Utf8String lineRange(uint fromLine, uint toLine) const;
+ uint toUtf8Position(int line, int column, bool *ok) const;
+ bool hasCharacterAt(int line, int column, char character) const;
+ Utf8String lineRange(int fromLine, int toLine) const;
// 0-based position
bool hasCharacterAt(uint position, char character) const;
diff --git a/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp b/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp
index 1d7ea1a88f..36f5747a5b 100644
--- a/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp
+++ b/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp
@@ -25,6 +25,8 @@
#include "utf8positionfromlinecolumn.h"
+#include <utils/textutils.h>
+
#include <QtGlobal>
namespace ClangBackEnd {
@@ -35,7 +37,7 @@ Utf8PositionFromLineColumn::Utf8PositionFromLineColumn(const char *utf8Text)
{
}
-bool Utf8PositionFromLineColumn::find(uint line, uint column)
+bool Utf8PositionFromLineColumn::find(int line, int column)
{
if (!m_utf8Text || *m_utf8Text == '\0' || line == 0 || column == 0)
return false;
@@ -49,12 +51,12 @@ uint Utf8PositionFromLineColumn::position() const
return m_previousByte - m_utf8Text;
}
-bool Utf8PositionFromLineColumn::advanceToLine(uint line)
+bool Utf8PositionFromLineColumn::advanceToLine(int line)
{
if (line == 1)
return true;
- uint currentLine = 1;
+ int currentLine = 1;
do {
if (*m_currentByte == '\n' && ++currentLine == line) {
advanceCodePoint();
@@ -65,7 +67,7 @@ bool Utf8PositionFromLineColumn::advanceToLine(uint line)
return false;
}
-bool Utf8PositionFromLineColumn::advanceToColumn(uint column)
+bool Utf8PositionFromLineColumn::advanceToColumn(int column)
{
while (column) {
if (advanceCodePoint(/*stopOnNewLine=*/ true))
@@ -77,31 +79,13 @@ bool Utf8PositionFromLineColumn::advanceToColumn(uint column)
return column == 0;
}
-static bool isByteOfMultiByteCodePoint(unsigned char byte)
-{
- return byte & 0x80; // Check if most significant bit is set
-}
-
bool Utf8PositionFromLineColumn::advanceCodePoint(bool stopOnNewLine)
{
if (Q_UNLIKELY(*m_currentByte == '\0') || (stopOnNewLine && *m_currentByte == '\n'))
return false;
m_previousByte = m_currentByte;
-
- // Process multi-byte UTF-8 code point (non-latin1)
- if (Q_UNLIKELY(isByteOfMultiByteCodePoint(*m_currentByte))) {
- unsigned trailingBytesCurrentCodePoint = 1;
- for (unsigned char c = (*m_currentByte) << 2; isByteOfMultiByteCodePoint(c); c <<= 1)
- ++trailingBytesCurrentCodePoint;
- m_currentByte += trailingBytesCurrentCodePoint + 1;
-
- // Process single-byte UTF-8 code point (latin1)
- } else {
- ++m_currentByte;
- }
-
- return true;
+ return Utils::Text::utf8AdvanceCodePoint(m_currentByte);
}
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/source/utf8positionfromlinecolumn.h b/src/tools/clangbackend/source/utf8positionfromlinecolumn.h
index facb152772..22f5b7ff54 100644
--- a/src/tools/clangbackend/source/utf8positionfromlinecolumn.h
+++ b/src/tools/clangbackend/source/utf8positionfromlinecolumn.h
@@ -35,20 +35,20 @@ public:
Utf8PositionFromLineColumn(const char *utf8Text);
// 1-based line and column
- bool find(uint line, uint column);
+ bool find(int line, int column);
uint position() const;
private:
- bool advanceToLine(uint line);
- bool advanceToColumn(uint column);
+ bool advanceToLine(int line);
+ bool advanceToColumn(int column);
bool advanceCodePoint(bool stopOnNewLine = false);
private:
- const char * const m_utf8Text = 0;
+ const char * const m_utf8Text = nullptr;
- const char *m_previousByte = 0;
- const char *m_currentByte = 0;
+ const char *m_previousByte = nullptr;
+ const char *m_currentByte = nullptr;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
index 5a634f8fe1..a4b5ec3b52 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -139,13 +139,13 @@ public:
using Processor = ClangBackEnd::PchCreator;
PchCreatorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
ClangBackEnd::Environment &environment,
- Sqlite::Database &database,
+ ClangBackEnd::FilePathCaching &filePathCache,
PchManagerServer &pchManagerServer,
ClangBackEnd::ClangPathWatcherInterface &pathWatcher,
ClangBackEnd::BuildDependenciesStorageInterface &buildDependenciesStorage)
: ProcessorManager(generatedFiles)
, m_environment(environment)
- , m_database(database)
+ , m_filePathCache(filePathCache)
, m_pchManagerServer(pchManagerServer)
, m_pathWatcher(pathWatcher)
, m_buildDependenciesStorage(buildDependenciesStorage)
@@ -155,7 +155,7 @@ protected:
std::unique_ptr<ClangBackEnd::PchCreator> createProcessor() const override
{
return std::make_unique<PchCreator>(m_environment,
- m_database,
+ m_filePathCache,
*m_pchManagerServer.client(),
m_pathWatcher,
m_buildDependenciesStorage);
@@ -163,7 +163,7 @@ protected:
private:
ClangBackEnd::Environment &m_environment;
- Sqlite::Database &m_database;
+ ClangBackEnd::FilePathCaching &m_filePathCache;
ClangBackEnd::PchManagerServer &m_pchManagerServer;
ClangBackEnd::ClangPathWatcherInterface &m_pathWatcher;
ClangBackEnd::BuildDependenciesStorageInterface &m_buildDependenciesStorage;
@@ -185,11 +185,16 @@ struct Data // because we have a cycle dependency
ApplicationEnvironment environment;
ProjectPartsStorage<> projectPartsStorage{database};
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
- ProjectPartsManager projectParts{projectPartsStorage, preCompiledHeaderStorage};
GeneratedFiles generatedFiles;
+ ProjectPartsManager projectParts{projectPartsStorage,
+ preCompiledHeaderStorage,
+ buildDependencyProvider,
+ filePathCache,
+ includeWatcher,
+ generatedFiles};
PchCreatorManager pchCreatorManager{generatedFiles,
environment,
- database,
+ filePathCache,
clangPchManagerServer,
includeWatcher,
buildDependencyStorage};
@@ -227,7 +232,8 @@ struct Data // because we have a cycle dependency
pchTaskGenerator,
projectParts,
generatedFiles,
- buildDependencyStorage};
+ buildDependencyStorage,
+ filePathCache};
TaskScheduler systemTaskScheduler{pchCreatorManager,
pchTaskQueue,
pchCreationProgressCounter,
@@ -241,8 +247,10 @@ struct Data // because we have a cycle dependency
};
#ifdef Q_OS_WIN
+extern "C" void OutputDebugStringW(const wchar_t* msg);
static void messageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg)
{
+ OutputDebugStringW(msg.toStdWString().c_str());
std::wcout << msg.toStdWString() << std::endl;
if (type == QtFatalMsg)
abort();
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
index c2e3b4a5f9..9e0f62bc7d 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
@@ -55,21 +55,24 @@ OutputContainer setUnion(InputContainer1 &&input1,
BuildDependency BuildDependenciesProvider::create(const ProjectPartContainer &projectPart)
{
- m_ensureAliveMessageIsSentCallback();
+ return create(projectPart,
+ createSourceEntriesFromStorage(projectPart.sourcePathIds, projectPart.projectPartId));
+}
- auto sourcesAndProjectPart = createSourceEntriesFromStorage(projectPart.sourcePathIds,
- projectPart.projectPartId);
+BuildDependency BuildDependenciesProvider::create(const ProjectPartContainer &projectPart,
+ SourceEntries &&sourceEntries)
+{
+ m_ensureAliveMessageIsSentCallback();
- if (!m_modifiedTimeChecker.isUpToDate(sourcesAndProjectPart.first)) {
+ if (!m_modifiedTimeChecker.isUpToDate(sourceEntries)) {
BuildDependency buildDependency = m_generator.create(projectPart);
- storeBuildDependency(buildDependency, sourcesAndProjectPart.second);
+ storeBuildDependency(buildDependency, projectPart.projectPartId);
return buildDependency;
}
- return createBuildDependencyFromStorage(
- std::move(sourcesAndProjectPart.first));
+ return createBuildDependencyFromStorage(std::move(sourceEntries));
}
BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(
@@ -103,7 +106,7 @@ UsedMacros BuildDependenciesProvider::createUsedMacrosFromStorage(const SourceEn
return usedMacros;
}
-std::pair<SourceEntries, ProjectPartId> BuildDependenciesProvider::createSourceEntriesFromStorage(
+SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage(
const FilePathIds &sourcePathIds, ProjectPartId projectPartId) const
{
SourceEntries includes;
@@ -119,7 +122,7 @@ std::pair<SourceEntries, ProjectPartId> BuildDependenciesProvider::createSourceE
transaction.commit();
- return {includes, projectPartId};
+ return includes;
}
void BuildDependenciesProvider::storeBuildDependency(const BuildDependency &buildDependency,
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
index 924e3e4f45..765ba98a68 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
@@ -52,17 +52,20 @@ public:
{}
BuildDependency create(const ProjectPartContainer &projectPart) override;
+ BuildDependency create(const ProjectPartContainer &projectPart,
+ SourceEntries &&sourceEntries) override;
void setEnsureAliveMessageIsSentCallback(std::function<void()> &&callback)
{
m_ensureAliveMessageIsSentCallback = std::move(callback);
}
+ SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds,
+ ProjectPartId projectPartId) const override;
+
private:
BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const;
UsedMacros createUsedMacrosFromStorage(const SourceEntries &includes) const;
- std::pair<SourceEntries, ProjectPartId> createSourceEntriesFromStorage(
- const FilePathIds &sourcePathIds, ProjectPartId projectPartId) const;
void storeBuildDependency(const BuildDependency &buildDependency, ProjectPartId projectPartId);
private:
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h
index 7af8c054cc..7b5e9342b6 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h
@@ -35,6 +35,9 @@ class BuildDependenciesProviderInterface
{
public:
virtual BuildDependency create(const ProjectPartContainer &projectPart) = 0;
+ virtual BuildDependency create(const ProjectPartContainer &projectPart, SourceEntries &&sourceEntries) = 0;
+ virtual SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds,
+ ProjectPartId projectPartId) const = 0;
protected:
~BuildDependenciesProviderInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
index f75d83b572..aac518af5a 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
@@ -177,11 +177,12 @@ public:
}
}
- void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) override
+ void insertOrUpdateIndexingTimeStampsWithoutTransaction(const FilePathIds &filePathIds,
+ TimeStamp indexingTimeStamp) override
{
- for (FileStatus fileStatus : fileStatuses) {
- inserOrUpdateIndexingTimesStampStatement.write(fileStatus.filePathId.filePathId,
- fileStatus.lastModified);
+ for (FilePathId filePathId : filePathIds) {
+ inserOrUpdateIndexingTimesStampStatement.write(filePathId.filePathId,
+ indexingTimeStamp.value);
}
}
@@ -393,7 +394,8 @@ public:
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT "
"dependencySourceId FROM sourceDependencies, collectedDependencies WHERE "
"sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT DISTINCT sourceId, "
- "indexingTimeStamp FROM collectedDependencies NATURAL JOIN fileStatuses ORDER BY sourceId",
+ "indexingTimeStamp FROM collectedDependencies NATURAL LEFT JOIN fileStatuses ORDER BY "
+ "sourceId",
database};
mutable ReadStatement fetchIndexingTimeStampsStatement{
"SELECT sourceId, indexingTimeStamp FROM fileStatuses", database};
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
index 953f2cca42..c4d102246e 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
@@ -59,7 +59,9 @@ public:
virtual FilePathIds fetchPchSources(ProjectPartId projectPartId) const = 0;
virtual FilePathIds fetchSources(ProjectPartId projectPartId) const = 0;
virtual void insertOrUpdateIndexingTimeStamps(const FilePathIds &filePathIds, TimeStamp indexingTimeStamp) = 0;
- virtual void insertOrUpdateIndexingTimeStamps(const FileStatuses &fileStatuses) = 0;
+ virtual void insertOrUpdateIndexingTimeStampsWithoutTransaction(const FilePathIds &filePathIds,
+ TimeStamp indexingTimeStamp)
+ = 0;
virtual SourceTimeStamps fetchIndexingTimeStamps() const = 0;
virtual SourceTimeStamps fetchIncludedIndexingTimeStamps(FilePathId sourcePathId) const = 0;
virtual FilePathIds fetchDependentSourceIds(const FilePathIds &sourcePathIds) const = 0;
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
index 46562c39a9..f9e94fc14f 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -112,7 +112,7 @@ Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTas
return builder.commandLine;
}
-FilePathIds PchCreator::existingSources(FilePathIds sources) const
+FilePathIds PchCreator::existingSources(const FilePathIds &sources) const
{
FilePathIds existingSources;
existingSources.reserve(sources.size());
@@ -196,19 +196,22 @@ void PchCreator::doInMainThreadAfterFinished()
if (m_projectPartPch.projectPartId.isValid()) {
m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified,
m_projectPartPch.projectPartId);
- m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::Source},
- existingSources(m_watchedSources)}});
- m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::UserInclude},
- existingSources(m_watchedUserIncludes)}});
- m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::ProjectInclude},
- existingSources(m_watchedProjectIncludes)}});
- m_clangPathwatcher.updateIdPaths({{{m_projectPartPch.projectPartId, SourceType::SystemInclude},
- existingSources(m_watchedSystemIncludes)}});
+ m_clangPathwatcher.updateIdPaths(
+ {{m_projectPartPch.projectPartId, SourceType::Source, existingSources(m_watchedSources)},
+ {m_projectPartPch.projectPartId,
+ SourceType::UserInclude,
+ existingSources(m_watchedUserIncludes)},
+ {m_projectPartPch.projectPartId,
+ SourceType::ProjectInclude,
+ existingSources(m_watchedProjectIncludes)},
+ {m_projectPartPch.projectPartId,
+ SourceType::SystemInclude,
+ existingSources(m_watchedSystemIncludes)}});
m_pchManagerClient.precompiledHeadersUpdated(m_projectPartPch.projectPartId);
}
}
-const FilePathCaching &PchCreator::filePathCache()
+const FilePathCachingInterface &PchCreator::filePathCache()
{
return m_filePathCache;
}
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h
index c30e011011..af8bf8bfdd 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h
@@ -54,14 +54,16 @@ class PchCreator final : public PchCreatorInterface
{
public:
PchCreator(Environment &environment,
- Sqlite::Database &database,
+ FilePathCaching &filePathCache,
PchManagerClientInterface &pchManagerClient,
ClangPathWatcherInterface &clangPathwatcher,
BuildDependenciesStorageInterface &buildDependenciesStorage)
- : m_filePathCache(database), m_environment(environment),
- m_pchManagerClient(pchManagerClient),
- m_clangPathwatcher(clangPathwatcher),
- m_buildDependenciesStorage(buildDependenciesStorage) {}
+ : m_filePathCache(filePathCache)
+ , m_environment(environment)
+ , m_pchManagerClient(pchManagerClient)
+ , m_clangPathwatcher(clangPathwatcher)
+ , m_buildDependenciesStorage(buildDependenciesStorage)
+ {}
void generatePch(PchTask &&pchTask) override;
const ProjectPartPch &projectPartPch() override;
@@ -71,7 +73,7 @@ public:
void clear() override;
void doInMainThreadAfterFinished() override;
- const FilePathCaching &filePathCache();
+ const FilePathCachingInterface &filePathCache();
Utils::SmallString generatePchIncludeFileContent(const FilePathIds &includeIds) const;
bool generatePch(NativeFilePathView path, Utils::SmallStringView content);
@@ -82,7 +84,7 @@ public:
const ClangTool &clangTool() const { return m_clangTool; }
- FilePathIds existingSources(FilePathIds sources) const;
+ FilePathIds existingSources(const FilePathIds &sources) const;
const FilePathIds &watchedSystemIncludes() const { return m_watchedSystemIncludes; }
const FilePathIds &watchedProjectIncludes() const { return m_watchedProjectIncludes; }
@@ -93,7 +95,7 @@ private:
mutable std::mt19937_64 randomNumberGenator{std::random_device{}()};
ClangTool m_clangTool;
ProjectPartPch m_projectPartPch;
- FilePathCaching m_filePathCache;
+ CopyableFilePathCaching m_filePathCache;
FilePathIds m_watchedSystemIncludes;
FilePathIds m_watchedProjectIncludes;
FilePathIds m_watchedUserIncludes;
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
index ec0d89d2c6..fa69cd56ca 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
@@ -26,6 +26,8 @@
#include "pchmanagerserver.h"
#include <builddependenciesstorage.h>
+#include <filepathcachinginterface.h>
+#include <filepathview.h>
#include <pchmanagerclientinterface.h>
#include <pchtaskgeneratorinterface.h>
#include <precompiledheadersupdatedmessage.h>
@@ -39,6 +41,7 @@
#include <utils/smallstring.h>
#include <QApplication>
+#include <QDirIterator>
#include <algorithm>
@@ -48,12 +51,14 @@ PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
PchTaskGeneratorInterface &pchTaskGenerator,
ProjectPartsManagerInterface &projectParts,
GeneratedFilesInterface &generatedFiles,
- BuildDependenciesStorageInterface &buildDependenciesStorage)
+ BuildDependenciesStorageInterface &buildDependenciesStorage,
+ FilePathCachingInterface &filePathCache)
: m_fileSystemWatcher(fileSystemWatcher)
, m_pchTaskGenerator(pchTaskGenerator)
, m_projectPartsManager(projectParts)
, m_generatedFiles(generatedFiles)
, m_buildDependenciesStorage(buildDependenciesStorage)
+ , m_filePathCache(filePathCache)
{
m_fileSystemWatcher.setNotifier(this);
}
@@ -70,19 +75,56 @@ ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectParts)
return projectPart.projectPartId;
});
}
+
+FilePaths gatherPathsInIncludePaths(const ProjectPartContainers &projectParts)
+{
+ FilePaths filePaths;
+
+ for (const ProjectPartContainer &projectPart : projectParts) {
+ for (const IncludeSearchPath &searchPath : projectPart.projectIncludeSearchPaths) {
+ QDirIterator directoryIterator(QString{searchPath.path},
+ {"*.h", "*.hpp"},
+ QDir::Files,
+ QDirIterator::FollowSymlinks
+ | QDirIterator::Subdirectories);
+ while (directoryIterator.hasNext()) {
+ filePaths.emplace_back(directoryIterator.next());
+ }
+ }
+ for (const IncludeSearchPath &searchPath : projectPart.systemIncludeSearchPaths) {
+ QDirIterator directoryIterator(QString{searchPath.path},
+ {"*.h", "*.hpp"},
+ QDir::Files,
+ QDirIterator::FollowSymlinks);
+ while (directoryIterator.hasNext()) {
+ filePaths.emplace_back(directoryIterator.next());
+ }
+ }
+ }
+
+ return filePaths;
+}
+
} // namespace
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
{
+ m_filePathCache.populateIfEmpty();
+
+ m_filePathCache.addFilePaths(gatherPathsInIncludePaths(message.projectsParts));
+
m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
auto upToDateProjectParts = m_projectPartsManager.update(message.takeProjectsParts());
if (m_generatedFiles.isValid()) {
- m_pchTaskGenerator.addProjectParts(std::move(upToDateProjectParts.notUpToDate),
- std::move(message.toolChainArguments));
+ m_pchTaskGenerator.addProjectParts(std::move(upToDateProjectParts.updateSystem),
+ message.toolChainArguments.clone());
+ m_pchTaskGenerator.addNonSystemProjectParts(std::move(upToDateProjectParts.updateProject),
+ std::move(message.toolChainArguments));
} else {
- m_projectPartsManager.updateDeferred(upToDateProjectParts.notUpToDate);
+ m_projectPartsManager.updateDeferred(std::move(upToDateProjectParts.updateSystem),
+ std::move(upToDateProjectParts.updateProject));
}
client()->precompiledHeadersUpdated(toProjectPartIds(upToDateProjectParts.upToDate));
@@ -119,13 +161,21 @@ void PchManagerServer::updateGeneratedFiles(UpdateGeneratedFilesMessage &&messag
m_generatedFiles.update(message.takeGeneratedFiles());
if (m_generatedFiles.isValid()) {
- ProjectPartContainers deferredProjectParts = m_projectPartsManager.deferredUpdates();
- ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(
- projectPartIds(deferredProjectParts));
+ ProjectPartContainers deferredSystems = m_projectPartsManager.deferredSystemUpdates();
+ ArgumentsEntries systemEntries = m_toolChainsArgumentsCache.arguments(
+ projectPartIds(deferredSystems));
+
+ for (ArgumentsEntry &entry : systemEntries) {
+ m_pchTaskGenerator.addProjectParts(std::move(deferredSystems), std::move(entry.arguments));
+ }
+
+ ProjectPartContainers deferredProjects = m_projectPartsManager.deferredProjectUpdates();
+ ArgumentsEntries projectEntries = m_toolChainsArgumentsCache.arguments(
+ projectPartIds(deferredProjects));
- for (ArgumentsEntry &entry : entries) {
- m_pchTaskGenerator.addProjectParts(std::move(deferredProjectParts),
- std::move(entry.arguments));
+ for (ArgumentsEntry &entry : projectEntries) {
+ m_pchTaskGenerator.addNonSystemProjectParts(std::move(deferredProjects),
+ std::move(entry.arguments));
}
}
}
@@ -220,7 +270,7 @@ void PchManagerServer::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths)
void PchManagerServer::pathsChanged(const FilePathIds &filePathIds)
{
- m_buildDependenciesStorage.insertOrUpdateIndexingTimeStamps(filePathIds, 0);
+ m_buildDependenciesStorage.insertOrUpdateIndexingTimeStamps(filePathIds, -1);
}
void PchManagerServer::setPchCreationProgress(int progress, int total)
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
index c8e5be4de5..7b1187d5f4 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
@@ -40,6 +40,7 @@ namespace ClangBackEnd {
class SourceRangesAndDiagnosticsForQueryMessage;
class PchTaskGeneratorInterface;
class BuildDependenciesStorageInterface;
+class FilePathCachingInterface;
class PchManagerServer : public PchManagerServerInterface,
public ClangPathWatcherNotifier,
@@ -51,7 +52,8 @@ public:
PchTaskGeneratorInterface &pchTaskGenerator,
ProjectPartsManagerInterface &projectParts,
GeneratedFilesInterface &generatedFiles,
- BuildDependenciesStorageInterface &buildDependenciesStorage);
+ BuildDependenciesStorageInterface &buildDependenciesStorage,
+ FilePathCachingInterface &filePathCache);
void end() override;
void updateProjectParts(UpdateProjectPartsMessage &&message) override;
@@ -76,6 +78,7 @@ private:
GeneratedFilesInterface &m_generatedFiles;
BuildDependenciesStorageInterface &m_buildDependenciesStorage;
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
+ FilePathCachingInterface &m_filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp
index b9d6a48fe3..7a6e29c584 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp
@@ -153,7 +153,8 @@ std::vector<PchTaskQueue::Task> PchTaskQueue::createProjectTasks(PchTasks &&pchT
pchCreator.generatePch(std::move(pchTask));
const auto &projectPartPch = pchCreator.projectPartPch();
if (projectPartPch.pchPath.empty()) {
- m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId);
+ m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId,
+ projectPartPch.lastModified);
} else {
m_precompiledHeaderStorage.insertProjectPrecompiledHeader(
projectPartId, projectPartPch.pchPath, projectPartPch.lastModified);
diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
index 5510376fd5..d781c96e52 100644
--- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
+++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
@@ -50,14 +50,14 @@ public:
void insertProjectPrecompiledHeader(ProjectPartId projectPartId,
Utils::SmallStringView pchPath,
- long long pchBuildTime) override
+ TimeStamp pchBuildTime) override
{
try {
Sqlite::ImmediateTransaction transaction{database};
insertProjectPrecompiledHeaderStatement.write(projectPartId.projectPathId,
pchPath,
- pchBuildTime);
+ pchBuildTime.value);
transaction.commit();
} catch (const Sqlite::StatementIsBusy &) {
@@ -65,16 +65,17 @@ public:
}
}
- void deleteProjectPrecompiledHeader(ProjectPartId projectPartId) override
+ void deleteProjectPrecompiledHeader(ProjectPartId projectPartId, TimeStamp pchBuildTime) override
{
try {
Sqlite::ImmediateTransaction transaction{database};
- deleteProjectPrecompiledHeaderStatement.write(projectPartId.projectPathId);
+ deleteProjectPrecompiledHeaderPathAndSetBuildTimeStatement.write(projectPartId.projectPathId,
+ pchBuildTime.value);
transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
- deleteProjectPrecompiledHeader(projectPartId);
+ deleteProjectPrecompiledHeader(projectPartId, pchBuildTime);
}
}
@@ -94,7 +95,7 @@ public:
void insertSystemPrecompiledHeaders(const ProjectPartIds &projectPartIds,
Utils::SmallStringView pchPath,
- long long pchBuildTime) override
+ TimeStamp pchBuildTime) override
{
try {
Sqlite::ImmediateTransaction transaction{database};
@@ -102,7 +103,7 @@ public:
for (ProjectPartId projectPartId : projectPartIds) {
insertSystemPrecompiledHeaderStatement.write(projectPartId.projectPathId,
pchPath,
- pchBuildTime);
+ pchBuildTime.value);
}
transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
@@ -124,6 +125,20 @@ public:
}
}
+ void deleteSystemAndProjectPrecompiledHeaders(const ProjectPartIds &projectPartIds) override
+ {
+ try {
+ Sqlite::ImmediateTransaction transaction{database};
+
+ for (ProjectPartId projectPartId : projectPartIds)
+ deleteSystemAndProjectPrecompiledHeaderStatement.write(projectPartId.projectPathId);
+
+ transaction.commit();
+ } catch (const Sqlite::StatementIsBusy) {
+ deleteSystemAndProjectPrecompiledHeaders(projectPartIds);
+ }
+ }
+
FilePath fetchSystemPrecompiledHeaderPath(ProjectPartId projectPartId) override
{
try {
@@ -132,10 +147,11 @@ public:
auto value = fetchSystemPrecompiledHeaderPathStatement.template value<FilePath>(
projectPartId.projectPathId);
+ transaction.commit();
+
if (value)
return *value;
- transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
return fetchSystemPrecompiledHeaderPath(projectPartId);
}
@@ -151,10 +167,11 @@ public:
auto value = fetchPrecompiledHeaderStatement.template value<FilePath>(
projectPartId.projectPathId);
+ transaction.commit();
+
if (value)
return *value;
- transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
return fetchPrecompiledHeader(projectPartId);
}
@@ -170,10 +187,11 @@ public:
auto value = fetchPrecompiledHeadersStatement.template value<PchPaths, 2>(
projectPartId.projectPathId);
+ transaction.commit();
+
if (value)
return *value;
- transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
return fetchPrecompiledHeaders(projectPartId);
}
@@ -181,6 +199,26 @@ public:
return {};
}
+ PrecompiledHeaderTimeStamps fetchTimeStamps(ProjectPartId projectPartId) const override
+ {
+ try {
+ Sqlite::DeferredTransaction transaction{database};
+
+ auto value = fetchTimeStampsStatement.template value<PrecompiledHeaderTimeStamps, 2>(
+ projectPartId.projectPathId);
+
+ transaction.commit();
+
+ if (value)
+ return *value;
+
+ } catch (const Sqlite::StatementIsBusy) {
+ return fetchTimeStamps(projectPartId);
+ }
+
+ return {};
+ }
+
public:
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
Database &database;
@@ -198,10 +236,19 @@ public:
"UPDATE OR IGNORE precompiledHeaders SET projectPchPath=NULL,projectPchBuildTime=NULL "
"WHERE projectPartId = ?",
database};
+ WriteStatement deleteProjectPrecompiledHeaderPathAndSetBuildTimeStatement{
+ "UPDATE OR IGNORE precompiledHeaders SET projectPchPath=NULL,projectPchBuildTime=?002 "
+ "WHERE projectPartId = ?001",
+ database};
WriteStatement deleteSystemPrecompiledHeaderStatement{
"UPDATE OR IGNORE precompiledHeaders SET systemPchPath=NULL,systemPchBuildTime=NULL "
"WHERE projectPartId = ?",
database};
+ WriteStatement deleteSystemAndProjectPrecompiledHeaderStatement{
+ "UPDATE OR IGNORE precompiledHeaders SET "
+ "systemPchPath=NULL,systemPchBuildTime=NULL,projectPchPath=NULL,projectPchBuildTime=NULL "
+ "WHERE projectPartId = ?",
+ database};
ReadStatement fetchSystemPrecompiledHeaderPathStatement{
"SELECT systemPchPath FROM precompiledHeaders WHERE projectPartId = ?", database};
mutable ReadStatement fetchPrecompiledHeaderStatement{
@@ -211,6 +258,10 @@ public:
mutable ReadStatement fetchPrecompiledHeadersStatement{
"SELECT projectPchPath, systemPchPath FROM precompiledHeaders WHERE projectPartId = ?",
database};
+ mutable ReadStatement fetchTimeStampsStatement{
+ "SELECT projectPchBuildTime, systemPchBuildTime FROM precompiledHeaders WHERE "
+ "projectPartId = ?",
+ database};
};
}
diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
index 2ce880cd6a..92b3604cdc 100644
--- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
@@ -29,6 +29,7 @@
#include <pchpaths.h>
#include <projectpartid.h>
+#include <sourceentry.h>
#include <utils/smallstringvector.h>
#include <utils/optional.h>
@@ -45,18 +46,20 @@ public:
virtual void insertProjectPrecompiledHeader(ProjectPartId projectPartId,
Utils::SmallStringView pchPath,
- long long pchBuildTime)
+ TimeStamp pchBuildTime)
= 0;
- virtual void deleteProjectPrecompiledHeader(ProjectPartId projectPartId) = 0;
+ virtual void deleteProjectPrecompiledHeader(ProjectPartId projectPartId, TimeStamp pchBuildTime) = 0;
virtual void deleteProjectPrecompiledHeaders(const ProjectPartIds &projectPartIds) = 0;
virtual void insertSystemPrecompiledHeaders(const ProjectPartIds &projectPartIds,
Utils::SmallStringView pchPath,
- long long pchBuildTime)
+ TimeStamp pchBuildTime)
= 0;
virtual void deleteSystemPrecompiledHeaders(const ProjectPartIds &projectPartIds) = 0;
+ virtual void deleteSystemAndProjectPrecompiledHeaders(const ProjectPartIds &projectPartIds) = 0;
virtual FilePath fetchSystemPrecompiledHeaderPath(ProjectPartId projectPartId) = 0;
virtual FilePath fetchPrecompiledHeader(ProjectPartId projectPartId) const = 0;
virtual PchPaths fetchPrecompiledHeaders(ProjectPartId projectPartId) const = 0;
+ virtual PrecompiledHeaderTimeStamps fetchTimeStamps(ProjectPartId projectPartId) const = 0;
protected:
~PrecompiledHeaderStorageInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp
index 191a13e16b..307041ed2e 100644
--- a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp
@@ -25,9 +25,17 @@
#include "projectpartsmanager.h"
+#include <builddependenciesproviderinterface.h>
+#include <clangpathwatcherinterface.h>
+#include <filecontainerv2.h>
+#include <filepathcachinginterface.h>
+#include <generatedfilesinterface.h>
#include <projectpartcontainer.h>
+#include <set_algorithm.h>
+#include <usedmacrofilter.h>
#include <algorithm>
+#include <utils/algorithm.h>
namespace ClangBackEnd {
@@ -44,38 +52,211 @@ ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectsParts)
return ids;
}
+namespace {
+
+enum class Change { System, Project, No };
+
+Change changedSourceType(SourceEntry sourceEntry, Change oldChange)
+{
+ switch (sourceEntry.sourceType) {
+ case SourceType::SystemInclude:
+ case SourceType::TopSystemInclude:
+ return Change::System;
+ case SourceType::ProjectInclude:
+ case SourceType::TopProjectInclude:
+ if (oldChange != Change::System)
+ return Change::Project;
+ break;
+ case SourceType::Source:
+ case SourceType::UserInclude:
+ break;
+ }
+
+ return oldChange;
+}
+
+FilePathIds existingSources(const FilePathIds &sources, const FilePathIds &generatedFilePathIds)
+{
+ FilePathIds existingSources;
+ existingSources.reserve(sources.size());
+ std::set_difference(sources.begin(),
+ sources.end(),
+ generatedFilePathIds.begin(),
+ generatedFilePathIds.end(),
+ std::back_inserter(existingSources));
+
+ return existingSources;
+}
+
+} // namespace
+
ProjectPartsManager::UpToDataProjectParts ProjectPartsManager::update(ProjectPartContainers &&projectsParts)
{
- auto notUpToDateProjectParts = filterProjectParts(projectsParts, m_projectParts);
+ auto updateSystemProjectParts = filterProjectParts(projectsParts, m_projectParts);
- if (notUpToDateProjectParts.empty())
- return {std::move(projectsParts), {}};
+ if (!updateSystemProjectParts.empty()) {
+ auto persistentProjectParts = m_projectPartsStorage.fetchProjectParts(
+ toProjectPartIds(updateSystemProjectParts));
- auto persistentProjectParts = m_projectPartsStorage.fetchProjectParts(
- toProjectPartIds(notUpToDateProjectParts));
+ if (persistentProjectParts.size() > 0) {
+ mergeProjectParts(persistentProjectParts);
- if (persistentProjectParts.size() > 0) {
- mergeProjectParts(persistentProjectParts);
+ updateSystemProjectParts = filterProjectParts(updateSystemProjectParts,
+ persistentProjectParts);
+ }
- notUpToDateProjectParts = filterProjectParts(notUpToDateProjectParts, persistentProjectParts);
+ if (updateSystemProjectParts.size()) {
+ m_projectPartsStorage.updateProjectParts(updateSystemProjectParts);
- if (notUpToDateProjectParts.empty())
- return {};
+ mergeProjectParts(updateSystemProjectParts);
+ }
}
- m_projectPartsStorage.updateProjectParts(notUpToDateProjectParts);
- m_projectPartsStorage.resetIndexingTimeStamps(notUpToDateProjectParts);
- m_precompiledHeaderStorage.deleteProjectPrecompiledHeaders(
- toProjectPartIds(notUpToDateProjectParts));
+ auto upToDateProjectParts = filterProjectParts(projectsParts, updateSystemProjectParts);
- mergeProjectParts(notUpToDateProjectParts);
+ auto updates = checkDependeciesAndTime(std::move(upToDateProjectParts),
+ std::move(updateSystemProjectParts));
- auto upToDateProjectParts = filterProjectParts(projectsParts, notUpToDateProjectParts);
+ if (updates.updateSystem.size()) {
+ m_projectPartsStorage.resetIndexingTimeStamps(updates.updateSystem);
+ m_precompiledHeaderStorage.deleteSystemAndProjectPrecompiledHeaders(
+ toProjectPartIds(updates.updateSystem));
+ }
+ if (updates.updateProject.size()) {
+ m_projectPartsStorage.resetIndexingTimeStamps(updates.updateProject);
+ m_precompiledHeaderStorage.deleteProjectPrecompiledHeaders(
+ toProjectPartIds(updates.updateProject));
+ }
- return {upToDateProjectParts, notUpToDateProjectParts};
+ return updates;
}
-void ProjectPartsManager::remove(const ProjectPartIds &projectPartIds)
+ProjectPartsManagerInterface::UpToDataProjectParts ProjectPartsManager::checkDependeciesAndTime(
+ ProjectPartContainers &&upToDateProjectParts, ProjectPartContainers &&orignalUpdateSystemProjectParts)
+{
+ ProjectPartContainerReferences changeProjectParts;
+ changeProjectParts.reserve(upToDateProjectParts.size());
+
+ ProjectPartContainers updateProjectProjectParts;
+ updateProjectProjectParts.reserve(upToDateProjectParts.size());
+
+ ProjectPartContainers addedUpToDateSystemProjectParts;
+ addedUpToDateSystemProjectParts.reserve(upToDateProjectParts.size());
+
+ FilePathIds generatedFiles = m_generatedFiles.filePathIds();
+
+ std::vector<IdPaths> watchedIdPaths;
+ watchedIdPaths.reserve(upToDateProjectParts.size() * 4);
+
+ for (ProjectPartContainer &projectPart : upToDateProjectParts) {
+ auto oldSources = m_buildDependenciesProvider.createSourceEntriesFromStorage(
+ projectPart.sourcePathIds, projectPart.projectPartId);
+
+ BuildDependency buildDependency = m_buildDependenciesProvider.create(projectPart,
+ Utils::clone(oldSources));
+
+ const auto &newSources = buildDependency.sources;
+
+ Change change = Change::No;
+
+ std::set_symmetric_difference(newSources.begin(),
+ newSources.end(),
+ oldSources.begin(),
+ oldSources.end(),
+ make_iterator([&](SourceEntry entry) {
+ change = changedSourceType(entry, change);
+ }),
+ [](SourceEntry first, SourceEntry second) {
+ return std::tie(first.sourceId, first.sourceType)
+ < std::tie(second.sourceId, second.sourceType);
+ });
+
+ switch (change) {
+ case Change::Project:
+ updateProjectProjectParts.emplace_back(std::move(projectPart));
+ projectPart.projectPartId = -1;
+ break;
+ case Change::System:
+ addedUpToDateSystemProjectParts.emplace_back(std::move(projectPart));
+ projectPart.projectPartId = -1;
+ break;
+ case Change::No:
+ break;
+ }
+
+ if (change == Change::No) {
+ Change change = mismatch_collect(
+ newSources.begin(),
+ newSources.end(),
+ oldSources.begin(),
+ oldSources.end(),
+ Change::No,
+ [](SourceEntry first, SourceEntry second) {
+ return first.timeStamp > second.timeStamp;
+ },
+ [](SourceEntry first, SourceEntry, Change change) {
+ return changedSourceType(first, change);
+ });
+
+ switch (change) {
+ case Change::Project:
+ updateProjectProjectParts.emplace_back(std::move(projectPart));
+ projectPart.projectPartId = -1;
+ break;
+ case Change::System:
+ addedUpToDateSystemProjectParts.emplace_back(std::move(projectPart));
+ projectPart.projectPartId = -1;
+ break;
+ case Change::No:
+ UsedMacroFilter usedMacroFilter{newSources, {}, {}};
+
+ watchedIdPaths.emplace_back(projectPart.projectPartId,
+ SourceType::Source,
+ existingSources(usedMacroFilter.sources, generatedFiles));
+ watchedIdPaths.emplace_back(projectPart.projectPartId,
+ SourceType::UserInclude,
+ existingSources(usedMacroFilter.userIncludes,
+ generatedFiles));
+ watchedIdPaths.emplace_back(projectPart.projectPartId,
+ SourceType::ProjectInclude,
+ existingSources(usedMacroFilter.projectIncludes,
+ generatedFiles));
+ watchedIdPaths.emplace_back(projectPart.projectPartId,
+ SourceType::SystemInclude,
+ existingSources(usedMacroFilter.systemIncludes,
+ generatedFiles));
+ break;
+ }
+ }
+ }
+
+ if (watchedIdPaths.size())
+ m_clangPathwatcher.updateIdPaths(watchedIdPaths);
+
+ ProjectPartContainers updateSystemProjectParts;
+ updateSystemProjectParts.reserve(orignalUpdateSystemProjectParts.size() + addedUpToDateSystemProjectParts.size());
+
+ std::merge(std::make_move_iterator(orignalUpdateSystemProjectParts.begin()),
+ std::make_move_iterator(orignalUpdateSystemProjectParts.end()),
+ std::make_move_iterator(addedUpToDateSystemProjectParts.begin()),
+ std::make_move_iterator(addedUpToDateSystemProjectParts.end()),
+ std::back_inserter(updateSystemProjectParts));
+
+ upToDateProjectParts.erase(std::remove_if(upToDateProjectParts.begin(),
+ upToDateProjectParts.end(),
+ [](const ProjectPartContainer &projectPart) {
+ return !projectPart.projectPartId.isValid();
+ }),
+ upToDateProjectParts.end());
+
+ return {std::move(upToDateProjectParts),
+ std::move(updateSystemProjectParts),
+ updateProjectProjectParts};
+}
+
+namespace {
+ProjectPartContainers removed(ProjectPartContainers &&projectParts,
+ const ProjectPartIds &projectPartIds)
{
ProjectPartContainers projectPartsWithoutIds;
@@ -99,14 +280,22 @@ void ProjectPartsManager::remove(const ProjectPartIds &projectPartIds)
}
};
- std::set_difference(std::make_move_iterator(m_projectParts.begin()),
- std::make_move_iterator(m_projectParts.end()),
+ std::set_difference(std::make_move_iterator(projectParts.begin()),
+ std::make_move_iterator(projectParts.end()),
projectPartIds.begin(),
projectPartIds.end(),
std::back_inserter(projectPartsWithoutIds),
Compare{});
- m_projectParts = std::move(projectPartsWithoutIds);
+ return projectPartsWithoutIds;
+}
+} // namespace
+
+void ProjectPartsManager::remove(const ProjectPartIds &projectPartIds)
+{
+ m_projectParts = removed(std::move(m_projectParts), projectPartIds);
+ m_systemDeferredProjectParts = removed(std::move(m_systemDeferredProjectParts), projectPartIds);
+ m_projectDeferredProjectParts = removed(std::move(m_projectDeferredProjectParts), projectPartIds);
}
ProjectPartContainers ProjectPartsManager::projects(const ProjectPartIds &projectPartIds) const
@@ -143,38 +332,42 @@ ProjectPartContainers ProjectPartsManager::projects(const ProjectPartIds &projec
return projectPartsWithIds;
}
-void ProjectPartsManager::updateDeferred(const ProjectPartContainers &deferredProjectsParts)
+namespace {
+ProjectPartContainers merge(ProjectPartContainers &&newProjectParts,
+ ProjectPartContainers &&oldProjectParts)
{
- ProjectPartContainerReferences deferredProjectPartPointers;
- deferredProjectPartPointers.reserve(deferredProjectsParts.size());
-
- std::set_intersection(m_projectParts.begin(),
- m_projectParts.end(),
- deferredProjectsParts.begin(),
- deferredProjectsParts.end(),
- std::back_inserter(deferredProjectPartPointers),
- [](const ProjectPartContainer &first, const ProjectPartContainer &second) {
- return first.projectPartId < second.projectPartId;
- });
-
- for (ProjectPartContainer &projectPart : deferredProjectPartPointers)
- projectPart.updateIsDeferred = true;
+ ProjectPartContainers mergedProjectParts;
+ mergedProjectParts.reserve(newProjectParts.size() + oldProjectParts.size());
+
+ std::set_union(std::make_move_iterator(newProjectParts.begin()),
+ std::make_move_iterator(newProjectParts.end()),
+ std::make_move_iterator(oldProjectParts.begin()),
+ std::make_move_iterator(oldProjectParts.end()),
+ std::back_inserter(mergedProjectParts),
+ [](const ProjectPartContainer &first, const ProjectPartContainer &second) {
+ return first.projectPartId < second.projectPartId;
+ });
+
+ return mergedProjectParts;
}
+} // namespace
-ProjectPartContainers ProjectPartsManager::deferredUpdates()
+void ProjectPartsManager::updateDeferred(ProjectPartContainers &&system,
+ ProjectPartContainers &&project)
{
- ProjectPartContainers deferredProjectParts;
- deferredProjectParts.reserve(m_projectParts.size());
-
- std::copy_if(m_projectParts.cbegin(),
- m_projectParts.cend(),
- std::back_inserter(deferredProjectParts),
- [](const ProjectPartContainer &projectPart) { return projectPart.updateIsDeferred; });
+ m_systemDeferredProjectParts = merge(std::move(system), std::move(m_systemDeferredProjectParts));
+ m_projectDeferredProjectParts = merge(std::move(project),
+ std::move(m_projectDeferredProjectParts));
+}
- for (ProjectPartContainer &projectPart : m_projectParts)
- projectPart.updateIsDeferred = false;
+ProjectPartContainers ProjectPartsManager::deferredSystemUpdates()
+{
+ return std::move(m_systemDeferredProjectParts);
+}
- return deferredProjectParts;
+ProjectPartContainers ProjectPartsManager::deferredProjectUpdates()
+{
+ return std::move(m_projectDeferredProjectParts);
}
ProjectPartContainers ProjectPartsManager::filterProjectParts(
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h
index 35d9e41c1c..426aa0229f 100644
--- a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h
@@ -35,32 +35,54 @@
namespace ClangBackEnd {
+class BuildDependenciesProviderInterface;
+class FilePathCachingInterface;
+class GeneratedFilesInterface;
+class ClangPathWatcherInterface;
+
inline namespace Pch {
class ProjectPartsManager final : public ProjectPartsManagerInterface
{
public:
ProjectPartsManager(ProjectPartsStorageInterface &projectPartsStorage,
- PrecompiledHeaderStorageInterface &precompiledHeaderStorage)
+ PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
+ BuildDependenciesProviderInterface &buildDependenciesProvider,
+ FilePathCachingInterface &filePathCache,
+ ClangPathWatcherInterface &clangPathwatcher,
+ GeneratedFilesInterface &generatedFiles)
: m_projectPartsStorage(projectPartsStorage)
, m_precompiledHeaderStorage(precompiledHeaderStorage)
+ , m_buildDependenciesProvider(buildDependenciesProvider)
+ , m_filePathCache(filePathCache)
+ , m_clangPathwatcher(clangPathwatcher)
+ , m_generatedFiles(generatedFiles)
{}
UpToDataProjectParts update(ProjectPartContainers &&projectsParts) override;
void remove(const ProjectPartIds &projectPartIds) override;
ProjectPartContainers projects(const ProjectPartIds &projectPartIds) const override;
- void updateDeferred(const ProjectPartContainers &projectsParts) override;
- ProjectPartContainers deferredUpdates() override;
+ void updateDeferred(ProjectPartContainers &&system, ProjectPartContainers &&project) override;
+ ProjectPartContainers deferredSystemUpdates() override;
+ ProjectPartContainers deferredProjectUpdates() override;
static ProjectPartContainers filterProjectParts(const ProjectPartContainers &newProjectsParts,
const ProjectPartContainers &oldProjectParts);
void mergeProjectParts(const ProjectPartContainers &projectsParts);
const ProjectPartContainers &projectParts() const;
+ UpToDataProjectParts checkDependeciesAndTime(ProjectPartContainers &&upToDateProjectParts,
+ ProjectPartContainers &&updateSystemProjectParts);
private:
ProjectPartContainers m_projectParts;
+ ProjectPartContainers m_systemDeferredProjectParts;
+ ProjectPartContainers m_projectDeferredProjectParts;
ProjectPartsStorageInterface &m_projectPartsStorage;
PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage;
+ BuildDependenciesProviderInterface &m_buildDependenciesProvider;
+ FilePathCachingInterface &m_filePathCache;
+ ClangPathWatcherInterface &m_clangPathwatcher;
+ GeneratedFilesInterface &m_generatedFiles;
};
} // namespace Pch
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h
index 54bae58c1a..696839c4b8 100644
--- a/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h
@@ -36,7 +36,8 @@ public:
{
public:
ProjectPartContainers upToDate;
- ProjectPartContainers notUpToDate;
+ ProjectPartContainers updateSystem;
+ ProjectPartContainers updateProject;
};
ProjectPartsManagerInterface() = default;
@@ -46,8 +47,9 @@ public:
virtual UpToDataProjectParts update(ProjectPartContainers &&projectsParts) = 0;
virtual void remove(const ProjectPartIds &projectPartIds) = 0;
virtual ProjectPartContainers projects(const ProjectPartIds &projectPartIds) const = 0;
- virtual void updateDeferred(const ProjectPartContainers &projectsParts) = 0;
- virtual ProjectPartContainers deferredUpdates() = 0;
+ virtual void updateDeferred(ProjectPartContainers &&system, ProjectPartContainers &&project) = 0;
+ virtual ProjectPartContainers deferredSystemUpdates() = 0;
+ virtual ProjectPartContainers deferredProjectUpdates() = 0;
protected:
~ProjectPartsManagerInterface() = default;
diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
index aaef21b608..bca4551b2f 100644
--- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
+++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
@@ -131,8 +131,10 @@ struct Data // because we have a cycle dependency
};
#ifdef Q_OS_WIN
+extern "C" void OutputDebugStringW(const wchar_t* msg);
static void messageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg)
{
+ OutputDebugStringW(msg.toStdWString().c_str());
std::wcout << msg.toStdWString() << std::endl;
if (type == QtFatalMsg)
abort();
diff --git a/src/tools/clangrefactoringbackend/source/CMakeLists.txt b/src/tools/clangrefactoringbackend/source/CMakeLists.txt
index 05c7c8a3ce..420e630c88 100644
--- a/src/tools/clangrefactoringbackend/source/CMakeLists.txt
+++ b/src/tools/clangrefactoringbackend/source/CMakeLists.txt
@@ -18,7 +18,6 @@ add_qtc_library(clangrefactoringbackend_lib STATIC
collectmacrospreprocessorcallbacks.h
collectmacrossourcefilecallbacks.cpp collectmacrossourcefilecallbacks.h
collectsymbolsaction.cpp collectsymbolsaction.h
- filestatuspreprocessorcallbacks.cpp filestatuspreprocessorcallbacks.h
indexdataconsumer.cpp indexdataconsumer.h
locationsourcefilecallbacks.cpp locationsourcefilecallbacks.h
macropreprocessorcallbacks.cpp macropreprocessorcallbacks.h
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index ce809e9efb..407621b4be 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -32,7 +32,6 @@ SOURCES += \
$$PWD/collectsymbolsaction.cpp \
$$PWD/collectmacrossourcefilecallbacks.cpp \
$$PWD/symbolscollector.cpp \
- $$PWD/filestatuspreprocessorcallbacks.cpp \
$$PWD/clangquerygatherer.cpp \
$$PWD/symbolindexing.cpp \
$$PWD/indexdataconsumer.cpp
@@ -51,7 +50,6 @@ HEADERS += \
$$PWD/symbolscollector.h \
$$PWD/symbolsvisitorbase.h \
$$PWD/indexdataconsumer.h \
- $$PWD/filestatuspreprocessorcallbacks.h \
$$PWD/clangquerygatherer.h
}
diff --git a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp
deleted file mode 100644
index 28efe39f9b..0000000000
--- a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "filestatuspreprocessorcallbacks.h"
-
-namespace ClangBackEnd {
-
-void FileStatusPreprocessorCallbacks::FileChanged(clang::SourceLocation sourceLocation,
- clang::PPCallbacks::FileChangeReason reason,
- clang::SrcMgr::CharacteristicKind,
- clang::FileID)
-{
- if (reason == clang::PPCallbacks::EnterFile) {
- const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(
- m_sourceManager->getFileID(sourceLocation));
- if (fileEntry)
- addFileStatus(fileEntry);
- }
-}
-
-void FileStatusPreprocessorCallbacks::addFileStatus(const clang::FileEntry *fileEntry)
-{
- auto id = filePathId(fileEntry);
-
- auto found = std::lower_bound(m_fileStatuses.begin(),
- m_fileStatuses.end(),
- id,
- [](const auto &first, const auto &second) {
- return first.filePathId < second;
- });
-
- if (found == m_fileStatuses.end() || found->filePathId != id) {
- m_fileStatuses.emplace(found, id, fileEntry->getSize(), fileEntry->getModificationTime());
- }
-}
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp b/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp
index cb9723b743..e287144462 100644
--- a/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp
+++ b/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp
@@ -25,7 +25,6 @@
#include "indexdataconsumer.h"
#include "collectsymbolsaction.h"
-#include "filestatuspreprocessorcallbacks.h"
#include <clang/AST/DeclVisitor.h>
#include <clang/Basic/SourceLocation.h>
@@ -53,12 +52,12 @@ Utils::SmallString symbolName(const clang::NamedDecl *declaration)
SourceLocationKind sourceLocationKind(clang::index::SymbolRoleSet roles)
{
- if (hasSymbolRole(clang::index::SymbolRole::Reference, roles))
- return SourceLocationKind::DeclarationReference;
+ if (hasSymbolRole(clang::index::SymbolRole::Definition, roles))
+ return SourceLocationKind::Definition;
else if (hasSymbolRole(clang::index::SymbolRole::Declaration, roles))
return SourceLocationKind::Declaration;
- else if (hasSymbolRole(clang::index::SymbolRole::Definition, roles))
- return SourceLocationKind::Definition;
+ else if (hasSymbolRole(clang::index::SymbolRole::Reference, roles))
+ return SourceLocationKind::DeclarationReference;
return SourceLocationKind::None;
}
@@ -68,9 +67,9 @@ using SymbolKindAndTags = std::pair<SymbolKind, SymbolTags>;
class IndexingDeclVisitor : public clang::ConstDeclVisitor<IndexingDeclVisitor, SymbolKindAndTags>
{
public:
- SymbolKindAndTags VisitEnumDecl(const clang::EnumDecl *declaration)
+ SymbolKindAndTags VisitEnumDecl(const clang::EnumDecl * /*declaration*/)
{
- return {SymbolKind::Enumeration, {}};;
+ return {SymbolKind::Enumeration, {}};
}
SymbolKindAndTags VisitRecordDecl(const clang::RecordDecl *declaration)
{
@@ -105,7 +104,7 @@ SymbolKindAndTags symbolKindAndTags(const clang::Decl *declaration)
} // namespace
-bool IndexDataConsumer::skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles)
+bool IndexDataConsumer::skipSymbol(clang::FileID fileId)
{
return isAlreadyParsed(fileId, m_symbolSourcesManager)
&& !m_symbolSourcesManager.dependentFilesModified();
@@ -119,12 +118,6 @@ bool IndexDataConsumer::isAlreadyParsed(clang::FileID fileId, SourcesManager &so
return sourcesManager.alreadyParsed(filePathId(fileEntry), fileEntry->getModificationTime());
}
-void IndexDataConsumer::setPreprocessor(std::shared_ptr<clang::Preprocessor> preprocessor)
-{
- preprocessor->addPPCallbacks(std::make_unique<FileStatusPreprocessorCallbacks>(
- m_fileStatuses, m_filePathCache, m_sourceManager, m_filePathIndices));
-}
-
bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration,
clang::index::SymbolRoleSet symbolRoles,
llvm::ArrayRef<clang::index::SymbolRelation> /*symbolRelations*/,
@@ -136,7 +129,7 @@ bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration,
if (!namedDeclaration->getIdentifier())
return true;
- if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles))
+ if (skipSymbol(m_sourceManager->getFileID(sourceLocation)))
return true;
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
diff --git a/src/tools/clangrefactoringbackend/source/indexdataconsumer.h b/src/tools/clangrefactoringbackend/source/indexdataconsumer.h
index 730ca12b23..c80e066b6c 100644
--- a/src/tools/clangrefactoringbackend/source/indexdataconsumer.h
+++ b/src/tools/clangrefactoringbackend/source/indexdataconsumer.h
@@ -43,14 +43,12 @@ class IndexDataConsumer : public clang::index::IndexDataConsumer,
public:
IndexDataConsumer(SymbolEntries &symbolEntries,
SourceLocationEntries &sourceLocationEntries,
- FileStatuses &fileStatuses,
FilePathCachingInterface &filePathCache,
SourcesManager &symbolSourcesManager,
SourcesManager &macroSourcesManager)
: SymbolsVisitorBase(filePathCache, nullptr, m_filePathIndices)
, m_symbolEntries(symbolEntries)
, m_sourceLocationEntries(sourceLocationEntries)
- , m_fileStatuses(fileStatuses)
, m_symbolSourcesManager(symbolSourcesManager)
, m_macroSourcesManager(macroSourcesManager)
@@ -59,8 +57,6 @@ public:
IndexDataConsumer(const IndexDataConsumer &) = delete;
IndexDataConsumer &operator=(const IndexDataConsumer &) = delete;
- void setPreprocessor(std::shared_ptr<clang::Preprocessor> preprocessor) override;
-
bool handleDeclOccurence(const clang::Decl *declaration,
clang::index::SymbolRoleSet symbolRoles,
llvm::ArrayRef<clang::index::SymbolRelation> symbolRelations,
@@ -75,14 +71,13 @@ public:
void finish() override;
private:
- bool skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles);
+ bool skipSymbol(clang::FileID fileId);
bool isAlreadyParsed(clang::FileID fileId, SourcesManager &sourcesManager);
private:
FilePathIds m_filePathIndices;
SymbolEntries &m_symbolEntries;
SourceLocationEntries &m_sourceLocationEntries;
- FileStatuses &m_fileStatuses;
SourcesManager &m_symbolSourcesManager;
SourcesManager &m_macroSourcesManager;
};
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
index 2f79ae31cc..b86a93ad32 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
@@ -81,6 +81,7 @@ void RefactoringServer::requestSourceRangesForQueryMessage(RequestSourceRangesFo
void RefactoringServer::updateProjectParts(UpdateProjectPartsMessage &&message)
{
+ m_filePathCache.populateIfEmpty();
m_symbolIndexing.updateProjectParts(message.takeProjectsParts());
}
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index c6909a0732..fb53a9d3a0 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -92,21 +92,40 @@ void SymbolIndexer::updateProjectParts(ProjectPartContainers &&projectParts)
}
namespace {
+
void store(SymbolStorageInterface &symbolStorage,
BuildDependenciesStorageInterface &buildDependencyStorage,
Sqlite::TransactionInterface &transactionInterface,
- SymbolsCollectorInterface &symbolsCollector)
+ SymbolsCollectorInterface &symbolsCollector,
+ const FilePathIds &dependentSources)
{
try {
+ long long now = std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+
Sqlite::ImmediateTransaction transaction{transactionInterface};
- buildDependencyStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses());
+ buildDependencyStorage.insertOrUpdateIndexingTimeStampsWithoutTransaction(dependentSources,
+ now);
+
symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
symbolsCollector.sourceLocations());
transaction.commit();
} catch (const Sqlite::StatementIsBusy &) {
- store(symbolStorage, buildDependencyStorage, transactionInterface, symbolsCollector);
+ store(symbolStorage,
+ buildDependencyStorage,
+ transactionInterface,
+ symbolsCollector,
+ dependentSources);
}
}
+
+FilePathIds toFilePathIds(const SourceTimeStamps &sourceTimeStamps)
+{
+ return Utils::transform<FilePathIds>(sourceTimeStamps, [](SourceTimeStamp sourceTimeStamp) {
+ return sourceTimeStamp.sourceId;
+ });
+}
} // namespace
void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
@@ -124,6 +143,7 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
auto indexing = [projectPart,
sourcePathId,
preIncludeSearchPath = m_environment.preIncludeSearchPath(),
+ dependentSources = toFilePathIds(dependentTimeStamps),
this](SymbolsCollectorInterface &symbolsCollector) {
auto collect = [&](const FilePath &pchPath) {
using Builder = CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector>;
@@ -147,17 +167,20 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
store(m_symbolStorage,
m_buildDependencyStorage,
m_transactionInterface,
- symbolsCollector);
+ symbolsCollector,
+ dependentSources);
} else if (pchPaths.systemPchPath.size() && collect(pchPaths.systemPchPath)) {
store(m_symbolStorage,
m_buildDependencyStorage,
m_transactionInterface,
- symbolsCollector);
+ symbolsCollector,
+ dependentSources);
} else if (collect({})) {
store(m_symbolStorage,
m_buildDependencyStorage,
m_transactionInterface,
- symbolsCollector);
+ symbolsCollector,
+ dependentSources);
}
};
@@ -183,12 +206,10 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
{
m_fileStatusCache.update(filePathId);
- Sqlite::DeferredTransaction transaction{m_transactionInterface};
const Utils::optional<ProjectPartArtefact>
optionalArtefact = m_projectPartsStorage.fetchProjectPartArtefact(filePathId);
if (!optionalArtefact)
return;
- transaction.commit();
ProjectPartId projectPartId = optionalArtefact->projectPartId;
@@ -198,6 +219,7 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
auto indexing = [optionalArtefact = std::move(optionalArtefact),
filePathId,
preIncludeSearchPath = m_environment.preIncludeSearchPath(),
+ dependentSources = toFilePathIds(dependentTimeStamps),
this](SymbolsCollectorInterface &symbolsCollector) {
auto collect = [&](const FilePath &pchPath) {
const ProjectPartArtefact &artefact = *optionalArtefact;
@@ -220,11 +242,23 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
optionalArtefact->projectPartId);
if (pchPaths.projectPchPath.size() && collect(pchPaths.projectPchPath)) {
- store(m_symbolStorage, m_buildDependencyStorage, m_transactionInterface, symbolsCollector);
+ store(m_symbolStorage,
+ m_buildDependencyStorage,
+ m_transactionInterface,
+ symbolsCollector,
+ dependentSources);
} else if (pchPaths.systemPchPath.size() && collect(pchPaths.systemPchPath)) {
- store(m_symbolStorage, m_buildDependencyStorage, m_transactionInterface, symbolsCollector);
+ store(m_symbolStorage,
+ m_buildDependencyStorage,
+ m_transactionInterface,
+ symbolsCollector,
+ dependentSources);
} else if (collect({})) {
- store(m_symbolStorage, m_buildDependencyStorage, m_transactionInterface, symbolsCollector);
+ store(m_symbolStorage,
+ m_buildDependencyStorage,
+ m_transactionInterface,
+ symbolsCollector,
+ dependentSources);
}
};
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h
index 1f15f2ffaa..aa74fb833b 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h
@@ -57,7 +57,7 @@ public:
, m_database(database)
{}
- void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
+ void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) override
{
auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
first.callable = std::move(second.callable);
@@ -71,7 +71,7 @@ public:
m_progressCounter.addTotal(int(m_tasks.size() - oldSize));
}
- void removeTasks(const std::vector<int> &projectPartIds)
+ void removeTasks(const ProjectPartIds &projectPartIds) override
{
auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
@@ -91,7 +91,7 @@ public:
return m_tasks;
}
- void processEntries()
+ void processEntries() override
{
auto slotUsage = m_symbolIndexerScheduler.slotUsage();
uint taskCount = slotUsage.free;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h
index dfcc78bd23..3c5bc3479f 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueueinterface.h
@@ -27,6 +27,8 @@
#include <queueinterface.h>
+#include <projectpartid.h>
+
#include <utils/smallstringvector.h>
namespace ClangBackEnd {
@@ -38,8 +40,8 @@ class SymbolIndexerTaskQueueInterface : public QueueInterface
public:
virtual void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) = 0
/* [[expects: std::is_sorted(tasks)]] */;
- virtual void removeTasks(const std::vector<int> &projectPartIds) = 0
- /* [[expects: std::is_sorted(projectPartIds)]] */;
+ virtual void removeTasks(const ProjectPartIds &projectPartIds) = 0
+ /* [[expects: std::is_sorted(projectPartIds)]] */;
protected:
~SymbolIndexerTaskQueueInterface() = default;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
index 936a34af00..e680a45be0 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexing.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -63,19 +63,19 @@ class SymbolsCollectorManager final : public ClangBackEnd::ProcessorManager<Symb
public:
using Processor = SymbolsCollector;
SymbolsCollectorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
- Sqlite::Database &database)
- : ProcessorManager(generatedFiles),
- m_database(database)
+ FilePathCaching &filePathCache)
+ : ProcessorManager(generatedFiles)
+ , m_filePathCache(filePathCache)
{}
protected:
std::unique_ptr<SymbolsCollector> createProcessor() const
{
- return std::make_unique<SymbolsCollector>(m_database);
+ return std::make_unique<SymbolsCollector>(m_filePathCache);
}
private:
- Sqlite::Database &m_database;
+ FilePathCaching &m_filePathCache;
};
class SymbolIndexing final : public SymbolIndexingInterface
@@ -84,7 +84,7 @@ public:
using BuildDependenciesStorage = ClangBackEnd::BuildDependenciesStorage<Sqlite::Database>;
using SymbolStorage = ClangBackEnd::SymbolStorage<Sqlite::Database>;
SymbolIndexing(Sqlite::Database &database,
- FilePathCachingInterface &filePathCache,
+ FilePathCaching &filePathCache,
const GeneratedFiles &generatedFiles,
ProgressCounter::SetProgressCallback &&setProgressCallback,
const Environment &environment)
@@ -93,7 +93,7 @@ public:
, m_precompiledHeaderStorage(database)
, m_projectPartsStorage(database)
, m_symbolStorage(database)
- , m_collectorManger(generatedFiles, database)
+ , m_collectorManger(generatedFiles, filePathCache)
, m_progressCounter(std::move(setProgressCallback))
, m_indexer(m_indexerQueue,
m_symbolStorage,
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
index ab5a00fc6b..a233f6d8fe 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
@@ -31,11 +31,10 @@
namespace ClangBackEnd {
-SymbolsCollector::SymbolsCollector(Sqlite::Database &database)
- : m_filePathCache(database)
+SymbolsCollector::SymbolsCollector(FilePathCaching &filePathCache)
+ : m_filePathCache(filePathCache)
, m_indexDataConsumer(std::make_shared<IndexDataConsumer>(m_symbolEntries,
m_sourceLocationEntries,
- m_fileStatuses,
m_filePathCache,
m_symbolSourcesManager,
m_macroSourcesManager))
@@ -63,7 +62,6 @@ void SymbolsCollector::clear()
{
m_symbolEntries.clear();
m_sourceLocationEntries.clear();
- m_fileStatuses.clear();
m_clangTool = ClangTool();
}
@@ -150,11 +148,6 @@ const SourceLocationEntries &SymbolsCollector::sourceLocations() const
return m_sourceLocationEntries;
}
-const FileStatuses &SymbolsCollector::fileStatuses() const
-{
- return m_fileStatuses;
-}
-
bool SymbolsCollector::isUsed() const
{
return m_isUsed;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h
index e103471372..824fe057fd 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h
@@ -42,7 +42,7 @@ namespace ClangBackEnd {
class SymbolsCollector final : public SymbolsCollectorInterface
{
public:
- SymbolsCollector(Sqlite::Database &database);
+ SymbolsCollector(FilePathCaching &filePathCache);
void addFiles(const FilePathIds &filePathIds,
const Utils::SmallStringVector &arguments);
@@ -58,7 +58,6 @@ public:
const SymbolEntries &symbols() const override;
const SourceLocationEntries &sourceLocations() const override;
- const FileStatuses &fileStatuses() const override;
bool isUsed() const override;
void setIsUsed(bool isUsed) override;
@@ -66,11 +65,10 @@ public:
bool isClean() const { return m_clangTool.isClean(); }
private:
- FilePathCaching m_filePathCache;
+ CopyableFilePathCaching m_filePathCache;
ClangTool m_clangTool;
SymbolEntries m_symbolEntries;
SourceLocationEntries m_sourceLocationEntries;
- FileStatuses m_fileStatuses;
std::shared_ptr<IndexDataConsumer> m_indexDataConsumer;
CollectSymbolsAction m_collectSymbolsAction;
SourcesManager m_symbolSourcesManager;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
index 07b5de223c..d90d4db528 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
@@ -48,7 +48,6 @@ public:
virtual const SymbolEntries &symbols() const = 0;
virtual const SourceLocationEntries &sourceLocations() const = 0;
- virtual const FileStatuses &fileStatuses() const = 0;
};
} // namespace ClangBackEnd
diff --git a/src/tools/cplusplus-ast2png/cplusplus-ast2png.cpp b/src/tools/cplusplus-ast2png/cplusplus-ast2png.cpp
index ad69adae56..86a2a34e39 100644
--- a/src/tools/cplusplus-ast2png/cplusplus-ast2png.cpp
+++ b/src/tools/cplusplus-ast2png/cplusplus-ast2png.cpp
@@ -127,15 +127,15 @@ protected:
return name;
}
- QByteArray terminalId(unsigned token)
+ QByteArray terminalId(int token)
{ return 't' + QByteArray::number(token); }
- void terminal(unsigned token, AST *node) {
+ void terminal(int token, AST *node) {
_connections.append(qMakePair(_id[node], terminalId(token)));
}
void generateTokens() {
- for (unsigned token = 1; token < translationUnit()->tokenCount(); ++token) {
+ for (int token = 1; token < translationUnit()->tokenCount(); ++token) {
if (translationUnit()->tokenKind(token) == T_EOF_SYMBOL)
break;
@@ -413,7 +413,7 @@ public:
void report(int level,
const StringLiteral *fileName,
- unsigned line, unsigned column,
+ int line, int column,
const char *format, va_list ap)
{
++m_errorCount;
diff --git a/src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor.cpp b/src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor.cpp
index 14e858cfcd..d834a62db0 100644
--- a/src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor.cpp
+++ b/src/tools/cplusplus-mkvisitor/cplusplus-mkvisitor.cpp
@@ -308,7 +308,7 @@ public:
<< " if (debug_todo)" << std::endl
<< " translationUnit()->warning(ast->firstToken(), \"TODO: %s\", __func__);" << std::endl;
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Declaration *decl = klass->memberAt(i)->asDeclaration();
if (! decl)
continue;
diff --git a/src/tools/cplusplus-update-frontend/cplusplus-update-frontend.cpp b/src/tools/cplusplus-update-frontend/cplusplus-update-frontend.cpp
index 2b83d7fa4e..47a8ead13f 100644
--- a/src/tools/cplusplus-update-frontend/cplusplus-update-frontend.cpp
+++ b/src/tools/cplusplus-update-frontend/cplusplus-update-frontend.cpp
@@ -100,9 +100,7 @@ static void closeAndPrintFilePath(QFile &file)
class ASTNodes
{
public:
- ASTNodes(): base(0) {}
-
- ClassSpecifierAST *base; // points to "class AST"
+ ClassSpecifierAST *base = nullptr; // points to "class AST"
QList<ClassSpecifierAST *> deriveds; // n where n extends AST
QList<QTextCursor> endOfPublicClassSpecifiers;
};
@@ -112,7 +110,7 @@ static ASTNodes astNodes;
static QTextCursor createCursor(TranslationUnit *unit, AST *ast, QTextDocument *document)
{
- unsigned startLine, startColumn, endLine, endColumn;
+ int startLine, startColumn, endLine, endColumn;
unit->getTokenStartPosition(ast->firstToken(), &startLine, &startColumn);
unit->getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn);
@@ -156,7 +154,7 @@ protected:
virtual bool visit(ClassSpecifierAST *ast)
{
Class *klass = ast->symbol;
- Q_ASSERT(klass != 0);
+ Q_ASSERT(klass != nullptr);
const QString className = oo(klass->name());
@@ -166,7 +164,7 @@ protected:
else {
_nodes.deriveds.append(ast);
- AccessDeclarationAST *accessDeclaration = 0;
+ AccessDeclarationAST *accessDeclaration = nullptr;
for (DeclarationListAST *it = ast->member_specifier_list; it; it = it->next) {
if (AccessDeclarationAST *decl = it->value->asAccessDeclaration()) {
if (tokenKind(decl->access_specifier_token) == T_PUBLIC)
@@ -177,7 +175,7 @@ protected:
if (! accessDeclaration)
qDebug() << "no access declaration for class:" << className;
- Q_ASSERT(accessDeclaration != 0);
+ Q_ASSERT(accessDeclaration != nullptr);
QTextCursor tc = createCursor(translationUnit(), accessDeclaration, document);
tc.setPosition(tc.position());
@@ -198,11 +196,11 @@ private:
class Accept0CG: protected ASTVisitor
{
QDir _cplusplusDir;
- QTextStream *out;
+ QTextStream *out = nullptr;
public:
Accept0CG(const QDir &cplusplusDir, TranslationUnit *unit)
- : ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
+ : ASTVisitor(unit), _cplusplusDir(cplusplusDir)
{ }
QList<QByteArray> classes() const { return classMap.keys(); }
@@ -248,7 +246,7 @@ protected:
void visitMembers(Class *klass)
{
// *out << " // visit " << className.constData() << endl;
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->name())
continue;
@@ -259,7 +257,7 @@ protected:
continue;
const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
- if (member->type().isUnsigned() && memberName.endsWith("_token")) {
+ if (member->type()->isIntegerType() && memberName.endsWith("_token")) {
// nothing to do. The member is a token.
} else if (PointerType *ptrTy = member->type()->asPointerType()) {
@@ -273,10 +271,10 @@ protected:
}
}
- for (unsigned i = 0; i < klass->baseClassCount(); ++i) {
+ for (int i = 0; i < klass->baseClassCount(); ++i) {
const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars();
- if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0))
+ if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, nullptr))
visitMembers(baseClassSpec->symbol);
}
}
@@ -337,11 +335,11 @@ protected:
class Match0CG: protected ASTVisitor
{
QDir _cplusplusDir;
- QTextStream *out;
+ QTextStream *out = nullptr;
public:
Match0CG(const QDir &cplusplusDir, TranslationUnit *unit)
- : ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
+ : ASTVisitor(unit), _cplusplusDir(cplusplusDir)
{ }
void operator()(AST *ast)
@@ -448,11 +446,11 @@ protected:
class MatcherCPPCG: protected ASTVisitor
{
QDir _cplusplusDir;
- QTextStream *out;
+ QTextStream *out = nullptr;
public:
MatcherCPPCG(const QDir &cplusplusDir, TranslationUnit *unit)
- : ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
+ : ASTVisitor(unit), _cplusplusDir(cplusplusDir)
{ }
void operator()(AST *ast)
@@ -502,7 +500,7 @@ protected:
void visitMembers(Class *klass)
{
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->name())
continue;
@@ -513,7 +511,7 @@ protected:
continue;
const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
- if (member->type().isUnsigned() && memberName.endsWith("_token")) {
+ if (member->type()->isIntegerType() && memberName.endsWith("_token")) {
*out
<< " pattern->" << memberName << " = node->" << memberName << ";" << endl
@@ -536,10 +534,10 @@ protected:
}
}
- for (unsigned i = 0; i < klass->baseClassCount(); ++i) {
+ for (int i = 0; i < klass->baseClassCount(); ++i) {
const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars();
- if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0))
+ if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, nullptr))
visitMembers(baseClassSpec->symbol);
}
}
@@ -601,11 +599,11 @@ protected:
class CloneCPPCG: protected ASTVisitor
{
QDir _cplusplusDir;
- QTextStream *out;
+ QTextStream *out = nullptr;
public:
CloneCPPCG(const QDir &cplusplusDir, TranslationUnit *unit)
- : ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
+ : ASTVisitor(unit), _cplusplusDir(cplusplusDir)
{ }
void operator()(AST *ast)
@@ -649,7 +647,7 @@ protected:
void visitMembers(Class *klass)
{
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->name())
continue;
@@ -660,7 +658,7 @@ protected:
continue;
const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
- if (member->type().isUnsigned() && memberName.endsWith("_token")) {
+ if (member->type()->isIntegerType() && memberName.endsWith("_token")) {
*out << " ast->" << memberName << " = " << memberName << ";" << endl;
} else if (PointerType *ptrTy = member->type()->asPointerType()) {
if (NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
@@ -678,10 +676,10 @@ protected:
}
}
- for (unsigned i = 0; i < klass->baseClassCount(); ++i) {
+ for (int i = 0; i < klass->baseClassCount(); ++i) {
const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars();
- if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0))
+ if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, nullptr))
visitMembers(baseClassSpec->symbol);
}
}
@@ -782,7 +780,7 @@ protected:
void visitMembers(Class *klass)
{
- for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ for (int i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->name())
continue;
@@ -793,7 +791,7 @@ protected:
continue;
const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size());
- if (member->type().isUnsigned() && memberName.endsWith("_token")) {
+ if (member->type()->isIntegerType() && memberName.endsWith("_token")) {
out << " if (ast->" << memberName << ")" << endl;
out << " terminal(ast->" << memberName << ", ast);" << endl;
} else if (PointerType *ptrTy = member->type()->asPointerType()) {
@@ -810,10 +808,10 @@ protected:
}
}
- for (unsigned i = 0; i < klass->baseClassCount(); ++i) {
+ for (int i = 0; i < klass->baseClassCount(); ++i) {
const QByteArray baseClassName = klass->baseClassAt(i)->identifier()->chars();
- if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, 0))
+ if (ClassSpecifierAST *baseClassSpec = classMap.value(baseClassName, nullptr))
visitMembers(baseClassSpec->symbol);
}
}
@@ -905,35 +903,12 @@ private:
Overview oo;
};
-static QList<QTextCursor> removeConstructors(ClassSpecifierAST *classAST,
- TranslationUnit *translationUnit,
- QTextDocument *document)
-{
- Overview oo;
- QList<QTextCursor> cursors;
- const QString className = oo(classAST->symbol->name());
-
- for (DeclarationListAST *iter = classAST->member_specifier_list; iter; iter = iter->next) {
- if (FunctionDefinitionAST *funDef = iter->value->asFunctionDefinition()) {
- if (oo(funDef->symbol->name()) == className) {
- // found it:
- QTextCursor tc = createCursor(translationUnit, funDef, document);
- tc.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- tc.setPosition(tc.position() + 1, QTextCursor::KeepAnchor);
- cursors.append(tc);
- }
- }
- }
-
- return cursors;
-}
-
static QStringList collectFieldNames(ClassSpecifierAST *classAST, bool onlyTokensAndASTNodes)
{
QStringList fields;
Overview oo;
Class *clazz = classAST->symbol;
- for (unsigned i = 0; i < clazz->memberCount(); ++i) {
+ for (int i = 0; i < clazz->memberCount(); ++i) {
Symbol *s = clazz->memberAt(i);
if (Declaration *decl = s->asDeclaration()) {
const QString declName = oo(decl->name());
@@ -947,7 +922,7 @@ static QStringList collectFieldNames(ClassSpecifierAST *classAST, bool onlyToken
} else {
fields.append(declName);
}
- } else if (ty.isUnsigned()) {
+ } else if (ty->isIntegerType()) {
fields.append(declName);
}
}
@@ -955,32 +930,6 @@ static QStringList collectFieldNames(ClassSpecifierAST *classAST, bool onlyToken
return fields;
}
-static QString createConstructor(ClassSpecifierAST *classAST)
-{
- Overview oo;
- Class *clazz = classAST->symbol;
-
- QString result(QLatin1String(" "));
- result.append(oo(clazz->name()));
- result.append(QLatin1String("()\n"));
-
- QStringList classFields = collectFieldNames(classAST, false);
- for (int i = 0; i < classFields.size(); ++i) {
- if (i == 0) {
- result.append(QLatin1String(" : "));
- result.append(classFields.at(i));
- result.append(QLatin1String("(0)\n"));
- } else {
- result.append(QLatin1String(" , "));
- result.append(classFields.at(i));
- result.append(QLatin1String("(0)\n"));
- }
- }
-
- result.append(QLatin1String(" {}\n"));
- return result;
-}
-
bool checkGenerated(const QTextCursor &cursor, int *doxyStart)
{
BackwardsScanner tokens(cursor, LanguageFeatures::defaultFeatures(), 10, QString(), false);
@@ -993,36 +942,27 @@ bool checkGenerated(const QTextCursor &cursor, int *doxyStart)
return tokens.text(tokens.startToken() - 1).contains(QLatin1String("\\generated"));
}
-struct GenInfo {
- GenInfo()
- : classAST(0)
- , start(0)
- , end(0)
- , firstToken(false)
- , lastToken(false)
- , remove(false)
- {}
-
- ClassSpecifierAST *classAST;
- int start;
- int end;
- bool firstToken;
- bool lastToken;
- bool remove;
+struct GenInfo
+{
+ ClassSpecifierAST *classAST = nullptr;
+ int start = 0;
+ int end = 0;
+ bool firstToken = false;
+ bool lastToken = false;
+ bool remove = false;
};
void generateFirstToken(QTextStream &os, const QString &className, const QStringList &fields)
{
- os << "unsigned "<< className << "::firstToken() const" << endl
- << "{" << endl;
+ os << "int " << className << "::firstToken() const" << endl << "{" << endl;
- foreach (const QString &field, fields) {
+ for (const QString &field : fields) {
os << " if (" << field << ")" << endl;
if (field.endsWith(QLatin1String("_token"))) {
os << " return " << field << ";" << endl;
} else {
- os << " if (unsigned candidate = " << field << "->firstToken())" << endl;
+ os << " if (int candidate = " << field << "->firstToken())" << endl;
os << " return candidate;" << endl;
}
}
@@ -1033,7 +973,7 @@ void generateFirstToken(QTextStream &os, const QString &className, const QString
void generateLastToken(QTextStream &os, const QString &className, const QStringList &fields)
{
- os << "unsigned "<< className << "::lastToken() const" << endl
+ os << "int "<< className << "::lastToken() const" << endl
<< "{" << endl;
for (int i = fields.size() - 1; i >= 0; --i) {
@@ -1044,7 +984,7 @@ void generateLastToken(QTextStream &os, const QString &className, const QStringL
if (field.endsWith(QLatin1String("_token"))) {
os << " return " << field << " + 1;" << endl;
} else {
- os << " if (unsigned candidate = " << field << "->lastToken())" << endl;
+ os << " if (int candidate = " << field << "->lastToken())" << endl;
os << " return candidate;" << endl;
}
}
@@ -1083,7 +1023,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
StringClassSpecifierASTMap classesNeedingLastToken;
// find all classes with method declarations for firstToken/lastToken
- foreach (ClassSpecifierAST *classAST, astNodes.deriveds) {
+ for (ClassSpecifierAST *classAST : qAsConst(astNodes.deriveds)) {
const QString className = oo(classAST->symbol->name());
if (className.isEmpty())
continue;
@@ -1120,7 +1060,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
QTextCursor cursor(&cpp_document);
- unsigned line = 0, column = 0;
+ int line = 0, column = 0;
AST_cpp_document->translationUnit()->getTokenStartPosition(funDef->firstToken(), &line, &column);
const int start = cpp_document.findBlockByNumber(line - 1).position() + column - 1;
cursor.setPosition(start);
@@ -1134,7 +1074,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
++end;
if (methodName == QLatin1String("firstToken")) {
- ClassSpecifierAST *classAST = classesNeedingFirstToken.value(className, 0);
+ ClassSpecifierAST *classAST = classesNeedingFirstToken.value(className, nullptr);
GenInfo info;
info.end = end;
if (classAST) {
@@ -1149,7 +1089,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
if (isGenerated)
todo.append(info);
} else if (methodName == QLatin1String("lastToken")) {
- ClassSpecifierAST *classAST = classesNeedingLastToken.value(className, 0);
+ ClassSpecifierAST *classAST = classesNeedingLastToken.value(className, nullptr);
GenInfo info;
info.end = end;
if (classAST) {
@@ -1173,7 +1113,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
const int documentEnd = cpp_document.lastBlock().position() + cpp_document.lastBlock().length() - 1;
Utils::ChangeSet changes;
- foreach (GenInfo info, todo) {
+ for (GenInfo info : qAsConst(todo)) {
if (info.end > documentEnd)
info.end = documentEnd;
@@ -1209,7 +1149,7 @@ void generateAST_cpp(const Snapshot &snapshot, const QDir &cplusplusDir)
const QStringList fields = collectFieldNames(it.value(), true);
os << "/** \\generated */" << endl;
generateFirstToken(os, className, fields);
- if (ClassSpecifierAST *classAST = classesNeedingLastToken.value(className, 0)) {
+ if (ClassSpecifierAST *classAST = classesNeedingLastToken.value(className, nullptr)) {
const QStringList fields = collectFieldNames(classAST, true);
os << "/** \\generated */" << endl;
generateLastToken(os, className, fields);
@@ -1266,27 +1206,27 @@ void generateASTVisitor_H(const Snapshot &, const QDir &cplusplusDir,
" void setTranslationUnit(TranslationUnit *translationUnit);\n"
"\n"
" Control *control() const;\n"
-" unsigned tokenCount() const;\n"
-" const Token &tokenAt(unsigned index) const;\n"
-" int tokenKind(unsigned index) const;\n"
-" const char *spell(unsigned index) const;\n"
-" const Identifier *identifier(unsigned index) const;\n"
-" const Literal *literal(unsigned index) const;\n"
-" const NumericLiteral *numericLiteral(unsigned index) const;\n"
-" const StringLiteral *stringLiteral(unsigned index) const;\n"
+" int tokenCount() const;\n"
+" const Token &tokenAt(int index) const;\n"
+" int tokenKind(int index) const;\n"
+" const char *spell(int index) const;\n"
+" const Identifier *identifier(int index) const;\n"
+" const Literal *literal(int index) const;\n"
+" const NumericLiteral *numericLiteral(int index) const;\n"
+" const StringLiteral *stringLiteral(int index) const;\n"
"\n"
-" void getPosition(unsigned offset,\n"
-" unsigned *line,\n"
-" unsigned *column = 0,\n"
-" const StringLiteral **fileName = 0) const;\n"
+" void getPosition(int offset,\n"
+" int *line,\n"
+" int *column = nullptr,\n"
+" const StringLiteral **fileName = nullptr) const;\n"
"\n"
-" void getTokenPosition(unsigned index,\n"
-" unsigned *line,\n"
-" unsigned *column = 0,\n"
-" const StringLiteral **fileName = 0) const;\n"
+" void getTokenPosition(int index,\n"
+" int *line,\n"
+" int *column = nullptr,\n"
+" const StringLiteral **fileName = nullptr) const;\n"
"\n"
-" void getTokenStartPosition(unsigned index, unsigned *line, unsigned *column) const;\n"
-" void getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const;\n"
+" void getTokenStartPosition(int index, int *line, int *column) const;\n"
+" void getTokenEndPosition(int index, int *line, int *column) const;\n"
"\n"
" void accept(AST *ast);\n"
"\n"
@@ -1301,14 +1241,12 @@ void generateASTVisitor_H(const Snapshot &, const QDir &cplusplusDir,
" virtual void postVisit(AST *) {}\n";
out << "\n";
- foreach (const QByteArray &klass, classes) {
+ for (const QByteArray &klass : classes)
out << " virtual bool visit(" << klass << " *) { return true; }\n";
- }
out << "\n";
- foreach (const QByteArray &klass, classes) {
+ for (const QByteArray &klass : classes)
out << " virtual void endVisit(" << klass << " *) {}\n";
- }
out << "\n";
out <<
@@ -1391,8 +1329,6 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir, co
QList<QTextCursor> baseCastMethodCursors = removeCastMethods(astNodes.base);
QMap<ClassSpecifierAST *, QList<QTextCursor> > cursors;
QMap<ClassSpecifierAST *, QString> replacementCastMethods;
- QMap<ClassSpecifierAST *, QList<QTextCursor> > constructors;
- QMap<ClassSpecifierAST *, QString> replacementConstructors;
Overview oo;
@@ -1405,13 +1341,9 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir, co
= QString::fromLatin1(" virtual %1 *%2() { return this; }\n")
.arg(className, methodName);
castMethods.append(
- QString::fromLatin1(" virtual %1 *%2() { return 0; }\n")
+ QString::fromLatin1(" virtual %1 *%2() { return nullptr; }\n")
.arg(className, methodName));
astDerivedClasses.append(className);
-
- constructors[classAST] = removeConstructors(classAST, AST_h_document->translationUnit(),
- &document);
- replacementConstructors[classAST] = createConstructor(classAST);
}
if (! baseCastMethodCursors.isEmpty()) {
@@ -1432,16 +1364,8 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir, co
c[i].removeSelectedText();
}
}
- { // remove the constructors.
- QList<QTextCursor> c = constructors.value(classAST);
- for (int i = 0; i < c.length(); ++i) {
- c[i].removeSelectedText();
- }
- }
astNodes.endOfPublicClassSpecifiers[classIndex].insertText(
- replacementConstructors.value(classAST) +
- QLatin1String("\n") +
replacementCastMethods.value(classAST));
}
@@ -1540,9 +1464,8 @@ void generateASTFwd_h(const Snapshot &snapshot, const QDir &cplusplusDir, const
cursors[i].removeSelectedText();
QString replacement;
- foreach (const QString &astDerivedClass, astDerivedClasses) {
- replacement += QString(QLatin1String("class %1;\n")).arg(astDerivedClass);
- }
+ for (const QString &astDerivedClass : astDerivedClasses)
+ replacement += QString("class %1;\n").arg(astDerivedClass);
cursors.first().insertText(replacement);
@@ -1589,7 +1512,7 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
Control *control = AST_h_document->control();
QSet<QString> classesSet;
- foreach (ClassSpecifierAST *classNode, astNodes.deriveds) {
+ for (ClassSpecifierAST *classNode : qAsConst(astNodes.deriveds)) {
Class *klass = classNode->symbol;
const Identifier *match0_id = control->identifier("match0");
@@ -1616,7 +1539,7 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
QList<StringPair> args;
bool first = true;
- for (unsigned index = 0; index < klass->memberCount(); ++index) {
+ for (int index = 0; index < klass->memberCount(); ++index) {
Declaration *member = klass->memberAt(index)->asDeclaration();
if (! member)
continue;
@@ -1634,7 +1557,7 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
const QString memberName = oo(member->name());
- out << tyName << " *" << memberName << " = 0";
+ out << tyName << " *" << memberName << " = nullptr";
args.append(qMakePair(tyName, memberName));
first = false;
}
@@ -1646,9 +1569,8 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
<< " " << className << " *ast = new (&pool) " << className << ';' << endl;
- foreach (const StringPair &p, args) {
+ for (const StringPair &p : qAsConst(args))
out << " ast->" << p.second << " = " << p.second << ';' << endl;
- }
out
<< " return ast;" << endl
@@ -1658,7 +1580,7 @@ void generateASTPatternBuilder_h(const QDir &cplusplusDir)
QStringList classesList = classesSet.toList();
Utils::sort(classesList);
- foreach (const QString &className, classesList) {
+ for (const QString &className : qAsConst(classesList)) {
const QString methodName = className.left(className.length() - 3);
const QString elementName = className.left(className.length() - 7) + QLatin1String("AST");
out
diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg
index cb6e4836af..a846a4e26e 100644
--- a/src/tools/icons/qtcreatoricons.svg
+++ b/src/tools/icons/qtcreatoricons.svg
@@ -299,45 +299,6 @@
id="rect3235"
style="fill:none;stroke:none" />
</clipPath>
- <filter
- id="filter4057"
- inkscape:label="Inner Shadow"
- inkscape:menu="Shadows and Glows"
- inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
- color-interpolation-filters="sRGB">
- <feGaussianBlur
- id="feGaussianBlur4059"
- stdDeviation="1.5"
- result="result8" />
- <feOffset
- id="feOffset4061"
- dx="0"
- dy="2"
- result="result11" />
- <feComposite
- id="feComposite4063"
- in2="result11"
- result="result6"
- in="SourceGraphic"
- operator="in" />
- <feFlood
- id="feFlood4065"
- result="result10"
- in="result6"
- flood-opacity="1"
- flood-color="rgb(0,0,0)" />
- <feBlend
- id="feBlend4067"
- in2="result10"
- mode="normal"
- in="result6"
- result="result12" />
- <feComposite
- id="feComposite4069"
- in2="SourceGraphic"
- result="result2"
- operator="atop" />
- </filter>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3231">
@@ -553,6 +514,78 @@
fy="91.5"
r="18.5"
gradientUnits="userSpaceOnUse" />
+ <filter
+ style="color-interpolation-filters:sRGB;"
+ height="1"
+ width="1"
+ y="0"
+ x="0"
+ inkscape:label="Outline"
+ id="filter4057">
+ <feGaussianBlur
+ in="SourceAlpha"
+ stdDeviation="1"
+ result="blur1"
+ id="feGaussianBlur4140" />
+ <feComposite
+ in="blur1"
+ in2="SourceGraphic"
+ operator="out"
+ result="composite1"
+ id="feComposite4142" />
+ <feColorMatrix
+ values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 -0 "
+ result="colormatrix1"
+ id="feColorMatrix4144" />
+ <feGaussianBlur
+ stdDeviation="0.40000000000000002"
+ result="blur2"
+ id="feGaussianBlur4146" />
+ <feComposite
+ in="blur2"
+ in2="blur2"
+ operator="out"
+ result="composite2"
+ id="feComposite4148" />
+ <feColorMatrix
+ values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 -0 "
+ result="colormatrix2"
+ id="feColorMatrix4150" />
+ <feGaussianBlur
+ stdDeviation="0.5"
+ result="blur3"
+ id="feGaussianBlur4152" />
+ <feColorMatrix
+ values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
+ result="colormatrix3"
+ id="feColorMatrix4154" />
+ <feFlood
+ flood-opacity="1"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood4156" />
+ <feComposite
+ in="flood"
+ in2="colormatrix3"
+ k2="1"
+ operator="in"
+ result="composite3"
+ id="feComposite4158" />
+ <feComposite
+ in="SourceGraphic"
+ in2="colormatrix3"
+ operator="copy"
+ result="composite4"
+ id="feComposite4160" />
+ <feComposite
+ in="composite4"
+ in2="composite3"
+ k2="1"
+ k3="1"
+ operator="arithmetic"
+ result="composite5"
+ id="feComposite4162" />
+ </filter>
</defs>
<sodipodi:namedview
id="base"
@@ -2206,7 +2239,8 @@
</g>
<g
id="share/qtcreator/templates/wizards/projects/vcs/git/icon"
- transform="translate(0,-60)">
+ transform="translate(0,-60)"
+ style="filter:url(#filter4057)">
<use
style="display:inline"
x="0"
@@ -2225,7 +2259,8 @@
</g>
<g
id="src/plugins/genericprojectmanager/images/genericprojectmanager"
- transform="translate(60)">
+ transform="translate(60)"
+ style="filter:url(#filter4057)">
<use
style="display:inline"
x="0"
@@ -2252,7 +2287,8 @@
height="100%" />
<g
id="share/qtcreator/templates/wizards/projects/vcs/cvs/icon"
- transform="translate(120)">
+ transform="translate(120)"
+ style="filter:url(#filter4057)">
<use
style="display:inline"
x="0"
@@ -3182,6 +3218,51 @@
inkscape:connector-curvature="0" />
</g>
<g
+ transform="translate(-213,-84)"
+ id="src/plugins/python/images/settingscategory_python">
+ <use
+ style="display:inline"
+ transform="translate(1128,148)"
+ height="100%"
+ width="100%"
+ id="use2493"
+ xlink:href="#backgroundRect_24"
+ y="0"
+ x="0" />
+ <path
+ sodipodi:nodetypes="ccccccsssscc"
+ inkscape:connector-curvature="0"
+ id="path1631-9"
+ d="m 1112,567 v 1 h 4 v 1 h -4 c -5.3,0 -5.3,7 0,7 v -1.5 c 0,-1.5 1.5,-2.5 2.5,-2.5 h 2 c 1.8137,0 2.5,-0.75 2.5,-2.5 V 567 c 0,-2.66 -7,-2.66 -7,0 z"
+ style="stroke-width:0" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#path1631-9"
+ id="use2537"
+ transform="rotate(-180,1116,572.5)"
+ width="100%"
+ height="100%" />
+ <path
+ style="fill:#ffffff"
+ d="m 1121,570.75 c 0,1.75 -1.5,3.25 -3.5,3.25 h -2.5 c -0.66,0 -1,0.33 -1,1 v 3 c 0,0 -0.031,1 2.3654,1 1.7918,0 2.6346,0.21875 2.6346,-0.99998 h -4 v -3 h 5 c 4,0 3.5,-4.75 1,-4.75 z"
+ id="path2539"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sscccscccccs" />
+ <circle
+ style="fill:#ffffff"
+ id="path2541"
+ cx="1113.5"
+ cy="566.5"
+ r="0.625" />
+ <circle
+ style="fill:#000000"
+ id="path2541-4"
+ cx="1117.5"
+ cy="578.5"
+ r="0.5" />
+ </g>
+ <g
id="src/plugins/autotest/images/settingscategory_autotest"
transform="translate(-220,-84)">
<use
@@ -3646,6 +3727,75 @@
width="100%"
height="100%" />
</g>
+ <g
+ id="src/libs/utils/images/online"
+ transform="translate(176)"
+ style="display:inline">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use6217"
+ width="100%"
+ height="100%"
+ transform="translate(1740,132)"
+ style="display:inline" />
+ <circle
+ style="fill:none;stroke:#000000"
+ id="path6227"
+ cx="1732.5"
+ cy="575.5"
+ r="6" />
+ <ellipse
+ cy="575.5"
+ cx="1732.5"
+ id="circle6239"
+ style="fill:none;stroke:#000000"
+ ry="6"
+ rx="2.8299999" />
+ <path
+ id="path2519"
+ style="fill:none;stroke:#000000"
+ d="m 1727,572.5 h 11 m -11,6 h 11 m -11,-3 h 11"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc" />
+ </g>
+ <g
+ id="src/libs/utils/images/download_arrow">
+ <use
+ style="display:inline"
+ transform="translate(1932,132)"
+ height="100%"
+ width="100%"
+ id="use2519"
+ xlink:href="#backgroundRect"
+ y="0"
+ x="0" />
+ <path
+ id="use2530"
+ style="fill:#000000"
+ d="m 1925,578 h -2 v -8 h 2 z m -1,-0.5 4,-4 v 2 l -4,4 -4,-4 v -2 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccc" />
+ </g>
+ <g
+ id="src/libs/utils/images/download_base">
+ <use
+ x="0"
+ y="0"
+ xlink:href="#backgroundRect"
+ id="use2547"
+ width="100%"
+ height="100%"
+ transform="translate(1948,132)"
+ style="display:inline" />
+ <path
+ style="fill:none;stroke:#000000"
+ d="m 1934.5,579 v 2.5 h 11 V 579"
+ id="path2553"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ </g>
</g>
<g
inkscape:groupmode="layer"
@@ -7972,7 +8122,7 @@
style="opacity:0.2"
clip-path="url(#clipPath3231)">
<rect
- style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter4057)"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;"
id="rect4866"
width="14"
height="14"
@@ -10170,6 +10320,54 @@
height="100%" />
</g>
<g
+ id="src/plugins/webassembly/images/webassemblydevice"
+ transform="translate(-67.75,310.5)">
+ <use
+ height="100%"
+ width="100%"
+ id="use6196"
+ xlink:href="#backgroundRect_32_28"
+ y="0"
+ x="0"
+ style="display:inline"
+ transform="translate(458.75,5.5)" />
+ <path
+ sodipodi:nodetypes="czcccccc"
+ style="fill:#000000"
+ inkscape:connector-curvature="0"
+ d="m 519.75,48.5 c 0,1.5 -1.25,3 -3,3 -1.75,0 -3,-1.5 -3,-3 h -9 v 24 h 24 v -24 z"
+ id="path2499" />
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccc"
+ style="fill:#ffffff"
+ inkscape:connector-curvature="0"
+ d="m 510.13397,61.5 h 1.60194 l 1.1035,6.125017 L 514.1637,61.5 h 1.49846 l 1.19888,6.200194 L 518.11917,61.5 h 1.57114 l -2.04153,9 h -1.58969 L 514.86632,64.374983 513.59062,70.5 h -1.61932 z m 11.36247,0 h 2.52534 l 2.50797,9 h -1.65249 l -0.8658,-3 h -2.3347 l -0.64281,3 h -1.60945 z m 0.99617,2 -0.63495,3 h 1.97747 l -0.73843,-3 z"
+ id="path2501" />
+ </g>
+ <g
+ transform="translate(-138,27)"
+ id="src/plugins/webassembly/images/webassemblydevicesmall">
+ <use
+ transform="translate(586,-73)"
+ height="100%"
+ width="100%"
+ id="use6204"
+ xlink:href="#backgroundRect"
+ y="0"
+ x="0" />
+ <path
+ sodipodi:nodetypes="czcccccc"
+ style="fill:#000000"
+ inkscape:connector-curvature="0"
+ d="m 580,365 c 0,0.75 -0.5,2 -2,2 -1.5,0 -2,-1.25 -2,-2 h -4 v 12 h 12 v -12 z"
+ id="path2499-9" />
+ <path
+ id="path2526"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel"
+ d="m 579.5,373.5 h 3 m -3,2.5 v -4 l 1.5,-2 1.5,2 v 4 m -9,-6 v 3 l 1,3 1,-4 1,4 1,-3 v -3"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
id="src/plugins/winrt/images/winrtdevice"
transform="translate(-206,-74)">
<use
diff --git a/src/tools/iostool/iosdevicemanager.cpp b/src/tools/iostool/iosdevicemanager.cpp
index 53a9fd1625..f4a7fe08b9 100644
--- a/src/tools/iostool/iosdevicemanager.cpp
+++ b/src/tools/iostool/iosdevicemanager.cpp
@@ -1297,8 +1297,8 @@ void CommandSession::reportProgress(CFDictionaryRef dict)
void CommandSession::reportProgress2(int progress, const QString &status)
{
- Q_UNUSED(progress);
- Q_UNUSED(status);
+ Q_UNUSED(progress)
+ Q_UNUSED(status)
}
QString CommandSession::commandName()
diff --git a/src/tools/iostool/main.cpp b/src/tools/iostool/main.cpp
index f62c0c6180..8eccc68d17 100644
--- a/src/tools/iostool/main.cpp
+++ b/src/tools/iostool/main.cpp
@@ -31,7 +31,6 @@
#include <QDebug>
#include <QXmlStreamWriter>
#include <QFile>
-#include <QMapIterator>
#include <QScopedArrayPointer>
#include <QTcpServer>
#include <QSocketNotifier>
@@ -657,8 +656,8 @@ void IosTool::doExit(int errorCode)
void IosTool::isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
const QString &info)
{
- Q_UNUSED(bundlePath);
- Q_UNUSED(deviceId);
+ Q_UNUSED(bundlePath)
+ Q_UNUSED(deviceId)
QMutexLocker l(&m_xmlMutex);
out.writeStartElement(QLatin1String("status"));
out.writeAttribute(QLatin1String("progress"), QString::number(progress));
@@ -671,8 +670,8 @@ void IosTool::isTransferringApp(const QString &bundlePath, const QString &device
void IosTool::didTransferApp(const QString &bundlePath, const QString &deviceId,
Ios::IosDeviceManager::OpStatus status)
{
- Q_UNUSED(bundlePath);
- Q_UNUSED(deviceId);
+ Q_UNUSED(bundlePath)
+ Q_UNUSED(deviceId)
{
QMutexLocker l(&m_xmlMutex);
if (status == Ios::IosDeviceManager::Success) {
@@ -698,8 +697,8 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
Ios::IosDeviceManager::OpStatus status, int gdbFd,
Ios::DeviceSession *deviceSession)
{
- Q_UNUSED(bundlePath);
- Q_UNUSED(deviceId);
+ Q_UNUSED(bundlePath)
+ Q_UNUSED(deviceId)
{
QMutexLocker l(&m_xmlMutex);
out.writeEmptyElement(QLatin1String("app_started"));
@@ -811,14 +810,12 @@ void IosTool::writeMaybeBin(const QString &extraMsg, const char *msg, quintptr l
void IosTool::deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::Dict &devInfo)
{
- Q_UNUSED(deviceId);
+ Q_UNUSED(deviceId)
{
QMutexLocker l(&m_xmlMutex);
out.writeTextElement(QLatin1String("device_id"), deviceId);
out.writeStartElement(QLatin1String("device_info"));
- QMapIterator<QString,QString> i(devInfo);
- while (i.hasNext()) {
- i.next();
+ for (auto i = devInfo.cbegin(); i != devInfo.cend(); ++i) {
out.writeStartElement(QLatin1String("item"));
out.writeTextElement(QLatin1String("key"), i.key());
out.writeTextElement(QLatin1String("value"), i.value());
diff --git a/src/tools/perfparser b/src/tools/perfparser
-Subproject 02b36dd2c5fe4d1cf2970bc396fa665b199463d
+Subproject f649c278d88b45af1e10dd22a958315d02b3967
diff --git a/src/tools/qtcdebugger/main.cpp b/src/tools/qtcdebugger/main.cpp
index 6beda7c1ec..aa14dfe324 100644
--- a/src/tools/qtcdebugger/main.cpp
+++ b/src/tools/qtcdebugger/main.cpp
@@ -35,6 +35,7 @@
#include <QTextStream>
#include <QFileInfo>
#include <QByteArray>
+#include <QElapsedTimer>
#include <QSysInfo>
#include <QString>
#include <QDir>
@@ -322,7 +323,7 @@ bool startCreatorAsDebugger(bool asClient, QString *errorMessage)
qDebug() << binary << args;
QProcess p;
p.setWorkingDirectory(dir);
- QTime executionTime;
+ QElapsedTimer executionTime;
executionTime.start();
p.start(binary, args, QIODevice::NotOpen);
if (!p.waitForStarted()) {
diff --git a/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp b/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp
index fd24e6b543..1cfd8d7b59 100644
--- a/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp
+++ b/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp
@@ -154,9 +154,9 @@ CrashHandlerSetup::CrashHandlerSetup(const QString &appName,
}
}
#else
- Q_UNUSED(appName);
- Q_UNUSED(restartCap);
- Q_UNUSED(executableDirPath);
+ Q_UNUSED(appName)
+ Q_UNUSED(restartCap)
+ Q_UNUSED(executableDirPath)
#endif // BUILD_CRASH_HANDLER
}
diff --git a/src/tools/sdktool/CMakeLists.txt b/src/tools/sdktool/CMakeLists.txt
index 3997c9763c..02139c50aa 100644
--- a/src/tools/sdktool/CMakeLists.txt
+++ b/src/tools/sdktool/CMakeLists.txt
@@ -13,6 +13,7 @@ add_qtc_executable(sdktool
addkitoperation.cpp addkitoperation.h
addqtoperation.cpp addqtoperation.h
addtoolchainoperation.cpp addtoolchainoperation.h
+ addvalueoperation.cpp addvalueoperation.h
findkeyoperation.cpp findkeyoperation.h
findvalueoperation.cpp findvalueoperation.h
getoperation.cpp getoperation.h
@@ -28,13 +29,15 @@ add_qtc_executable(sdktool
settings.cpp settings.h
)
-extend_qtc_target(sdktool
+extend_qtc_executable(sdktool
SOURCES_PREFIX "${UtilsSourcesDir}"
DEFINES QTCREATOR_UTILS_STATIC_LIB
SOURCES
environment.cpp environment.h
fileutils.cpp fileutils.h
hostosinfo.cpp hostosinfo.h
+ namevaluedictionary.cpp namevaluedictionary.h
+ namevalueitem.cpp namevalueitem.h
persistentsettings.cpp persistentsettings.h
qtcassert.cpp qtcassert.h
qtcprocess.cpp qtcprocess.h
@@ -42,7 +45,7 @@ extend_qtc_target(sdktool
stringutils.cpp stringutils.h
)
-extend_qtc_target(sdktool CONDITION APPLE
+extend_qtc_executable(sdktool CONDITION APPLE
SOURCES_PREFIX "${UtilsSourcesDir}"
SOURCES
fileutils_mac.mm fileutils_mac.h
@@ -50,7 +53,7 @@ extend_qtc_target(sdktool CONDITION APPLE
${FWFoundation}
)
-extend_qtc_target(sdktool CONDITION WIN32
+extend_qtc_executable(sdktool CONDITION WIN32
DEPENDS
user32 iphlpapi ws2_32 shell32
DEFINES
diff --git a/src/tools/sdktool/addtoolchainoperation.cpp b/src/tools/sdktool/addtoolchainoperation.cpp
index afcab9a5e2..a5be70e877 100644
--- a/src/tools/sdktool/addtoolchainoperation.cpp
+++ b/src/tools/sdktool/addtoolchainoperation.cpp
@@ -264,7 +264,7 @@ QVariantMap AddToolChainOperation::addToolChain(const QVariantMap &map, const QS
QString newLang; // QtC 4.3 and later
QString oldLang; // QtC 4.2
int langInt = lang.toInt(&ok);
- Q_UNUSED(langInt);
+ Q_UNUSED(langInt)
if (lang == "2" || lang == "Cxx") {
newLang = "Cxx";
oldLang = "2";
diff --git a/src/tools/sdktool/addvalueoperation.cpp b/src/tools/sdktool/addvalueoperation.cpp
new file mode 100644
index 0000000000..a243ec53bd
--- /dev/null
+++ b/src/tools/sdktool/addvalueoperation.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Christoph Schlosser, B/S/H/ <christoph.schlosser@bshg.com>
+**
+** 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 "addvalueoperation.h"
+#include "addkeysoperation.h"
+#include "getoperation.h"
+#include "rmkeysoperation.h"
+
+#include <iomanip>
+#include <iostream>
+
+namespace {
+constexpr auto SUCCESS = 0;
+constexpr auto FAILURE = !SUCCESS;
+} // namespace
+
+QString AddValueOperation::name() const
+{
+ return QLatin1String("addValue");
+}
+
+QString AddValueOperation::helpText() const
+{
+ return QLatin1String("add a value to an existing list");
+}
+
+QString AddValueOperation::argumentsHelpText() const
+{
+ return QLatin1String(
+ "A file (relative to top-level settings directory and without .xml extension)\n"
+ "followed by the key of the list followed by one or more type:values to append to the "
+ "list.\n");
+}
+
+bool AddValueOperation::setArguments(const QStringList &args)
+{
+ if (args.size() < 3) {
+ std::cerr << "Error: No";
+ switch (args.size()) {
+ case 0:
+ std::cerr << " file,";
+ Q_FALLTHROUGH();
+ case 1:
+ std::cerr << " key and";
+ Q_FALLTHROUGH();
+ case 2:
+ std::cerr << " values";
+ break;
+ }
+ std::cerr << " given.\n" << std::endl;
+ return false;
+ }
+
+ auto tempArgs = args;
+ m_file = tempArgs.takeFirst();
+ m_key = tempArgs.takeFirst();
+ for (const auto &arg : tempArgs) {
+ const auto val = Operation::valueFromString(arg);
+ if (!val.isValid() || val.isNull()) {
+ std::cerr << "Error: " << std::quoted(arg.toStdString())
+ << " is not a valid QVariant like string Type:Value.\n"
+ << std::endl;
+ return false;
+ }
+ m_values.append(val);
+ }
+
+ return true;
+}
+
+int AddValueOperation::execute() const
+{
+ auto map = load(m_file);
+
+ if (map.empty()) {
+ std::cerr << "Error: Could not load " << m_file.toStdString() << std::endl;
+ return FAILURE;
+ }
+
+ auto status = appendListToMap(map, m_key, m_values);
+
+ if (status) {
+ status = save(map, m_file);
+ }
+
+ return status ? SUCCESS : FAILURE;
+}
+
+#ifdef WITH_TESTS
+bool AddValueOperation::test() const
+{
+ QVariantList testDataList;
+ testDataList.append(QLatin1String("Some String"));
+ testDataList.append(int(1860));
+
+ KeyValuePairList testKvpList;
+ testKvpList.append(KeyValuePair(QLatin1String("test/foo"), QString::fromLatin1("QString:Foo")));
+ testKvpList.append(KeyValuePair(QLatin1String("test/foobar"), QString::fromLatin1("int:42")));
+ testKvpList.append(KeyValuePair(QLatin1String("test/bar"), testDataList));
+
+ const auto valueList = QVariantList(
+ {Operation::valueFromString("QString:ELIL"), Operation::valueFromString("int:-1")});
+
+ QVariantMap testMap;
+
+ // add to empty map
+ auto result = appendListToMap(testMap, "some key", valueList);
+
+ if (result)
+ return false;
+
+ testMap.insert(QLatin1String("someEmptyThing"), QVariantMap());
+ testMap.insert(QLatin1String("aKey"), "withAString");
+
+ // append to a value
+ result = appendListToMap(testMap, "aKey", valueList);
+
+ if (result)
+ return false;
+
+ testMap = AddKeysOperation::addKeys(testMap, testKvpList);
+
+ // quick sanity check
+ if (testMap.count() != 3 && testDataList.count() != 2 && testKvpList.count() != 3)
+ return false;
+
+ // successful adding of values
+ result = appendListToMap(testMap, "test/bar", valueList);
+ if (!result)
+ return false;
+
+ const auto newList = qvariant_cast<QVariantList>(GetOperation::get(testMap, "test/bar"));
+ if (newList.count() != (testDataList.count() + valueList.count()))
+ return false;
+
+ if (!newList.contains(1860) || !newList.contains(QString("Some String"))
+ || !newList.contains("ELIL") || !newList.contains(-1))
+ return false;
+
+ return true;
+}
+#endif
+
+bool AddValueOperation::appendListToMap(QVariantMap &map,
+ const QString &key,
+ const QVariantList &values)
+{
+ const auto data = GetOperation::get(map, key);
+
+ if (!data.isValid() || data.isNull()) {
+ std::cerr << "Error: Could not retrieve value for key " << std::quoted(key.toStdString())
+ << std::endl;
+ return false;
+ }
+
+ if (!data.canConvert<QVariantList>()) {
+ std::cerr << "Error: Data stored in " << std::quoted(key.toStdString())
+ << " can not be converted into QVariantList." << std::endl;
+ return false;
+ }
+
+ auto newList = qvariant_cast<QVariantList>(data);
+
+ newList.append(values);
+
+ map = RmKeysOperation::rmKeys(map, {key});
+ map = AddKeysOperation::addKeys(map, {Operation::KeyValuePair(key, newList)});
+
+ return true;
+}
diff --git a/src/tools/sdktool/addvalueoperation.h b/src/tools/sdktool/addvalueoperation.h
new file mode 100644
index 0000000000..fe1910a227
--- /dev/null
+++ b/src/tools/sdktool/addvalueoperation.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2019 Christoph Schlosser, B/S/H/ <christoph.schlosser@bshg.com>
+** 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 "operation.h"
+
+class AddValueOperation : public Operation
+{
+public:
+ QString name() const override;
+ QString helpText() const override;
+ QString argumentsHelpText() const override;
+
+ bool setArguments(const QStringList &args) override;
+
+ int execute() const override;
+
+#ifdef WITH_TESTS
+ bool test() const override;
+#endif
+
+ static bool appendListToMap(QVariantMap &map, const QString &key, const QVariantList &values);
+
+private:
+ QString m_file;
+ QString m_key;
+ QVariantList m_values;
+};
diff --git a/src/tools/sdktool/main.cpp b/src/tools/sdktool/main.cpp
index 808a2652fa..c1ecb28746 100644
--- a/src/tools/sdktool/main.cpp
+++ b/src/tools/sdktool/main.cpp
@@ -35,6 +35,7 @@
#include "addkitoperation.h"
#include "addqtoperation.h"
#include "addtoolchainoperation.h"
+#include "addvalueoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
@@ -187,6 +188,7 @@ int main(int argc, char *argv[])
operations.emplace_back(std::make_unique<AddDeviceOperation>());
operations.emplace_back(std::make_unique<AddQtOperation>());
operations.emplace_back(std::make_unique<AddToolChainOperation>());
+ operations.emplace_back(std::make_unique<AddValueOperation>());
operations.emplace_back(std::make_unique<AddKitOperation>());
diff --git a/src/tools/sdktool/sdktool.pro b/src/tools/sdktool/sdktool.pro
index 9869d50dc4..1e6a676959 100644
--- a/src/tools/sdktool/sdktool.pro
+++ b/src/tools/sdktool/sdktool.pro
@@ -18,6 +18,7 @@ SOURCES += \
addkitoperation.cpp \
addqtoperation.cpp \
addtoolchainoperation.cpp \
+ addvalueoperation.cpp \
findkeyoperation.cpp \
findvalueoperation.cpp \
getoperation.cpp \
@@ -33,6 +34,8 @@ SOURCES += \
$$UTILS/environment.cpp \
$$UTILS/fileutils.cpp \
$$UTILS/hostosinfo.cpp \
+ $$UTILS/namevaluedictionary.cpp \
+ $$UTILS/namevalueitem.cpp \
$$UTILS/persistentsettings.cpp \
$$UTILS/qtcassert.cpp \
$$UTILS/qtcprocess.cpp \
@@ -48,6 +51,7 @@ HEADERS += \
addkitoperation.h \
addqtoperation.h \
addtoolchainoperation.h \
+ addvalueoperation.h \
findkeyoperation.h \
findvalueoperation.h \
getoperation.h \
@@ -63,6 +67,8 @@ HEADERS += \
$$UTILS/environment.h \
$$UTILS/fileutils.h \
$$UTILS/hostosinfo.h \
+ $$UTILS/namevaluedictionary.h \
+ $$UTILS/namevalueitem.h \
$$UTILS/persistentsettings.h \
$$UTILS/qtcassert.h \
$$UTILS/qtcprocess.h \
diff --git a/src/tools/sdktool/sdktool.qbs b/src/tools/sdktool/sdktool.qbs
index c26db6ad3f..8e6408971c 100644
--- a/src/tools/sdktool/sdktool.qbs
+++ b/src/tools/sdktool/sdktool.qbs
@@ -38,6 +38,8 @@ QtcTool {
"addqtoperation.h",
"addtoolchainoperation.cpp",
"addtoolchainoperation.h",
+ "addvalueoperation.cpp",
+ "addvalueoperation.h",
"findkeyoperation.cpp",
"findkeyoperation.h",
"findvalueoperation.cpp",
@@ -69,6 +71,8 @@ QtcTool {
"environment.cpp", "environment.h",
"fileutils.cpp", "fileutils.h",
"hostosinfo.cpp", "hostosinfo.h",
+ "namevaluedictionary.cpp", "namevaluedictionary.h",
+ "namevalueitem.cpp", "namevalueitem.h",
"persistentsettings.cpp", "persistentsettings.h",
"qtcassert.cpp", "qtcassert.h",
"qtcprocess.cpp", "qtcprocess.h",
diff --git a/src/tools/sdktool/settings.cpp b/src/tools/sdktool/settings.cpp
index 01f5120e16..971e9f47ea 100644
--- a/src/tools/sdktool/settings.cpp
+++ b/src/tools/sdktool/settings.cpp
@@ -33,7 +33,7 @@
#include <QCoreApplication>
#include <QDir>
-Settings *Settings::m_instance = 0;
+Settings *Settings::m_instance = nullptr;
Settings *Settings::instance()
{
@@ -41,7 +41,7 @@ Settings *Settings::instance()
}
Settings::Settings() :
- operation(0)
+ operation(nullptr)
{
Q_ASSERT(!m_instance);
m_instance = this;
diff --git a/src/tools/valgrindfake/outputgenerator.cpp b/src/tools/valgrindfake/outputgenerator.cpp
index d2c944dac7..d851eb1769 100644
--- a/src/tools/valgrindfake/outputgenerator.cpp
+++ b/src/tools/valgrindfake/outputgenerator.cpp
@@ -45,7 +45,7 @@ void doSleep(int msec) { ::Sleep(msec); }
void doSleep(int msec)
{
struct timespec ts = {msec / 1000, (msec % 1000) * 1000000};
- ::nanosleep(&ts, NULL);
+ ::nanosleep(&ts, nullptr);
}
#endif
@@ -107,7 +107,7 @@ void OutputGenerator::produceRuntimeError()
#ifndef __clang_analyzer__
int zero = 0; // hide the error at compile-time to avoid a compiler warning
int i = 1 / zero;
- Q_UNUSED(i);
+ Q_UNUSED(i)
#endif
Q_ASSERT(false);
} else if (m_garbage) {
diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp
index e444a4b8e5..eaac17ade3 100644
--- a/tests/auto/cplusplus/ast/tst_ast.cpp
+++ b/tests/auto/cplusplus/ast/tst_ast.cpp
@@ -92,7 +92,7 @@ public:
virtual void report(int /*level*/,
const StringLiteral *fileName,
- unsigned line, unsigned column,
+ int line, int column,
const char *format, va_list ap)
{
++errorCount;
@@ -301,7 +301,7 @@ void tst_AST::simple_name_1()
QVERIFY(ast != 0);
QVERIFY(ast->asIdExpression()->name->asSimpleName() != 0);
- QCOMPARE(ast->asIdExpression()->name->asSimpleName()->identifier_token, 1U);
+ QCOMPARE(ast->asIdExpression()->name->asSimpleName()->identifier_token, 1);
}
void tst_AST::template_id_1()
@@ -311,14 +311,14 @@ void tst_AST::template_id_1()
QVERIFY(ast != 0);
QVERIFY(ast->asIdExpression()->name->asTemplateId() != 0);
- QCOMPARE(ast->asIdExpression()->name->asTemplateId()->identifier_token, 1U);
- QCOMPARE(ast->asIdExpression()->name->asTemplateId()->less_token, 2U);
+ QCOMPARE(ast->asIdExpression()->name->asTemplateId()->identifier_token, 1);
+ QCOMPARE(ast->asIdExpression()->name->asTemplateId()->less_token, 2);
QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list != 0);
QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value != 0);
QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value->asNumericLiteral() != 0);
- QCOMPARE(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value->asNumericLiteral()->literal_token, 3U);
+ QCOMPARE(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value->asNumericLiteral()->literal_token, 3);
QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list->next == 0);
- QCOMPARE(ast->asIdExpression()->name->asTemplateId()->greater_token, 4U);
+ QCOMPARE(ast->asIdExpression()->name->asTemplateId()->greater_token, 4);
}
void tst_AST::new_expression_1()
@@ -333,12 +333,12 @@ void tst_AST::new_expression_1()
NewExpressionAST *expr = ast->asNewExpression();
QVERIFY(expr != 0);
- QCOMPARE(expr->scope_token, 0U);
- QCOMPARE(expr->new_token, 1U);
+ QCOMPARE(expr->scope_token, 0);
+ QCOMPARE(expr->new_token, 1);
QVERIFY(expr->new_placement == 0);
- QCOMPARE(expr->lparen_token, 0U);
+ QCOMPARE(expr->lparen_token, 0);
QVERIFY(expr->type_id == 0);
- QCOMPARE(expr->rparen_token, 0U);
+ QCOMPARE(expr->rparen_token, 0);
QVERIFY(expr->new_type_id != 0);
QVERIFY(expr->new_initializer == 0);
@@ -364,12 +364,12 @@ void tst_AST::new_expression_2()
NewExpressionAST *expr = stmt->expression->asNewExpression();
QVERIFY(expr != 0);
- QCOMPARE(expr->scope_token, 1U);
- QCOMPARE(expr->new_token, 2U);
+ QCOMPARE(expr->scope_token, 1);
+ QCOMPARE(expr->new_token, 2);
QVERIFY(expr->new_placement != 0);
- QCOMPARE(expr->lparen_token, 0U);
+ QCOMPARE(expr->lparen_token, 0);
QVERIFY(expr->type_id == 0);
- QCOMPARE(expr->rparen_token, 0U);
+ QCOMPARE(expr->rparen_token, 0);
QVERIFY(expr->new_type_id != 0);
QVERIFY(expr->new_initializer != 0);
}
@@ -868,23 +868,23 @@ void tst_AST::if_statement_1()
IfStatementAST *stmt = ast->asIfStatement();
QVERIFY(stmt != 0);
- QCOMPARE(stmt->if_token, 1U);
- QCOMPARE(stmt->lparen_token, 2U);
+ QCOMPARE(stmt->if_token, 1);
+ QCOMPARE(stmt->lparen_token, 2);
QVERIFY(stmt->condition != 0);
- QCOMPARE(stmt->rparen_token, 4U);
+ QCOMPARE(stmt->rparen_token, 4);
QVERIFY(stmt->statement != 0);
- QCOMPARE(stmt->else_token, 0U);
+ QCOMPARE(stmt->else_token, 0);
QVERIFY(stmt->else_statement == 0);
// check the `then' statement1
ExpressionStatementAST *then_stmt = stmt->statement->asExpressionStatement();
QVERIFY(then_stmt != 0);
QVERIFY(then_stmt->expression != 0);
- QCOMPARE(then_stmt->semicolon_token, 6U);
+ QCOMPARE(then_stmt->semicolon_token, 6);
SimpleNameAST *id_expr = then_stmt->expression->asIdExpression()->name->asSimpleName();
QVERIFY(id_expr != 0);
- QCOMPARE(id_expr->identifier_token, 5U);
+ QCOMPARE(id_expr->identifier_token, 5);
}
void tst_AST::if_statement_2()
@@ -924,33 +924,33 @@ void tst_AST::if_else_statement()
IfStatementAST *stmt = ast->asIfStatement();
QVERIFY(stmt != 0);
- QCOMPARE(stmt->if_token, 1U);
- QCOMPARE(stmt->lparen_token, 2U);
+ QCOMPARE(stmt->if_token, 1);
+ QCOMPARE(stmt->lparen_token, 2);
QVERIFY(stmt->condition != 0);
- QCOMPARE(stmt->rparen_token, 4U);
+ QCOMPARE(stmt->rparen_token, 4);
QVERIFY(stmt->statement != 0);
- QCOMPARE(stmt->else_token, 7U);
+ QCOMPARE(stmt->else_token, 7);
QVERIFY(stmt->else_statement != 0);
// check the `then' statement
ExpressionStatementAST *then_stmt = stmt->statement->asExpressionStatement();
QVERIFY(then_stmt != 0);
QVERIFY(then_stmt->expression != 0);
- QCOMPARE(then_stmt->semicolon_token, 6U);
+ QCOMPARE(then_stmt->semicolon_token, 6);
SimpleNameAST *a_id_expr = then_stmt->expression->asIdExpression()->name->asSimpleName();
QVERIFY(a_id_expr != 0);
- QCOMPARE(a_id_expr->identifier_token, 5U);
+ QCOMPARE(a_id_expr->identifier_token, 5);
// check the `then' statement
ExpressionStatementAST *else_stmt = stmt->else_statement->asExpressionStatement();
QVERIFY(else_stmt != 0);
QVERIFY(else_stmt->expression != 0);
- QCOMPARE(else_stmt->semicolon_token, 9U);
+ QCOMPARE(else_stmt->semicolon_token, 9);
SimpleNameAST *b_id_expr = else_stmt->expression->asIdExpression()->name->asSimpleName();
QVERIFY(b_id_expr != 0);
- QCOMPARE(b_id_expr->identifier_token, 8U);
+ QCOMPARE(b_id_expr->identifier_token, 8);
}
void tst_AST::while_statement()
@@ -962,22 +962,22 @@ void tst_AST::while_statement()
WhileStatementAST *stmt = ast->asWhileStatement();
QVERIFY(stmt != 0);
- QCOMPARE(stmt->while_token, 1U);
- QCOMPARE(stmt->lparen_token, 2U);
+ QCOMPARE(stmt->while_token, 1);
+ QCOMPARE(stmt->lparen_token, 2);
QVERIFY(stmt->condition != 0);
- QCOMPARE(stmt->rparen_token, 4U);
+ QCOMPARE(stmt->rparen_token, 4);
QVERIFY(stmt->statement != 0);
// check condition
QVERIFY(stmt->condition->asIdExpression()->name->asSimpleName() != 0);
- QCOMPARE(stmt->condition->asIdExpression()->name->asSimpleName()->identifier_token, 3U);
+ QCOMPARE(stmt->condition->asIdExpression()->name->asSimpleName()->identifier_token, 3);
// check the `body' statement
CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement();
QVERIFY(body_stmt != 0);
- QCOMPARE(body_stmt->lbrace_token, 5U);
+ QCOMPARE(body_stmt->lbrace_token, 5);
QVERIFY(body_stmt->statement_list == 0);
- QCOMPARE(body_stmt->rbrace_token, 6U);
+ QCOMPARE(body_stmt->rbrace_token, 6);
}
void tst_AST::while_condition_statement()
@@ -989,10 +989,10 @@ void tst_AST::while_condition_statement()
WhileStatementAST *stmt = ast->asWhileStatement();
QVERIFY(stmt != 0);
- QCOMPARE(stmt->while_token, 1U);
- QCOMPARE(stmt->lparen_token, 2U);
+ QCOMPARE(stmt->while_token, 1);
+ QCOMPARE(stmt->lparen_token, 2);
QVERIFY(stmt->condition != 0);
- QCOMPARE(stmt->rparen_token, 7U);
+ QCOMPARE(stmt->rparen_token, 7);
QVERIFY(stmt->statement != 0);
// check condition
@@ -1000,25 +1000,25 @@ void tst_AST::while_condition_statement()
QVERIFY(condition != 0);
QVERIFY(condition->type_specifier_list != 0);
QVERIFY(condition->type_specifier_list->value->asSimpleSpecifier() != 0);
- QCOMPARE(condition->type_specifier_list->value->asSimpleSpecifier()->specifier_token, 3U);
+ QCOMPARE(condition->type_specifier_list->value->asSimpleSpecifier()->specifier_token, 3);
QVERIFY(condition->type_specifier_list->next == 0);
QVERIFY(condition->declarator != 0);
QVERIFY(condition->declarator->core_declarator != 0);
QVERIFY(condition->declarator->core_declarator->asDeclaratorId() != 0);
QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name != 0);
QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName() != 0);
- QCOMPARE(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName()->identifier_token, 4U);
+ QCOMPARE(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName()->identifier_token, 4);
QVERIFY(condition->declarator->postfix_declarator_list == 0);
QVERIFY(condition->declarator->initializer != 0);
QVERIFY(condition->declarator->initializer->asIdExpression()->name->asSimpleName() != 0);
- QCOMPARE(condition->declarator->initializer->asIdExpression()->name->asSimpleName()->identifier_token, 6U);
+ QCOMPARE(condition->declarator->initializer->asIdExpression()->name->asSimpleName()->identifier_token, 6);
// check the `body' statement
CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement();
QVERIFY(body_stmt != 0);
- QCOMPARE(body_stmt->lbrace_token, 8U);
+ QCOMPARE(body_stmt->lbrace_token, 8);
QVERIFY(body_stmt->statement_list == 0);
- QCOMPARE(body_stmt->rbrace_token, 9U);
+ QCOMPARE(body_stmt->rbrace_token, 9);
}
void tst_AST::for_statement()
@@ -1029,20 +1029,20 @@ void tst_AST::for_statement()
ForStatementAST *stmt = ast->asForStatement();
QVERIFY(stmt != 0);
- QCOMPARE(stmt->for_token, 1U);
- QCOMPARE(stmt->lparen_token, 2U);
+ QCOMPARE(stmt->for_token, 1);
+ QCOMPARE(stmt->lparen_token, 2);
QVERIFY(stmt->initializer != 0);
QVERIFY(stmt->initializer->asExpressionStatement() != 0);
- QCOMPARE(stmt->initializer->asExpressionStatement()->semicolon_token, 3U);
+ QCOMPARE(stmt->initializer->asExpressionStatement()->semicolon_token, 3);
QVERIFY(stmt->condition == 0);
- QCOMPARE(stmt->semicolon_token, 4U);
+ QCOMPARE(stmt->semicolon_token, 4);
QVERIFY(stmt->expression == 0);
- QCOMPARE(stmt->rparen_token, 5U);
+ QCOMPARE(stmt->rparen_token, 5);
QVERIFY(stmt->statement != 0);
QVERIFY(stmt->statement->asCompoundStatement() != 0);
- QCOMPARE(stmt->statement->asCompoundStatement()->lbrace_token, 6U);
+ QCOMPARE(stmt->statement->asCompoundStatement()->lbrace_token, 6);
QVERIFY(stmt->statement->asCompoundStatement()->statement_list == 0);
- QCOMPARE(stmt->statement->asCompoundStatement()->rbrace_token, 7U);
+ QCOMPARE(stmt->statement->asCompoundStatement()->rbrace_token, 7);
}
void tst_AST::cpp_initializer_or_function_declaration()
@@ -1063,7 +1063,7 @@ void tst_AST::cpp_initializer_or_function_declaration()
QVERIFY(simple_decl->decl_specifier_list->next == 0);
QVERIFY(simple_decl->declarator_list != 0);
QVERIFY(simple_decl->declarator_list->next == 0);
- QCOMPARE(simple_decl->semicolon_token, 6U);
+ QCOMPARE(simple_decl->semicolon_token, 6);
NamedTypeSpecifierAST *named_ty = simple_decl->decl_specifier_list->value->asNamedTypeSpecifier();
QVERIFY(named_ty != 0);
@@ -1071,7 +1071,7 @@ void tst_AST::cpp_initializer_or_function_declaration()
SimpleNameAST *simple_named_ty = named_ty->name->asSimpleName();
QVERIFY(simple_named_ty != 0);
- QCOMPARE(simple_named_ty->identifier_token, 1U);
+ QCOMPARE(simple_named_ty->identifier_token, 1);
DeclaratorAST *declarator = simple_decl->declarator_list->value;
QVERIFY(declarator != 0);
@@ -1084,19 +1084,19 @@ void tst_AST::cpp_initializer_or_function_declaration()
QVERIFY(decl_id != 0);
QVERIFY(decl_id->name != 0);
QVERIFY(decl_id->name->asSimpleName() != 0);
- QCOMPARE(decl_id->name->asSimpleName()->identifier_token, 2U);
+ QCOMPARE(decl_id->name->asSimpleName()->identifier_token, 2);
FunctionDeclaratorAST *fun_declarator = declarator->postfix_declarator_list->value->asFunctionDeclarator();
QVERIFY(fun_declarator != 0);
- QCOMPARE(fun_declarator->lparen_token, 3U);
+ QCOMPARE(fun_declarator->lparen_token, 3);
QVERIFY(fun_declarator->parameter_declaration_clause != 0);
- QCOMPARE(fun_declarator->rparen_token, 5U);
+ QCOMPARE(fun_declarator->rparen_token, 5);
// check the formal arguments
ParameterDeclarationClauseAST *param_clause = fun_declarator->parameter_declaration_clause;
QVERIFY(param_clause->parameter_declaration_list != 0);
QVERIFY(param_clause->parameter_declaration_list->next == 0);
- QCOMPARE(param_clause->dot_dot_dot_token, 0U);
+ QCOMPARE(param_clause->dot_dot_dot_token, 0);
// check the parameter
ParameterDeclarationListAST *declarations = param_clause->parameter_declaration_list;
@@ -1111,7 +1111,7 @@ void tst_AST::cpp_initializer_or_function_declaration()
QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier() != 0);
QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier()->name != 0);
QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName() != 0);
- QCOMPARE(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U);
+ QCOMPARE(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4);
}
void tst_AST::cpp_constructor_one_unamed_arg()
@@ -2026,13 +2026,13 @@ void tst_AST::line_and_column_1()
QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
"int i;\n",
false, true));
- unsigned line, column = 0;
+ int line, column = 0;
QVERIFY(unit->ast());
QVERIFY(unit->tokenAt(1).is(T_INT));
unit->getTokenPosition(1, &line, &column);
QEXPECT_FAIL("", "See QTCREATORBUG-9799.", Continue);
- QCOMPARE(line, 2U);
- QCOMPARE(column, 1U);
+ QCOMPARE(line, 2);
+ QCOMPARE(column, 1);
}
QTEST_APPLESS_MAIN(tst_AST)
diff --git a/tests/auto/cplusplus/c99/tst_c99.cpp b/tests/auto/cplusplus/c99/tst_c99.cpp
index edcb5f955f..ddbea96278 100644
--- a/tests/auto/cplusplus/c99/tst_c99.cpp
+++ b/tests/auto/cplusplus/c99/tst_c99.cpp
@@ -75,7 +75,7 @@ class tst_c99: public QObject
virtual void report(int level,
const StringLiteral *fileName,
- unsigned line, unsigned column,
+ int line, int column,
const char *format, va_list ap)
{
if (! errors)
diff --git a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
index 2c2564f8d6..850e79e14f 100644
--- a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
+++ b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
@@ -147,7 +147,7 @@ public:
return document;
}
- Use findUse(unsigned line, unsigned column)
+ Use findUse(int line, int column)
{
const int resultCount = future.resultCount();
for (int i = resultCount - 1; i >= 0; --i) {
@@ -1326,8 +1326,8 @@ void tst_CheckSymbols::findField()
QVERIFY(position != -1);
QByteArray truncated = source;
truncated.truncate(position);
- const unsigned line = truncated.count('\n') + 1;
- const unsigned column = position - truncated.lastIndexOf('\n', position) + 1;
+ const int line = truncated.count('\n') + 1;
+ const int column = position - truncated.lastIndexOf('\n', position) + 1;
source[position] = ' ';
BaseTestCase tc(source);
Use use = tc.findUse(line, column);
diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
index abef7cc1e1..f6a3c24f91 100644
--- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
+++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp
@@ -77,8 +77,8 @@ class tst_cxx11: public QObject
virtual void report(int level,
const StringLiteral *fileName,
- unsigned line, unsigned column,
- const char *format, va_list ap)
+ int line, int column,
+ const char *format, va_list ap) override
{
if (! errors)
return;
diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp
index a1a5219f49..d961cb449d 100644
--- a/tests/auto/cplusplus/findusages/tst_findusages.cpp
+++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp
@@ -145,17 +145,17 @@ void tst_FindUsages::inlineMethod()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 1U);
+ QCOMPARE(doc->globalSymbolCount(), 1);
Snapshot snapshot;
snapshot.insert(doc);
Class *tst = doc->globalSymbolAt(0)->asClass();
QVERIFY(tst);
- QCOMPARE(tst->memberCount(), 1U);
+ QCOMPARE(tst->memberCount(), 1);
Function *method = tst->memberAt(0)->asFunction();
QVERIFY(method);
- QCOMPARE(method->argumentCount(), 1U);
+ QCOMPARE(method->argumentCount(), 1);
Argument *arg = method->argumentAt(0)->asArgument();
QVERIFY(arg);
QCOMPARE(arg->identifier()->chars(), "arg");
@@ -179,16 +179,16 @@ void tst_FindUsages::lambdaCaptureByValue()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 1U);
+ QCOMPARE(doc->globalSymbolCount(), 1);
Snapshot snapshot;
snapshot.insert(doc);
Function *f = doc->globalSymbolAt(0)->asFunction();
QVERIFY(f);
- QCOMPARE(f->memberCount(), 1U);
+ QCOMPARE(f->memberCount(), 1);
Block *b = f->memberAt(0)->asBlock();
- QCOMPARE(b->memberCount(), 2U);
+ QCOMPARE(b->memberCount(), 2);
Declaration *d = b->memberAt(0)->asDeclaration();
QVERIFY(d);
QCOMPARE(d->name()->identifier()->chars(), "test");
@@ -211,16 +211,16 @@ void tst_FindUsages::lambdaCaptureByReference()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 1U);
+ QCOMPARE(doc->globalSymbolCount(), 1);
Snapshot snapshot;
snapshot.insert(doc);
Function *f = doc->globalSymbolAt(0)->asFunction();
QVERIFY(f);
- QCOMPARE(f->memberCount(), 1U);
+ QCOMPARE(f->memberCount(), 1);
Block *b = f->memberAt(0)->asBlock();
- QCOMPARE(b->memberCount(), 2U);
+ QCOMPARE(b->memberCount(), 2);
Declaration *d = b->memberAt(0)->asDeclaration();
QVERIFY(d);
QCOMPARE(d->name()->identifier()->chars(), "test");
@@ -246,7 +246,7 @@ void tst_FindUsages::shadowedNames_1()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 5U);
+ QCOMPARE(doc->globalSymbolCount(), 5);
Snapshot snapshot;
snapshot.insert(doc);
@@ -275,7 +275,7 @@ void tst_FindUsages::shadowedNames_2()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 5U);
+ QCOMPARE(doc->globalSymbolCount(), 5);
Snapshot snapshot;
snapshot.insert(doc);
@@ -283,7 +283,7 @@ void tst_FindUsages::shadowedNames_2()
Class *c = doc->globalSymbolAt(1)->asClass();
QVERIFY(c);
QCOMPARE(c->name()->identifier()->chars(), "X");
- QCOMPARE(c->memberCount(), 1U);
+ QCOMPARE(c->memberCount(), 1);
Declaration *d = c->memberAt(0)->asDeclaration();
QVERIFY(d);
QCOMPARE(d->name()->identifier()->chars(), "a");
@@ -321,7 +321,7 @@ void tst_FindUsages::staticVariables()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
@@ -329,7 +329,7 @@ void tst_FindUsages::staticVariables()
Class *c = doc->globalSymbolAt(0)->asClass();
QVERIFY(c);
QCOMPARE(c->name()->identifier()->chars(), "Outer");
- QCOMPARE(c->memberCount(), 2U);
+ QCOMPARE(c->memberCount(), 2);
Declaration *d = c->memberAt(0)->asDeclaration();
QVERIFY(d);
QCOMPARE(d->name()->identifier()->chars(), "Foo");
@@ -361,7 +361,7 @@ void tst_FindUsages::objc_args()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
@@ -373,7 +373,7 @@ void tst_FindUsages::objc_args()
ObjCClass *iface = doc->globalSymbolAt(0)->asObjCClass();
QVERIFY(iface);
QVERIFY(iface->isInterface());
- QCOMPARE(iface->memberCount(), 1U);
+ QCOMPARE(iface->memberCount(), 1);
Declaration *methodIface = iface->memberAt(0)->asDeclaration();
QVERIFY(methodIface);
@@ -383,12 +383,12 @@ void tst_FindUsages::objc_args()
ObjCClass *impl = doc->globalSymbolAt(1)->asObjCClass();
QVERIFY(impl);
QVERIFY(!impl->isInterface());
- QCOMPARE(impl->memberCount(), 1U);
+ QCOMPARE(impl->memberCount(), 1);
ObjCMethod *methodImpl = impl->memberAt(0)->asObjCMethod();
QVERIFY(methodImpl);
QCOMPARE(methodImpl->identifier()->chars(), "method");
- QCOMPARE(methodImpl->argumentCount(), 1U);
+ QCOMPARE(methodImpl->argumentCount(), 1);
Argument *arg = methodImpl->argumentAt(0)->asArgument();
QCOMPARE(arg->identifier()->chars(), "arg");
@@ -417,18 +417,18 @@ void tst_FindUsages::qproperty_1()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 1U);
+ QCOMPARE(doc->globalSymbolCount(), 1);
Snapshot snapshot;
snapshot.insert(doc);
Class *tst = doc->globalSymbolAt(0)->asClass();
QVERIFY(tst);
- QCOMPARE(tst->memberCount(), 5U);
+ QCOMPARE(tst->memberCount(), 5);
Function *setX_method = tst->memberAt(2)->asFunction();
QVERIFY(setX_method);
QCOMPARE(setX_method->identifier()->chars(), "setX");
- QCOMPARE(setX_method->argumentCount(), 1U);
+ QCOMPARE(setX_method->argumentCount(), 1);
FindUsages findUsages(src, doc, snapshot);
findUsages(setX_method);
@@ -462,14 +462,14 @@ void tst_FindUsages::instantiateTemplateWithNestedClass()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
Class *classFoo = doc->globalSymbolAt(0)->asClass();
QVERIFY(classFoo);
- QCOMPARE(classFoo->memberCount(), 1U);
+ QCOMPARE(classFoo->memberCount(), 1);
Declaration *barDeclaration = classFoo->memberAt(0)->asDeclaration();
QVERIFY(barDeclaration);
QCOMPARE(barDeclaration->name()->identifier()->chars(), "bar");
@@ -507,13 +507,13 @@ void tst_FindUsages::operatorAsteriskOfNestedClassOfTemplateClass_QTCREATORBUG90
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
Class *classFoo = doc->globalSymbolAt(0)->asClass();
QVERIFY(classFoo);
- QCOMPARE(classFoo->memberCount(), 1U);
+ QCOMPARE(classFoo->memberCount(), 1);
Declaration *fooDeclaration = classFoo->memberAt(0)->asDeclaration();
QVERIFY(fooDeclaration);
QCOMPARE(fooDeclaration->name()->identifier()->chars(), "foo");
@@ -549,14 +549,14 @@ void tst_FindUsages::anonymousClass_QTCREATORBUG8963()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 5U);
+ QCOMPARE(doc->globalSymbolCount(), 5);
Snapshot snapshot;
snapshot.insert(doc);
Class *structSymbol = doc->globalSymbolAt(2)->asClass();
QVERIFY(structSymbol);
- QCOMPARE(structSymbol->memberCount(), 2U);
+ QCOMPARE(structSymbol->memberCount(), 2);
Declaration *isNotIntDeclaration = structSymbol->memberAt(1)->asDeclaration();
QVERIFY(isNotIntDeclaration);
QCOMPARE(isNotIntDeclaration->name()->identifier()->chars(), "isNotInt");
@@ -588,7 +588,7 @@ void tst_FindUsages::anonymousClass_QTCREATORBUG11859()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 4U);
+ QCOMPARE(doc->globalSymbolCount(), 4);
Snapshot snapshot;
snapshot.insert(doc);
@@ -597,7 +597,7 @@ void tst_FindUsages::anonymousClass_QTCREATORBUG11859()
QVERIFY(fooAsStruct);
Class *structSymbol = doc->globalSymbolAt(1)->asClass();
QVERIFY(structSymbol);
- QCOMPARE(structSymbol->memberCount(), 1U);
+ QCOMPARE(structSymbol->memberCount(), 1);
Declaration *fooAsMemberOfAnonymousStruct = structSymbol->memberAt(0)->asDeclaration();
QVERIFY(fooAsMemberOfAnonymousStruct);
QCOMPARE(fooAsMemberOfAnonymousStruct->name()->identifier()->chars(), "Foo");
@@ -633,14 +633,14 @@ void tst_FindUsages::using_insideGlobalNamespace()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
Namespace *nsSymbol = doc->globalSymbolAt(0)->asNamespace();
QVERIFY(nsSymbol);
- QCOMPARE(nsSymbol->memberCount(), 1U);
+ QCOMPARE(nsSymbol->memberCount(), 1);
Class *structSymbol = nsSymbol->memberAt(0)->asClass();
QVERIFY(structSymbol);
@@ -676,14 +676,14 @@ void tst_FindUsages::using_insideNamespace()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
Namespace *nsSymbol = doc->globalSymbolAt(0)->asNamespace();
QVERIFY(nsSymbol);
- QCOMPARE(nsSymbol->memberCount(), 1U);
+ QCOMPARE(nsSymbol->memberCount(), 1);
Class *structSymbol = nsSymbol->memberAt(0)->asClass();
QVERIFY(structSymbol);
@@ -716,14 +716,14 @@ void tst_FindUsages::using_insideFunction()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
Namespace *nsSymbol = doc->globalSymbolAt(0)->asNamespace();
QVERIFY(nsSymbol);
- QCOMPARE(nsSymbol->memberCount(), 1U);
+ QCOMPARE(nsSymbol->memberCount(), 1);
Class *structSymbol = nsSymbol->memberAt(0)->asClass();
QVERIFY(structSymbol);
@@ -760,14 +760,14 @@ void tst_FindUsages::operatorArrowOfNestedClassOfTemplateClass_QTCREATORBUG9005(
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
Class *classFoo = doc->globalSymbolAt(0)->asClass();
QVERIFY(classFoo);
- QCOMPARE(classFoo->memberCount(), 1U);
+ QCOMPARE(classFoo->memberCount(), 1);
Declaration *fooDeclaration = classFoo->memberAt(0)->asDeclaration();
QVERIFY(fooDeclaration);
QCOMPARE(fooDeclaration->name()->identifier()->chars(), "foo");
@@ -795,15 +795,15 @@ void tst_FindUsages::templateClassParameters()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 1U);
+ QCOMPARE(doc->globalSymbolCount(), 1);
Snapshot snapshot;
snapshot.insert(doc);
Template *templateClassTS = doc->globalSymbolAt(0)->asTemplate();
QVERIFY(templateClassTS);
- QCOMPARE(templateClassTS->memberCount(), 2U);
- QCOMPARE(templateClassTS->templateParameterCount(), 1U);
+ QCOMPARE(templateClassTS->memberCount(), 2);
+ QCOMPARE(templateClassTS->templateParameterCount(), 1);
TypenameArgument *templArgument = templateClassTS->templateParameterAt(0)->asTypenameArgument();
QVERIFY(templArgument);
@@ -837,7 +837,7 @@ void tst_FindUsages::templateClass_className()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
@@ -846,7 +846,7 @@ void tst_FindUsages::templateClass_className()
QVERIFY(templateClassTS);
Class *classTS = templateClassTS->memberAt(1)->asClass();
QVERIFY(classTS);
- QCOMPARE(classTS->memberCount(), 2U);
+ QCOMPARE(classTS->memberCount(), 2);
FindUsages findUsages(src, doc, snapshot);
findUsages(classTS);
@@ -869,15 +869,15 @@ void tst_FindUsages::templateFunctionParameters()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 1U);
+ QCOMPARE(doc->globalSymbolCount(), 1);
Snapshot snapshot;
snapshot.insert(doc);
Template *templateFunctionTS = doc->globalSymbolAt(0)->asTemplate();
QVERIFY(templateFunctionTS);
- QCOMPARE(templateFunctionTS->memberCount(), 2U);
- QCOMPARE(templateFunctionTS->templateParameterCount(), 1U);
+ QCOMPARE(templateFunctionTS->memberCount(), 2);
+ QCOMPARE(templateFunctionTS->templateParameterCount(), 1);
TypenameArgument *templArgument = templateFunctionTS->templateParameterAt(0)->asTypenameArgument();
QVERIFY(templArgument);
@@ -901,14 +901,14 @@ void tst_FindUsages::templatedFunction_QTCREATORBUG9749()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
Template *funcTempl = doc->globalSymbolAt(0)->asTemplate();
QVERIFY(funcTempl);
- QCOMPARE(funcTempl->memberCount(), 2U);
+ QCOMPARE(funcTempl->memberCount(), 2);
Function *func = funcTempl->memberAt(1)->asFunction();
FindUsages findUsages(src, doc, snapshot);
@@ -940,14 +940,14 @@ void tst_FindUsages::usingInDifferentNamespace_QTCREATORBUG7978()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 4U);
+ QCOMPARE(doc->globalSymbolCount(), 4);
Snapshot snapshot;
snapshot.insert(doc);
Namespace *ns = doc->globalSymbolAt(1)->asNamespace();
QVERIFY(ns);
- QCOMPARE(ns->memberCount(), 1U);
+ QCOMPARE(ns->memberCount(), 1);
Template *templateClass = ns->memberAt(0)->asTemplate();
FindUsages findUsages(src, doc, snapshot);
@@ -968,7 +968,7 @@ void tst_FindUsages::unicodeIdentifier()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
@@ -997,7 +997,7 @@ void tst_FindUsages::inAlignas()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
@@ -1037,7 +1037,7 @@ void tst_FindUsages::memberAccessAsTemplate()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 4U);
+ QCOMPARE(doc->globalSymbolCount(), 4);
Snapshot snapshot;
snapshot.insert(doc);
@@ -1060,7 +1060,7 @@ void tst_FindUsages::memberAccessAsTemplate()
Class *c = doc->globalSymbolAt(1)->asClass();
QVERIFY(c);
QCOMPARE(c->name()->identifier()->chars(), "Bar");
- QCOMPARE(c->memberCount(), 1U);
+ QCOMPARE(c->memberCount(), 1);
Template *f = c->memberAt(0)->asTemplate();
QVERIFY(f);
diff --git a/tests/auto/cplusplus/lexer/tst_lexer.cpp b/tests/auto/cplusplus/lexer/tst_lexer.cpp
index 1721efaedd..79548e6fd4 100644
--- a/tests/auto/cplusplus/lexer/tst_lexer.cpp
+++ b/tests/auto/cplusplus/lexer/tst_lexer.cpp
@@ -127,7 +127,7 @@ void tst_SimpleLexer::run(const QByteArray &source,
languageFeatures.flags |= extraLanguageFeatures.flags;
lexer.setLanguageFeatures(languageFeatures);
}
- const Tokens tokens = lexer(source, preserveState ? _state : 0);
+ const Tokens tokens = lexer(QString::fromUtf8(source), preserveState ? _state : 0);
if (preserveState)
_state = lexer.state();
@@ -277,7 +277,10 @@ void tst_SimpleLexer::literals()
QFETCH(QByteArray, source);
QFETCH(TokenKindList, expectedTokenKindList);
- run(source, toTokens(expectedTokenKindList), false, CompareKind);
+ LanguageFeatures features;
+ features.cxx14Enabled = true;
+ run(source, toTokens(expectedTokenKindList), false, CompareKind, false,
+ features);
}
void tst_SimpleLexer::literals_data()
@@ -320,14 +323,18 @@ void tst_SimpleLexer::literals_data()
source = // these are all the same
"42\n"
"0b101010u\n"
+ "0b101'010u\n"
"052ll\n"
+ "0'5'2ll\n"
"0x2aL\n"
+ "0x2'aL\n"
"123FOO\n"
"0xfOo\n"
"33_\n"
;
expectedTokenKindList =
TokenKindList() << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL
+ << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL << T_NUMERIC_LITERAL
<< T_NUMERIC_LITERAL << T_ERROR << T_ERROR << T_ERROR
;
QTest::newRow("integer-literals") << source << expectedTokenKindList;
diff --git a/tests/auto/cplusplus/lookup/tst_lookup.cpp b/tests/auto/cplusplus/lookup/tst_lookup.cpp
index 98af0cbc15..b9482d77df 100644
--- a/tests/auto/cplusplus/lookup/tst_lookup.cpp
+++ b/tests/auto/cplusplus/lookup/tst_lookup.cpp
@@ -119,7 +119,7 @@ void tst_Lookup::base_class_defined_1()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
@@ -238,7 +238,7 @@ void tst_Lookup::simple_class_1()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
@@ -246,12 +246,12 @@ void tst_Lookup::simple_class_1()
ObjCClass *iface = doc->globalSymbolAt(0)->asObjCClass();
QVERIFY(iface);
QVERIFY(iface->isInterface());
- QCOMPARE(iface->memberCount(), 2U);
+ QCOMPARE(iface->memberCount(), 2);
ObjCClass *impl = doc->globalSymbolAt(1)->asObjCClass();
QVERIFY(impl);
QVERIFY(!impl->isInterface());
- QCOMPARE(impl->memberCount(), 3U);
+ QCOMPARE(impl->memberCount(), 3);
Declaration *allocMethodIface = iface->memberAt(0)->asDeclaration();
QVERIFY(allocMethodIface);
@@ -301,7 +301,7 @@ void tst_Lookup::class_with_baseclass()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 3U);
+ QCOMPARE(doc->globalSymbolCount(), 3);
Snapshot snapshot;
snapshot.insert(doc);
@@ -311,7 +311,7 @@ void tst_Lookup::class_with_baseclass()
ObjCClass *baseZoo = doc->globalSymbolAt(0)->asObjCClass();
QVERIFY(baseZoo);
QVERIFY(!baseZoo->isInterface());
- QCOMPARE(baseZoo->memberCount(), 2U);
+ QCOMPARE(baseZoo->memberCount(), 2);
ObjCClass *zooIface = doc->globalSymbolAt(1)->asObjCClass();
QVERIFY(zooIface);
@@ -321,7 +321,7 @@ void tst_Lookup::class_with_baseclass()
ObjCClass *zooImpl = doc->globalSymbolAt(2)->asObjCClass();
QVERIFY(zooImpl);
QVERIFY(!zooImpl->isInterface());
- QCOMPARE(zooImpl->memberCount(), 3U);
+ QCOMPARE(zooImpl->memberCount(), 3);
Declaration *baseDecl = baseZoo->memberAt(0)->asDeclaration();
QVERIFY(baseDecl);
@@ -362,15 +362,15 @@ void tst_Lookup::class_with_protocol_with_protocol()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 4U);
+ QCOMPARE(doc->globalSymbolCount(), 4);
Snapshot snapshot;
snapshot.insert(doc);
ObjCProtocol *P1 = doc->globalSymbolAt(0)->asObjCProtocol();
QVERIFY(P1);
- QCOMPARE(P1->memberCount(), 1U);
- QCOMPARE(P1->protocolCount(), 0U);
+ QCOMPARE(P1->memberCount(), 1);
+ QCOMPARE(P1->protocolCount(), 0);
Declaration *p1method = P1->memberAt(0)->asDeclaration();
QVERIFY(p1method);
@@ -378,8 +378,8 @@ void tst_Lookup::class_with_protocol_with_protocol()
ObjCProtocol *P2 = doc->globalSymbolAt(1)->asObjCProtocol();
QVERIFY(P2);
- QCOMPARE(P2->memberCount(), 1U);
- QCOMPARE(P2->protocolCount(), 1U);
+ QCOMPARE(P2->memberCount(), 1);
+ QCOMPARE(P2->protocolCount(), 1);
QCOMPARE(QLatin1String(P2->protocolAt(0)->name()->identifier()->chars()), QLatin1String("P1"));
ObjCClass *zooImpl = doc->globalSymbolAt(3)->asObjCClass();
@@ -416,7 +416,7 @@ void tst_Lookup::iface_impl_scoping()
doc->check();
QVERIFY(doc->diagnosticMessages().isEmpty());
- QCOMPARE(doc->globalSymbolCount(), 2U);
+ QCOMPARE(doc->globalSymbolCount(), 2);
Snapshot snapshot;
snapshot.insert(doc);
@@ -428,15 +428,15 @@ void tst_Lookup::iface_impl_scoping()
QVERIFY(impl);
QVERIFY(!impl->isInterface());
- QCOMPARE(iface->memberCount(), 2U);
- QCOMPARE(impl->memberCount(), 1U);
+ QCOMPARE(iface->memberCount(), 2);
+ QCOMPARE(impl->memberCount(), 1);
ObjCMethod *method1Impl = impl->memberAt(0)->asObjCMethod();
QVERIFY(method1Impl);
QCOMPARE(method1Impl->identifier()->chars(), "method1");
// get the body of method1
- QCOMPARE(method1Impl->memberCount(), 2U);
+ QCOMPARE(method1Impl->memberCount(), 2);
Argument *method1Arg = method1Impl->memberAt(0)->asArgument();
QVERIFY(method1Arg);
QCOMPARE(method1Arg->identifier()->chars(), "arg");
@@ -448,7 +448,7 @@ void tst_Lookup::iface_impl_scoping()
const LookupContext context(doc, snapshot);
{ // verify if we can resolve "arg" in the body
- QCOMPARE(method1Impl->argumentCount(), 1U);
+ QCOMPARE(method1Impl->argumentCount(), 1);
Argument *arg = method1Impl->argumentAt(0)->asArgument();
QVERIFY(arg);
QVERIFY(arg->name());
diff --git a/tests/auto/cplusplus/misc/tst_misc.cpp b/tests/auto/cplusplus/misc/tst_misc.cpp
index 808408df40..e4dc6e7f07 100644
--- a/tests/auto/cplusplus/misc/tst_misc.cpp
+++ b/tests/auto/cplusplus/misc/tst_misc.cpp
@@ -68,8 +68,8 @@ void tst_Misc::diagnosticClient_error()
const Document::DiagnosticMessage &msg = diagnostics.at(0);
QCOMPARE(msg.level(), (int) Document::DiagnosticMessage::Error);
- QCOMPARE(msg.line(), 2U);
- QCOMPARE(msg.column(), 1U);
+ QCOMPARE(msg.line(), 2);
+ QCOMPARE(msg.column(), 1);
}
void tst_Misc::diagnosticClient_warning()
@@ -88,8 +88,8 @@ void tst_Misc::diagnosticClient_warning()
const Document::DiagnosticMessage &msg = diagnostics.at(0);
QCOMPARE(msg.level(), (int) Document::DiagnosticMessage::Warning);
- QCOMPARE(msg.line(), 1U);
- QCOMPARE(msg.column(), 17U);
+ QCOMPARE(msg.line(), 1);
+ QCOMPARE(msg.column(), 17);
}
void tst_Misc::findBreakpoints()
@@ -138,11 +138,11 @@ void tst_Misc::findBreakpoints()
QCOMPARE(doc->diagnosticMessages().size(), 0);
FindCdbBreakpoint findBreakpoint(doc->translationUnit());
- QCOMPARE(findBreakpoint(0), 5U);
- QCOMPARE(findBreakpoint(7), 8U);
- QCOMPARE(findBreakpoint(11), 16U);
- QCOMPARE(findBreakpoint(17), 23U);
- QCOMPARE(findBreakpoint(18), 23U);
+ QCOMPARE(findBreakpoint(0), 5);
+ QCOMPARE(findBreakpoint(7), 8);
+ QCOMPARE(findBreakpoint(11), 16);
+ QCOMPARE(findBreakpoint(17), 23);
+ QCOMPARE(findBreakpoint(18), 23);
}
void tst_Misc::findBreakpoints2()
@@ -167,14 +167,14 @@ void tst_Misc::findBreakpoints2()
QCOMPARE(doc->diagnosticMessages().size(), 0);
FindCdbBreakpoint findBreakpoint(doc->translationUnit());
- QCOMPARE(findBreakpoint(0), 2U);
- QCOMPARE(findBreakpoint(1), 2U);
- QCOMPARE(findBreakpoint(2), 2U);
- QCOMPARE(findBreakpoint(3), 3U);
- QCOMPARE(findBreakpoint(4), 5U);
- QCOMPARE(findBreakpoint(5), 5U);
- QCOMPARE(findBreakpoint(6), 6U);
- QCOMPARE(findBreakpoint(7), 7U);
+ QCOMPARE(findBreakpoint(0), 2);
+ QCOMPARE(findBreakpoint(1), 2);
+ QCOMPARE(findBreakpoint(2), 2);
+ QCOMPARE(findBreakpoint(3), 3);
+ QCOMPARE(findBreakpoint(4), 5);
+ QCOMPARE(findBreakpoint(5), 5);
+ QCOMPARE(findBreakpoint(6), 6);
+ QCOMPARE(findBreakpoint(7), 7);
}
void tst_Misc::findBreakpoints3()
@@ -197,11 +197,11 @@ void tst_Misc::findBreakpoints3()
QCOMPARE(doc->diagnosticMessages().size(), 0);
FindCdbBreakpoint findBreakpoint(doc->translationUnit());
- QCOMPARE(findBreakpoint(2), 3U);
- QCOMPARE(findBreakpoint(3), 3U);
- QCOMPARE(findBreakpoint(4), 5U);
- QCOMPARE(findBreakpoint(5), 5U);
- QCOMPARE(findBreakpoint(7), 7U);
+ QCOMPARE(findBreakpoint(2), 3);
+ QCOMPARE(findBreakpoint(3), 3);
+ QCOMPARE(findBreakpoint(4), 5);
+ QCOMPARE(findBreakpoint(5), 5);
+ QCOMPARE(findBreakpoint(7), 7);
}
static Document::Ptr documentCreatedWithFastPreprocessor(const QByteArray source)
diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp
index e00adbfe53..005ea5c1fa 100644
--- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp
+++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp
@@ -84,13 +84,13 @@ static bool compare(const QByteArray &actual, const QByteArray &expected)
struct Include
{
- Include(const QString &fileName, Client::IncludeType type, unsigned line)
+ Include(const QString &fileName, Client::IncludeType type, int line)
: fileName(fileName), type(type), line(line)
{}
QString fileName;
Client::IncludeType type;
- unsigned line;
+ int line;
};
QDebug &operator<<(QDebug& d, const Include &i)
@@ -108,10 +108,10 @@ class MockClient : public Client
public:
struct Block {
Block() : start(0), end(0) {}
- Block(unsigned start) : start(start), end(0) {}
+ Block(int start) : start(start), end(0) {}
- unsigned start;
- unsigned end;
+ int start;
+ int end;
};
public:
@@ -130,31 +130,31 @@ public:
m_definedMacrosLine.append(macro.line());
}
- virtual void passedMacroDefinitionCheck(unsigned /*bytesOffset*/,
- unsigned /*utf16charsOffset*/,
- unsigned line,
+ virtual void passedMacroDefinitionCheck(int /*bytesOffset*/,
+ int /*utf16charsOffset*/,
+ int line,
const Macro &macro)
{
m_definitionsResolvedFromLines[macro.name()].append(line);
}
- virtual void failedMacroDefinitionCheck(unsigned /*offset*/,
- unsigned /*utf16charsOffset*/,
+ virtual void failedMacroDefinitionCheck(int /*offset*/,
+ int /*utf16charsOffset*/,
const ByteArrayRef &name)
{
m_unresolvedDefines.insert(name.toByteArray());
}
- virtual void notifyMacroReference(unsigned bytesOffset, unsigned /*utf16charsOffset*/,
- unsigned line, const Macro &macro)
+ virtual void notifyMacroReference(int bytesOffset, int /*utf16charsOffset*/,
+ int line, const Macro &macro)
{
m_macroUsesLine[macro.name()].append(line);
m_expandedMacrosOffset.append(bytesOffset);
}
- virtual void startExpandingMacro(unsigned bytesOffset,
- unsigned /*utf16charsOffset*/,
- unsigned line,
+ virtual void startExpandingMacro(int bytesOffset,
+ int /*utf16charsOffset*/,
+ int line,
const Macro &macro,
const QVector<MacroArgumentReference> &actuals
= QVector<MacroArgumentReference>())
@@ -166,24 +166,24 @@ public:
m_usedMacros.insert(macro.name(), actuals);
}
- virtual void stopExpandingMacro(unsigned /*offset*/, const Macro &/*macro*/) {}
+ virtual void stopExpandingMacro(int /*offset*/, const Macro &/*macro*/) {}
- virtual void startSkippingBlocks(unsigned utf16charsOffset)
+ virtual void startSkippingBlocks(int utf16charsOffset)
{ m_skippedBlocks.append(Block(utf16charsOffset)); }
- virtual void stopSkippingBlocks(unsigned utf16charsOffset)
+ virtual void stopSkippingBlocks(int utf16charsOffset)
{ m_skippedBlocks.last().end = utf16charsOffset; }
- virtual void sourceNeeded(unsigned line, const QString &includedFileName, IncludeType mode,
+ virtual void sourceNeeded(int line, const QString &includedFileName, IncludeType mode,
const QStringList &initialIncludes = QStringList())
{
Q_UNUSED(initialIncludes)
#if 1
m_recordedIncludes.append(Include(includedFileName, mode, line));
- Q_UNUSED(m_env);
- Q_UNUSED(m_includeDepth);
+ Q_UNUSED(m_env)
+ Q_UNUSED(m_includeDepth)
#else
- Q_UNUSED(line);
+ Q_UNUSED(line)
QString resolvedFileName;
if (mode == IncludeLocal)
@@ -217,10 +217,8 @@ public:
dir = QFileInfo(currentFileName).dir();
const QFileInfo inc(dir, includedFileName);
if (inc.exists()) {
- const QString resolved = inc.filePath();
- return resolved.toUtf8().constData();
+ return inc.filePath();
} else {
- // std::cerr<<"Cannot find " << inc.fileName().toUtf8().constData()<<std::endl;
return QString();
}
}
@@ -267,19 +265,19 @@ public:
QList<QByteArray> expandedMacros() const
{ return m_expandedMacros; }
- QList<unsigned> expandedMacrosOffset() const
+ QList<int> expandedMacrosOffset() const
{ return m_expandedMacrosOffset; }
QList<QByteArray> definedMacros() const
{ return m_definedMacros; }
- QList<unsigned> definedMacrosLine() const
+ QList<int> definedMacrosLine() const
{ return m_definedMacrosLine; }
- QHash<QByteArray, QList<unsigned> > macroUsesLine() const
+ QHash<QByteArray, QList<int> > macroUsesLine() const
{ return m_macroUsesLine; }
- QHash<QByteArray, QList<unsigned> > definitionsResolvedFromLines() const
+ QHash<QByteArray, QList<int> > definitionsResolvedFromLines() const
{ return m_definitionsResolvedFromLines; }
QSet<QByteArray> unresolvedDefines() const
@@ -296,16 +294,16 @@ private:
QByteArray *m_output;
Preprocessor m_pp;
QList<QDir> m_includePaths;
- unsigned m_includeDepth;
+ int m_includeDepth;
QByteArray m_includeGuardMacro;
QList<Block> m_skippedBlocks;
QList<Include> m_recordedIncludes;
QList<QByteArray> m_expandedMacros;
- QList<unsigned> m_expandedMacrosOffset;
+ QList<int> m_expandedMacrosOffset;
QList<QByteArray> m_definedMacros;
- QList<unsigned> m_definedMacrosLine;
- QHash<QByteArray, QList<unsigned> > m_macroUsesLine;
- QHash<QByteArray, QList<unsigned> > m_definitionsResolvedFromLines;
+ QList<int> m_definedMacrosLine;
+ QHash<QByteArray, QList<int> > m_macroUsesLine;
+ QHash<QByteArray, QList<int> > m_definitionsResolvedFromLines;
QSet<QByteArray> m_unresolvedDefines;
QList<int> m_macroArgsCount;
QMap<QByteArray, QVector<MacroArgumentReference >> m_usedMacros;
@@ -313,10 +311,10 @@ private:
QT_BEGIN_NAMESPACE
namespace QTest {
- template<> char *toString(const QList<unsigned> &list)
+ template<> char *toString(const QList<int> &list)
{
- QByteArray ba = "QList<unsigned>(";
- foreach (const unsigned& item, list) {
+ QByteArray ba = "QList<int>(";
+ foreach (const int& item, list) {
ba += QTest::toString(item);
ba += ',';
}
@@ -418,8 +416,8 @@ QByteArray tst_Preprocessor::simplified(const QByteArray &buf)
QList<QByteArray> lines = buf.split('\n');
foreach (const QByteArray &line, lines) {
if (!line.startsWith('#')) {
- out.append(' ');
- out.append(line);
+ out.append(" ");
+ out.append(QString::fromUtf8(line));
}
}
@@ -545,10 +543,10 @@ void tst_Preprocessor::macro_args_offsets()
QFETCH(QString, fileName);
QFETCH(QByteArray, source);
QFETCH(QByteArray, macroName);
- QFETCH(unsigned, bytesOffset);
- QFETCH(unsigned, bytesLength);
- QFETCH(unsigned, utf16charsOffset);
- QFETCH(unsigned, utf16charsLength);
+ QFETCH(int, bytesOffset);
+ QFETCH(int, bytesLength);
+ QFETCH(int, utf16charsOffset);
+ QFETCH(int, utf16charsLength);
Environment env;
QByteArray output;
@@ -573,10 +571,10 @@ void tst_Preprocessor::macro_args_offsets_data()
QTest::addColumn<QString>("fileName");
QTest::addColumn<QByteArray>("source");
QTest::addColumn<QByteArray>("macroName");
- QTest::addColumn<unsigned>("bytesOffset");
- QTest::addColumn<unsigned>("bytesLength");
- QTest::addColumn<unsigned>("utf16charsOffset");
- QTest::addColumn<unsigned>("utf16charsLength");
+ QTest::addColumn<int>("bytesOffset");
+ QTest::addColumn<int>("bytesLength");
+ QTest::addColumn<int>("utf16charsOffset");
+ QTest::addColumn<int>("utf16charsLength");
QString fN = QLatin1String("<stdin>");
QByteArray src = QByteArray("#define SQR(a) ( a * a )\n"
@@ -585,26 +583,26 @@ void tst_Preprocessor::macro_args_offsets_data()
"int j = SQR(10);\n"
"}");
QTest::newRow("ascii_only_before_ref") << fN << src << QByteArray("SQR")
- << 59u << 2u << 59u << 2u;
+ << 59 << 2 << 59 << 2;
src.replace("int i", "int äöü");
QTest::newRow("ascii_with_umlauts_before_ref") << fN << src << QByteArray("SQR")
- << 64u << 2u << 61u << 2u;
+ << 64 << 2 << 61 << 2;
src.clear();
src.append("#define OUT(format, ...) printf(\"%s %d: \" format, __FILE__, __LINE__)\n"
"void f(){\n"
"OUT(\"Hei verden!\\n\");\n"
"}\n");
QTest::newRow("arg_ascii_only") << fN << src << QByteArray("OUT")
- << 84u << 15u << 84u << 15u;
+ << 84 << 15 << 84 << 15;
src.replace("Hei verden", UC_U00FC);
QTest::newRow("arg_ascii_with_unicode_00fc") << fN << src << QByteArray("OUT")
- << 84u << 7u << 84u << 6u;
+ << 84 << 7 << 84 << 6;
src.replace(UC_U00FC, UC_U4E8C);
QTest::newRow("arg_ascii_with_unicode_4e8c") << fN << src << QByteArray("OUT")
- << 84u << 8u << 84u << 6u;
+ << 84 << 8 << 84 << 6;
src.replace(UC_U4E8C, UC_U10302);
QTest::newRow("arg_ascii_with_unicode_10302") << fN << src << QByteArray("OUT")
- << 84u << 9u << 84u << 7u;
+ << 84 << 9 << 84 << 7;
}
void tst_Preprocessor::invalid_param_count()
@@ -643,9 +641,9 @@ void tst_Preprocessor::macro_uses()
QByteArray preprocessed = preprocess.run(QLatin1String("<stdin>"), buffer);
QVERIFY(compare(simplified(preprocessed), "void test(){int x=8;int y=9;}"));
QCOMPARE(client.expandedMacros(), QList<QByteArray>() << QByteArray("FOO") << QByteArray("BAR"));
- QCOMPARE(client.expandedMacrosOffset(), QList<unsigned>() << buffer.indexOf("FOO;") << buffer.indexOf("BAR;"));
+ QCOMPARE(client.expandedMacrosOffset(), QList<int>() << buffer.indexOf("FOO;") << buffer.indexOf("BAR;"));
QCOMPARE(client.definedMacros(), QList<QByteArray>() << QByteArray("FOO") << QByteArray("BAR"));
- QCOMPARE(client.definedMacrosLine(), QList<unsigned>() << 2 << 3);
+ QCOMPARE(client.definedMacrosLine(), QList<int>() << 2 << 3);
}
void tst_Preprocessor::macro_uses_lines()
@@ -680,14 +678,14 @@ void tst_Preprocessor::macro_uses_lines()
Preprocessor preprocess(&client, &env);
preprocess.run(QLatin1String("<stdin>"), buffer);
- QCOMPARE(client.macroUsesLine().value("FOO"), QList<unsigned>() << 2U << 23U);
- QCOMPARE(client.macroUsesLine().value("HEADER"), QList<unsigned>() << 5U);
- QCOMPARE(client.macroUsesLine().value("DECLARE"), QList<unsigned>() << 9U);
- QCOMPARE(client.macroUsesLine().value("NOTHING"), QList<unsigned>() << 13U);
- QCOMPARE(client.macroUsesLine().value("ENABLE"), QList<unsigned>() << 18U << 22U << 23U);
- QCOMPARE(client.macroUsesLine().value("ENABLE_COOL"), QList<unsigned>() << 21U);
- QCOMPARE(client.definitionsResolvedFromLines().value("ENABLE_COOL"), QList<unsigned>() << 18U);
- QCOMPARE(client.expandedMacrosOffset(), QList<unsigned>()
+ QCOMPARE(client.macroUsesLine().value("FOO"), QList<int>() << 2 << 23);
+ QCOMPARE(client.macroUsesLine().value("HEADER"), QList<int>() << 5);
+ QCOMPARE(client.macroUsesLine().value("DECLARE"), QList<int>() << 9);
+ QCOMPARE(client.macroUsesLine().value("NOTHING"), QList<int>() << 13);
+ QCOMPARE(client.macroUsesLine().value("ENABLE"), QList<int>() << 18 << 22 << 23);
+ QCOMPARE(client.macroUsesLine().value("ENABLE_COOL"), QList<int>() << 21);
+ QCOMPARE(client.definitionsResolvedFromLines().value("ENABLE_COOL"), QList<int>() << 18);
+ QCOMPARE(client.expandedMacrosOffset(), QList<int>()
<< buffer.lastIndexOf("FOO\n")
<< buffer.lastIndexOf("HEADER")
<< buffer.lastIndexOf("DECLARE")
@@ -1007,8 +1005,8 @@ void tst_Preprocessor::blockSkipping()
QList<MockClient::Block> blocks = client.skippedBlocks();
QCOMPARE(blocks.size(), 1);
MockClient::Block b = blocks.at(0);
- QCOMPARE(b.start, 6U);
- QCOMPARE(b.end, 34U);
+ QCOMPARE(b.start, 6);
+ QCOMPARE(b.end, 34);
}
void tst_Preprocessor::includes_1()
@@ -1034,16 +1032,16 @@ void tst_Preprocessor::includes_1()
QCOMPARE(incs.size(), 4);
QCOMPARE(incs.at(0).fileName, QLatin1String("foo.h"));
QCOMPARE(incs.at(0).type, Client::IncludeGlobal);
- QCOMPARE(incs.at(0).line, 4U);
+ QCOMPARE(incs.at(0).line, 4);
QCOMPARE(incs.at(1).fileName, QLatin1String("bar.h"));
QCOMPARE(incs.at(1).type, Client::IncludeLocal);
- QCOMPARE(incs.at(1).line, 5U);
+ QCOMPARE(incs.at(1).line, 5);
QCOMPARE(incs.at(2).fileName, QLatin1String("zoo.h"));
QCOMPARE(incs.at(2).type, Client::IncludeGlobal);
- QCOMPARE(incs.at(2).line, 7U);
+ QCOMPARE(incs.at(2).line, 7);
QCOMPARE(incs.at(3).fileName, QLatin1String("mooze.h"));
QCOMPARE(incs.at(3).type, Client::IncludeLocal);
- QCOMPARE(incs.at(3).line, 8U);
+ QCOMPARE(incs.at(3).line, 8);
}
void tst_Preprocessor::defined()
@@ -1202,10 +1200,10 @@ void tst_Preprocessor::defined_usage()
"#endif\n"
;
pp.run(QLatin1String("<stdin>"), source);
- QHash<QByteArray, QList<unsigned> > definitionsResolvedFromLines =
+ QHash<QByteArray, QList<int> > definitionsResolvedFromLines =
client.definitionsResolvedFromLines();
- QCOMPARE(definitionsResolvedFromLines["X"], QList<unsigned>() << 3 << 7 << 17 << 19);
- QCOMPARE(definitionsResolvedFromLines["Y"], QList<unsigned>() << 5 << 9 << 19);
+ QCOMPARE(definitionsResolvedFromLines["X"], QList<int>() << 3 << 7 << 17 << 19);
+ QCOMPARE(definitionsResolvedFromLines["Y"], QList<int>() << 5 << 9 << 19);
QCOMPARE(client.unresolvedDefines(), QSet<QByteArray>() << "ABSENT" << "ABSENT2" << "ABSENT3");
}
@@ -1989,27 +1987,27 @@ void tst_Preprocessor::undef()
Macro *macro = env.macroAt(0);
QCOMPARE(macro->name(), QByteArray("FOO"));
QCOMPARE(macro->bytesOffset(), 8U);
- QCOMPARE(macro->line(), 1U);
+ QCOMPARE(macro->line(), 1);
QVERIFY(!macro->isHidden());
macro = env.macroAt(1);
QCOMPARE(macro->name(), QByteArray("FOO2"));
QCOMPARE(macro->bytesOffset(), 20U);
- QCOMPARE(macro->line(), 2U);
+ QCOMPARE(macro->line(), 2);
QVERIFY(!macro->isHidden());
macro = env.macroAt(2);
QCOMPARE(macro->name(), QByteArray("FOO"));
QCOMPARE(macro->bytesOffset(), 32U);
- QCOMPARE(macro->line(), 3U);
+ QCOMPARE(macro->line(), 3);
QVERIFY(macro->isHidden());
macro = env.macroAt(3);
QCOMPARE(macro->name(), QByteArray("BAR"));
QCOMPARE(macro->bytesOffset(), 43U);
- QCOMPARE(macro->line(), 4U);
+ QCOMPARE(macro->line(), 4);
QVERIFY(macro->isHidden());
QList<QByteArray> macros = client.definedMacros();
QVERIFY(macros.contains("FOO"));
QVERIFY(macros.contains("FOO2"));
- QCOMPARE(client.macroUsesLine()["FOO"], (QList<unsigned>() << 3U));
+ QCOMPARE(client.macroUsesLine()["FOO"], (QList<int>() << 3));
QVERIFY(client.macroUsesLine()["BAR"].isEmpty());
}
diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp
index e13795154b..51c1fadf7e 100644
--- a/tests/auto/cplusplus/semantic/tst_semantic.cpp
+++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp
@@ -114,7 +114,7 @@ public:
virtual void report(int /*level*/,
const StringLiteral *fileName,
- unsigned line, unsigned column,
+ int line, int column,
const char *format, va_list ap)
{
++errorCount;
@@ -122,11 +122,11 @@ public:
#ifndef NO_PARSER_OR_SEMANTIC_ERROR_MESSAGES
qDebug() << fileName->chars()<<':'<<line<<':'<<column<<' ' << QString::vasprintf(format, ap);
#else
- Q_UNUSED(fileName);
- Q_UNUSED(line);
- Q_UNUSED(column);
- Q_UNUSED(format);
- Q_UNUSED(ap);
+ Q_UNUSED(fileName)
+ Q_UNUSED(line)
+ Q_UNUSED(column)
+ Q_UNUSED(format)
+ Q_UNUSED(ap)
#endif
}
};
@@ -198,7 +198,7 @@ void tst_Semantic::function_declaration_1()
{
QSharedPointer<Document> doc = document("void foo();");
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl);
@@ -207,7 +207,7 @@ void tst_Semantic::function_declaration_1()
Function *funTy = declTy->asFunctionType();
QVERIFY(funTy);
QVERIFY(funTy->returnType()->isVoidType());
- QCOMPARE(funTy->argumentCount(), 0U);
+ QCOMPARE(funTy->argumentCount(), 0);
QCOMPARE(funTy->refQualifier(), Function::NoRefQualifier);
QVERIFY(decl->name()->isNameId());
@@ -222,7 +222,7 @@ void tst_Semantic::function_declaration_2()
{
QSharedPointer<Document> doc = document("void foo(const QString &s);");
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl);
@@ -231,7 +231,7 @@ void tst_Semantic::function_declaration_2()
Function *funTy = declTy->asFunctionType();
QVERIFY(funTy);
QVERIFY(funTy->returnType()->isVoidType());
- QCOMPARE(funTy->argumentCount(), 1U);
+ QCOMPARE(funTy->argumentCount(), 1);
QCOMPARE(funTy->refQualifier(), Function::NoRefQualifier);
// check the formal argument.
@@ -351,7 +351,7 @@ void tst_Semantic::function_declaration_ref_qualifier()
return;
}
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl);
@@ -360,7 +360,7 @@ void tst_Semantic::function_declaration_ref_qualifier()
Function *funTy = declTy->asFunctionType();
QVERIFY(funTy);
QVERIFY(funTy->returnType()->isVoidType());
- QCOMPARE(funTy->argumentCount(), 0U);
+ QCOMPARE(funTy->argumentCount(), 0);
// check the ref-qualifier
QCOMPARE(funTy->refQualifier(), refQualifier);
@@ -370,12 +370,12 @@ void tst_Semantic::function_definition_1()
{
QSharedPointer<Document> doc = document("void foo() {}");
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Function *funTy = doc->globals->memberAt(0)->asFunction();
QVERIFY(funTy);
QVERIFY(funTy->returnType()->isVoidType());
- QCOMPARE(funTy->argumentCount(), 0U);
+ QCOMPARE(funTy->argumentCount(), 0);
QCOMPARE(funTy->refQualifier(), Function::NoRefQualifier);
QVERIFY(funTy->name()->isNameId());
@@ -398,7 +398,7 @@ void tst_Semantic::nested_class_1()
"};\n"
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 2U);
+ QCOMPARE(doc->globals->memberCount(), 2);
Class *classObject = doc->globals->memberAt(0)->asClass();
QVERIFY(classObject);
@@ -407,8 +407,8 @@ void tst_Semantic::nested_class_1()
QVERIFY(classObjectNameId);
const Identifier *objectId = classObjectNameId->identifier();
QCOMPARE(QByteArray(objectId->chars(), objectId->size()), QByteArray("Object"));
- QCOMPARE(classObject->baseClassCount(), 0U);
- QCOMPARE(classObject->memberCount(), 2U);
+ QCOMPARE(classObject->baseClassCount(), 0);
+ QCOMPARE(classObject->memberCount(), 2);
Class *classObjectData = doc->globals->memberAt(1)->asClass();
QVERIFY(classObjectData);
@@ -439,7 +439,7 @@ void tst_Semantic::alias_declaration_1()
, false, false, true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl->name());
@@ -464,11 +464,11 @@ void tst_Semantic::typedef_1()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 3U);
+ QCOMPARE(doc->globals->memberCount(), 3);
Class *anonStruct = doc->globals->memberAt(0)->asClass();
QVERIFY(anonStruct);
- QCOMPARE(anonStruct->memberCount(), 2U);
+ QCOMPARE(anonStruct->memberCount(), 2);
Declaration *typedefPointDecl = doc->globals->memberAt(1)->asDeclaration();
QVERIFY(typedefPointDecl);
@@ -493,11 +493,11 @@ void tst_Semantic::typedef_2()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 3U);
+ QCOMPARE(doc->globals->memberCount(), 3);
Class *_pointStruct= doc->globals->memberAt(0)->asClass();
QVERIFY(_pointStruct);
- QCOMPARE(_pointStruct->memberCount(), 2U);
+ QCOMPARE(_pointStruct->memberCount(), 2);
Declaration *typedefPointDecl = doc->globals->memberAt(1)->asDeclaration();
QVERIFY(typedefPointDecl);
@@ -518,11 +518,11 @@ void tst_Semantic::typedef_3()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 2U);
+ QCOMPARE(doc->globals->memberCount(), 2);
Class *_pointStruct= doc->globals->memberAt(0)->asClass();
QVERIFY(_pointStruct);
- QCOMPARE(_pointStruct->memberCount(), 2U);
+ QCOMPARE(_pointStruct->memberCount(), 2);
Declaration *typedefPointDecl = doc->globals->memberAt(1)->asDeclaration();
QVERIFY(typedefPointDecl);
@@ -539,14 +539,14 @@ void tst_Semantic::const_1()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl);
QVERIFY(decl->type()->isFunctionType());
Function *funTy = decl->type()->asFunctionType();
QVERIFY(funTy->returnType()->isIntegerType());
- QCOMPARE(funTy->argumentCount(), 1U);
+ QCOMPARE(funTy->argumentCount(), 1);
Argument *arg = funTy->argumentAt(0)->asArgument();
QVERIFY(arg);
QVERIFY(! arg->type().isConst());
@@ -562,14 +562,14 @@ void tst_Semantic::const_2()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl);
QVERIFY(decl->type()->isFunctionType());
Function *funTy = decl->type()->asFunctionType();
QVERIFY(funTy->returnType()->isIntegerType());
- QCOMPARE(funTy->argumentCount(), 1U);
+ QCOMPARE(funTy->argumentCount(), 1);
Argument *arg = funTy->argumentAt(0)->asArgument();
QVERIFY(arg);
QVERIFY(arg->type().isConst());
@@ -582,7 +582,7 @@ void tst_Semantic::pointer_to_function_1()
{
QSharedPointer<Document> doc = document("void (*QtSomething)();");
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Declaration *decl = doc->globals->memberAt(0)->asDeclaration();
QVERIFY(decl);
@@ -604,7 +604,7 @@ void tst_Semantic::template_instance_1()
{
QSharedPointer<Document> doc = document("template <typename _Tp> class QList { void append(const _Tp &value); };");
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Template *templ = doc->globals->memberAt(0)->asTemplate();
QVERIFY(templ);
@@ -716,17 +716,17 @@ void tst_Semantic::objcClass_1()
true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 2U);
+ QCOMPARE(doc->globals->memberCount(), 2);
ObjCClass *iface = doc->globals->memberAt(0)->asObjCClass();
QVERIFY(iface);
QVERIFY(iface->isInterface());
- QCOMPARE(iface->memberCount(), 2U);
+ QCOMPARE(iface->memberCount(), 2);
ObjCClass *impl = doc->globals->memberAt(1)->asObjCClass();
QVERIFY(impl);
QVERIFY(!impl->isInterface());
- QCOMPARE(impl->memberCount(), 3U);
+ QCOMPARE(impl->memberCount(), 3);
ObjCMethod *allocMethod = impl->memberAt(0)->asObjCMethod();
QVERIFY(allocMethod);
@@ -750,19 +750,19 @@ void tst_Semantic::objcSelector_1()
true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
ObjCClass *iface = doc->globals->memberAt(0)->asObjCClass();
QVERIFY(iface);
QVERIFY(iface->isInterface());
- QCOMPARE(iface->memberCount(), 1U);
+ QCOMPARE(iface->memberCount(), 1);
Declaration *decl = iface->memberAt(0)->asDeclaration();
QVERIFY(decl);
QVERIFY(decl->name());
const SelectorNameId *selId = decl->name()->asSelectorNameId();
QVERIFY(selId);
- QCOMPARE(selId->nameCount(), 3U);
+ QCOMPARE(selId->nameCount(), 3);
QCOMPARE(selId->nameAt(0)->identifier()->chars(), "a");
QCOMPARE(selId->nameAt(1)->identifier()->chars(), "b");
QCOMPARE(selId->nameAt(2)->identifier()->chars(), "c");
@@ -796,11 +796,11 @@ void tst_Semantic::objcSelector_2()
true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
ObjCClass *iface = doc->globals->memberAt(0)->asObjCClass();
QVERIFY(iface);
- QCOMPARE(iface->memberCount(), 1U);
+ QCOMPARE(iface->memberCount(), 1);
QList<ObjCSelectorAST*>selectors = CollectSelectors(doc->unit)();
QCOMPARE(selectors.size(), 2);
@@ -810,7 +810,7 @@ void tst_Semantic::objcSelector_2()
const SelectorNameId *selId = sel->name->asSelectorNameId();
QVERIFY(selId);
- QCOMPARE(selId->nameCount(), 3U);
+ QCOMPARE(selId->nameCount(), 3);
QCOMPARE(selId->nameAt(0)->identifier()->chars(), "a");
QCOMPARE(selId->nameAt(1)->identifier()->chars(), "b");
QCOMPARE(selId->nameAt(2)->identifier()->chars(), "c");
@@ -827,7 +827,7 @@ void tst_Semantic::q_enum_1()
false, true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
QVERIFY(doc->unit);
TranslationUnitAST *xUnit = doc->unit->ast()->asTranslationUnit();
QVERIFY(xUnit);
@@ -851,7 +851,7 @@ void tst_Semantic::lambda_1()
"}\n", false, false, true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
}
void tst_Semantic::lambda_2()
@@ -864,15 +864,15 @@ void tst_Semantic::lambda_2()
, false, false, true);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Class *A = doc->globals->memberAt(0)->asClass();
QVERIFY(A);
- QCOMPARE(A->memberCount(), 1U);
+ QCOMPARE(A->memberCount(), 1);
Declaration *d = A->memberAt(0)->asDeclaration();
QCOMPARE(d->name()->identifier()->chars(), "f");
Function *ty = d->type()->asFunctionType();
QVERIFY(ty);
- QCOMPARE(ty->argumentCount(), 1U);
+ QCOMPARE(ty->argumentCount(), 1);
Argument *arg = ty->argumentAt(0)->asArgument();
QVERIFY(arg);
const StringLiteral *init = arg->initializer();
@@ -888,7 +888,7 @@ void tst_Semantic::diagnostic_error()
false, false);
QCOMPARE(doc->errorCount, 1U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
}
namespace {
@@ -916,10 +916,10 @@ void tst_Semantic::enum_constantValue1()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Enum *e = doc->globals->memberAt(0)->asEnum();
QVERIFY(e);
- QCOMPARE(e->memberCount(), 3U);
+ QCOMPARE(e->memberCount(), 3);
testEnumaratorDeclarator(e, 0, "0");
testEnumaratorDeclarator(e, 1, "1");
@@ -937,10 +937,10 @@ void tst_Semantic::enum_constantValue2()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Enum *e = doc->globals->memberAt(0)->asEnum();
QVERIFY(e);
- QCOMPARE(e->memberCount(), 3U);
+ QCOMPARE(e->memberCount(), 3);
testEnumaratorDeclarator(e, 0, "10");
testEnumaratorDeclarator(e, 1, "11");
@@ -958,10 +958,10 @@ void tst_Semantic::enum_constantValue3()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Enum *e = doc->globals->memberAt(0)->asEnum();
QVERIFY(e);
- QCOMPARE(e->memberCount(), 3U);
+ QCOMPARE(e->memberCount(), 3);
testEnumaratorDeclarator(e, 0, "0");
testEnumaratorDeclarator(e, 1, "10");
@@ -981,10 +981,10 @@ void tst_Semantic::enum_constantValue4()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Enum *e = doc->globals->memberAt(0)->asEnum();
QVERIFY(e);
- QCOMPARE(e->memberCount(), 5U);
+ QCOMPARE(e->memberCount(), 5);
testEnumaratorDeclarator(e, 0, "0");
testEnumaratorDeclarator(e, 1, "E1+10");
@@ -1006,10 +1006,10 @@ void tst_Semantic::enum_constantValue5()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Enum *e = doc->globals->memberAt(0)->asEnum();
QVERIFY(e);
- QCOMPARE(e->memberCount(), 5U);
+ QCOMPARE(e->memberCount(), 5);
testEnumaratorDeclarator(e, 0, "0");
testEnumaratorDeclarator(e, 1, "0");
@@ -1030,10 +1030,10 @@ void tst_Semantic::enum_constantValueNegative()
);
QCOMPARE(doc->errorCount, 0U);
- QCOMPARE(doc->globals->memberCount(), 1U);
+ QCOMPARE(doc->globals->memberCount(), 1);
Enum *e = doc->globals->memberAt(0)->asEnum();
QVERIFY(e);
- QCOMPARE(e->memberCount(), 4U);
+ QCOMPARE(e->memberCount(), 4);
testEnumaratorDeclarator(e, 0, "-2");
testEnumaratorDeclarator(e, 1, "-1");
diff --git a/tests/auto/cplusplus/translationunit/tst_translationunit.cpp b/tests/auto/cplusplus/translationunit/tst_translationunit.cpp
index 2c651676bc..12dfd8960c 100644
--- a/tests/auto/cplusplus/translationunit/tst_translationunit.cpp
+++ b/tests/auto/cplusplus/translationunit/tst_translationunit.cpp
@@ -40,9 +40,9 @@
struct LineColumn
{
- LineColumn(unsigned line = 0, unsigned column = 0) : line(line), column(column) {}
- unsigned line;
- unsigned column;
+ LineColumn(int line = 0, int column = 0) : line(line), column(column) {}
+ int line;
+ int column;
};
typedef QList<LineColumn> LineColumnList;
Q_DECLARE_METATYPE(LineColumnList)
@@ -128,8 +128,8 @@ private:
Diagnostic() : errorCount(0) {}
- void report(int /*level*/, const StringLiteral *fileName, unsigned line,
- unsigned column, const char *format, va_list ap)
+ void report(int /*level*/, const StringLiteral *fileName, int line,
+ int column, const char *format, va_list ap)
{
++errorCount;
qDebug() << fileName->chars() << ':' << line << ':' << column
@@ -145,8 +145,8 @@ private:
public:
TokenGetter(TranslationUnit *translationUnit) : m_translationUnit(translationUnit) {}
virtual ~TokenGetter() {}
- virtual unsigned tokenCount() { return m_translationUnit->tokenCount(); }
- virtual Token tokenAt(unsigned index) { return m_translationUnit->tokenAt(index); }
+ virtual int tokenCount() { return m_translationUnit->tokenCount(); }
+ virtual Token tokenAt(int index) { return m_translationUnit->tokenAt(index); }
protected:
TranslationUnit *m_translationUnit;
};
@@ -155,8 +155,8 @@ private:
{
public:
CommentTokenGetter(TranslationUnit *translationUnit) : TokenGetter(translationUnit) {}
- unsigned tokenCount() { return m_translationUnit->commentCount(); }
- Token tokenAt(unsigned index) { return m_translationUnit->commentAt(index); }
+ int tokenCount() override { return m_translationUnit->commentCount(); }
+ Token tokenAt(int index) override { return m_translationUnit->commentAt(index); }
};
static void compareTokenLocations(TranslationUnit *translationUnit,
@@ -168,11 +168,11 @@ void tst_TranslationUnit::compareTokenLocations(TranslationUnit *translationUnit
tst_TranslationUnit::TokenGetter *tokenGetter,
const LineColumnList &expectedLinesColumns)
{
- QCOMPARE(tokenGetter->tokenCount(), (unsigned) expectedLinesColumns.count());
- for (unsigned i = 0, tokenCount = tokenGetter->tokenCount(); i < tokenCount; ++i) {
+ QCOMPARE(tokenGetter->tokenCount(), expectedLinesColumns.count());
+ for (int i = 0, tokenCount = tokenGetter->tokenCount(); i < tokenCount; ++i) {
const LineColumn expected = expectedLinesColumns.at(i);
- const unsigned utf16CharOffset = tokenGetter->tokenAt(i).utf16charsBegin();
- unsigned line, column;
+ const int utf16CharOffset = tokenGetter->tokenAt(i).utf16charsBegin();
+ int line, column;
translationUnit->getPosition(utf16CharOffset, &line, &column);
// qDebug("%d: LineColumn(%u, %u)", i, line, column);
QCOMPARE(line, expected.line);
@@ -222,7 +222,7 @@ static QByteArray stripEncodingPrefixAndQuotationMarks(const QByteArray &literal
Q_ASSERT(firstQuotationMarkPosition != -1);
Q_ASSERT(lastQuotationMarkPosition == literal.size() - 1);
Q_ASSERT(firstQuotationMarkPosition < lastQuotationMarkPosition - 1);
- Q_UNUSED(lastQuotationMarkPosition);
+ Q_UNUSED(lastQuotationMarkPosition)
QByteArray result = literal.mid(firstQuotationMarkPosition + 1);
result.chop(1);
diff --git a/tests/auto/debugger/CMakeLists.txt b/tests/auto/debugger/CMakeLists.txt
index c0b315d859..fb90869cde 100644
--- a/tests/auto/debugger/CMakeLists.txt
+++ b/tests/auto/debugger/CMakeLists.txt
@@ -47,6 +47,8 @@ add_qtc_test(tst_debugger_offsets
add_qtc_test(tst_debugger_simplifytypes
INCLUDES "${DEBUGGERDIR}"
+ DEPENDS Utils
+ DEFINES DUMPERDIR="${PROJECT_SOURCE_DIR}/share/qtcreator/debugger"
SOURCES
tst_simplifytypes.cpp
"${DEBUGGERDIR}/simplifytype.cpp" "${DEBUGGERDIR}/simplifytype.h"
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index 99b7f2ef2b..bbee83bc47 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -94,7 +94,7 @@ static bool generateEnvironmentSettings(Utils::Environment &env,
= Utils::FilePath::fromString(QString::fromLocal8Bit(qgetenv("COMSPEC")));
// Windows SDK setup scripts require command line switches for environment expansion.
QString cmdArguments = " /E:ON /V:ON /c \"" + QDir::toNativeSeparators(saver.fileName()) + '"';
- run.setCommand(Utils::CommandLine(cmdPath, cmdArguments));
+ run.setCommand(Utils::CommandLine(cmdPath, cmdArguments, Utils::CommandLine::Raw));
run.start();
if (!run.waitForStarted()) {
@@ -281,7 +281,7 @@ static QString parentIName(const QString &iname)
struct Value
{
Value() : value(noValue) {}
- Value(const char *str) : value(str) {}
+ Value(const char *str) : value(QString::fromUtf8(str)) {}
Value(const QString &str) : value(str) {}
bool matches(const QString &actualValue0, const Context &context) const
@@ -595,11 +595,11 @@ struct CheckType : public Check
{
CheckType(const QByteArray &iname, const Name &name,
const Type &type)
- : Check(iname, name, noValue, type)
+ : Check(QString::fromUtf8(iname), name, noValue, type)
{}
CheckType(const QByteArray &iname, const Type &type)
- : Check(iname, noValue, type)
+ : Check(QString::fromUtf8(iname), noValue, type)
{}
};
@@ -609,19 +609,23 @@ const QtVersion Qt5 = QtVersion(0x50000);
struct Check4 : Check
{
Check4(const QByteArray &iname, const Value &value, const Type &type)
- : Check(iname, value, type) { qtVersionForCheck = Qt4; }
+ : Check(QString::fromUtf8(iname), value, type)
+ { qtVersionForCheck = Qt4; }
Check4(const QByteArray &iname, const Name &name, const Value &value, const Type &type)
- : Check(iname, name, value, type) { qtVersionForCheck = Qt4; }
+ : Check(QString::fromUtf8(iname), name, value, type)
+ { qtVersionForCheck = Qt4; }
};
struct Check5 : Check
{
Check5(const QByteArray &iname, const Value &value, const Type &type)
- : Check(iname, value, type) { qtVersionForCheck = Qt5; }
+ : Check(QString::fromUtf8(iname), value, type)
+ { qtVersionForCheck = Qt5; }
Check5(const QByteArray &iname, const Name &name, const Value &value, const Type &type)
- : Check(iname, name, value, type) { qtVersionForCheck = Qt5; }
+ : Check(QString::fromUtf8(iname), name, value, type)
+ { qtVersionForCheck = Qt5; }
};
@@ -733,8 +737,8 @@ public:
const Data &operator+(const Profile &profile) const
{
- profileExtra += profile.contents;
- includes += profile.includes;
+ profileExtra += QString::fromUtf8(profile.contents);
+ includes += QString::fromUtf8(profile.includes);
return *this;
}
@@ -1613,7 +1617,7 @@ void tst_Dumpers::dumper()
contents = output.mid(posDataStart);
contents.replace("\\\"", "\"");
- actual.fromStringMultiple(contents);
+ actual.fromStringMultiple(QString::fromLocal8Bit(contents));
context.nameSpace = actual["qtnamespace"].data();
actual = actual["data"];
//qDebug() << "FOUND NS: " << context.nameSpace;
@@ -1632,12 +1636,13 @@ void tst_Dumpers::dumper()
posNameSpaceStart += sizeof("@NS@") - 1;
int posNameSpaceEnd = output.indexOf("@", posNameSpaceStart);
QVERIFY(posNameSpaceEnd != -1);
- context.nameSpace = output.mid(posNameSpaceStart, posNameSpaceEnd - posNameSpaceStart);
+ context.nameSpace = QString::fromLocal8Bit(output.mid(
+ posNameSpaceStart, posNameSpaceEnd - posNameSpaceStart));
//qDebug() << "FOUND NS: " << context.nameSpace;
if (context.nameSpace == "::")
context.nameSpace.clear();
contents.replace("\\\"", "\"");
- actual.fromString(contents);
+ actual.fromString(QString::fromLocal8Bit(contents));
} else {
QByteArray localsAnswerStart("<qtcreatorcdbext>|R|42|");
QByteArray locals("|script|");
@@ -1653,7 +1658,7 @@ void tst_Dumpers::dumper()
if (localsBeginPos != -1)
localsBeginPos = output.indexOf(locals, localsBeginPos);
} while (localsBeginPos != -1);
- actual.fromString(contents);
+ actual.fromString(QString::fromLocal8Bit(contents));
context.nameSpace = actual["result"]["qtnamespace"].data();
actual = actual["result"]["data"];
}
diff --git a/tests/auto/environment/tst_environment.cpp b/tests/auto/environment/tst_environment.cpp
index ed42cbbefa..d91e8800ed 100644
--- a/tests/auto/environment/tst_environment.cpp
+++ b/tests/auto/environment/tst_environment.cpp
@@ -57,6 +57,9 @@ private slots:
void environmentUnsetUnknownWindows();
void environmentUnsetUnknownUnix();
+ void expansion_data();
+ void expansion();
+
void find_data();
void find();
@@ -195,7 +198,7 @@ void tst_Environment::environmentSetNewWindows()
env.set("bar", "baz");
- QCOMPARE(env.toStringList(), QStringList({"Foo=bar", "Hi=HO", "bar=baz"}));
+ QCOMPARE(env.toStringList(), QStringList({"bar=baz", "Foo=bar", "Hi=HO"}));
}
void tst_Environment::environmentSetNewUnix()
@@ -252,6 +255,27 @@ void tst_Environment::environmentUnsetUnknownUnix()
QCOMPARE(env.toStringList(), QStringList({"Foo=bar", "Hi=HO"}));
}
+void tst_Environment::expansion_data()
+{
+ QTest::addColumn<Utils::OsType>("osType");
+ QTest::addColumn<QString>("eu");
+ QTest::addColumn<QString>("ew");
+
+ QTest::newRow("win") << Utils::OsTypeWindows << "${v}" << "blubb";
+ QTest::newRow("lin") << Utils::OsTypeLinux << "blubb" << "%v%";
+}
+
+void tst_Environment::expansion()
+{
+ QFETCH(Utils::OsType, osType);
+ QFETCH(QString, eu);
+ QFETCH(QString, ew);
+
+ const Environment env(QStringList{"eu=${v}", "ew=%v%", "v=blubb"}, osType);
+ QCOMPARE(env.expandedValueForKey("eu"), eu);
+ QCOMPARE(env.expandedValueForKey("ew"), ew);
+}
+
void tst_Environment::find_data()
{
QTest::addColumn<Utils::OsType>("osType");
@@ -280,7 +304,7 @@ void tst_Environment::find()
QCOMPARE((end != it), contains);
if (contains)
- QCOMPARE(it.value(), QString("bar"));
+ QCOMPARE(env.value(it), QString("bar"));
}
diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/CMakeLists.txt b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/CMakeLists.txt
index 0d3e8e3858..f5d99692d1 100644
--- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/CMakeLists.txt
@@ -4,4 +4,5 @@ add_qtc_plugin(plugin1
plugin1.cpp plugin1.h
PLUGIN_PATH "${TEST_PLUGIN_PATH}"
SKIP_INSTALL
- )
+ INTERNAL_ONLY
+)
diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/CMakeLists.txt b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/CMakeLists.txt
index fd58e173c2..f13d71b971 100644
--- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/CMakeLists.txt
@@ -4,4 +4,5 @@ add_qtc_plugin(plugin2
plugin2.cpp plugin2.h
PLUGIN_PATH "${TEST_PLUGIN_PATH}"
SKIP_INSTALL
- )
+ INTERNAL_ONLY
+)
diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/CMakeLists.txt b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/CMakeLists.txt
index dec94785f1..7a275e7338 100644
--- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/CMakeLists.txt
@@ -4,4 +4,5 @@ add_qtc_plugin(plugin3
plugin3.cpp plugin3.h
PLUGIN_PATH "${TEST_PLUGIN_PATH}"
SKIP_INSTALL
- )
+ INTERNAL_ONLY
+)
diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/CMakeLists.txt b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/CMakeLists.txt
index 6302992c2a..ea3200d38f 100644
--- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/CMakeLists.txt
@@ -5,4 +5,5 @@ add_qtc_plugin(correct_plugin1
plugin1.cpp plugin1.h
PLUGIN_PATH "${TEST_PLUGIN_PATH}"
SKIP_INSTALL
+ INTERNAL_ONLY
)
diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/CMakeLists.txt b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/CMakeLists.txt
index 075a08e58d..aca0c123f4 100644
--- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/CMakeLists.txt
@@ -5,4 +5,5 @@ add_qtc_plugin(correct_plugin2
plugin2.cpp plugin2.h
PLUGIN_PATH "${TEST_PLUGIN_PATH}"
SKIP_INSTALL
+ INTERNAL_ONLY
)
diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/CMakeLists.txt b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/CMakeLists.txt
index 2326ac08b4..aa05fc64db 100644
--- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/CMakeLists.txt
@@ -5,4 +5,5 @@ add_qtc_plugin(correct_plugin3
plugin3.cpp plugin3.h
PLUGIN_PATH "${TEST_PLUGIN_PATH}"
SKIP_INSTALL
+ INTERNAL_ONLY
)
diff --git a/tests/auto/extensionsystem/pluginspec/testplugin/CMakeLists.txt b/tests/auto/extensionsystem/pluginspec/testplugin/CMakeLists.txt
index 8bf159368b..391c90862f 100644
--- a/tests/auto/extensionsystem/pluginspec/testplugin/CMakeLists.txt
+++ b/tests/auto/extensionsystem/pluginspec/testplugin/CMakeLists.txt
@@ -18,6 +18,7 @@ add_qtc_plugin(testplugin
PROPERTIES
OUTPUT_NAME ${plugin_output_name}
SKIP_INSTALL
+ INTERNAL_ONLY
)
# The empty string gets removed if I put it above
diff --git a/tests/auto/json/tst_json.cpp b/tests/auto/json/tst_json.cpp
index 1253f00806..cb38a70489 100644
--- a/tests/auto/json/tst_json.cpp
+++ b/tests/auto/json/tst_json.cpp
@@ -1571,8 +1571,8 @@ void tst_Json::fromBinary()
void tst_Json::toAndFromBinary_data()
{
QTest::addColumn<QString>("filename");
- QTest::newRow("test.json") << (testDataDir + QLatin1String("/test.json"));
- QTest::newRow("test2.json") << (testDataDir + QLatin1String("/test2.json"));
+ QTest::newRow("test.json") << QString(testDataDir + QLatin1String("/test.json"));
+ QTest::newRow("test2.json") << QString(testDataDir + QLatin1String("/test2.json"));
}
void tst_Json::toAndFromBinary()
diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp
index 8c5e2d7f59..4efbacce88 100644
--- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp
+++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp
@@ -610,7 +610,7 @@ void tst_LanguageServerProtocol::documentUri_data()
QTest::newRow("home dir")
- << DocumentUri::fromFileName(Utils::FilePath::fromString(QDir::homePath()))
+ << DocumentUri::fromFilePath(Utils::FilePath::fromString(QDir::homePath()))
<< true
<< Utils::FilePath::fromUserInput(QDir::homePath())
<< QString(filePrefix + QDir::homePath());
@@ -618,7 +618,7 @@ void tst_LanguageServerProtocol::documentUri_data()
const QString argv0 = QFileInfo(qApp->arguments().first()).absoluteFilePath();
const auto argv0FileName = Utils::FilePath::fromUserInput(argv0);
QTest::newRow("argv0 file name")
- << DocumentUri::fromFileName(argv0FileName)
+ << DocumentUri::fromFilePath(argv0FileName)
<< true
<< argv0FileName
<< QString(filePrefix + QDir::fromNativeSeparators(argv0));
@@ -648,7 +648,7 @@ void tst_LanguageServerProtocol::documentUri()
QFETCH(QString, string);
QCOMPARE(uri.isValid(), isValid);
- QCOMPARE(uri.toFileName(), fileName);
+ QCOMPARE(uri.toFilePath(), fileName);
QCOMPARE(uri.toString(), string);
}
diff --git a/tests/auto/qml/codemodel/check/tst_check.cpp b/tests/auto/qml/codemodel/check/tst_check.cpp
index 4c9a8e4d65..9f5207284b 100644
--- a/tests/auto/qml/codemodel/check/tst_check.cpp
+++ b/tests/auto/qml/codemodel/check/tst_check.cpp
@@ -114,7 +114,7 @@ void tst_Check::test()
Document::MutablePtr doc = Document::create(path, Dialect::Qml);
QFile file(doc->fileName());
file.open(QFile::ReadOnly | QFile::Text);
- doc->setSource(file.readAll());
+ doc->setSource(QString::fromUtf8(file.readAll()));
file.close();
doc->parse();
snapshot.insert(doc);
diff --git a/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp b/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp
index 79ce9cec1b..3139e6feca 100644
--- a/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp
+++ b/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp
@@ -74,7 +74,7 @@ struct TestData
static TestData testData(const QString &path) {
QFile file(path);
file.open(QFile::ReadOnly | QFile::Text);
- const QString content = QString(file.readAll());
+ const QString content = QString::fromUtf8(file.readAll());
file.close();
Document::MutablePtr doc = Document::create(path, Dialect::Qml);
diff --git a/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp b/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp
index 735daa04f7..ea530d2143 100644
--- a/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp
+++ b/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp
@@ -76,7 +76,7 @@ static TestData testData(const QString &path)
{
QFile file(path);
file.open(QFile::ReadOnly | QFile::Text);
- const QString content = QString(file.readAll());
+ const QString content = QString::fromUtf8(file.readAll());
file.close();
Document::MutablePtr doc = Document::create(path, Dialect::Qml);
@@ -96,7 +96,7 @@ static QStringList readSkipList(const QDir &dir, const QString &filename)
return QStringList();
while (!f.atEnd()) {
- const QString s = f.readLine().trimmed();
+ const QString s = QString::fromUtf8(f.readLine().trimmed());
if (!s.isEmpty())
result << dir.absoluteFilePath(s);
}
diff --git a/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp b/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp
index c42053083e..a17ef2d993 100644
--- a/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp
+++ b/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp
@@ -67,7 +67,7 @@ void tst_SimpleReader::testWellFormed()
SimpleReaderNode::WeakPtr weak02;
{
SimpleReader reader;
- SimpleReaderNode::Ptr rootNode = reader.readFromSource(source);
+ SimpleReaderNode::Ptr rootNode = reader.readFromSource(QString::fromUtf8(source));
QVERIFY(reader.errors().isEmpty());
QVERIFY(rootNode);
QVERIFY(rootNode->isValid());
@@ -130,7 +130,7 @@ void tst_SimpleReader::testIllFormed01()
" propertyBlah: false\n"
"}\n";
SimpleReader reader;
- SimpleReaderNode::Ptr rootNode = reader.readFromSource(source);
+ SimpleReaderNode::Ptr rootNode = reader.readFromSource(QString::fromUtf8(source));
QVERIFY(!rootNode);
QVERIFY(!reader.errors().empty());
@@ -153,7 +153,7 @@ void tst_SimpleReader::testIllFormed02()
"}\n";
SimpleReader reader;
- SimpleReaderNode::Ptr rootNode = reader.readFromSource(source);
+ SimpleReaderNode::Ptr rootNode = reader.readFromSource(QString::fromUtf8(source));
QVERIFY(rootNode);
QVERIFY(rootNode->isValid());
@@ -188,7 +188,7 @@ void tst_SimpleReader::testArrays()
const QVariant variant = variantList;
SimpleReader reader;
- SimpleReaderNode::Ptr rootNode = reader.readFromSource(source);
+ SimpleReaderNode::Ptr rootNode = reader.readFromSource(QString::fromUtf8(source));
QVERIFY(rootNode);
QVERIFY(rootNode->isValid());
@@ -239,7 +239,7 @@ void tst_SimpleReader::testBug01()
"}\n";
SimpleReader reader;
- SimpleReaderNode::Ptr rootNode = reader.readFromSource(source);
+ SimpleReaderNode::Ptr rootNode = reader.readFromSource(QString::fromUtf8(source));
QVERIFY(rootNode);
QVERIFY(rootNode->isValid());
diff --git a/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp b/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp
index fe61dd0ea5..571fc96c4f 100644
--- a/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp
+++ b/tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp
@@ -26,12 +26,24 @@
#include "qmlprojectitem.h"
#include "filefilteritems.h"
#include "qmlprojectfileformat.h"
+
+#include <utils/algorithm.h>
+
#include <QtTest>
//TESTED_COMPONENT=src/plugins/qmlprojectmanager/fileformat
using namespace QmlProjectManager;
+#define COMPARE_AS_SETS(actual, expected) \
+ do {\
+ if (!QTest::qCompare(Utils::toSet(actual), Utils::toSet(expected), #actual, #expected, __FILE__, __LINE__)) {\
+ qDebug() << actual << "\nvs." << expected; \
+ return;\
+ }\
+ } while (false)
+
+
class tst_FileFormat : public QObject
{
Q_OBJECT
@@ -49,7 +61,7 @@ tst_FileFormat::tst_FileFormat()
{
}
-QString testDataDir = QLatin1String(SRCDIR "/data");
+static QString testDataDir = QLatin1String(SRCDIR "/data");
static QmlProjectItem *loadQmlProject(QString name, QString *error)
{
@@ -73,7 +85,7 @@ void tst_FileFormat::testFileFilter()
QStringList expectedFiles(QStringList() << testDataDir + "/file1.qml"
<< testDataDir + "/file2.qml"
<< testDataDir + "/subdir/file3.qml");
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -89,7 +101,7 @@ void tst_FileFormat::testFileFilter()
QStringList expectedFiles(QStringList() << testDataDir + "/file1.qml"
<< testDataDir + "/file2.qml");
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -104,7 +116,7 @@ void tst_FileFormat::testFileFilter()
project->setSourceDirectory(testDataDir);
QStringList expectedFiles(QStringList() << testDataDir + "/subdir/file3.qml");
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -122,7 +134,7 @@ void tst_FileFormat::testFileFilter()
<< testDataDir + "/file2.qml"
<< testDataDir + "/subdir/file3.qml");
QCOMPARE(project->files().size(), 3);
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -138,7 +150,7 @@ void tst_FileFormat::testFileFilter()
QStringList expectedFiles(QStringList() << testDataDir + "/file1.qml"
<< testDataDir + "/file2.qml");
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -153,8 +165,7 @@ void tst_FileFormat::testFileFilter()
project->setSourceDirectory(testDataDir);
QStringList expectedFiles(QStringList() << testDataDir + "/image.gif");
- qDebug() << project->files().toSet() << expectedFiles.toSet();
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -169,8 +180,7 @@ void tst_FileFormat::testFileFilter()
project->setSourceDirectory(testDataDir);
QStringList expectedFiles(QStringList() << testDataDir + "/image.gif");
- qDebug() << project->files().toSet() << expectedFiles.toSet();
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
@@ -185,8 +195,7 @@ void tst_FileFormat::testFileFilter()
project->setSourceDirectory(testDataDir);
QStringList expectedFiles(QStringList() << testDataDir + "/image.gif");
- qDebug() << project->files().toSet() << expectedFiles.toSet();
- QCOMPARE(project->files().toSet(), expectedFiles.toSet());
+ COMPARE_AS_SETS(project->files(), expectedFiles);
delete project;
}
}
@@ -226,8 +235,7 @@ void tst_FileFormat::testLibraryPaths()
const QDir base(testDataDir);
const QStringList expectedPaths({base.relativeFilePath(SRCDIR "/otherLibrary"),
base.relativeFilePath(SRCDIR "/data/library")});
- qDebug() << expectedPaths << project->importPaths();
- QCOMPARE(project->importPaths().toSet(), expectedPaths.toSet());
+ COMPARE_AS_SETS(project->importPaths(), expectedPaths);
delete project;
}
diff --git a/tests/auto/ssh/tst_ssh.cpp b/tests/auto/ssh/tst_ssh.cpp
index dfc60952ae..5283f71960 100644
--- a/tests/auto/ssh/tst_ssh.cpp
+++ b/tests/auto/ssh/tst_ssh.cpp
@@ -89,10 +89,10 @@ static SshConnectionParameters getParameters()
} \
if (params.userName().isEmpty()) \
QSKIP(qPrintable(QString::fromLatin1("No user name provided. Set %1.") \
- .arg(userVar()))); \
+ .arg(QString::fromUtf8(userVar())))); \
if (params.privateKeyFile.isEmpty()) \
QSKIP(qPrintable(QString::fromLatin1("No key file provided. Set %1.") \
- .arg(keyFileVar()))); \
+ .arg(QString::fromUtf8(keyFileVar())))); \
} while (false)
class tst_Ssh : public QObject
@@ -234,9 +234,9 @@ void tst_Ssh::remoteProcess()
connect(&runner, &SshRemoteProcessRunner::readyReadStandardError,
[&remoteStderr, &runner] { remoteStderr += runner.readAllStandardError(); });
if (useTerminal)
- runner.runInTerminal(commandLine, params);
+ runner.runInTerminal(QString::fromUtf8(commandLine), params);
else
- runner.run(commandLine, params);
+ runner.run(QString::fromUtf8(commandLine), params);
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
timer.setSingleShot(true);
@@ -254,7 +254,7 @@ void tst_Ssh::remoteProcess()
SshRemoteProcessRunner killer;
if (isBlocking)
- killer.run("pkill -f -9 \"" + commandLine + '"', params);
+ killer.run("pkill -f -9 \"" + QString::fromUtf8(commandLine) + '"', params);
timer.start();
loop.exec();
@@ -285,7 +285,7 @@ void tst_Ssh::remoteProcessChannels()
QByteArray remoteStderr;
QByteArray remoteData;
SshRemoteProcessPtr echoProcess
- = connection.createRemoteProcess("printf " + testString + " >&2");
+ = connection.createRemoteProcess("printf " + QString::fromUtf8(testString) + " >&2");
echoProcess->setReadChannel(QProcess::StandardError);
QEventLoop loop;
connect(echoProcess.get(), &SshRemoteProcess::done, &loop, &QEventLoop::quit);
diff --git a/tests/auto/toolchaincache/CMakeLists.txt b/tests/auto/toolchaincache/CMakeLists.txt
index 3a0637c9fd..01edb5d5d4 100644
--- a/tests/auto/toolchaincache/CMakeLists.txt
+++ b/tests/auto/toolchaincache/CMakeLists.txt
@@ -1,5 +1,5 @@
add_qtc_test(tst_toolchaincache
- DEPENDS ProjectExplorer Qt5::Gui
+ DEPENDS ProjectExplorer Qt5::Widgets
INCLUDES "${PROJECT_SOURCE_DIR}/src/libs"
SOURCES tst_toolchaincache.cpp
)
diff --git a/tests/auto/toolchaincache/tst_toolchaincache.cpp b/tests/auto/toolchaincache/tst_toolchaincache.cpp
index 10226802c3..3e4da445ac 100644
--- a/tests/auto/toolchaincache/tst_toolchaincache.cpp
+++ b/tests/auto/toolchaincache/tst_toolchaincache.cpp
@@ -46,7 +46,7 @@ void tst_ToolChainCache::insertOne()
{
const QStringList key1 = {"one"};
const QString value1 = "value1";
- ProjectExplorer::Cache<QString, 2> cache;
+ ProjectExplorer::Cache<QStringList, QString, 2> cache;
cache.insert(key1, value1);
@@ -59,7 +59,7 @@ void tst_ToolChainCache::insertOneOne()
{
const QStringList key1 = {"one"};
const QString value1 = "value1";
- ProjectExplorer::Cache<QString, 2> cache;
+ ProjectExplorer::Cache<QStringList, QString, 2> cache;
cache.insert(key1, value1);
cache.insert(key1, value1);
@@ -75,7 +75,7 @@ void tst_ToolChainCache::insertOneTwo()
const QString value1 = "value1";
const QStringList key2 = {"two"};
const QString value2 = "value2";
- ProjectExplorer::Cache<QString, 2> cache;
+ ProjectExplorer::Cache<QStringList, QString, 2> cache;
cache.insert(key1, value1);
cache.insert(key2, value2);
@@ -95,7 +95,7 @@ void tst_ToolChainCache::insertOneTwoThree()
const QString value2 = "value2";
const QStringList key3 = {"three"};
const QString value3 = "value3";
- ProjectExplorer::Cache<QString, 2> cache;
+ ProjectExplorer::Cache<QStringList, QString, 2> cache;
cache.insert(key1, value1);
cache.insert(key2, value2);
@@ -117,7 +117,7 @@ void tst_ToolChainCache::insertOneTwoOneThree()
const QString value2 = "value2";
const QStringList key3 = {"three"};
const QString value3 = "value3";
- ProjectExplorer::Cache<QString, 2> cache;
+ ProjectExplorer::Cache<QStringList, QString, 2> cache;
cache.insert(key1, value1);
cache.insert(key2, value2);
diff --git a/tests/auto/tracing/flamegraphview/TestFlameGraphView.qml b/tests/auto/tracing/flamegraphview/TestFlameGraphView.qml
index 3be69a445a..7324360b2a 100644
--- a/tests/auto/tracing/flamegraphview/TestFlameGraphView.qml
+++ b/tests/auto/tracing/flamegraphview/TestFlameGraphView.qml
@@ -28,7 +28,6 @@ import "../tracing/"
FlameGraphView {
id: root
- sizeRole: TestFlameGraphModel.SizeRole
model: flameGraphModel
diff --git a/tests/auto/tracing/flamegraphview/tst_flamegraphview.cpp b/tests/auto/tracing/flamegraphview/tst_flamegraphview.cpp
index d29ee1f7c8..1046a83597 100644
--- a/tests/auto/tracing/flamegraphview/tst_flamegraphview.cpp
+++ b/tests/auto/tracing/flamegraphview/tst_flamegraphview.cpp
@@ -87,9 +87,9 @@ public:
Q_INVOKABLE void gotoSourceLocation(const QString &file, int line, int column)
{
- Q_UNUSED(file);
- Q_UNUSED(line);
- Q_UNUSED(column);
+ Q_UNUSED(file)
+ Q_UNUSED(line)
+ Q_UNUSED(column)
}
};
diff --git a/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp b/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp
index cfff804e52..d59fad4284 100644
--- a/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp
+++ b/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp
@@ -45,12 +45,12 @@ TimelineRenderPass::State *DummyRenderPass::update(const TimelineAbstractRendere
State *state, int indexFrom, int indexTo,
bool stateChanged, float spacing) const
{
- Q_UNUSED(renderer);
- Q_UNUSED(parentState);
- Q_UNUSED(indexFrom);
- Q_UNUSED(indexTo);
- Q_UNUSED(stateChanged);
- Q_UNUSED(spacing);
+ Q_UNUSED(renderer)
+ Q_UNUSED(parentState)
+ Q_UNUSED(indexFrom)
+ Q_UNUSED(indexTo)
+ Q_UNUSED(stateChanged)
+ Q_UNUSED(spacing)
return state;
}
diff --git a/tests/auto/utils/fileutils/tst_fileutils.cpp b/tests/auto/utils/fileutils/tst_fileutils.cpp
index c13db0bf55..b6eab1655b 100644
--- a/tests/auto/utils/fileutils/tst_fileutils.cpp
+++ b/tests/auto/utils/fileutils/tst_fileutils.cpp
@@ -161,7 +161,7 @@ void tst_fileutils::fileName()
QFETCH(QString, path);
QFETCH(int, components);
QFETCH(QString, result);
- QCOMPARE(FilePath::fromString(path).fileName(components), result);
+ QCOMPARE(FilePath::fromString(path).fileNameWithPathComponents(components), result);
}
QTEST_APPLESS_MAIN(tst_fileutils)
diff --git a/tests/auto/utils/fuzzymatcher/tst_fuzzymatcher.cpp b/tests/auto/utils/fuzzymatcher/tst_fuzzymatcher.cpp
index 65dd4c495e..3a64524d59 100644
--- a/tests/auto/utils/fuzzymatcher/tst_fuzzymatcher.cpp
+++ b/tests/auto/utils/fuzzymatcher/tst_fuzzymatcher.cpp
@@ -68,7 +68,12 @@ void tst_FuzzyMatcher::fuzzyMatcher_data()
QTest::newRow("incorrect-hump") << "lyn" << "VeryLongCamelHump" << -1;
QTest::newRow("humps") << "VL" << "VeryLongCamelHump" << 0;
QTest::newRow("skipped-humps-upper") << "VH" << "VeryLongCamelHump" << -1;
- QTest::newRow("numbers") << "4" << "Test4Fun" << 4;
+ QTest::newRow("numbers-searched") << "4" << "Test4Fun" << 4;
+ QTest::newRow("numbers-skipped") << "fpt" << "Fancy4PartThingy" << 0;
+ QTest::newRow("numbers-camel") << "f4pt" << "Fancy4PartThingy" << 0;
+ QTest::newRow("multi-numbers-camel") << "f4pt" << "Fancy4567PartThingy" << 0;
+ QTest::newRow("numbers-underscore") << "f4pt" << "fancy_4_part_thingy" << 0;
+ QTest::newRow("numbers-underscore-upper") << "f4pt" << "FANCY_4_PART_THINGY" << 0;
QTest::newRow("question-wildcard") << "Lon?Ca" << "VeryLongCamelHump" << 4;
QTest::newRow("unmatched-question-wildcard") << "Long?Ca" << "VeryLongCamelHump" << -1;
QTest::newRow("asterisk-wildcard") << "Long*Ca" << "VeryLongCamelHump" << 4;
@@ -81,6 +86,7 @@ void tst_FuzzyMatcher::fuzzyMatcher_data()
QTest::newRow("middle-no-hump") << "window" << "mainwindow.cpp" << 4;
QTest::newRow("case-insensitive") << "window" << "MAINWINDOW.cpp" << 4;
QTest::newRow("case-insensitive-2") << "wINDow" << "MainwiNdow.cpp" << 4;
+ QTest::newRow("uppercase-word-and-humps") << "htvideoele" << "HTMLVideoElement" << 0;
}
typedef QVector<QPair<int, int>> Matches;
@@ -136,14 +142,26 @@ void tst_FuzzyMatcher::highlighting_data()
<< Matches{{4, 2}, {8, 2}};
QTest::newRow("duplicate-match") << "som" << "SomeMatch"
<< Matches{{0, 3}};
- QTest::newRow("numbers") << "4" << "TestJust4Fun"
- << Matches{{8, 1}};
+ QTest::newRow("numbers-searched") << "4" << "TestJust4Fun"
+ << Matches{{8, 1}};
+ QTest::newRow("numbers-plain") << "boot2qt" << "use_boot2qt_for_embedded"
+ << Matches{{4, 7}};
+ QTest::newRow("numbers-skipped") << "fpt" << "Fancy4PartThingy"
+ << Matches{{0, 1}, {6, 1}, {10, 1}};
+ QTest::newRow("numbers-camel") << "f4pt" << "Fancy4PartThingy"
+ << Matches{{0, 1}, {5, 2}, {10, 1}};
+ QTest::newRow("numbers-snake") << "f4pt" << "fancy_4_part_thingy"
+ << Matches{{0, 1}, {6, 1}, {8, 1}, {13, 1}};
+ QTest::newRow("numbers-snake-upper") << "f4pt" << "FANCY_4_PART_THINGY"
+ << Matches{{0, 1}, {6, 1}, {8, 1}, {13, 1}};
QTest::newRow("wildcard-asterisk") << "Lo*Hu" << "VeryLongCamelHump"
<< Matches{{4, 2}, {13, 2}};
QTest::newRow("wildcard-question") << "Lo?g" << "VeryLongCamelHump"
<< Matches{{4, 2}, {7, 1}};
QTest::newRow("middle-no-hump") << "window" << "mainwindow.cpp"
<< Matches{{4, 6}};
+ QTest::newRow("uppercase-word-and-humps") << "htvideoele" << "HTMLVideoElement"
+ << Matches{{0, 2}, {4, 8}};
}
QTEST_APPLESS_MAIN(tst_FuzzyMatcher)
diff --git a/tests/auto/utils/settings/tst_settings.cpp b/tests/auto/utils/settings/tst_settings.cpp
index 931c601a6e..5e76f7be55 100644
--- a/tests/auto/utils/settings/tst_settings.cpp
+++ b/tests/auto/utils/settings/tst_settings.cpp
@@ -92,7 +92,7 @@ protected:
SettingsMergeResult merge(const SettingsMergeData &global,
const SettingsMergeData &local) const final
{
- Q_UNUSED(global);
+ Q_UNUSED(global)
const QString key = local.key;
const QVariant main = local.main.value(key);
@@ -602,7 +602,7 @@ void tst_SettingsAccessor::findIssues_ok()
{
const TestSettingsAccessor accessor;
const QVariantMap data = versionedMap(6, TESTACCESSOR_DEFAULT_ID);
- const Utils::FileName path = Utils::FileName::fromString("/foo/baz.user");
+ const Utils::FilePath path = Utils::FilePath::fromString("/foo/baz.user");
const Utils::optional<Utils::SettingsAccessor::Issue> info = accessor.findIssues(data, path);
@@ -613,7 +613,7 @@ void tst_SettingsAccessor::findIssues_emptyData()
{
const TestSettingsAccessor accessor;
const QVariantMap data;
- const Utils::FileName path = Utils::FileName::fromString("/foo/bar.user");
+ const Utils::FilePath path = Utils::FilePath::fromString("/foo/bar.user");
const Utils::optional<Utils::SettingsAccessor::Issue> info = accessor.findIssues(data, path);
@@ -624,7 +624,7 @@ void tst_SettingsAccessor::findIssues_tooNew()
{
const TestSettingsAccessor accessor;
const QVariantMap data = versionedMap(42, TESTACCESSOR_DEFAULT_ID);
- const Utils::FileName path = Utils::FileName::fromString("/foo/bar.user");
+ const Utils::FilePath path = Utils::FilePath::fromString("/foo/bar.user");
const Utils::optional<Utils::SettingsAccessor::Issue> info = accessor.findIssues(data, path);
@@ -635,7 +635,7 @@ void tst_SettingsAccessor::findIssues_tooOld()
{
const TestSettingsAccessor accessor;
const QVariantMap data = versionedMap(2, TESTACCESSOR_DEFAULT_ID);
- const Utils::FileName path = Utils::FileName::fromString("/foo/bar.user");
+ const Utils::FilePath path = Utils::FilePath::fromString("/foo/bar.user");
const Utils::optional<Utils::SettingsAccessor::Issue> info = accessor.findIssues(data, path);
@@ -646,7 +646,7 @@ void tst_SettingsAccessor::findIssues_wrongId()
{
const TestSettingsAccessor accessor;
const QVariantMap data = versionedMap(6, "foo");
- const Utils::FileName path = Utils::FileName::fromString("/foo/bar.user");
+ const Utils::FilePath path = Utils::FilePath::fromString("/foo/bar.user");
const Utils::optional<Utils::SettingsAccessor::Issue> info = accessor.findIssues(data, path);
@@ -657,7 +657,7 @@ void tst_SettingsAccessor::findIssues_nonDefaultPath()
{
const TestSettingsAccessor accessor;
const QVariantMap data = versionedMap(6, TESTACCESSOR_DEFAULT_ID);
- const Utils::FileName path = Utils::FileName::fromString("/foo/bar.user.foobar");
+ const Utils::FilePath path = Utils::FilePath::fromString("/foo/bar.user.foobar");
const Utils::optional<Utils::SettingsAccessor::Issue> info = accessor.findIssues(data, path);
diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp
index 98e04185ab..010e6ce8b4 100644
--- a/tests/auto/utils/stringutils/tst_stringutils.cpp
+++ b/tests/auto/utils/stringutils/tst_stringutils.cpp
@@ -194,7 +194,7 @@ void tst_StringUtils::testStripAccelerator()
{
QFETCH(QString, expected);
- QCOMPARE(Utils::stripAccelerator(QTest::currentDataTag()), expected);
+ QCOMPARE(Utils::stripAccelerator(QString::fromUtf8(QTest::currentDataTag())), expected);
}
void tst_StringUtils::testStripAccelerator_data()
diff --git a/tests/auto/valgrind/memcheck/modeldemo.cpp b/tests/auto/valgrind/memcheck/modeldemo.cpp
index 1bc878d9c2..9f809161da 100644
--- a/tests/auto/valgrind/memcheck/modeldemo.cpp
+++ b/tests/auto/valgrind/memcheck/modeldemo.cpp
@@ -44,8 +44,8 @@ int main(int argc, char *argv[])
qRegisterMetaType<Error>();
ValgrindRunner runner;
- runner.setValgrindExecutable(VALGRIND_FAKE_PATH);
- runner.setValgrindArguments({"-i", PARSERTESTS_DATA_DIR "/memcheck-output-sample1.xml"});
+ runner.setValgrindCommand({VALGRIND_FAKE_PATH,
+ {"-i", PARSERTESTS_DATA_DIR "/memcheck-output-sample1.xml"}});
ModelDemo demo(&runner);
QObject::connect(&runner, &ValgrindRunner::finished,
diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp
index 864e20d40a..cda17dc97d 100644
--- a/tests/manual/debugger/simple/simple_test_app.cpp
+++ b/tests/manual/debugger/simple/simple_test_app.cpp
@@ -423,7 +423,7 @@ class XX : virtual public Foo { public: XX() { } };
class Y : virtual public Foo { public: Y() { } };
-class D : public X, public Y { int diamond; D(){Q_UNUSED(diamond);} };
+class D : public X, public Y { int diamond; D(){Q_UNUSED(diamond)} };
namespace peekandpoke {
@@ -3408,7 +3408,7 @@ namespace lambda {
std::string x;
auto f = [&] () -> const std::string & {
size_t z = x.size();
- Q_UNUSED(z);
+ Q_UNUSED(z)
return x;
};
auto c = f();
@@ -6633,7 +6633,7 @@ namespace bug5106 {
class A5106
{
public:
- A5106(int a, int b) : m_a(a), m_b(b) {Q_UNUSED(m_a);Q_UNUSED(m_b);}
+ A5106(int a, int b) : m_a(a), m_b(b) {Q_UNUSED(m_a);Q_UNUSED(m_b)}
virtual int test() { return 5; }
private:
int m_a, m_b;
@@ -6642,7 +6642,7 @@ namespace bug5106 {
class B5106 : public A5106
{
public:
- B5106(int c, int a, int b) : A5106(a, b), m_c(c) {Q_UNUSED(m_c);}
+ B5106(int c, int a, int b) : A5106(a, b), m_c(c) {Q_UNUSED(m_c)}
virtual int test() { return 4; BREAK_HERE; }
private:
int m_c;
@@ -7224,7 +7224,7 @@ template <class X> int ffff(X)
int main(int argc, char *argv[])
{
int z = ffff(3) + ffff(2.0);
- Q_UNUSED(z);
+ Q_UNUSED(z)
#if USE_GUILIB
QApplication app(argc, argv);
diff --git a/tests/manual/process/mainwindow.cpp b/tests/manual/process/mainwindow.cpp
index 7a99e8a872..85a7b2ef9f 100644
--- a/tests/manual/process/mainwindow.cpp
+++ b/tests/manual/process/mainwindow.cpp
@@ -25,6 +25,7 @@
#include "mainwindow.h"
+#include <utils/fileutils.h>
#include <utils/synchronousprocess.h>
#include <QPlainTextEdit>
@@ -56,6 +57,6 @@ void MainWindow::test()
qDebug() << "Async: " << cmd << args;
connect(&process, &Utils::SynchronousProcess::stdOutBuffered, this, &MainWindow::append);
connect(&process, &Utils::SynchronousProcess::stdErrBuffered, this, &MainWindow::append);
- const Utils::SynchronousProcessResponse resp = process.run(cmd, args);
+ const Utils::SynchronousProcessResponse resp = process.run({Utils::FilePath::fromString(cmd), args});
qDebug() << resp;
}
diff --git a/tests/unit/mockup/projectexplorer/buildconfiguration.h b/tests/unit/mockup/projectexplorer/buildconfiguration.h
index 75b5a293c4..cc1c57e828 100644
--- a/tests/unit/mockup/projectexplorer/buildconfiguration.h
+++ b/tests/unit/mockup/projectexplorer/buildconfiguration.h
@@ -32,6 +32,6 @@ namespace ProjectExplorer {
class BuildConfiguration
{
public:
- Utils::FileName buildDirectory() const { return {}; }
+ Utils::FilePath buildDirectory() const { return {}; }
}; // namespace Target
} // namespace ProjectExplorer
diff --git a/tests/unit/mockup/projectexplorer/kitinformation.h b/tests/unit/mockup/projectexplorer/kitinformation.h
index fced31a50f..f8e54ae3de 100644
--- a/tests/unit/mockup/projectexplorer/kitinformation.h
+++ b/tests/unit/mockup/projectexplorer/kitinformation.h
@@ -34,7 +34,7 @@ class Kit;
class SysRootKitInformation
{
public:
- static Utils::FileName sysRoot(const Kit *) { return Utils::FileName(); }
+ static Utils::FilePath sysRoot(const Kit *) { return Utils::FilePath(); }
};
} // namespace ProjectExplorer
diff --git a/tests/unit/mockup/projectexplorer/project.h b/tests/unit/mockup/projectexplorer/project.h
index c69eb6e47b..0cf902c8f9 100644
--- a/tests/unit/mockup/projectexplorer/project.h
+++ b/tests/unit/mockup/projectexplorer/project.h
@@ -37,16 +37,16 @@ class Project : public QObject {
public:
Project() = default;
- Utils::FileName projectDirectory() const { return {}; }
+ Utils::FilePath projectDirectory() const { return {}; }
- Utils::FileName rootProjectDirectory() const { return rootProjectDirectoryPath; }
+ Utils::FilePath rootProjectDirectory() const { return rootProjectDirectoryPath; }
Target *activeTarget() const { return {}; }
QVariant namedSettings(const QString &name) const { return settings.at(name); }
void setNamedSettings(const QString &name, const QVariant &value) { settings[name] = value; }
- Utils::FileName rootProjectDirectoryPath;
+ Utils::FilePath rootProjectDirectoryPath;
mutable std::map<QString, QVariant> settings;
};
} // namespace ProjectExplorer
diff --git a/tests/unit/mockup/projectexplorer/toolchain.h b/tests/unit/mockup/projectexplorer/toolchain.h
index 925b0a2ae8..022520cec0 100644
--- a/tests/unit/mockup/projectexplorer/toolchain.h
+++ b/tests/unit/mockup/projectexplorer/toolchain.h
@@ -33,6 +33,8 @@
#include <functional>
+namespace Utils { class Environment; }
+
namespace ProjectExplorer {
class ToolChain
@@ -45,7 +47,9 @@ public:
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(
const QStringList &cxxflags, const QString &sysRoot, const QString &originalTargetTriple)>;
- virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); }
+ virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner(const Utils::Environment &env) const {
+ return BuiltInHeaderPathsRunner();
+ }
class MacroInspectionReport
{
diff --git a/tests/unit/mockup/texteditor/semantichighlighter.h b/tests/unit/mockup/texteditor/semantichighlighter.h
index 323a48347c..94fdfecb9f 100644
--- a/tests/unit/mockup/texteditor/semantichighlighter.h
+++ b/tests/unit/mockup/texteditor/semantichighlighter.h
@@ -31,9 +31,9 @@ namespace TextEditor {
class HighlightingResult {
public:
- unsigned line;
- unsigned column;
- unsigned length;
+ int line;
+ int column;
+ int length;
TextStyles textStyles;
int kind;
bool useTextSyles;
@@ -48,11 +48,11 @@ public:
: line(0), column(0), length(0), kind(0)
{}
- HighlightingResult(unsigned line, unsigned column, unsigned length, int kind)
+ HighlightingResult(int line, int column, int length, int kind)
: line(line), column(column), length(length), kind(kind), useTextSyles(false)
{}
- HighlightingResult(unsigned line, unsigned column, unsigned length, TextStyles textStyles)
+ HighlightingResult(int line, int column, int length, TextStyles textStyles)
: line(line), column(column), length(length), textStyles(textStyles), useTextSyles(true)
{}
diff --git a/tests/unit/unittest/CMakeLists.txt b/tests/unit/unittest/CMakeLists.txt
index 2dbb0411cf..99f221aa0e 100644
--- a/tests/unit/unittest/CMakeLists.txt
+++ b/tests/unit/unittest/CMakeLists.txt
@@ -18,8 +18,6 @@ add_qtc_test(unittest GTEST
clangrefactoringbackend_lib clangbackend_lib clangpchmanagerbackend_lib
CPlusPlus Sqlite Utils
DEFINES
- QT_NO_CAST_TO_ASCII QT_RESTRICTED_CAST_FROM_ASCII
- QT_USE_FAST_OPERATOR_PLUS QT_USE_FAST_CONCATENATION
UNIT_TESTS
DONT_CHECK_MESSAGE_COUNTER
QTC_RESOURCE_DIR="${PROJECT_SOURCE_DIR}/share/qtcreator"
@@ -29,7 +27,7 @@ add_qtc_test(unittest GTEST
SOURCES
builddependenciesprovider-test.cpp
builddependenciesstorage-test.cpp
- directorypathcompressor-test.cpp
+ clangindexingsettingsmanager-test.cpp
clangpathwatcher-test.cpp
clangqueryexamplehighlightmarker-test.cpp
clangqueryhighlightmarker-test.cpp
@@ -81,7 +79,6 @@ add_qtc_test(unittest GTEST
mockgeneratedfiles.h
mockmodifiedtimechecker.h
mockmutex.h
- mockfilesystem.h
mockpchcreator.h
mockpchmanagerclient.h
mockpchmanagernotifier.h
@@ -126,6 +123,7 @@ add_qtc_test(unittest GTEST
pchtaskqueue-test.cpp
pchtasksmerger-test.cpp
precompiledheaderstorage-test.cpp
+ preprocessormacrocollector-test.cpp
processcreator-test.cpp
processevents-utilities.cpp processevents-utilities.h
processormanager-test.cpp
@@ -393,10 +391,13 @@ extend_qtc_target(unittest
SOURCES_PREFIX "${ClangPchManagerSourcesDir}"
DEFINES CLANGPCHMANAGER_STATIC_LIB
SOURCES
+ clangindexingprojectsettings.cpp clangindexingprojectsettings.h
+ clangindexingsettingsmanager.cpp clangindexingsettingsmanager.h
pchmanagerclient.h pchmanagerclient.cpp
pchmanagernotifierinterface.h pchmanagernotifierinterface.cpp
pchmanagerconnectionclient.h pchmanagerconnectionclient.cpp
clangpchmanager_global.h
+ preprocessormacrocollector.cpp preprocessormacrocollector.h
projectupdater.h projectupdater.cpp
pchmanagerprojectupdater.h pchmanagerprojectupdater.cpp
progressmanager.h
diff --git a/tests/unit/unittest/builddependenciesprovider-test.cpp b/tests/unit/unittest/builddependenciesprovider-test.cpp
index 9983e42d8d..69bc966c08 100644
--- a/tests/unit/unittest/builddependenciesprovider-test.cpp
+++ b/tests/unit/unittest/builddependenciesprovider-test.cpp
@@ -176,13 +176,30 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTi
provider.create(projectPart1);
}
+TEST_F(BuildDependenciesProvider,
+ CreateCallsFetchDependSourcesFromGeneratorIfProvidedTimeStampsAreNotUpToDate)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(false));
+ EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1)).WillOnce(Return(buildDependency));
+ EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSources(Eq(secondSources), {1}));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatuses)));
+ EXPECT_CALL(mockBuildDependenciesStorage,
+ insertOrUpdateSourceDependencies(Eq(sourceDependencies)));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(secondUsedMacros)));
+ EXPECT_CALL(mockSqliteTransactionBackend, commit());
+
+ provider.create(projectPart1, std::move(firstSources));
+}
+
TEST_F(BuildDependenciesProvider, FetchDependSourcesFromGenerator)
{
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, {1})).WillByDefault(Return(firstSources));
ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(false));
ON_CALL(mockBuildDependenciesGenerator, create(projectPart1)).WillByDefault(Return(buildDependency));
- auto buildDependency = provider.create(projectPart1);
+ auto buildDependency = provider.create(projectPart1, std::move(firstSources));
ASSERT_THAT(buildDependency.sources, ElementsAre(HasSourceId(1), HasSourceId(3), HasSourceId(8)));
}
@@ -191,10 +208,6 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeSta
{
InSequence s;
- EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
- EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, {1}))
- .WillRepeatedly(Return(firstSources));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true));
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1}));
@@ -202,26 +215,60 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeSta
EXPECT_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10}));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
- provider.create(projectPart1);
+ provider.create(projectPart1, std::move(firstSources));
}
TEST_F(BuildDependenciesProvider, FetchUsedMacrosFromStorageIfDependSourcesAreUpToDate)
{
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, {1})).WillByDefault(Return(firstSources));
ON_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillByDefault(Return(true));
ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1})).WillByDefault(Return(firstUsedMacros));
ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2})).WillByDefault(Return(secondUsedMacros));
ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({10})).WillByDefault(Return(thirdUsedMacros));
- auto buildDependency = provider.create(projectPart1);
+ auto buildDependency = provider.create(projectPart1, std::move(firstSources));
- ASSERT_THAT(buildDependency.usedMacros, ElementsAre(UsedMacro{"YI", 1}, UsedMacro{"ER", 2}, UsedMacro{"LIANG", 2}, UsedMacro{"SAN", 10}));
+ ASSERT_THAT(buildDependency.usedMacros,
+ ElementsAre(UsedMacro{"YI", 1},
+ UsedMacro{"ER", 2},
+ UsedMacro{"LIANG", 2},
+ UsedMacro{"SAN", 10}));
}
TEST_F(BuildDependenciesProvider, CallEnsureAliveMessageIsSentCallback)
{
EXPECT_CALL(mockEnsureAliveMessageIsSentCallback, Call());
- provider.create(projectPart1);
+ provider.create(projectPart1, std::move(firstSources));
}
+
+TEST_F(BuildDependenciesProvider, CreateSourceEntriesFromStorage)
+{
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, {2})).WillByDefault(Return(firstSources));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, {2}))
+ .WillByDefault(Return(secondSources));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, {2})).WillByDefault(Return(thirdSources));
+ ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(true));
+
+ auto sources = provider.createSourceEntriesFromStorage(projectPart2.sourcePathIds,
+ projectPart2.projectPartId);
+
+ ASSERT_THAT(sources,
+ ElementsAre(HasSourceId(1),
+ HasSourceId(2),
+ HasSourceId(3),
+ HasSourceId(4),
+ HasSourceId(8),
+ HasSourceId(10)));
+}
+
+TEST_F(BuildDependenciesProvider, CreateSourceEntriesFromStorageCalls)
+{
+ EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
+ EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, {1}))
+ .WillRepeatedly(Return(firstSources));
+ EXPECT_CALL(mockSqliteTransactionBackend, commit());
+
+ auto sources = provider.createSourceEntriesFromStorage(projectPart1.sourcePathIds,
+ projectPart1.projectPartId);
}
+} // namespace
diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp
index b542fd3082..125ac526d5 100644
--- a/tests/unit/unittest/builddependenciesstorage-test.cpp
+++ b/tests/unit/unittest/builddependenciesstorage-test.cpp
@@ -302,14 +302,32 @@ TEST_F(BuildDependenciesStorage, FetchIndexingTimeStampsIsBusy)
storage.fetchIndexingTimeStamps();
}
+TEST_F(BuildDependenciesStorage, InsertIndexingTimeStampWithoutTransaction)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, immediateBegin()).Times(0);
+ EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement,
+ write(TypedEq<int>(1), TypedEq<long long>(34)));
+ EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement,
+ write(TypedEq<int>(2), TypedEq<long long>(34)));
+ EXPECT_CALL(mockDatabase, commit()).Times(0);
+
+ storage.insertOrUpdateIndexingTimeStampsWithoutTransaction({1, 2}, 34);
+}
+
TEST_F(BuildDependenciesStorage, InsertIndexingTimeStamp)
{
- ClangBackEnd::FileStatuses fileStatuses{{1, 0, 34}, {2, 0, 37}};
+ InSequence s;
- EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34)));
- EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(37)));
+ EXPECT_CALL(mockDatabase, immediateBegin());
+ EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement,
+ write(TypedEq<int>(1), TypedEq<long long>(34)));
+ EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement,
+ write(TypedEq<int>(2), TypedEq<long long>(34)));
+ EXPECT_CALL(mockDatabase, commit());
- storage.insertOrUpdateIndexingTimeStamps(fileStatuses);
+ storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
}
TEST_F(BuildDependenciesStorage, InsertIndexingTimeStampsIsBusy)
@@ -318,8 +336,10 @@ TEST_F(BuildDependenciesStorage, InsertIndexingTimeStampsIsBusy)
EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""}));
EXPECT_CALL(mockDatabase, immediateBegin());
- EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(1), TypedEq<int>(34)));
- EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement, write(TypedEq<int>(2), TypedEq<int>(34)));
+ EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement,
+ write(TypedEq<int>(1), TypedEq<long long>(34)));
+ EXPECT_CALL(inserOrUpdateIndexingTimesStampStatement,
+ write(TypedEq<int>(2), TypedEq<long long>(34)));
EXPECT_CALL(mockDatabase, commit());
storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
@@ -386,19 +406,11 @@ TEST_F(BuildDependenciesStorageSlow, UpdateIndexingTimeStamps)
ElementsAre(SourceTimeStamp{1, 37}, SourceTimeStamp{2, 34}));
}
-TEST_F(BuildDependenciesStorageSlow, InsertIndexingTimeStamp)
-{
- storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 37}});
-
- ASSERT_THAT(storage.fetchIndexingTimeStamps(),
- ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37}));
-}
-
TEST_F(BuildDependenciesStorageSlow, UpdateIndexingTimeStamp)
{
- storage.insertOrUpdateIndexingTimeStamps({{1, 0, 34}, {2, 0, 34}});
+ storage.insertOrUpdateIndexingTimeStamps({1, 2}, 34);
- storage.insertOrUpdateIndexingTimeStamps({{2, 0, 37}});
+ storage.insertOrUpdateIndexingTimeStamps({2}, 37);
ASSERT_THAT(storage.fetchIndexingTimeStamps(),
ElementsAre(SourceTimeStamp{1, 34}, SourceTimeStamp{2, 37}));
diff --git a/tests/unit/unittest/builddependencycollector-test.cpp b/tests/unit/unittest/builddependencycollector-test.cpp
index 352a60f1de..5be0689ef6 100644
--- a/tests/unit/unittest/builddependencycollector-test.cpp
+++ b/tests/unit/unittest/builddependencycollector-test.cpp
@@ -106,6 +106,7 @@ protected:
collector.addUnsavedFiles(
{{{TESTDATA_DIR, "BuildDependencyCollector/project/generated_file.h"},
+ id(TESTDATA_DIR "/BuildDependencyCollector/project/generated_file.h"),
"#pragma once",
{}}});
@@ -127,7 +128,7 @@ protected:
static std::time_t lastModified(Utils::SmallStringView filePath)
{
- return QFileInfo(QString(filePath)).lastModified().toTime_t();
+ return QFileInfo(QString(filePath)).lastModified().toSecsSinceEpoch();
}
ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const
@@ -741,6 +742,7 @@ TEST_F(BuildDependencyCollector, GeneratedFile)
{
generatedFiles.update(
{{TESTDATA_DIR "/builddependencycollector/project/generated/generated_file.h",
+ id(TESTDATA_DIR "/builddependencycollector/project/generated/generated_file.h"),
"#pragma once"}});
emptyCollector.addFile(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
{"cc",
@@ -754,9 +756,9 @@ TEST_F(BuildDependencyCollector, GeneratedFile)
emptyCollector.collect();
- ASSERT_THAT(
- emptyCollector.sourceEntries(),
- ElementsAre(HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
+ ASSERT_THAT(emptyCollector.sourceEntries(),
+ UnorderedElementsAre(
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
SourceType::Source),
HasSource(id(TESTDATA_DIR
"/builddependencycollector/project/generated/generated_file.h"),
@@ -783,8 +785,9 @@ TEST_F(BuildDependencyCollector, Create)
{
using ClangBackEnd::IncludeSearchPathType;
ClangBackEnd::BuildDependencyCollector collector{filePathCache, generatedFiles, environment};
- generatedFiles.update(
- {{TESTDATA_DIR "/builddependencycollector/project/generated_file.h", "#pragma once"}});
+ generatedFiles.update({{TESTDATA_DIR "/builddependencycollector/project/generated_file.h",
+ id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"),
+ "#pragma once"}});
ClangBackEnd::ProjectPartContainer projectPart{
1,
{},
diff --git a/tests/unit/unittest/clangindexingsettingsmanager-test.cpp b/tests/unit/unittest/clangindexingsettingsmanager-test.cpp
new file mode 100644
index 0000000000..e3c4eb7c67
--- /dev/null
+++ b/tests/unit/unittest/clangindexingsettingsmanager-test.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <clangindexingsettingsmanager.h>
+#include <projectexplorer/project.h>
+
+namespace {
+class ClangIndexingSettingsManager : public testing::Test
+{
+protected:
+ ClangPchManager::ClangIndexingSettingsManager manager;
+ ProjectExplorer::Project project;
+ ProjectExplorer::Project project2;
+};
+
+TEST_F(ClangIndexingSettingsManager, FetchSettings)
+{
+ auto setting = manager.settings(&project);
+
+ ASSERT_THAT(setting, Not(IsNull()));
+}
+
+TEST_F(ClangIndexingSettingsManager, SettingsAreTheSameForTheSameProject)
+{
+ auto setting1 = manager.settings(&project);
+
+ auto setting2 = manager.settings(&project);
+
+ ASSERT_THAT(setting1, Eq(setting2));
+}
+
+TEST_F(ClangIndexingSettingsManager, SettingsAreTheDifferentForDifferentProjects)
+{
+ manager.settings(&project);
+ manager.settings(&project2);
+
+ auto setting1 = manager.settings(&project);
+
+ auto setting2 = manager.settings(&project2);
+
+ ASSERT_THAT(setting1, Not(Eq(setting2)));
+}
+
+TEST_F(ClangIndexingSettingsManager, RemoveSettings)
+{
+ manager.settings(&project);
+
+ manager.remove(&project);
+
+ ASSERT_FALSE(manager.hasSettings(&project));
+}
+
+TEST_F(ClangIndexingSettingsManager, RemoveNonExistingSettings)
+{
+ manager.remove(&project);
+
+ ASSERT_FALSE(manager.hasSettings(&project));
+}
+} // namespace
diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp
index 77a049210b..f17d416613 100644
--- a/tests/unit/unittest/clangquery-test.cpp
+++ b/tests/unit/unittest/clangquery-test.cpp
@@ -40,6 +40,7 @@
#include <mutex>
using ClangBackEnd::ClangQuery;
+using ClangBackEnd::FilePath;
using ClangBackEnd::FilePathCaching;
using ClangBackEnd::RefactoringDatabaseInitializer;
@@ -98,7 +99,11 @@ TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange)
"#include \"unsaved.h\"",
{"cc", "-std=c++14"});
query.setQuery("functionDecl()");
- ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"}, "void unsaved();", {}};
+ ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR, "unsaved.h"},
+ filePathCache.filePathId(
+ FilePath{TESTDATA_DIR, "unsaved.h"}),
+ "void unsaved();",
+ {}};
query.addUnsavedFiles({unsavedFile});
query.findLocations();
@@ -125,6 +130,8 @@ TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOver
query.addFile({TESTDATA_DIR "/query_simplefunction.cpp"}, "void f() {}", {"cc", "-std=c++14"});
query.setQuery("functionDecl()");
ClangBackEnd::V2::FileContainer unsavedFile{{TESTDATA_DIR "/query_simplefunction.cpp"},
+ filePathCache.filePathId(
+ FilePath{TESTDATA_DIR, "query_simplefunction.cpp"}),
"void unsaved();",
{}};
query.addUnsavedFiles({unsavedFile});
diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp
index 3b5f9239fe..c301af4ad0 100644
--- a/tests/unit/unittest/clangquerygatherer-test.cpp
+++ b/tests/unit/unittest/clangquerygatherer-test.cpp
@@ -59,10 +59,10 @@ using testing::SizeIs;
using testing::UnorderedElementsAre;
using testing::_;
-using ClangBackEnd::V2::FileContainer;
-using ClangBackEnd::SourceRangesForQueryMessage;
-using ClangBackEnd::SourceRangesContainer;
+using ClangBackEnd::FilePath;
using ClangBackEnd::SourceRangesContainer;
+using ClangBackEnd::SourceRangesForQueryMessage;
+using ClangBackEnd::V2::FileContainer;
MATCHER_P2(Contains, line, column,
std::string(negation ? "isn't " : "is ")
@@ -86,22 +86,20 @@ protected:
ClangBackEnd::FilePathCaching filePathCache{database};
Utils::SmallString sourceContent{"#include \"query_simplefunction.h\"\nvoid f() {}"};
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.cpp"}),
sourceContent.clone(),
- {"cc",
- "-I",
- TESTDATA_DIR}};
+ {"cc", "-I", TESTDATA_DIR}};
FileContainer source2{{TESTDATA_DIR, "query_simplefunction2.cpp"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction2.cpp"}),
{},
- {"cc",
- "-I",
- TESTDATA_DIR}};
+ {"cc", "-I", TESTDATA_DIR}};
FileContainer source3{{TESTDATA_DIR, "query_simplefunction3.cpp"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction3.cpp"}),
{},
- {"cc",
- "-I",
- TESTDATA_DIR}};
+ {"cc", "-I", TESTDATA_DIR}};
Utils::SmallString unsavedContent{"void f();"};
FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
unsavedContent.clone(),
{}};
Utils::SmallString query{"functionDecl()"};
diff --git a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp
index 3981980902..65169cb745 100644
--- a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp
+++ b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp
@@ -122,9 +122,7 @@ protected:
QString unsavedDocumentContent{"void f();"};
std::vector<Utils::SmallStringVector> commandLines;
std::vector<CppTools::ProjectPart::Ptr> projectsParts;
- ClangBackEnd::V2::FileContainer unsavedContent{{"/path/to", "unsaved.cpp"},
- "void f();",
- {}};
+ ClangBackEnd::V2::FileContainer unsavedContent{{"/path/to", "unsaved.cpp"}, 1, "void f();", {}};
ProjectExplorer::Project project;
};
@@ -186,17 +184,12 @@ TEST_F(ClangQueryProjectFindFilter, FindAllIsSettingExprectedResultCountInTheRef
TEST_F(ClangQueryProjectFindFilter, FindAllIsCallingRequestSourceRangesAndDiagnosticsForQueryMessage)
{
- ClangBackEnd::RequestSourceRangesForQueryMessage message(findDeclQueryText,
- {{{"/path/to", "file1.h"},
- "",
- commandLines[0].clone()},
- {{"/path/to", "file1.cpp"},
- "",
- commandLines[1].clone()},
- {{"/path/to", "file2.cpp"},
- "",
- commandLines[2].clone()}},
- {unsavedContent.clone()});
+ ClangBackEnd::RequestSourceRangesForQueryMessage message(
+ findDeclQueryText,
+ {{{"/path/to", "file1.h"}, 1, "", commandLines[0].clone()},
+ {{"/path/to", "file1.cpp"}, 2, "", commandLines[1].clone()},
+ {{"/path/to", "file2.cpp"}, 3, "", commandLines[2].clone()}},
+ {unsavedContent.clone()});
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
diff --git a/tests/unit/unittest/clangtranslationunit-test.cpp b/tests/unit/unittest/clangtranslationunit-test.cpp
index 2cb936c999..52fd447e98 100644
--- a/tests/unit/unittest/clangtranslationunit-test.cpp
+++ b/tests/unit/unittest/clangtranslationunit-test.cpp
@@ -53,8 +53,8 @@ protected:
DiagnosticContainer createDiagnostic(const QString &text,
ClangBackEnd::DiagnosticSeverity severity,
- uint line,
- uint column,
+ int line,
+ int column,
const QString &filePath) const;
QVector<DiagnosticContainer> diagnosticsFromMainFile() const;
QVector<DiagnosticContainer> errorDiagnosticsFromHeaders() const;
@@ -141,8 +141,8 @@ void TranslationUnit::reparse()
DiagnosticContainer TranslationUnit::createDiagnostic(const QString &text,
ClangBackEnd::DiagnosticSeverity severity,
- uint line,
- uint column,
+ int line,
+ int column,
const QString &filePath) const
{
return DiagnosticContainer(
diff --git a/tests/unit/unittest/compileroptionsbuilder-test.cpp b/tests/unit/unittest/compileroptionsbuilder-test.cpp
index 372149c046..9d026e2500 100644
--- a/tests/unit/unittest/compileroptionsbuilder-test.cpp
+++ b/tests/unit/unittest/compileroptionsbuilder-test.cpp
@@ -64,7 +64,7 @@ protected:
ProjectExplorer::Macro{"_MSC_FULL_VER", "1900"},
ProjectExplorer::Macro{"_MSC_VER", "19"}};
projectPart.projectMacros = {ProjectExplorer::Macro{"projectFoo", "projectBar"}};
- projectPart.qtVersion = ProjectPart::Qt5;
+ projectPart.qtVersion = Utils::QtVersion::Qt5;
projectPart.headerPaths = {HeaderPath{"/tmp/builtin_path", HeaderPathType::BuiltIn},
HeaderPath{"/tmp/system_path", HeaderPathType::System},
diff --git a/tests/unit/unittest/cppprojectinfogenerator-test.cpp b/tests/unit/unittest/cppprojectinfogenerator-test.cpp
index 7db9f0e439..ceb3c8b8aa 100644
--- a/tests/unit/unittest/cppprojectinfogenerator-test.cpp
+++ b/tests/unit/unittest/cppprojectinfogenerator-test.cpp
@@ -35,11 +35,11 @@
using CppTools::Internal::ProjectInfoGenerator;
using CppTools::ProjectFile;
using CppTools::ProjectInfo;
-using CppTools::ProjectUpdateInfo;
using CppTools::ProjectPart;
-using CppTools::RawProjectPart;
using ProjectExplorer::Macros;
+using ProjectExplorer::ProjectUpdateInfo;
+using ProjectExplorer::RawProjectPart;
using ProjectExplorer::ToolChain;
using testing::Eq;
diff --git a/tests/unit/unittest/creator_dependency.pri b/tests/unit/unittest/creator_dependency.pri
index 46d936d9c3..2e84e1cdca 100644
--- a/tests/unit/unittest/creator_dependency.pri
+++ b/tests/unit/unittest/creator_dependency.pri
@@ -4,6 +4,7 @@ IDE_LIBEXEC_PATH=$$PWD
IDE_BIN_PATH=$$PWD
include($$PWD/../../../src/libs/utils/utils-lib.pri)
+include($$PWD/../../../src/libs/3rdparty/yaml-cpp/yaml-cpp.pri)
include($$PWD/../../../src/libs/sqlite/sqlite-lib.pri)
include($$PWD/../../../src/libs/clangsupport/clangsupport-lib.pri)
include($$PWD/../../../src/plugins/coreplugin/corepluginunittestfiles.pri)
@@ -13,6 +14,8 @@ include($$PWD/../../../src/tools/clangpchmanagerbackend/source/clangpchmanagerba
include($$PWD/../../../src/plugins/clangrefactoring/clangrefactoring-source.pri)
include($$PWD/../../../src/plugins/clangpchmanager/clangpchmanager-source.pri)
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
+include($$PWD/../../../src/plugins/clangtools/clangtoolsunittestfiles.pri)
+include($$PWD/../../../src/plugins/debugger/debuggerunittestfiles.pri)
include($$PWD/../../../src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri)
include(cplusplus.pri)
!isEmpty(LLVM_VERSION) {
diff --git a/tests/unit/unittest/data/clangtools/CMakeLists.txt b/tests/unit/unittest/data/clangtools/CMakeLists.txt
new file mode 100644
index 0000000000..b445f81b7d
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(clangtools LANGUAGES CXX)
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt5 COMPONENTS Widgets REQUIRED)
+
+add_executable(clangtools
+ main.cpp
+ clang-analyzer.dividezero.cpp
+ clang.unused-parameter.cpp
+ clang.unused-parameter.h
+ clazy.qgetenv.cpp
+ tidy.modernize-use-nullptr.cpp
+)
+
+target_link_libraries(clangtools PRIVATE Qt5::Widgets)
diff --git a/tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.cpp b/tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.cpp
new file mode 100644
index 0000000000..5f623dc114
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.cpp
@@ -0,0 +1,5 @@
+// clang-tidy -export-fixes=clang-analyzer.dividezero.yaml "-checks=-*,clang-analyzer-core.DivideZero" clang-analyzer.dividezero.cpp
+void test(int z) {
+ if (z == 0)
+ int x = 1 / z;
+}
diff --git a/tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.yaml b/tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.yaml
new file mode 100644
index 0000000000..d19c5887a9
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clang-analyzer.dividezero.yaml
@@ -0,0 +1,23 @@
+---
+MainSourceFile: 'FILE_PATH'
+Diagnostics:
+ - DiagnosticName: clang-analyzer-core.DivideZero
+ DiagnosticMessage:
+ Message: Division by zero
+ FilePath: 'FILE_PATH'
+ FileOffset: 180
+ Replacements: []
+ Notes:
+ - Message: 'Assuming ''z'' is equal to 0'
+ FilePath: 'FILE_PATH'
+ FileOffset: 158
+ Replacements: []
+ - Message: Taking true branch
+ FilePath: 'FILE_PATH'
+ FileOffset: 154
+ Replacements: []
+ - Message: Division by zero
+ FilePath: 'FILE_PATH'
+ FileOffset: 180
+ Replacements: []
+...
diff --git a/tests/unit/unittest/data/clangtools/clang.unused-parameter.cpp b/tests/unit/unittest/data/clangtools/clang.unused-parameter.cpp
new file mode 100644
index 0000000000..80d9047c52
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clang.unused-parameter.cpp
@@ -0,0 +1,5 @@
+// clang-tidy -export-fixes=clang.unused-parameter.yaml clang.unused-parameter.cpp -- -Wunused-parameter
+#include "clang.unused-parameter.h"
+
+void g(int g) {}
+
diff --git a/tests/unit/unittest/data/clangtools/clang.unused-parameter.h b/tests/unit/unittest/data/clangtools/clang.unused-parameter.h
new file mode 100644
index 0000000000..39d55b8fce
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clang.unused-parameter.h
@@ -0,0 +1 @@
+void f(int i) {}
diff --git a/tests/unit/unittest/data/clangtools/clang.unused-parameter.yaml b/tests/unit/unittest/data/clangtools/clang.unused-parameter.yaml
new file mode 100644
index 0000000000..6622953a2f
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clang.unused-parameter.yaml
@@ -0,0 +1,10 @@
+---
+MainSourceFile: 'FILE_PATH'
+Diagnostics:
+ - DiagnosticName: clang-diagnostic-unused-parameter
+ DiagnosticMessage:
+ Message: 'unused parameter ''g'''
+ FilePath: 'FILE_PATH'
+ FileOffset: 153
+ Replacements: []
+...
diff --git a/tests/unit/unittest/data/clangtools/clazy.qgetenv.cpp b/tests/unit/unittest/data/clangtools/clazy.qgetenv.cpp
new file mode 100644
index 0000000000..e04518821c
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clazy.qgetenv.cpp
@@ -0,0 +1,8 @@
+// clazy-standalone -export-fixes=/tmp/clazy.qgetenv.yaml -checks=qgetenv clazy.qgetenv.cpp
+#include <QByteArray>
+#include <QtGlobal>
+
+void g()
+{
+ qgetenv("Foo").isEmpty();
+}
diff --git a/tests/unit/unittest/data/clangtools/clazy.qgetenv.yaml b/tests/unit/unittest/data/clangtools/clazy.qgetenv.yaml
new file mode 100644
index 0000000000..a465a1ca63
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/clazy.qgetenv.yaml
@@ -0,0 +1,17 @@
+---
+MainSourceFile: 'FILE_PATH'
+Diagnostics:
+ - DiagnosticName: clazy-qgetenv
+ Message: 'qgetenv().isEmpty() allocates. Use qEnvironmentVariableIsEmpty() instead'
+ FileOffset: 150
+ FilePath: 'FILE_PATH'
+ Replacements:
+ - FilePath: 'FILE_PATH'
+ Offset: 150
+ Length: 7
+ ReplacementText: qEnvironmentVariableIsEmpty
+ - FilePath: 'FILE_PATH'
+ Offset: 163
+ Length: 11
+ ReplacementText: ')'
+...
diff --git a/tests/unit/unittest/data/clangtools/empty.yaml b/tests/unit/unittest/data/clangtools/empty.yaml
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/empty.yaml
diff --git a/tests/unit/unittest/data/clangtools/main.cpp b/tests/unit/unittest/data/clangtools/main.cpp
new file mode 100644
index 0000000000..df38a77648
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/main.cpp
@@ -0,0 +1,4 @@
+int main(int, char *[])
+{
+ return 0;
+}
diff --git a/tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.cpp b/tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.cpp
new file mode 100644
index 0000000000..fedae86330
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.cpp
@@ -0,0 +1,2 @@
+// clang-tidy -export-fixes=tidy.modernize-use-nullptr.yaml "-checks=-*,modernize-use-nullptr" tidy.modernize-use-nullptr.cpp
+int *ret_ptr() { return 0; }
diff --git a/tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.yaml b/tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.yaml
new file mode 100644
index 0000000000..7724d3bdfc
--- /dev/null
+++ b/tests/unit/unittest/data/clangtools/tidy.modernize-use-nullptr.yaml
@@ -0,0 +1,14 @@
+---
+MainSourceFile: 'FILE_PATH'
+Diagnostics:
+ - DiagnosticName: modernize-use-nullptr
+ DiagnosticMessage:
+ Message: use nullptr
+ FilePath: 'FILE_PATH'
+ FileOffset: 150
+ Replacements:
+ - FilePath: 'FILE_PATH'
+ Offset: 150
+ Length: 1
+ ReplacementText: nullptr
+...
diff --git a/tests/unit/unittest/data/symbolscollector/class.cpp b/tests/unit/unittest/data/symbolscollector/class.cpp
new file mode 100644
index 0000000000..5f393c44cd
--- /dev/null
+++ b/tests/unit/unittest/data/symbolscollector/class.cpp
@@ -0,0 +1,14 @@
+class Class
+{
+ Class();
+ Class(int);
+
+ void foo();
+
+ void bar() {}
+};
+
+void Class::foo()
+{
+ bar();
+}
diff --git a/tests/unit/unittest/filepathcache-test.cpp b/tests/unit/unittest/filepathcache-test.cpp
index 478e5f0215..4b43d3924c 100644
--- a/tests/unit/unittest/filepathcache-test.cpp
+++ b/tests/unit/unittest/filepathcache-test.cpp
@@ -26,6 +26,7 @@
#include "googletest.h"
#include "mockfilepathstorage.h"
+#include "mocksqlitedatabase.h"
#include <filepathcache.h>
@@ -37,6 +38,7 @@ using Cache = ClangBackEnd::FilePathCache<NiceMock<MockFilePathStorage>>;
using ClangBackEnd::FilePathId;
using NFP = ClangBackEnd::FilePath;
using ClangBackEnd::FilePathView;
+using ClangBackEnd::FilePathViews;
using ClangBackEnd::Sources::SourceNameAndDirectoryId;
class FilePathCache : public testing::Test
@@ -54,15 +56,30 @@ protected:
.WillByDefault(Return(63));
ON_CALL(mockStorage, fetchSourceId(6, Eq("file.cpp")))
.WillByDefault(Return(72));
- ON_CALL(mockStorage, fetchDirectoryPath(5))
- .WillByDefault(Return(Utils::PathString("/path/to")));
+ ON_CALL(mockStorage, fetchDirectoryPath(5)).WillByDefault(Return(Utils::PathString("/path/to")));
ON_CALL(mockStorage, fetchSourceNameAndDirectoryId(42))
- .WillByDefault(Return(SourceNameAndDirectoryId("file.cpp", 5)));
+ .WillByDefault(Return(SourceNameAndDirectoryId("file.cpp", 5)));
+ ON_CALL(mockStorageFilled, fetchAllSources())
+ .WillByDefault(Return(std::vector<ClangBackEnd::Sources::Source>({
+ {"file.cpp", 6, 72},
+ {"file2.cpp", 5, 63},
+ {"file.cpp", 5, 42},
+ })));
+ ON_CALL(mockStorageFilled, fetchAllDirectories())
+ .WillByDefault(Return(
+ std::vector<ClangBackEnd::Sources::Directory>({{"/path2/to", 6}, {"/path/to", 5}})));
+ ON_CALL(mockStorageFilled, fetchDirectoryIdUnguarded(Eq("/path3/to"))).WillByDefault(Return(7));
+ ON_CALL(mockStorageFilled, fetchSourceIdUnguarded(7, Eq("file.h"))).WillByDefault(Return(101));
+ ON_CALL(mockStorageFilled, fetchSourceIdUnguarded(6, Eq("file2.h"))).WillByDefault(Return(106));
+ ON_CALL(mockStorageFilled, fetchSourceIdUnguarded(5, Eq("file.h"))).WillByDefault(Return(99));
}
protected:
- NiceMock<MockFilePathStorage> mockStorage;
+ NiceMock<MockSqliteDatabase> mockDatabase;
+ NiceMock<MockFilePathStorage> mockStorage{mockDatabase};
Cache cache{mockStorage};
+ NiceMock<MockFilePathStorage> mockStorageFilled{mockDatabase};
+ Cache cacheNotFilled{mockStorageFilled};
};
TEST_F(FilePathCache, FilePathIdWithOutAnyEntryCallDirectoryId)
@@ -316,4 +333,158 @@ TEST_F(FilePathCache, FetchDirectoryPathIdAfterFetchingFilePathByFilePathId)
ASSERT_THAT(directoryId, Eq(5));
}
+
+TEST_F(FilePathCache, FetchAllDirectoriesAndSourcesAtCreation)
+{
+ EXPECT_CALL(mockStorage, fetchAllDirectories());
+ EXPECT_CALL(mockStorage, fetchAllSources());
+
+ Cache cache{mockStorage};
+}
+
+TEST_F(FilePathCache, GetFileIdInFilledCache)
+{
+ Cache cacheFilled{mockStorageFilled};
+
+ auto id = cacheFilled.filePathId("/path2/to/file.cpp");
+
+ ASSERT_THAT(id, Eq(72));
+}
+
+TEST_F(FilePathCache, GetDirectoryIdInFilledCache)
+{
+ Cache cacheFilled{mockStorageFilled};
+
+ auto id = cacheFilled.directoryPathId(42);
+
+ ASSERT_THAT(id, Eq(5));
+}
+
+TEST_F(FilePathCache, GetDirectoryPathInFilledCache)
+{
+ Cache cacheFilled{mockStorageFilled};
+
+ auto path = cacheFilled.directoryPath(5);
+
+ ASSERT_THAT(path, Eq("/path/to"));
+}
+
+TEST_F(FilePathCache, GetFilePathInFilledCache)
+{
+ Cache cacheFilled{mockStorageFilled};
+
+ auto path = cacheFilled.filePath(42);
+
+ ASSERT_THAT(path, Eq("/path/to/file.cpp"));
+}
+
+TEST_F(FilePathCache, GetFileIdAfterAddFilePaths)
+{
+ Cache cacheFilled{mockStorageFilled};
+
+ cacheFilled.addFilePaths(
+ FilePathViews{"/path3/to/file.h", "/path/to/file.h", "/path2/to/file2.h", "/path/to/file.cpp"});
+
+ ASSERT_THAT(cacheFilled.filePath(101), Eq("/path3/to/file.h"));
+}
+
+TEST_F(FilePathCache, GetFileIdAfterAddFilePathsWhichWasAlreadyAdded)
+{
+ Cache cacheFilled{mockStorageFilled};
+
+ cacheFilled.addFilePaths(FilePathViews{"/path3/to/file.h", "/path/to/file.h", "/path2/to/file2.h"});
+
+ ASSERT_THAT(cacheFilled.filePath(42), Eq("/path/to/file.cpp"));
+}
+
+TEST_F(FilePathCache, AddFilePathsCalls)
+{
+ Cache cacheFilled{mockStorageFilled};
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(mockStorageFilled, fetchDirectoryIdUnguarded(Eq("/path3/to"))).WillOnce(Return(7));
+ EXPECT_CALL(mockStorageFilled, fetchDirectoryIdUnguarded(Eq("/path/to"))).Times(0);
+ EXPECT_CALL(mockStorageFilled, fetchSourceIdUnguarded(5, Eq("file.h"))).WillOnce(Return(99));
+ EXPECT_CALL(mockStorageFilled, fetchSourceIdUnguarded(6, Eq("file2.h"))).WillOnce(Return(106));
+ EXPECT_CALL(mockStorageFilled, fetchSourceIdUnguarded(7, Eq("file.h"))).WillOnce(Return(101));
+ EXPECT_CALL(mockStorageFilled, fetchSourceIdUnguarded(5, Eq("file.cpp"))).Times(0);
+ EXPECT_CALL(mockDatabase, commit());
+
+ cacheFilled.addFilePaths(
+ FilePathViews{"/path3/to/file.h", "/path/to/file.h", "/path2/to/file2.h", "/path/to/file.cpp"});
+}
+
+TEST_F(FilePathCache, DontUseTransactionIfNotAddingFilesInAddFilePathsCalls)
+{
+ Cache cacheFilled{mockStorageFilled};
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin()).Times(0);
+ EXPECT_CALL(mockStorageFilled, fetchDirectoryIdUnguarded(Eq("/path/to"))).Times(0);
+ EXPECT_CALL(mockStorageFilled, fetchSourceIdUnguarded(5, Eq("file.cpp"))).Times(0);
+ EXPECT_CALL(mockDatabase, commit()).Times(0);
+
+ cacheFilled.addFilePaths(FilePathViews{"/path/to/file.cpp"});
+}
+
+TEST_F(FilePathCache, UseTransactionIfAddingFilesOnlyInAddFilePathsCalls)
+{
+ Cache cacheFilled{mockStorageFilled};
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(mockStorageFilled, fetchDirectoryIdUnguarded(Eq("/path/to"))).Times(0);
+ EXPECT_CALL(mockStorageFilled, fetchSourceIdUnguarded(5, Eq("file.h")));
+ EXPECT_CALL(mockDatabase, commit());
+
+ cacheFilled.addFilePaths(FilePathViews{"/path/to/file.h"});
+}
+
+TEST_F(FilePathCache, GetFileIdInAfterPopulateIfEmpty)
+{
+ cacheNotFilled.populateIfEmpty();
+
+ auto id = cacheNotFilled.filePathId("/path2/to/file.cpp");
+
+ ASSERT_THAT(id, Eq(72));
+}
+
+TEST_F(FilePathCache, DontPopulateIfNotEmpty)
+{
+ cacheNotFilled.filePathId("/path/to/file.cpp");
+
+ EXPECT_CALL(mockStorageFilled, fetchAllDirectories()).Times(0);
+ EXPECT_CALL(mockStorageFilled, fetchAllSources()).Times(0);
+
+ cacheNotFilled.populateIfEmpty();
+}
+
+TEST_F(FilePathCache, GetDirectoryIdAfterPopulateIfEmpty)
+{
+ cacheNotFilled.populateIfEmpty();
+
+ auto id = cacheNotFilled.directoryPathId(42);
+
+ ASSERT_THAT(id, Eq(5));
+}
+
+TEST_F(FilePathCache, GetDirectoryPathAfterPopulateIfEmpty)
+{
+ cacheNotFilled.populateIfEmpty();
+
+ auto path = cacheNotFilled.directoryPath(5);
+
+ ASSERT_THAT(path, Eq("/path/to"));
+}
+
+TEST_F(FilePathCache, GetFilePathAfterPopulateIfEmptye)
+{
+ cacheNotFilled.populateIfEmpty();
+
+ auto path = cacheNotFilled.filePath(42);
+
+ ASSERT_THAT(path, Eq("/path/to/file.cpp"));
+}
+
} // namespace
diff --git a/tests/unit/unittest/filepathstorage-test.cpp b/tests/unit/unittest/filepathstorage-test.cpp
index fb60e32512..e943ab43da 100644
--- a/tests/unit/unittest/filepathstorage-test.cpp
+++ b/tests/unit/unittest/filepathstorage-test.cpp
@@ -56,9 +56,8 @@ protected:
.WillByDefault(Return(Utils::optional<int>(5)));
ON_CALL(mockDatabase, lastInsertedRowId())
.WillByDefault(Return(12));
- ON_CALL(selectAllDirectories,
- valuesReturnStdVectorDirectory(_))
- .WillByDefault(Return(std::vector<Directory>{{1, "/path/to"}, {2, "/other/path"}}));
+ ON_CALL(selectAllDirectories, valuesReturnStdVectorDirectory(_))
+ .WillByDefault(Return(std::vector<Directory>{{"/path/to", 1}, {"/other/path", 2}}));
ON_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
valueReturnInt32(_, _))
.WillByDefault(Return(Utils::optional<int>()));
@@ -68,9 +67,8 @@ protected:
ON_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
valueReturnInt32(5, Utils::SmallStringView("file.h")))
.WillByDefault(Return(Utils::optional<int>(42)));
- ON_CALL(selectAllSources,
- valuesReturnStdVectorSource(_))
- .WillByDefault(Return(std::vector<Source>{{1, "file.h"}, {4, "file.cpp"}}));
+ ON_CALL(selectAllSources, valuesReturnStdVectorSource(_))
+ .WillByDefault(Return(std::vector<Source>{{"file.h", 1, 1}, {"file.cpp", 2, 4}}));
ON_CALL(selectDirectoryPathFromDirectoriesByDirectoryId,
valueReturnPathString(5))
.WillByDefault(Return(Utils::optional<Utils::PathString>("/path/to")));
@@ -407,16 +405,14 @@ TEST_F(FilePathStorage, SelectAllDirectories)
{
auto directories = storage.fetchAllDirectories();
- ASSERT_THAT(directories,
- ElementsAre(Directory{1, "/path/to"}, Directory{2, "/other/path"}));
+ ASSERT_THAT(directories, ElementsAre(Directory{"/path/to", 1}, Directory{"/other/path", 2}));
}
TEST_F(FilePathStorage, SelectAllSources)
{
auto sources = storage.fetchAllSources();
- ASSERT_THAT(sources,
- ElementsAre(Source{1, "file.h"}, Source{4, "file.cpp"}));
+ ASSERT_THAT(sources, ElementsAre(Source{"file.h", 1, 1}, Source{"file.cpp", 2, 4}));
}
TEST_F(FilePathStorage, CallSelectAllDirectories)
@@ -603,4 +599,75 @@ TEST_F(FilePathStorage, FetchDirectoryIdCallsThrows)
ASSERT_ANY_THROW(storage.fetchDirectoryId(41));
}
+TEST_F(FilePathStorage, GetTheDirectoryIdBackAfterFetchingANewEntryFromDirectoriesUnguarded)
+{
+ auto directoryId = storage.fetchDirectoryIdUnguarded("/some/not/known/path");
+
+ ASSERT_THAT(directoryId, 12);
+}
+
+TEST_F(FilePathStorage, GetTheSourceIdBackAfterFetchingANewEntryFromSourcesUnguarded)
+{
+ auto sourceId = storage.fetchSourceIdUnguarded(5, "unknownfile.h");
+
+ ASSERT_THAT(sourceId, 12);
+}
+
+TEST_F(FilePathStorage, CallSelectForFetchingDirectoryIdForKnownPathUnguarded)
+{
+ InSequence s;
+
+ EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/path/to")));
+
+ storage.fetchDirectoryIdUnguarded("/path/to");
+}
+
+TEST_F(FilePathStorage, CallSelectForFetchingSourceIdForKnownPathUnguarded)
+{
+ InSequence s;
+
+ EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
+ valueReturnInt32(5, Eq("file.h")));
+
+ storage.fetchSourceIdUnguarded(5, "file.h");
+}
+
+TEST_F(FilePathStorage, CallNotWriteForFetchingDirectoryIdForKnownPathUnguarded)
+{
+ EXPECT_CALL(insertIntoDirectories, write(An<Utils::SmallStringView>())).Times(0);
+
+ storage.fetchDirectoryIdUnguarded("/path/to");
+}
+
+TEST_F(FilePathStorage, CallNotWriteForFetchingSoureIdForKnownEntryUnguarded)
+{
+ EXPECT_CALL(insertIntoSources, write(An<uint>(), An<Utils::SmallStringView>())).Times(0);
+
+ storage.fetchSourceIdUnguarded(5, "file.h");
+}
+
+TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdForUnknownPathUnguarded)
+{
+ InSequence s;
+
+ EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/some/not/known/path")));
+ EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/some/not/known/path")));
+
+ storage.fetchDirectoryIdUnguarded("/some/not/known/path");
+}
+
+TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceIdForUnknownEntryUnguarded)
+{
+ InSequence s;
+
+ EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
+ valueReturnInt32(5, Eq("unknownfile.h")));
+ EXPECT_CALL(insertIntoSources,
+ write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("unknownfile.h")));
+
+ storage.fetchSourceIdUnguarded(5, "unknownfile.h");
+}
+
} // namespace
diff --git a/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp b/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp
index 40af2d99c3..42c1d0541a 100644
--- a/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp
+++ b/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp
@@ -73,12 +73,6 @@ TEST_F(FilePathStorageSqliteStatementFactory, SelectSourceNameAndDirectoryIdBySo
Eq("SELECT sourceName, directoryId FROM sources WHERE sourceId = ?"));
}
-TEST_F(FilePathStorageSqliteStatementFactory, SelectAllDirectories)
-{
- ASSERT_THAT(factory.selectAllDirectories.sqlStatement,
- Eq("SELECT directoryId, directoryPath FROM directories"));
-}
-
TEST_F(FilePathStorageSqliteStatementFactory, InsertIntoDirectories)
{
ASSERT_THAT(factory.insertIntoDirectories.sqlStatement,
@@ -91,10 +85,4 @@ TEST_F(FilePathStorageSqliteStatementFactory, InsertIntoSources)
Eq("INSERT INTO sources(directoryId, sourceName) VALUES (?,?)"));
}
-TEST_F(FilePathStorageSqliteStatementFactory, SelectAllSources)
-{
- ASSERT_THAT(factory.selectAllSources.sqlStatement,
- Eq("SELECT sourceId, sourceName FROM sources"));
-}
-
}
diff --git a/tests/unit/unittest/fixit-test.cpp b/tests/unit/unittest/fixit-test.cpp
index 0063dc27fc..0d64107d09 100644
--- a/tests/unit/unittest/fixit-test.cpp
+++ b/tests/unit/unittest/fixit-test.cpp
@@ -108,17 +108,17 @@ TEST_F(FixIt, Text)
TEST_F(FixIt, DISABLED_ON_WINDOWS(Start))
{
ASSERT_THAT(fixIt.range().start(), IsSourceLocation(Utf8StringLiteral("diagnostic_semicolon_fixit.cpp"),
- 3u,
- 13u,
- 29u));
+ 3,
+ 13,
+ 29));
}
TEST_F(FixIt, DISABLED_ON_WINDOWS(End))
{
ASSERT_THAT(fixIt.range().end(), IsSourceLocation(Utf8StringLiteral("diagnostic_semicolon_fixit.cpp"),
- 3u,
- 13u,
- 29u));
+ 3,
+ 13,
+ 29));
}
void FixIt::SetUpTestCase()
diff --git a/tests/unit/unittest/generatedfiles-test.cpp b/tests/unit/unittest/generatedfiles-test.cpp
index 9db9c4b0ae..8e5a34ffd7 100644
--- a/tests/unit/unittest/generatedfiles-test.cpp
+++ b/tests/unit/unittest/generatedfiles-test.cpp
@@ -35,12 +35,12 @@ using ClangBackEnd::V2::FileContainers;
class GeneratedFiles : public testing::Test
{
protected:
- FileContainer file1{"/file1", "content1"};
- FileContainer file1b{"/file1", "content1b"};
- FileContainer file2{"/file2", "content2"};
- FileContainer file2b{"/file2", "content2b"};
- FileContainer file3{"/file3", "content3"};
- FileContainer file4{"/file4", "content4"};
+ FileContainer file1{"/file1", 1, "content1"};
+ FileContainer file1b{"/file1", 1, "content1b"};
+ FileContainer file2{"/file2", 2, "content2"};
+ FileContainer file2b{"/file2", 2, "content2b"};
+ FileContainer file3{"/file3", 3, "content3"};
+ FileContainer file4{"/file4", 4, "content4"};
ClangBackEnd::GeneratedFiles generatedFiles;
};
@@ -76,7 +76,7 @@ TEST_F(GeneratedFiles, IsValidForNoGeneratedFiles)
TEST_F(GeneratedFiles, IsNotValidIfFilesWithNotContentExists)
{
- generatedFiles.update({{"/file2", ""}});
+ generatedFiles.update({{"/file2", 2, ""}});
ASSERT_FALSE(generatedFiles.isValid());
}
@@ -86,4 +86,15 @@ TEST_F(GeneratedFiles, IsValidIfAllFilesHasContent)
generatedFiles.update({file1, file2, file3, file4});
ASSERT_TRUE(generatedFiles.isValid());
-}}
+}
+
+TEST_F(GeneratedFiles, GetFilePathIds)
+{
+ generatedFiles.update({file3, file2, file1, file4});
+
+ auto ids = generatedFiles.filePathIds();
+
+ ASSERT_THAT(ids, ElementsAre(1, 2, 3, 4));
+}
+
+} // namespace
diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp
index 141a926d9e..2bbcdbaa45 100644
--- a/tests/unit/unittest/gtest-creator-printing.cpp
+++ b/tests/unit/unittest/gtest-creator-printing.cpp
@@ -37,6 +37,9 @@
#include <clangcodemodelservermessages.h>
#include <clangpathwatcher.h>
#include <clangrefactoringmessages.h>
+#include <coreplugin/find/searchresultitem.h>
+#include <coreplugin/locator/ilocatorfilter.h>
+#include <cpptools/usages.h>
#include <filepath.h>
#include <filepathcaching.h>
#include <filepathview.h>
@@ -46,6 +49,8 @@
#include <pchpaths.h>
#include <pchtask.h>
#include <precompiledheadersupdatedmessage.h>
+#include <projectexplorer/headerpath.h>
+#include <projectexplorer/projectmacro.h>
#include <projectpartartefact.h>
#include <projectpartentry.h>
#include <projectpartpch.h>
@@ -58,11 +63,13 @@
#include <toolchainargumentscache.h>
#include <tooltipinfo.h>
#include <usedmacro.h>
+#include <utils/link.h>
#include <cpptools/usages.h>
#include <projectexplorer/projectmacro.h>
#include <projectexplorer/headerpath.h>
#include <coreplugin/find/searchresultitem.h>
#include <coreplugin/locator/ilocatorfilter.h>
+#include <clangtools/clangtoolsdiagnostic.h>
namespace {
ClangBackEnd::FilePathCaching *filePathCache = nullptr;
@@ -178,6 +185,12 @@ std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn)
return out << "(" << lineColumn.line << ", " << lineColumn.column << ")";
}
+std::ostream &operator<<(std::ostream &out, const Link &link)
+{
+ return out << "(" << link.targetFileName << ", " << link.targetLine << ", " << link.targetColumn
+ << ", " << link.linkTextStart << ", " << link.linkTextEnd << ")";
+}
+
const char * toText(Utils::Language language)
{
using Utils::Language;
@@ -1296,6 +1309,38 @@ std::ostream &operator<<(std::ostream &out, const Usage &usage)
}
} // namespace CppTools
+namespace Debugger {
+std::ostream &operator<<(std::ostream &out, const DiagnosticLocation &loc)
+{
+ return out << "(" << loc.filePath << ", " << loc.line << ", " << loc.column << ")";
+}
+} // namespace Debugger
+
+namespace ClangTools {
+namespace Internal {
+std::ostream &operator<<(std::ostream &out, const ExplainingStep &step)
+{
+ return out << "("
+ << step.message << ", "
+ << step.location << ", "
+ << step.ranges << ", "
+ << step.isFixIt
+ << ")";
+}
+
+std::ostream &operator<<(std::ostream &out, const Diagnostic &diag) {
+ return out << "("
+ << diag.description << ", "
+ << diag.category << ", "
+ << diag.type << ", "
+ << diag.location << ", "
+ << diag.explainingSteps << ", "
+ << diag.hasFixits
+ << ")";
+}
+} // namespace Internal
+} // namespace ClangTools
+
void setFilePathCache(ClangBackEnd::FilePathCaching *cache)
{
filePathCache = cache;
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index b533186739..2a43f7d1a1 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -81,11 +81,13 @@ std::ostream &operator<<(std::ostream &out, const HeaderPath &headerPath);
namespace Utils {
class LineColumn;
class SmallStringView;
+class Link;
std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn);
std::ostream &operator<<(std::ostream &out, const Utils::Language &language);
std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion);
std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension);
+std::ostream &operator<<(std::ostream &out, const Link &link);
template <typename Type>
std::ostream &operator<<(std::ostream &out, const Utils::optional<Type> &optional)
@@ -106,7 +108,7 @@ void PrintTo(Utils::SmallStringView text, ::std::ostream *os);
void PrintTo(const Utils::SmallString &text, ::std::ostream *os);
void PrintTo(const Utils::PathString &text, ::std::ostream *os);
-} // namespace ProjectExplorer
+} // namespace Utils
namespace ClangBackEnd {
class SourceLocationEntry;
@@ -326,4 +328,18 @@ class Usage;
std::ostream &operator<<(std::ostream &out, const Usage &usage);
} // namespace CppTools
+namespace Debugger {
+class DiagnosticLocation;
+std::ostream &operator<<(std::ostream &out, const DiagnosticLocation &loc);
+} // namespace Debugger
+
+namespace ClangTools {
+namespace Internal {
+class ExplainingStep;
+class Diagnostic;
+std::ostream &operator<<(std::ostream &out, const ExplainingStep &step);
+std::ostream &operator<<(std::ostream &out, const Diagnostic &diag);
+} // namespace Internal
+} // namespace CppTools
+
void setFilePathCache(ClangBackEnd::FilePathCaching *filePathCache);
diff --git a/tests/unit/unittest/mockbuilddependenciesprovider.h b/tests/unit/unittest/mockbuilddependenciesprovider.h
index a4a57db33b..65dd7c5313 100644
--- a/tests/unit/unittest/mockbuilddependenciesprovider.h
+++ b/tests/unit/unittest/mockbuilddependenciesprovider.h
@@ -35,4 +35,15 @@ public:
MOCK_METHOD1(
create,
ClangBackEnd::BuildDependency(const ClangBackEnd::ProjectPartContainer &projectPart));
+ MOCK_METHOD2(create,
+ ClangBackEnd::BuildDependency(const ClangBackEnd::ProjectPartContainer &projectPart,
+ const ClangBackEnd::SourceEntries &sourceEntries));
+ MOCK_CONST_METHOD2(createSourceEntriesFromStorage,
+ ClangBackEnd::SourceEntries(const ClangBackEnd::FilePathIds &sourcePathIds,
+ ClangBackEnd::ProjectPartId projectPartId));
+ ClangBackEnd::BuildDependency create(const ClangBackEnd::ProjectPartContainer &projectPart,
+ ClangBackEnd::SourceEntries &&sourceEntries) override
+ {
+ return create(projectPart, sourceEntries);
+ }
};
diff --git a/tests/unit/unittest/mockbuilddependenciesstorage.h b/tests/unit/unittest/mockbuilddependenciesstorage.h
index 0436e27f92..c98b3fd3ae 100644
--- a/tests/unit/unittest/mockbuilddependenciesstorage.h
+++ b/tests/unit/unittest/mockbuilddependenciesstorage.h
@@ -58,6 +58,9 @@ public:
MOCK_METHOD2(insertOrUpdateIndexingTimeStamps,
void(const ClangBackEnd::FilePathIds &filePathIds,
ClangBackEnd::TimeStamp indexingTimeStamp));
+ MOCK_METHOD2(insertOrUpdateIndexingTimeStampsWithoutTransaction,
+ void(const ClangBackEnd::FilePathIds &filePathIds,
+ ClangBackEnd::TimeStamp indexingTimeStamp));
MOCK_METHOD1(insertOrUpdateIndexingTimeStamps, void(const ClangBackEnd::FileStatuses &));
MOCK_CONST_METHOD0(fetchIndexingTimeStamps, ClangBackEnd::SourceTimeStamps());
MOCK_CONST_METHOD1(fetchIncludedIndexingTimeStamps,
diff --git a/tests/unit/unittest/mockfilepathcaching.h b/tests/unit/unittest/mockfilepathcaching.h
index ca7960513e..155aa491c9 100644
--- a/tests/unit/unittest/mockfilepathcaching.h
+++ b/tests/unit/unittest/mockfilepathcaching.h
@@ -42,5 +42,6 @@ public:
Utils::PathString(ClangBackEnd::DirectoryPathId directoryPathId));
MOCK_CONST_METHOD1(directoryPathId,
ClangBackEnd::DirectoryPathId(ClangBackEnd::FilePathId filePathId));
+ MOCK_METHOD1(addFilePaths, void(const ClangBackEnd::FilePaths &filePaths));
+ MOCK_METHOD0(populateIfEmpty, void());
};
-
diff --git a/tests/unit/unittest/mockfilepathstorage.h b/tests/unit/unittest/mockfilepathstorage.h
index 7056ee2480..cc6cfa07c7 100644
--- a/tests/unit/unittest/mockfilepathstorage.h
+++ b/tests/unit/unittest/mockfilepathstorage.h
@@ -27,18 +27,31 @@
#include "googletest.h"
+#include "mocksqlitedatabase.h"
+
#include <filepathstoragesources.h>
class MockFilePathStorage
{
public:
- MOCK_METHOD1(fetchDirectoryId,
- int (Utils::SmallStringView directoryPath));
+ MockFilePathStorage(MockSqliteDatabase &mockDatabase)
+ : mockDatabase{mockDatabase}
+ {}
+
+ MOCK_METHOD1(fetchDirectoryId, int(Utils::SmallStringView directoryPath));
MOCK_METHOD2(fetchSourceId,
int (int directoryId, Utils::SmallStringView sourceName));
+ MOCK_METHOD1(fetchDirectoryIdUnguarded, int(Utils::SmallStringView directoryPath));
+ MOCK_METHOD2(fetchSourceIdUnguarded, int(int directoryId, Utils::SmallStringView sourceName));
MOCK_METHOD1(fetchDirectoryPath,
Utils::PathString (int directoryId));
MOCK_METHOD1(fetchSourceNameAndDirectoryId,
ClangBackEnd::Sources::SourceNameAndDirectoryId (int sourceId));
+ MOCK_METHOD0(fetchAllDirectories, std::vector<ClangBackEnd::Sources::Directory>());
+ MOCK_METHOD0(fetchAllSources, std::vector<ClangBackEnd::Sources::Source>());
+
+ MockSqliteDatabase &database() { return mockDatabase; }
+
+ MockSqliteDatabase &mockDatabase;
};
diff --git a/tests/unit/unittest/mockgeneratedfiles.h b/tests/unit/unittest/mockgeneratedfiles.h
index 75b182355c..481747c27f 100644
--- a/tests/unit/unittest/mockgeneratedfiles.h
+++ b/tests/unit/unittest/mockgeneratedfiles.h
@@ -38,6 +38,7 @@ public:
void (const ClangBackEnd::FilePaths &filePaths));
MOCK_CONST_METHOD0(fileContainers,
const ClangBackEnd::V2::FileContainers &());
+ MOCK_CONST_METHOD0(filePathIds, ClangBackEnd::FilePathIds());
MOCK_CONST_METHOD0(isValid, bool());
void update(ClangBackEnd::V2::FileContainers &&fileContainers)
diff --git a/tests/unit/unittest/mockmutex.h b/tests/unit/unittest/mockmutex.h
index f922210392..625efd713d 100644
--- a/tests/unit/unittest/mockmutex.h
+++ b/tests/unit/unittest/mockmutex.h
@@ -27,6 +27,8 @@
#include "googletest.h"
+#include <stringcache.h>
+
class MockMutex
{
public:
@@ -37,3 +39,14 @@ public:
MOCK_METHOD0(lock_shared, void ());
MOCK_METHOD0(unlock_shared, void ());
};
+
+class MockMutexNonLocking : public ClangBackEnd::NonLockingMutex
+{
+public:
+ using MutexType = MockMutexNonLocking;
+
+ MOCK_METHOD0(lock, void());
+ MOCK_METHOD0(unlock, void());
+ MOCK_METHOD0(lock_shared, void());
+ MOCK_METHOD0(unlock_shared, void());
+};
diff --git a/tests/unit/unittest/mockprecompiledheaderstorage.h b/tests/unit/unittest/mockprecompiledheaderstorage.h
index 84caea55be..de755e07eb 100644
--- a/tests/unit/unittest/mockprecompiledheaderstorage.h
+++ b/tests/unit/unittest/mockprecompiledheaderstorage.h
@@ -35,20 +35,26 @@ public:
MOCK_METHOD3(insertProjectPrecompiledHeader,
void(ClangBackEnd::ProjectPartId projectPartId,
Utils::SmallStringView pchPath,
- long long pchBuildTime));
- MOCK_METHOD1(deleteProjectPrecompiledHeader, void(ClangBackEnd::ProjectPartId projectPartId));
+ ClangBackEnd::TimeStamp pchBuildTime));
+ MOCK_METHOD2(deleteProjectPrecompiledHeader,
+ void(ClangBackEnd::ProjectPartId projectPartId, ClangBackEnd::TimeStamp buildTime));
MOCK_METHOD1(deleteProjectPrecompiledHeaders,
void(const ClangBackEnd::ProjectPartIds &projectPartIds));
MOCK_METHOD3(insertSystemPrecompiledHeaders,
void(const ClangBackEnd::ProjectPartIds &projectPartIds,
Utils::SmallStringView pchPath,
- long long pchBuildTime));
+ ClangBackEnd::TimeStamp pchBuildTime));
MOCK_METHOD1(deleteSystemPrecompiledHeaders,
void(const ClangBackEnd::ProjectPartIds &projectPartIds));
+ MOCK_METHOD1(deleteSystemAndProjectPrecompiledHeaders,
+ void(const ClangBackEnd::ProjectPartIds &projectPartIds));
MOCK_METHOD1(fetchSystemPrecompiledHeaderPath,
ClangBackEnd::FilePath(ClangBackEnd::ProjectPartId projectPartId));
MOCK_CONST_METHOD1(fetchPrecompiledHeader,
ClangBackEnd::FilePath(ClangBackEnd::ProjectPartId projectPartId));
MOCK_CONST_METHOD1(fetchPrecompiledHeaders,
ClangBackEnd::PchPaths(ClangBackEnd::ProjectPartId projectPartId));
+ MOCK_CONST_METHOD1(
+ fetchTimeStamps,
+ ClangBackEnd::PrecompiledHeaderTimeStamps(ClangBackEnd::ProjectPartId projectPartId));
};
diff --git a/tests/unit/unittest/mockprojectpartsmanager.h b/tests/unit/unittest/mockprojectpartsmanager.h
index 613faf7dfc..d458cb7231 100644
--- a/tests/unit/unittest/mockprojectpartsmanager.h
+++ b/tests/unit/unittest/mockprojectpartsmanager.h
@@ -39,12 +39,21 @@ public:
MOCK_CONST_METHOD1(
projects,
ClangBackEnd::ProjectPartContainers(const ClangBackEnd::ProjectPartIds &projectPartIds));
- MOCK_METHOD1(updateDeferred, void(const ClangBackEnd::ProjectPartContainers &projectsParts));
- MOCK_METHOD0(deferredUpdates, ClangBackEnd::ProjectPartContainers());
+ MOCK_METHOD2(updateDeferred,
+ void(const ClangBackEnd::ProjectPartContainers &system,
+ const ClangBackEnd::ProjectPartContainers &project));
+ MOCK_METHOD0(deferredSystemUpdates, ClangBackEnd::ProjectPartContainers());
+ MOCK_METHOD0(deferredProjectUpdates, ClangBackEnd::ProjectPartContainers());
ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts update(
ClangBackEnd::ProjectPartContainers &&projectsParts) override
{
return update(projectsParts);
}
+
+ void updateDeferred(ClangBackEnd::ProjectPartContainers &&system,
+ ClangBackEnd::ProjectPartContainers &&project) override
+ {
+ return updateDeferred(system, project);
+ }
};
diff --git a/tests/unit/unittest/mockprojectpartsstorage.h b/tests/unit/unittest/mockprojectpartsstorage.h
index e8dcbc94b2..cdca4ef78e 100644
--- a/tests/unit/unittest/mockprojectpartsstorage.h
+++ b/tests/unit/unittest/mockprojectpartsstorage.h
@@ -36,8 +36,11 @@ public:
MOCK_CONST_METHOD1(
fetchProjectParts,
ClangBackEnd::ProjectPartContainers(const ClangBackEnd::ProjectPartIds &projectPartIds));
+ MOCK_CONST_METHOD0(fetchAllProjectPartNamesAndIds, ClangBackEnd::Internal::ProjectPartNameIds());
MOCK_CONST_METHOD1(fetchProjectPartId,
ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName));
+ MOCK_CONST_METHOD1(fetchProjectPartIdUnguarded,
+ ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName));
MOCK_CONST_METHOD1(fetchProjectPartName,
Utils::PathString(ClangBackEnd::ProjectPartId projectPartId));
MOCK_METHOD8(updateProjectPart,
diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp
index 1e800e2be1..1a27eea50f 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.cpp
+++ b/tests/unit/unittest/mocksqlitereadstatement.cpp
@@ -46,6 +46,16 @@ MockSqliteReadStatement::values<CppTools::Usage, 3>(
return valuesReturnSourceUsages(reserveSize, sourceId, line, column);
}
+template<>
+CppTools::Usages MockSqliteReadStatement::values<CppTools::Usage, 3>(std::size_t reserveSize,
+ const int &sourceId,
+ const int &line,
+ const int &column,
+ const int &locationKind)
+{
+ return valuesReturnSourceUsages(reserveSize, sourceId, line, column, locationKind);
+}
+
template <>
Symbols
MockSqliteReadStatement::values<Symbol, 3>(
@@ -103,12 +113,18 @@ std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directo
return valuesReturnStdVectorDirectory(reserveSize);
}
-template <>
-std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 2>(std::size_t reserveSize)
+template<>
+std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 3>(std::size_t reserveSize)
{
return valuesReturnStdVectorSource(reserveSize);
}
+template<>
+ProjectPartNameIds MockSqliteReadStatement::values<ProjectPartNameId, 2>(std::size_t reserveSize)
+{
+ return valuesReturnProjectPartNameIds(reserveSize);
+}
+
template <>
Utils::optional<int>
MockSqliteReadStatement::value<int>(const Utils::SmallStringView &text)
@@ -253,3 +269,10 @@ MockSqliteReadStatement::value<Sources::SourceNameAndDirectoryId, 2>(const int &
{
return valueReturnSourceNameAndDirectoryId(id);
}
+
+template<>
+Utils::optional<ClangBackEnd::PrecompiledHeaderTimeStamps>
+MockSqliteReadStatement::value<ClangBackEnd::PrecompiledHeaderTimeStamps, 2>(const int &projectPartId)
+{
+ return valuesReturnPrecompiledHeaderTimeStamps(projectPartId);
+}
diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h
index 191c38accd..04e1f8effc 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.h
+++ b/tests/unit/unittest/mocksqlitereadstatement.h
@@ -34,6 +34,7 @@
#include <projectpartartefact.h>
#include <projectpartcontainer.h>
#include <projectpartpch.h>
+#include <projectpartstoragestructs.h>
#include <sourceentry.h>
#include <stringcachefwd.h>
#include <symbol.h>
@@ -57,9 +58,12 @@ using ClangRefactoring::SourceLocation;
using ClangRefactoring::SourceLocations;
using std::int64_t;
namespace Sources = ClangBackEnd::Sources;
+using ClangBackEnd::PrecompiledHeaderTimeStamps;
+using ClangBackEnd::UsedMacros;
+using ClangBackEnd::Internal::ProjectPartNameId;
+using ClangBackEnd::Internal::ProjectPartNameIds;
using ClangRefactoring::Symbol;
using ClangRefactoring::Symbols;
-using ClangBackEnd::UsedMacros;
class MockSqliteDatabase;
@@ -74,8 +78,9 @@ public:
MOCK_METHOD4(valuesReturnSourceLocations,
SourceLocations(std::size_t, int, int, int));
- MOCK_METHOD4(valuesReturnSourceUsages,
- CppTools::Usages(std::size_t, int, int, int));
+ MOCK_METHOD4(valuesReturnSourceUsages, CppTools::Usages(std::size_t, int, int, int));
+
+ MOCK_METHOD5(valuesReturnSourceUsages, CppTools::Usages(std::size_t, int, int, int, int));
MOCK_METHOD1(valuesReturnStdVectorDirectory,
std::vector<Sources::Directory>(std::size_t));
@@ -90,6 +95,8 @@ public:
MOCK_METHOD2(valuesReturnFilePathIds, FilePathIds(std::size_t, int));
+ MOCK_METHOD1(valuesReturnProjectPartNameIds, ProjectPartNameIds(std::size_t));
+
MOCK_METHOD1(valueReturnInt32, Utils::optional<int>(Utils::SmallStringView));
MOCK_METHOD2(valueReturnInt32, Utils::optional<int>(int, Utils::SmallStringView));
@@ -142,10 +149,11 @@ public:
MOCK_METHOD1(valuesReturnSourceTimeStamps, SourceTimeStamps(std::size_t));
MOCK_METHOD2(valuesReturnSourceTimeStamps, SourceTimeStamps(std::size_t, int sourcePathId));
- template <typename ResultType,
- int ResultTypeCount = 1,
- typename... QueryType>
- std::vector<ResultType> values(std::size_t reserveSize, const QueryType&... queryValues);
+ MOCK_METHOD1(valuesReturnPrecompiledHeaderTimeStamps,
+ PrecompiledHeaderTimeStamps(int projectPartId));
+
+ template<typename ResultType, int ResultTypeCount = 1, typename... QueryType>
+ std::vector<ResultType> values(std::size_t reserveSize, const QueryType &... queryValues);
template <typename ResultType,
int ResultTypeCount = 1,
@@ -184,6 +192,13 @@ MockSqliteReadStatement::values<CppTools::Usage, 3>(
const int &line,
const int &column);
+template<>
+CppTools::Usages MockSqliteReadStatement::values<CppTools::Usage, 3>(std::size_t reserveSize,
+ const int &sourceId,
+ const int &line,
+ const int &column,
+ const int &locationKind);
+
template <>
Symbols
MockSqliteReadStatement::values<Symbol, 3>(
@@ -221,12 +236,14 @@ FilePathIds MockSqliteReadStatement::values<ClangBackEnd::FilePathId>(std::size_
template <>
std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize);
-template <>
-std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 2>(std::size_t reserveSize);
+template<>
+std::vector<Sources::Source> MockSqliteReadStatement::values<Sources::Source, 3>(std::size_t reserveSize);
-template <>
-Utils::optional<int>
-MockSqliteReadStatement::value<int>(const Utils::SmallStringView&);
+template<>
+ProjectPartNameIds MockSqliteReadStatement::values<ProjectPartNameId, 2>(std::size_t reserveSize);
+
+template<>
+Utils::optional<int> MockSqliteReadStatement::value<int>(const Utils::SmallStringView &);
template <>
Utils::optional<int>
@@ -306,3 +323,7 @@ SourceTimeStamps MockSqliteReadStatement::values<SourceTimeStamp, 2>(std::size_t
template <>
Utils::optional<Sources::SourceNameAndDirectoryId>
MockSqliteReadStatement::value<Sources::SourceNameAndDirectoryId, 2>(const int&);
+
+template<>
+Utils::optional<ClangBackEnd::PrecompiledHeaderTimeStamps>
+MockSqliteReadStatement::value<ClangBackEnd::PrecompiledHeaderTimeStamps, 2>(const int &);
diff --git a/tests/unit/unittest/mocksqlitewritestatement.h b/tests/unit/unittest/mocksqlitewritestatement.h
index 5644fd9bb8..329c5f7f39 100644
--- a/tests/unit/unittest/mocksqlitewritestatement.h
+++ b/tests/unit/unittest/mocksqlitewritestatement.h
@@ -95,6 +95,8 @@ public:
MOCK_METHOD1(write,
void (int));
+ MOCK_METHOD2(write, void(int, long long));
+
MOCK_METHOD2(write,
void (int, int));
diff --git a/tests/unit/unittest/mocksymbolindexertaskqueue.h b/tests/unit/unittest/mocksymbolindexertaskqueue.h
index 7fb0d3f0bd..cef60ac776 100644
--- a/tests/unit/unittest/mocksymbolindexertaskqueue.h
+++ b/tests/unit/unittest/mocksymbolindexertaskqueue.h
@@ -34,7 +34,6 @@ class MockSymbolIndexerTaskQueue : public ClangBackEnd::SymbolIndexerTaskQueueIn
public:
MOCK_METHOD1(addOrUpdateTasks,
void (std::vector<ClangBackEnd::SymbolIndexerTask> &&tasks));
- MOCK_METHOD1(removeTasks,
- void (const std::vector<int> &projectPartIds));
+ MOCK_METHOD1(removeTasks, void(const ClangBackEnd::ProjectPartIds &projectPartIds));
MOCK_METHOD0(processEntries, void());
};
diff --git a/tests/unit/unittest/mocksymbolquery.h b/tests/unit/unittest/mocksymbolquery.h
index 0b3f4d5984..f8333ed7aa 100644
--- a/tests/unit/unittest/mocksymbolquery.h
+++ b/tests/unit/unittest/mocksymbolquery.h
@@ -40,4 +40,11 @@ public:
ClangRefactoring::Symbols(const ClangBackEnd::SymbolKinds &symbolKinds, Utils::SmallStringView searchTerm));
MOCK_CONST_METHOD2(locationForSymbolId,
Utils::optional<ClangRefactoring::SourceLocation>(ClangRefactoring::SymbolId symbolId, ClangBackEnd::SourceLocationKind kind));
+ MOCK_CONST_METHOD4(sourceUsagesAtByLocationKind,
+ CppTools::Usages(ClangBackEnd::FilePathId filePathId,
+ int line,
+ int utf8Column,
+ ClangBackEnd::SourceLocationKind));
+ MOCK_CONST_METHOD3(declarationsAt,
+ CppTools::Usages(ClangBackEnd::FilePathId filePathId, int line, int utf8Column));
};
diff --git a/tests/unit/unittest/mocksymbolscollector.h b/tests/unit/unittest/mocksymbolscollector.h
index 34cd71b17d..7c62e54e17 100644
--- a/tests/unit/unittest/mocksymbolscollector.h
+++ b/tests/unit/unittest/mocksymbolscollector.h
@@ -74,9 +74,6 @@ public:
MOCK_CONST_METHOD0(usedMacros,
const ClangBackEnd::UsedMacros &());
- MOCK_CONST_METHOD0(fileStatuses,
- const ClangBackEnd::FileStatuses &());
-
MOCK_CONST_METHOD0(sourceDependencies,
const ClangBackEnd::SourceDependencies &());
diff --git a/tests/unit/unittest/modifiedtimechecker-test.cpp b/tests/unit/unittest/modifiedtimechecker-test.cpp
index 0e18228ac3..7651039f93 100644
--- a/tests/unit/unittest/modifiedtimechecker-test.cpp
+++ b/tests/unit/unittest/modifiedtimechecker-test.cpp
@@ -50,13 +50,17 @@ protected:
NiceMock<MockFileSystem> mockFileSystem;
ClangBackEnd::ModifiedTimeChecker<> checker{mockFileSystem};
- SourceEntries upToDateEntries = {{1, SourceType::UserInclude, 100},
+ SourceEntries upToDateEntries = {{1, SourceType::UserInclude, 51},
{2, SourceType::SystemInclude, 30},
- {3, SourceType::UserInclude, 100},
- {4, SourceType::SystemInclude, 30}};
+ {3, SourceType::UserInclude, 50},
+ {4, SourceType::SystemInclude, 31}};
+ SourceEntries equalEntries = {{1, SourceType::UserInclude, 50},
+ {2, SourceType::SystemInclude, 30},
+ {3, SourceType::UserInclude, 50},
+ {4, SourceType::SystemInclude, 30}};
SourceEntries notUpToDateEntries = {{1, SourceType::UserInclude, 50},
- {2, SourceType::SystemInclude, 20},
- {3, SourceType::UserInclude, 100},
+ {2, SourceType::SystemInclude, 29},
+ {3, SourceType::UserInclude, 50},
{4, SourceType::SystemInclude, 30}};
};
@@ -67,6 +71,13 @@ TEST_F(ModifiedTimeChecker, IsUpToDate)
ASSERT_TRUE(isUpToDate);
}
+TEST_F(ModifiedTimeChecker, EqualEntriesAreUpToDate)
+{
+ auto isUpToDate = checker.isUpToDate(equalEntries);
+
+ ASSERT_TRUE(isUpToDate);
+}
+
TEST_F(ModifiedTimeChecker, IsUpToDateSecondRun)
{
checker.isUpToDate(upToDateEntries);
@@ -120,63 +131,4 @@ TEST_F(ModifiedTimeChecker, IsNotUpToDateAnyMoreAfterUpdating)
ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
}
-TEST_F(ModifiedTimeChecker, Reset)
-{
- checker.isUpToDate(upToDateEntries);
-
- checker.reset({2, 3});
-
- ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
-}
-
-TEST_F(ModifiedTimeChecker, UpdateNonResetedId)
-{
- checker.isUpToDate(upToDateEntries);
-
- checker.reset({2, 3});
-
- ASSERT_TRUE(checker.isUpToDate({upToDateEntries[0]}));
-}
-
-TEST_F(ModifiedTimeChecker, ResetTwoTimes)
-{
- checker.isUpToDate(upToDateEntries);
- checker.reset({2, 3});
-
- checker.reset({2, 3});
-
- ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
- ASSERT_TRUE(checker.isUpToDate(upToDateEntries));
-}
-
-TEST_F(ModifiedTimeChecker, ResetSecondUpdate)
-{
- checker.isUpToDate(upToDateEntries);
- checker.reset({2, 3});
- checker.isUpToDate(upToDateEntries);
-
- auto isUpToDate = checker.isUpToDate(upToDateEntries);
-
- ASSERT_TRUE(isUpToDate);
-}
-
-TEST_F(ModifiedTimeChecker, ResetPartialUpdate)
-{
- checker.isUpToDate(upToDateEntries);
- checker.reset({2, 3});
- checker.isUpToDate({upToDateEntries[1]});
-
- ASSERT_FALSE(checker.isUpToDate({upToDateEntries[2]}));
-}
-
-TEST_F(ModifiedTimeChecker, ResetMoreIds)
-{
- checker.isUpToDate(upToDateEntries);
- checker.reset({2, 3});
-
- checker.reset({1, 5});
-
- ASSERT_FALSE(checker.isUpToDate({upToDateEntries[2]}));
-}
-
} // namespace
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
index e6ae4a943d..ad5b57b4f5 100644
--- a/tests/unit/unittest/pchcreator-test.cpp
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -91,7 +91,7 @@ protected:
ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path)
{
- return creator.filePathCache().filePathId(path);
+ return filePathCache.filePathId(path);
}
FilePathIds sorted(FilePathIds &&filePathIds)
@@ -104,18 +104,19 @@ protected:
protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
+ ClangBackEnd::FilePathCaching filePathCache{database};
FilePath main1Path = TESTDATA_DIR "/builddependencycollector/project/main3.cpp";
FilePath main2Path = TESTDATA_DIR "/builddependencycollector/project/main2.cpp";
FilePath header1Path = TESTDATA_DIR "/builddependencycollector/project/header1.h";
FilePath header2Path = TESTDATA_DIR "/builddependencycollector/project/header2.h";
FilePath generatedFilePath = TESTDATA_DIR "/builddependencycollector/project/generated_file.h";
TestEnvironment environment;
- FileContainer generatedFile{generatedFilePath.clone(), "#pragma once", {}};
+ FileContainer generatedFile{generatedFilePath.clone(), id(generatedFilePath), "#pragma once", {}};
NiceMock<MockPchManagerClient> mockPchManagerClient;
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
ClangBackEnd::PchCreator creator{environment,
- database,
+ filePathCache,
mockPchManagerClient,
mockClangPathWatcher,
mockBuildDependenciesStorage};
@@ -228,34 +229,26 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterSucess)
{
creator.generatePch(std::move(pchTask1));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(
- AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(id(main2Path)))))));
-
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(AllOf(
- Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))))));
EXPECT_CALL(
mockClangPathWatcher,
- updateIdPaths(ElementsAre(
+ updateIdPaths(UnorderedElementsAre(
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
+ Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre(id(main2Path)))),
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))))));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(AllOf(
- Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
- id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))),
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
creator.doInMainThreadAfterFinished();
}
@@ -266,34 +259,26 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterFail)
pchTask1.projectIncludeSearchPaths = {};
creator.generatePch(std::move(pchTask1));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(
- AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(id(main2Path)))))));
-
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(AllOf(
- Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))))));
EXPECT_CALL(
mockClangPathWatcher,
- updateIdPaths(ElementsAre(
+ updateIdPaths(UnorderedElementsAre(
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
+ Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre(id(main2Path)))),
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))))));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(AllOf(
- Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
- id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))),
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
creator.doInMainThreadAfterFinished();
}
@@ -421,33 +406,26 @@ TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls)
precompiledHeadersUpdated(
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(
- AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(id(main2Path)))))));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(AllOf(
- Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))))));
EXPECT_CALL(
mockClangPathWatcher,
- updateIdPaths(ElementsAre(
+ updateIdPaths(UnorderedElementsAre(
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::Source}),
+ Field(&ClangBackEnd::IdPaths::filePathIds, UnorderedElementsAre(id(main2Path)))),
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::UserInclude}),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h")))),
AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::ProjectInclude}),
Field(&ClangBackEnd::IdPaths::filePathIds,
UnorderedElementsAre(
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))))));
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(AllOf(
- Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
- Field(&ClangBackEnd::IdPaths::filePathIds,
- UnorderedElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
- id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h")))),
+ AllOf(Field(&ClangBackEnd::IdPaths::id, ProjectChunkId{1, SourceType::SystemInclude}),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/system/system2.h")))))));
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1)));
creator.doInMainThreadAfterFinished();
diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp
index 20f16d8e42..38b9757aa3 100644
--- a/tests/unit/unittest/pchmanagerclient-test.cpp
+++ b/tests/unit/unittest/pchmanagerclient-test.cpp
@@ -34,10 +34,11 @@
#include <pchmanagerclient.h>
#include <pchmanagerprojectupdater.h>
+#include <clangindexingsettingsmanager.h>
#include <filepathcaching.h>
-#include <refactoringdatabaseinitializer.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
+#include <refactoringdatabaseinitializer.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
#include <updategeneratedfilesmessage.h>
@@ -60,10 +61,12 @@ protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
+ ClangPchManager::ClangIndexingSettingsManager settingsManager;
ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer,
client,
filePathCache,
- mockProjectPartsStorage};
+ mockProjectPartsStorage,
+ settingsManager};
ClangBackEnd::ProjectPartId projectPartId{1};
PrecompiledHeadersUpdatedMessage message{projectPartId};
ClangBackEnd::ProjectPartId projectPartId2{2};
diff --git a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
index 194f52afd3..e468521a54 100644
--- a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
@@ -117,7 +117,7 @@ TEST_F(PchManagerClientServerInProcess, SendUpdateProjectPartsMessage)
TEST_F(PchManagerClientServerInProcess, SendUpdateGeneratedFilesMessage)
{
- FileContainer fileContainer{{"/path/to/", "file"}, "content", {}};
+ FileContainer fileContainer{{"/path/to/", "file"}, 1, "content", {}};
UpdateGeneratedFilesMessage message{{fileContainer}};
EXPECT_CALL(mockPchManagerServer, updateGeneratedFiles(message));
diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp
index 4657051fc5..bf14b628b8 100644
--- a/tests/unit/unittest/pchmanagerserver-test.cpp
+++ b/tests/unit/unittest/pchmanagerserver-test.cpp
@@ -27,6 +27,7 @@
#include "mockbuilddependenciesstorage.h"
#include "mockclangpathwatcher.h"
+#include "mockfilepathcaching.h"
#include "mockgeneratedfiles.h"
#include "mockpchmanagerclient.h"
#include "mockpchtaskgenerator.h"
@@ -59,7 +60,7 @@ class PchManagerServer : public ::testing::Test
server.setClient(&mockPchManagerClient);
ON_CALL(mockProjectPartsManager, update(projectParts))
- .WillByDefault(Return(UpToDataProjectParts{{}, projectParts}));
+ .WillByDefault(Return(UpToDataProjectParts{{}, projectParts, projectParts4}));
ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(true));
}
@@ -77,11 +78,13 @@ protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
+ NiceMock<MockFilePathCaching> mockFilePathCache;
ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
mockPchTaskGenerator,
mockProjectPartsManager,
mockGeneratedFiles,
- mockBuildDependenciesStorage};
+ mockBuildDependenciesStorage,
+ mockFilePathCache};
NiceMock<MockPchManagerClient> mockPchManagerClient;
ClangBackEnd::ProjectPartId projectPartId1{1};
ClangBackEnd::ProjectPartId projectPartId2{2};
@@ -98,7 +101,7 @@ protected:
projectPartId1,
{"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
{{"DEFINE", "1", 1}},
- {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{TESTDATA_DIR "/symbolscollector/include", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
{id(header1Path)},
{id(main1Path)},
@@ -110,7 +113,7 @@ protected:
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
{{"DEFINE", "1", 1}},
{{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
- {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {{TESTDATA_DIR "/builddependencycollector", 1, ClangBackEnd::IncludeSearchPathType::User}},
{id(header2Path)},
{id(main2Path)},
Utils::Language::C,
@@ -163,7 +166,9 @@ protected:
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
std::vector<ProjectPartContainer> projectParts1{projectPart1};
std::vector<ProjectPartContainer> projectParts2{projectPart2};
- FileContainer generatedFile{{"/path/to/", "file"}, "content", {}};
+ std::vector<ProjectPartContainer> projectParts3{projectPart3};
+ std::vector<ProjectPartContainer> projectParts4{projectPart3, projectPart4};
+ FileContainer generatedFile{{"/path/to/", "file"}, id("/path/to/file"), "content", {}};
ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{
Utils::clone(projectParts), {"toolChainArgument"}};
ClangBackEnd::RemoveProjectPartsMessage removeProjectPartsMessage{
@@ -175,9 +180,11 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts))
- .WillOnce(Return(UpToDataProjectParts{{}, projectParts2}));
+ .WillOnce(Return(UpToDataProjectParts{{}, projectParts2, projectParts4}));
EXPECT_CALL(
mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
+ EXPECT_CALL(mockPchTaskGenerator,
+ addNonSystemProjectParts(Eq(projectParts4), ElementsAre("toolChainArgument")));
server.updateProjectParts(updateProjectPartsMessage.clone());
}
@@ -222,7 +229,8 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
mockPchTaskGenerator,
mockProjectPartsManager,
mockGeneratedFiles,
- mockBuildDependenciesStorage};
+ mockBuildDependenciesStorage,
+ filePathCache};
}
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
@@ -267,6 +275,7 @@ TEST_F(PchManagerServer, DontUpdateProjectPartQueueByPathIdsIfItUserFile)
EXPECT_CALL(mockProjectPartsManager, projects(_)).Times(0);
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
+ EXPECT_CALL(mockPchTaskGenerator, addNonSystemProjectParts(_, _)).Times(0);
server.pathsWithIdsChanged({{{projectPartId1, ClangBackEnd::SourceType::UserInclude}, {}},
{{projectPartId2, ClangBackEnd::SourceType::Source}, {}}});
@@ -290,7 +299,7 @@ TEST_F(PchManagerServer, ResetTimeStampForChangedFilesInDatabase)
{
EXPECT_CALL(mockBuildDependenciesStorage,
insertOrUpdateIndexingTimeStamps(ElementsAre(FilePathId{1}, FilePathId{3}, FilePathId{5}),
- TypedEq<ClangBackEnd::TimeStamp>(0)));
+ TypedEq<ClangBackEnd::TimeStamp>(-1)));
server.pathsChanged({1, 3, 5});
}
@@ -323,6 +332,7 @@ TEST_F(PchManagerServer, RemoveToolChainsArguments)
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
+ EXPECT_CALL(mockPchTaskGenerator, addNonSystemProjectParts(_, _)).Times(0);
server.removeProjectParts(removeProjectPartsMessage.clone());
server.pathsWithIdsChanged({{{projectPart1.projectPartId, ClangBackEnd::SourceType::Source}, {}}});
@@ -333,10 +343,12 @@ TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1)))
- .WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}}));
+ .WillOnce(Return(UpToDataProjectParts{{}, {projectPart1}, {projectPart2}}));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
- EXPECT_CALL(mockProjectPartsManager, updateDeferred(ElementsAre(projectPart1)));
+ EXPECT_CALL(mockPchTaskGenerator, addNonSystemProjectParts(_, _)).Times(0);
+ EXPECT_CALL(mockProjectPartsManager,
+ updateDeferred(ElementsAre(projectPart1), ElementsAre(projectPart2)));
server.updateProjectParts(
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
@@ -347,10 +359,11 @@ TEST_F(PchManagerServer, GeneratePchIfGeneratedFilesAreValid)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1)))
- .WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}}));
+ .WillOnce(Return(UpToDataProjectParts{{}, {projectPart1}, {projectPart2}}));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _));
- EXPECT_CALL(mockProjectPartsManager, updateDeferred(_)).Times(0);
+ EXPECT_CALL(mockPchTaskGenerator, addNonSystemProjectParts(_, _));
+ EXPECT_CALL(mockProjectPartsManager, updateDeferred(_, _)).Times(0);
server.updateProjectParts(
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
@@ -361,15 +374,19 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreValidSoGeneratePchs)
InSequence s;
ClangBackEnd::UpdateGeneratedFilesMessage updateGeneratedFilesMessage{{generatedFile}};
ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(false));
- server.updateProjectParts(
- ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
+ server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{{projectPart1, projectPart2},
+ {"toolChainArgument"}});
EXPECT_CALL(mockGeneratedFiles, update(updateGeneratedFilesMessage.generatedFiles));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true));
- EXPECT_CALL(mockProjectPartsManager, deferredUpdates())
+ EXPECT_CALL(mockProjectPartsManager, deferredSystemUpdates())
.WillOnce(Return(ClangBackEnd::ProjectPartContainers{projectPart1}));
EXPECT_CALL(mockPchTaskGenerator,
addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument")));
+ EXPECT_CALL(mockProjectPartsManager, deferredProjectUpdates())
+ .WillOnce(Return(ClangBackEnd::ProjectPartContainers{projectPart2}));
+ EXPECT_CALL(mockPchTaskGenerator,
+ addNonSystemProjectParts(ElementsAre(projectPart2), ElementsAre("toolChainArgument")));
server.updateGeneratedFiles(updateGeneratedFilesMessage.clone());
}
@@ -379,13 +396,14 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreStillInvalidSoNoPchsGener
InSequence s;
ClangBackEnd::UpdateGeneratedFilesMessage updateGeneratedFilesMessage{{generatedFile}};
ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(false));
- server.updateProjectParts(
- ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
+ server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{{projectPart1, projectPart2},
+ {"toolChainArgument"}});
EXPECT_CALL(mockGeneratedFiles, update(updateGeneratedFilesMessage.generatedFiles));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false));
- EXPECT_CALL(mockProjectPartsManager, deferredUpdates()).Times(0);
+ EXPECT_CALL(mockProjectPartsManager, deferredSystemUpdates()).Times(0);
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
+ EXPECT_CALL(mockPchTaskGenerator, addNonSystemProjectParts(_, _)).Times(0);
server.updateGeneratedFiles(updateGeneratedFilesMessage.clone());
}
@@ -395,7 +413,7 @@ TEST_F(PchManagerServer, SentUpToDateProjectPartIdsToClient)
InSequence s;
EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts))
- .WillOnce(Return(UpToDataProjectParts{projectParts1, projectParts2}));
+ .WillOnce(Return(UpToDataProjectParts{projectParts1, projectParts2, projectParts3}));
EXPECT_CALL(mockPchTaskGenerator,
addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
EXPECT_CALL(mockPchManagerClient,
@@ -405,4 +423,20 @@ TEST_F(PchManagerServer, SentUpToDateProjectPartIdsToClient)
server.updateProjectParts(updateProjectPartsMessage.clone());
}
+
+TEST_F(PchManagerServer, AddingIncludesToFileCacheForProjectUpdates)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockFilePathCache, populateIfEmpty());
+ EXPECT_CALL(mockFilePathCache,
+ addFilePaths(AllOf(
+ Contains(Eq(TESTDATA_DIR "/symbolscollector/include/unmodified_header.h")),
+ Contains(Eq(TESTDATA_DIR "/symbolscollector/include/unmodified_header2.h")),
+ Contains(Eq(TESTDATA_DIR "/builddependencycollector/project/header2.h")),
+ Contains(Eq(TESTDATA_DIR "/builddependencycollector/external/external3.h")))));
+ EXPECT_CALL(mockProjectPartsManager, update(_));
+
+ server.updateProjectParts(updateProjectPartsMessage.clone());
+}
} // namespace
diff --git a/tests/unit/unittest/pchtaskqueue-test.cpp b/tests/unit/unittest/pchtaskqueue-test.cpp
index 0715602f97..f516858862 100644
--- a/tests/unit/unittest/pchtaskqueue-test.cpp
+++ b/tests/unit/unittest/pchtaskqueue-test.cpp
@@ -47,7 +47,7 @@ class PchTaskQueue : public testing::Test
protected:
NiceMock<MockTaskScheduler<ClangBackEnd::PchTaskQueue::Task>> mockSytemPchTaskScheduler;
NiceMock<MockTaskScheduler<ClangBackEnd::PchTaskQueue::Task>> mockProjectPchTaskScheduler;
- MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage;
+ NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
MockSqliteTransactionBackend mockSqliteTransactionBackend;
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
@@ -334,7 +334,7 @@ TEST_F(PchTaskQueue, CreateProjectTaskFromPchTask)
EXPECT_CALL(mockPchCreator, generatePch(Eq(projectTask)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
EXPECT_CALL(mockPrecompiledHeaderStorage,
- insertProjectPrecompiledHeader(Eq(1), Eq("/path/to/pch"), 99));
+ insertProjectPrecompiledHeader(Eq(1), Eq("/path/to/pch"), Eq(99)));
tasks.front()(mockPchCreator);
}
@@ -343,7 +343,7 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated)
{
InSequence s;
MockPchCreator mockPchCreator;
- ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 0};
+ ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 34};
auto tasks = queue.createProjectTasks({projectTask1});
auto projectTask = projectTask1;
projectTask.systemPchPath = "/path/to/pch";
@@ -353,7 +353,7 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated)
.WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
EXPECT_CALL(mockPchCreator, generatePch(Eq(projectTask)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq(1)));
+ EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq(1), Eq(34)));
tasks.front()(mockPchCreator);
}
@@ -377,7 +377,7 @@ TEST_F(PchTaskQueue, CreateSystemTaskFromPchTask)
EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
EXPECT_CALL(mockPrecompiledHeaderStorage,
- insertSystemPrecompiledHeaders(UnorderedElementsAre(1, 3), Eq("/path/to/pch"), 99));
+ insertSystemPrecompiledHeaders(UnorderedElementsAre(1, 3), Eq("/path/to/pch"), Eq(99)));
tasks.front()(mockPchCreator);
}
diff --git a/tests/unit/unittest/precompiledheaderstorage-test.cpp b/tests/unit/unittest/precompiledheaderstorage-test.cpp
index 9fb161d0eb..8b3727decd 100644
--- a/tests/unit/unittest/precompiledheaderstorage-test.cpp
+++ b/tests/unit/unittest/precompiledheaderstorage-test.cpp
@@ -44,11 +44,15 @@ protected:
Storage storage{database};
MockSqliteWriteStatement &insertProjectPrecompiledHeaderStatement = storage.insertProjectPrecompiledHeaderStatement;
MockSqliteWriteStatement &deleteProjectPrecompiledHeaderStatement = storage.deleteProjectPrecompiledHeaderStatement;
+ MockSqliteWriteStatement &deleteProjectPrecompiledHeaderPathAndSetBuildTimeStatement
+ = storage.deleteProjectPrecompiledHeaderPathAndSetBuildTimeStatement;
MockSqliteWriteStatement &insertSystemPrecompiledHeaderStatement = storage.insertSystemPrecompiledHeaderStatement;
MockSqliteWriteStatement &deleteSystemPrecompiledHeaderStatement = storage.deleteSystemPrecompiledHeaderStatement;
+ MockSqliteWriteStatement &deleteSystemAndProjectPrecompiledHeaderStatement = storage.deleteSystemAndProjectPrecompiledHeaderStatement;
MockSqliteReadStatement &fetchSystemPrecompiledHeaderPathStatement = storage.fetchSystemPrecompiledHeaderPathStatement;
MockSqliteReadStatement &fetchPrecompiledHeaderStatement = storage.fetchPrecompiledHeaderStatement;
MockSqliteReadStatement &fetchPrecompiledHeadersStatement = storage.fetchPrecompiledHeadersStatement;
+ MockSqliteReadStatement &fetchTimeStampsStatement = storage.fetchTimeStampsStatement;
};
TEST_F(PrecompiledHeaderStorage, UseTransaction)
@@ -95,10 +99,11 @@ TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeader)
InSequence s;
EXPECT_CALL(database, immediateBegin());
- EXPECT_CALL(deleteProjectPrecompiledHeaderStatement, write(TypedEq<int>(1)));
+ EXPECT_CALL(deleteProjectPrecompiledHeaderPathAndSetBuildTimeStatement,
+ write(TypedEq<int>(1), TypedEq<long long>(13)));
EXPECT_CALL(database, commit());
- storage.deleteProjectPrecompiledHeader(1);
+ storage.deleteProjectPrecompiledHeader(1, 13);
}
TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaderStatementIsBusy)
@@ -107,10 +112,11 @@ TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaderStatementIsBusy)
EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
EXPECT_CALL(database, immediateBegin());
- EXPECT_CALL(deleteProjectPrecompiledHeaderStatement, write(TypedEq<int>(1)));
+ EXPECT_CALL(deleteProjectPrecompiledHeaderPathAndSetBuildTimeStatement,
+ write(TypedEq<int>(1), TypedEq<long long>(13)));
EXPECT_CALL(database, commit());
- storage.deleteProjectPrecompiledHeader(1);
+ storage.deleteProjectPrecompiledHeader(1, 13);
}
TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaders)
@@ -200,6 +206,31 @@ TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeadersStatementIsBusy)
storage.deleteSystemPrecompiledHeaders({1, 2});
}
+TEST_F(PrecompiledHeaderStorage, DeleteSystemAndProjectPrecompiledHeaders)
+{
+ InSequence s;
+
+ EXPECT_CALL(database, immediateBegin());
+ EXPECT_CALL(deleteSystemAndProjectPrecompiledHeaderStatement, write(TypedEq<int>(1)));
+ EXPECT_CALL(deleteSystemAndProjectPrecompiledHeaderStatement, write(TypedEq<int>(2)));
+ EXPECT_CALL(database, commit());
+
+ storage.deleteSystemAndProjectPrecompiledHeaders({1, 2});
+}
+
+TEST_F(PrecompiledHeaderStorage, DeleteSystemAndProjectPrecompiledHeadersStatementIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
+ EXPECT_CALL(database, immediateBegin());
+ EXPECT_CALL(deleteSystemAndProjectPrecompiledHeaderStatement, write(TypedEq<int>(1)));
+ EXPECT_CALL(deleteSystemAndProjectPrecompiledHeaderStatement, write(TypedEq<int>(2)));
+ EXPECT_CALL(database, commit());
+
+ storage.deleteSystemAndProjectPrecompiledHeaders({1, 2});
+}
+
TEST_F(PrecompiledHeaderStorage, CompilePrecompiledHeaderStatements)
{
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
@@ -219,6 +250,18 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderCalls)
storage.fetchSystemPrecompiledHeaderPath(1);
}
+TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderCallsWithReturnValue)
+{
+ InSequence s;
+
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement, valueReturnFilePath(TypedEq<int>(1)))
+ .WillOnce(Return(ClangBackEnd::FilePath{}));
+ EXPECT_CALL(database, commit());
+
+ storage.fetchSystemPrecompiledHeaderPath(1);
+}
+
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeader)
{
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement, valueReturnFilePath(TypedEq<int>(1)))
@@ -258,6 +301,16 @@ TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCallsValueInStatement)
storage.fetchPrecompiledHeader(25);
}
+TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCallsWithValue)
+{
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchPrecompiledHeaderStatement, valueReturnFilePath(Eq(25)))
+ .WillOnce(Return(ClangBackEnd::FilePath{}));
+ EXPECT_CALL(database, commit());
+
+ storage.fetchPrecompiledHeader(25);
+}
+
TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderIsBusy)
{
InSequence s;
@@ -300,6 +353,16 @@ TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCalls)
storage.fetchPrecompiledHeaders(25);
}
+TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCallsWithReturnValue)
+{
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchPrecompiledHeadersStatement, valueReturnPchPaths(Eq(25)))
+ .WillOnce(Return(ClangBackEnd::PchPaths{}));
+ EXPECT_CALL(database, commit());
+
+ storage.fetchPrecompiledHeaders(25);
+}
+
TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeadersIsBusy)
{
InSequence s;
@@ -335,4 +398,84 @@ TEST_F(PrecompiledHeaderStorage, FetchEmptyPrecompiledHeaders)
Field(&ClangBackEnd::PchPaths::systemPchPath, IsEmpty())));
}
+TEST_F(PrecompiledHeaderStorage, FetchTimeStamps)
+{
+ ClangBackEnd::PrecompiledHeaderTimeStamps precompiledHeaderTimeStamps{22, 33};
+ ON_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)))
+ .WillByDefault(Return(precompiledHeaderTimeStamps));
+
+ auto timeStamps = storage.fetchTimeStamps(23);
+
+ ASSERT_THAT(timeStamps,
+ AllOf(Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::project, Eq(22)),
+ Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(33))));
+}
+
+TEST_F(PrecompiledHeaderStorage, NoFetchTimeStamps)
+{
+ auto timeStamps = storage.fetchTimeStamps(23);
+
+ ASSERT_THAT(timeStamps,
+ AllOf(Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::project, Eq(-1)),
+ Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(-1))));
+}
+
+TEST_F(PrecompiledHeaderStorage, FetchTimeStampsCalls)
+{
+ InSequence s;
+
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)));
+ EXPECT_CALL(database, commit());
+
+ storage.fetchTimeStamps(23);
+}
+
+TEST_F(PrecompiledHeaderStorage, FetchTimeStampsCallsWithReturnValue)
+{
+ InSequence s;
+
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)))
+ .WillOnce(Return(ClangBackEnd::PrecompiledHeaderTimeStamps{}));
+ EXPECT_CALL(database, commit());
+
+ storage.fetchTimeStamps(23);
+}
+
+TEST_F(PrecompiledHeaderStorage, FetchTimeStampsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)))
+ .WillOnce(Throw(Sqlite::StatementIsBusy{""}));
+ EXPECT_CALL(database, rollback());
+ EXPECT_CALL(database, deferredBegin());
+ EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)));
+ EXPECT_CALL(database, commit());
+
+ storage.fetchTimeStamps(23);
+}
+
+class PrecompiledHeaderStorageSlowTest : public testing::Test
+{
+protected:
+ Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
+ ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
+ ClangBackEnd::PrecompiledHeaderStorage<> storage{database};
+};
+
+TEST_F(PrecompiledHeaderStorageSlowTest, NoFetchTimeStamps)
+{
+ storage.insertProjectPrecompiledHeader(23, {}, 22);
+ storage.insertSystemPrecompiledHeaders({23}, {}, 33);
+
+ auto timeStamps = storage.fetchTimeStamps(23);
+
+ ASSERT_THAT(timeStamps,
+ AllOf(Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::project, Eq(22)),
+ Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(33))));
+}
+
} // namespace
diff --git a/tests/unit/unittest/preprocessormacrocollector-test.cpp b/tests/unit/unittest/preprocessormacrocollector-test.cpp
new file mode 100644
index 0000000000..94eaa01a8b
--- /dev/null
+++ b/tests/unit/unittest/preprocessormacrocollector-test.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <preprocessormacrocollector.h>
+
+namespace {
+
+using ProjectExplorer::Macros;
+using ProjectExplorer::MacroType;
+using PM = ClangPchManager::PreprocessorMacro;
+
+class PreprocessorMacrosManager : public testing::Test
+{
+protected:
+ Macros macros1{{"yi", "1"}, {"er", "2"}};
+ Macros macros2{{"san", "3"}, {"se", "4"}};
+ Macros macrosWithDuplicates{{"yi", "1"}, {"san", "3"}, {"se", "4"}, {"er", "0"}};
+ ClangPchManager::PreprocessorMacroCollector manager;
+};
+
+TEST_F(PreprocessorMacrosManager, Add)
+{
+ manager.add(macros1);
+
+ ASSERT_THAT(manager.macros(), ElementsAre(PM{"er", "2"}, PM{"yi", "1"}));
+}
+
+TEST_F(PreprocessorMacrosManager, AddMore)
+{
+ manager.add(macros1);
+
+ manager.add(macros2);
+
+ ASSERT_THAT(manager.macros(),
+ ElementsAre(PM{"er", "2"}, PM{"san", "3"}, PM{"se", "4"}, PM{"yi", "1"}));
+}
+
+TEST_F(PreprocessorMacrosManager, FilterDuplicates)
+{
+ manager.add(macros1);
+
+ manager.add(macrosWithDuplicates);
+
+ ASSERT_THAT(manager.macros(),
+ ElementsAre(PM{"er", "0"}, PM{"er", "2"}, PM{"san", "3"}, PM{"se", "4"}, PM{"yi", "1"}));
+}
+} // namespace
diff --git a/tests/unit/unittest/processevents-utilities.cpp b/tests/unit/unittest/processevents-utilities.cpp
index 32162edecd..6779fb7b06 100644
--- a/tests/unit/unittest/processevents-utilities.cpp
+++ b/tests/unit/unittest/processevents-utilities.cpp
@@ -26,8 +26,8 @@
#include "processevents-utilities.h"
#include <QCoreApplication>
+#include <QElapsedTimer>
#include <QThread>
-#include <QTime>
#include <QDebug>
@@ -38,7 +38,7 @@ bool processEventsUntilTrue(std::function<bool ()> condition, int timeOutInMs)
if (condition())
return true;
- QTime time;
+ QElapsedTimer time;
time.start();
forever {
diff --git a/tests/unit/unittest/projectpartsmanager-test.cpp b/tests/unit/unittest/projectpartsmanager-test.cpp
index d86543e9c2..2dd7a7afc4 100644
--- a/tests/unit/unittest/projectpartsmanager-test.cpp
+++ b/tests/unit/unittest/projectpartsmanager-test.cpp
@@ -24,6 +24,10 @@
****************************************************************************/
#include "googletest.h"
+#include "mockbuilddependenciesprovider.h"
+#include "mockclangpathwatcher.h"
+#include "mockfilepathcaching.h"
+#include "mockgeneratedfiles.h"
#include "mockprecompiledheaderstorage.h"
#include "mockprojectpartsstorage.h"
@@ -34,21 +38,48 @@
namespace {
using ClangBackEnd::FilePathId;
+using ClangBackEnd::FilePathIds;
using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::ProjectPartContainers;
using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts;
+using ClangBackEnd::SourceEntries;
+using ClangBackEnd::SourceEntry;
+using ClangBackEnd::SourceType;
+
+MATCHER_P3(IsIdPaths,
+ projectPartId,
+ sourceIds,
+ sourceType,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(ClangBackEnd::IdPaths{{projectPartId, sourceType},
+ Utils::clone(sourceIds)}))
+{
+ const ClangBackEnd::IdPaths &idPaths = arg;
+
+ return idPaths.filePathIds == sourceIds && idPaths.id.sourceType == sourceType
+ && idPaths.id.id == projectPartId;
+}
class ProjectPartsManager : public testing::Test
{
protected:
ProjectPartsManager()
{
- projectPartContainerWithoutPrecompiledHeader1.hasPrecompiledHeader = false;
+ projectPartContainerWithoutPrecompiledHeader1.preCompiledHeaderWasGenerated = false;
+ ON_CALL(mockGeneratedFiles, fileContainers()).WillByDefault(ReturnRef(generatedFiles));
}
NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
-
- ClangBackEnd::ProjectPartsManager manager{mockProjectPartsStorage, mockPrecompiledHeaderStorage};
+ NiceMock<MockBuildDependenciesProvider> mockBuildDependenciesProvider;
+ NiceMock<MockFilePathCaching> mockFilePathCaching;
+ NiceMock<MockGeneratedFiles> mockGeneratedFiles;
+ NiceMock<MockClangPathWatcher> mockClangPathWatcher;
+ ClangBackEnd::ProjectPartsManager manager{mockProjectPartsStorage,
+ mockPrecompiledHeaderStorage,
+ mockBuildDependenciesProvider,
+ mockFilePathCaching,
+ mockClangPathWatcher,
+ mockGeneratedFiles};
FilePathId firstHeader{1};
FilePathId secondHeader{2};
FilePathId firstSource{11};
@@ -101,13 +132,36 @@ protected:
2,
{"-DUNIX", "-O2"},
{{"DEFINE", "1", 1}},
- {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::System}},
{{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
- {firstHeader, secondHeader},
- {firstSource, secondSource},
+ {firstHeader},
+ {firstSource},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX14,
+ Utils::LanguageExtension::All};
+ ProjectPartContainer projectPartContainer3{
+ 3,
+ {"-DUNIX", "-O2"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::Framework}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {secondHeader},
+ {firstSource},
Utils::Language::C,
- Utils::LanguageVersion::C11,
+ Utils::LanguageVersion::C18,
+ Utils::LanguageExtension::All};
+ ProjectPartContainer projectPartContainer4{
+ 4,
+ {"-DUNIX", "-O2"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {firstHeader},
+ {firstSource},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX03,
Utils::LanguageExtension::All};
+ ClangBackEnd::V2::FileContainers generatedFiles;
};
TEST_F(ProjectPartsManager, GetNoProjectPartsForAddingEmptyProjectParts)
@@ -116,7 +170,7 @@ TEST_F(ProjectPartsManager, GetNoProjectPartsForAddingEmptyProjectParts)
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
- Field(&UpToDataProjectParts::notUpToDate, IsEmpty())));
+ Field(&UpToDataProjectParts::updateSystem, IsEmpty())));
}
TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPart)
@@ -125,7 +179,7 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPart)
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
- Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1))));
+ Field(&UpToDataProjectParts::updateSystem, ElementsAre(projectPartContainer1))));
}
TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlreadyInTheDatabase)
@@ -137,7 +191,7 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlr
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)),
- Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer2))));
+ Field(&UpToDataProjectParts::updateSystem, ElementsAre(projectPartContainer2))));
}
TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPartAlreadyInTheDatabase)
@@ -149,7 +203,7 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPa
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
- Field(&UpToDataProjectParts::notUpToDate,
+ Field(&UpToDataProjectParts::updateSystem,
ElementsAre(updatedProjectPartContainer1, projectPartContainer2))));
}
@@ -198,7 +252,7 @@ TEST_F(ProjectPartsManager, DoNotUpdateNotNewProjectPart)
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)),
- Field(&UpToDataProjectParts::notUpToDate, IsEmpty())));
+ Field(&UpToDataProjectParts::updateSystem, IsEmpty())));
}
TEST_F(ProjectPartsManager, NoDuplicateProjectPartAfterUpdatingWithNotNewProjectPart)
@@ -242,7 +296,7 @@ TEST_F(ProjectPartsManager, GetUpdatedProjectPart)
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
- Field(&UpToDataProjectParts::notUpToDate,
+ Field(&UpToDataProjectParts::updateSystem,
ElementsAre(updatedProjectPartContainer1))));
}
@@ -265,6 +319,24 @@ TEST_F(ProjectPartsManager, Remove)
ASSERT_THAT(manager.projectParts(), ElementsAre(projectPartContainer2));
}
+TEST_F(ProjectPartsManager, RemoveSystemDeferred)
+{
+ manager.updateDeferred({projectPartContainer1, projectPartContainer2}, {});
+
+ manager.remove({projectPartContainer1.projectPartId});
+
+ ASSERT_THAT(manager.deferredSystemUpdates(), ElementsAre(projectPartContainer2));
+}
+
+TEST_F(ProjectPartsManager, RemoveProjectDeferred)
+{
+ manager.updateDeferred({}, {projectPartContainer1, projectPartContainer2});
+
+ manager.remove({projectPartContainer1.projectPartId});
+
+ ASSERT_THAT(manager.deferredProjectUpdates(), ElementsAre(projectPartContainer2));
+}
+
TEST_F(ProjectPartsManager, GetProjectById)
{
manager.update({projectPartContainer1, projectPartContainer2});
@@ -284,40 +356,84 @@ TEST_F(ProjectPartsManager, GetProjectsByIds)
ASSERT_THAT(projectPartContainers, UnorderedElementsAre(projectPartContainer1, projectPartContainer2));
}
-TEST_F(ProjectPartsManager, UpdateDeferred)
+TEST_F(ProjectPartsManager, UpdateSystemDeferred)
+{
+ manager.updateDeferred({projectPartContainer1}, {});
+
+ ASSERT_THAT(manager.deferredSystemUpdates(), ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectPartsManager, UpdateProjectDeferred)
{
- auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2});
+ manager.updateDeferred({}, {projectPartContainer1});
- manager.updateDeferred({projectPartContainer1});
+ ASSERT_THAT(manager.deferredProjectUpdates(), ElementsAre(projectPartContainer1));
+}
- ASSERT_THAT(manager.deferredUpdates(), ElementsAre(projectPartContainer1));
+TEST_F(ProjectPartsManager, NotUpdateSystemDeferred)
+{
+ ASSERT_THAT(manager.deferredSystemUpdates(), IsEmpty());
}
-TEST_F(ProjectPartsManager, NotUpdateDeferred)
+TEST_F(ProjectPartsManager, NotUpdateProjectDeferred)
{
- manager.update({projectPartContainer1, projectPartContainer2});
+ ASSERT_THAT(manager.deferredProjectUpdates(), IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, UpdateSystemDeferredCleansDeferredUpdates)
+{
+ manager.updateDeferred({projectPartContainer1}, {});
- ASSERT_THAT(manager.deferredUpdates(), IsEmpty());
+ manager.deferredSystemUpdates();
+
+ ASSERT_THAT(manager.deferredSystemUpdates(), IsEmpty());
}
-TEST_F(ProjectPartsManager, UpdateDeferredCleansDeferredUpdates)
+TEST_F(ProjectPartsManager, UpdateProjectDeferredCleansDeferredUpdates)
{
- manager.update({projectPartContainer1, projectPartContainer2});
- manager.updateDeferred({projectPartContainer1});
+ manager.updateDeferred({}, {projectPartContainer1});
- manager.deferredUpdates();
+ manager.deferredProjectUpdates();
- ASSERT_THAT(manager.deferredUpdates(), IsEmpty());
+ ASSERT_THAT(manager.deferredProjectUpdates(), IsEmpty());
}
+TEST_F(ProjectPartsManager, UpdateSystemDeferredMultiple)
+{
+ manager.updateDeferred({projectPartContainer1, projectPartContainer3}, {});
+
+ manager.updateDeferred({updatedProjectPartContainer1, projectPartContainer2, projectPartContainer4},
+ {});
+
+ ASSERT_THAT(manager.deferredSystemUpdates(),
+ ElementsAre(updatedProjectPartContainer1,
+ projectPartContainer2,
+ projectPartContainer3,
+ projectPartContainer4));
+}
+
+TEST_F(ProjectPartsManager, UpdateProjectDeferredMultiple)
+{
+ manager.updateDeferred({}, {projectPartContainer1, projectPartContainer3});
+
+ manager.updateDeferred({},
+ {updatedProjectPartContainer1, projectPartContainer2, projectPartContainer4});
+
+ ASSERT_THAT(manager.deferredProjectUpdates(),
+ ElementsAre(updatedProjectPartContainer1,
+ projectPartContainer2,
+ projectPartContainer3,
+ projectPartContainer4));
+}
TEST_F(ProjectPartsManager, UpdateCallsIfNewProjectPartIsAdded)
{
EXPECT_CALL(mockProjectPartsStorage,
fetchProjectParts(ElementsAre(Eq(projectPartContainer1.projectPartId))));
EXPECT_CALL(mockProjectPartsStorage, updateProjectParts(ElementsAre(projectPartContainer1)));
- EXPECT_CALL(mockPrecompiledHeaderStorage,
- deleteProjectPrecompiledHeaders(ElementsAre(projectPartContainer1.projectPartId)));
EXPECT_CALL(mockProjectPartsStorage, resetIndexingTimeStamps(ElementsAre(projectPartContainer1)));
+ EXPECT_CALL(mockPrecompiledHeaderStorage,
+ deleteSystemAndProjectPrecompiledHeaders(
+ ElementsAre(projectPartContainer1.projectPartId)));
manager.update({projectPartContainer1});
}
@@ -353,6 +469,19 @@ TEST_F(ProjectPartsManager, UpdateCallsNotDeleteProjectPrecompiledHeadersIfNoNew
manager.update({projectPartContainer1});
}
+TEST_F(ProjectPartsManager,
+ UpdateCallsNotDeleteSystemAndProjectPrecompiledHeadersIfNoNewerProjectPartsExists)
+{
+ manager.update({projectPartContainer1});
+
+ EXPECT_CALL(mockPrecompiledHeaderStorage,
+ deleteSystemAndProjectPrecompiledHeaders(
+ ElementsAre(projectPartContainer1.projectPartId)))
+ .Times(0);
+
+ manager.update({projectPartContainer1});
+}
+
TEST_F(ProjectPartsManager, UpdateCallsNotResetIndexingTimeStampsIfNoNewerProjectPartsExists)
{
manager.update({projectPartContainer1});
@@ -388,7 +517,8 @@ TEST_F(ProjectPartsManager, UpdateCallsIfUpdatedProjectPartIsAdded)
EXPECT_CALL(mockProjectPartsStorage,
updateProjectParts(ElementsAre(updatedProjectPartContainer1)));
EXPECT_CALL(mockPrecompiledHeaderStorage,
- deleteProjectPrecompiledHeaders(ElementsAre(projectPartContainer1.projectPartId)));
+ deleteSystemAndProjectPrecompiledHeaders(
+ ElementsAre(projectPartContainer1.projectPartId)));
EXPECT_CALL(mockProjectPartsStorage,
resetIndexingTimeStamps(ElementsAre(updatedProjectPartContainer1)));
@@ -405,7 +535,7 @@ TEST_F(ProjectPartsManager,
ASSERT_THAT(projectParts,
AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()),
- Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1))));
+ Field(&UpToDataProjectParts::updateSystem, ElementsAre(projectPartContainer1))));
}
TEST_F(ProjectPartsManager, ProjectPartAddedWithProjectPartAlreadyInTheDatabaseButWithoutEntries)
@@ -418,4 +548,398 @@ TEST_F(ProjectPartsManager, ProjectPartAddedWithProjectPartAlreadyInTheDatabaseB
ASSERT_THAT(manager.projectParts(), ElementsAre(projectPartContainer1));
}
+TEST_F(ProjectPartsManager, SystemSourcesTimeChanged)
+{
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100},
+ {2, SourceType::ProjectInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 101},
+ {2, SourceType::ProjectInclude, 101}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, TopSystemSourcesTimeChanged)
+{
+ SourceEntries oldSources{{1, SourceType::TopSystemInclude, 100},
+ {2, SourceType::ProjectInclude, 100}};
+ SourceEntries newSources{{1, SourceType::TopSystemInclude, 101},
+ {2, SourceType::ProjectInclude, 101}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ProjectSourcesTimeChanged)
+{
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100},
+ {2, SourceType::ProjectInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 100},
+ {2, SourceType::ProjectInclude, 101}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateProject, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, TopProjectSourcesTimeChanged)
+{
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100},
+ {2, SourceType::TopProjectInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 100},
+ {2, SourceType::TopProjectInclude, 101}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateProject, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, UserIncludeSourcesTimeChanged)
+{
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}, {2, SourceType::UserInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 100}, {2, SourceType::UserInclude, 101}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.upToDate, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, SourcesTimeChanged)
+{
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}, {2, SourceType::Source, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 100}, {2, SourceType::Source, 101}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.upToDate, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, SourcesTimeNotChanged)
+{
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 99}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.upToDate, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, TimeChangedForOneProject)
+{
+ manager.update({projectPartContainer1, projectPartContainer2});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(SourceEntries{{1, SourceType::SystemInclude, 100}}));
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer2.sourcePathIds),
+ Eq(projectPartContainer2.projectPartId)))
+ .WillByDefault(Return(SourceEntries{{4, SourceType::SystemInclude, 100}}));
+ ON_CALL(mockBuildDependenciesProvider,
+ create(Eq(projectPartContainer1), Eq(SourceEntries{{1, SourceType::SystemInclude, 100}})))
+ .WillByDefault(Return(
+ ClangBackEnd::BuildDependency{{{1, SourceType::SystemInclude, 101}}, {}, {}, {}, {}}));
+ ON_CALL(mockBuildDependenciesProvider,
+ create(Eq(projectPartContainer2), Eq(SourceEntries{{4, SourceType::SystemInclude, 100}})))
+ .WillByDefault(Return(
+ ClangBackEnd::BuildDependency{{{4, SourceType::SystemInclude, 100}}, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1, projectPartContainer2});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, ElementsAre(projectPartContainer2));
+}
+
+TEST_F(ProjectPartsManager, AddSystemInclude)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 100}, {2, SourceType::SystemInclude, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ChangeFromProjectToSystemInclude)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::ProjectInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ChangeFromSystemToProjectInclude)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}};
+ SourceEntries newSources{{1, SourceType::ProjectInclude, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ChangeFromProjectToUserInclude)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::ProjectInclude, 100}};
+ SourceEntries newSources{{1, SourceType::UserInclude, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateProject, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ChangeFromSystemToUserInclude)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}};
+ SourceEntries newSources{{1, SourceType::UserInclude, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.updateSystem, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.upToDate, IsEmpty());
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ChangeFromSourceToUserInclude)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::Source, 100}};
+ SourceEntries newSources{{1, SourceType::UserInclude, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.upToDate, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, ChangeFromUserIncludeToSource)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::UserInclude, 100}};
+ SourceEntries newSources{{1, SourceType::Source, 100}};
+ manager.update({projectPartContainer1});
+ ON_CALL(mockBuildDependenciesProvider,
+ createSourceEntriesFromStorage(Eq(projectPartContainer1.sourcePathIds),
+ Eq(projectPartContainer1.projectPartId)))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(Eq(projectPartContainer1), Eq(oldSources)))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ auto upToDate = manager.update({projectPartContainer1});
+
+ ASSERT_THAT(upToDate.upToDate, ElementsAre(projectPartContainer1));
+ ASSERT_THAT(upToDate.updateSystem, IsEmpty());
+ ASSERT_THAT(upToDate.updateProject, IsEmpty());
+}
+
+TEST_F(ProjectPartsManager, DontWatchNewSources)
+{
+ EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0);
+
+ manager.update({projectPartContainer1});
+}
+
+TEST_F(ProjectPartsManager, DontWatchUpdatedSources)
+{
+ manager.update({projectPartContainer1});
+
+ EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0);
+
+ manager.update({updatedProjectPartContainer1});
+}
+
+TEST_F(ProjectPartsManager, DontWatchChangedTimeStamps)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}};
+ SourceEntries newSources{{1, SourceType::SystemInclude, 101}};
+ ON_CALL(mockBuildDependenciesProvider, createSourceEntriesFromStorage(_, _))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(_, _))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0);
+
+ manager.update({projectPartContainer1});
+}
+
+TEST_F(ProjectPartsManager, DontWatchChangedSources)
+{
+ manager.update({projectPartContainer1});
+ SourceEntries oldSources{{1, SourceType::SystemInclude, 100}};
+ SourceEntries newSources{{1, SourceType::ProjectInclude, 100}};
+ ON_CALL(mockBuildDependenciesProvider, createSourceEntriesFromStorage(_, _))
+ .WillByDefault(Return(oldSources));
+ ON_CALL(mockBuildDependenciesProvider, create(_, _))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{newSources, {}, {}, {}, {}}));
+
+ EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0);
+
+ manager.update({projectPartContainer1});
+}
+
+TEST_F(ProjectPartsManager, WatchNoUpdatedSources)
+{
+ manager.update({projectPartContainer1, projectPartContainer2});
+ SourceEntries sources1{{1, SourceType::TopSystemInclude, 100},
+ {2, SourceType::SystemInclude, 100},
+ {3, SourceType::TopProjectInclude, 100},
+ {4, SourceType::ProjectInclude, 100},
+ {5, SourceType::UserInclude, 100},
+ {6, SourceType::Source, 100}};
+ SourceEntries sources2{{11, SourceType::TopSystemInclude, 100},
+ {21, SourceType::SystemInclude, 100},
+ {31, SourceType::TopProjectInclude, 100},
+ {41, SourceType::ProjectInclude, 100},
+ {51, SourceType::UserInclude, 100},
+ {61, SourceType::Source, 100}};
+ ON_CALL(mockBuildDependenciesProvider, createSourceEntriesFromStorage(_, Eq(1)))
+ .WillByDefault(Return(sources1));
+ ON_CALL(mockBuildDependenciesProvider,
+ create(Field(&ProjectPartContainer::projectPartId, Eq(1)), _))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{sources1, {}, {}, {}, {}}));
+ ON_CALL(mockBuildDependenciesProvider, createSourceEntriesFromStorage(_, Eq(2)))
+ .WillByDefault(Return(sources2));
+ ON_CALL(mockBuildDependenciesProvider,
+ create(Field(&ProjectPartContainer::projectPartId, Eq(2)), _))
+ .WillByDefault(Return(ClangBackEnd::BuildDependency{sources2, {}, {}, {}, {}}));
+
+ EXPECT_CALL(mockClangPathWatcher,
+ updateIdPaths(UnorderedElementsAre(
+ IsIdPaths(1, FilePathIds{6}, SourceType::Source),
+ IsIdPaths(2, FilePathIds{61}, SourceType::Source),
+ IsIdPaths(1, FilePathIds{5}, SourceType::UserInclude),
+ IsIdPaths(2, FilePathIds{51}, SourceType::UserInclude),
+ IsIdPaths(1, FilePathIds{3, 4}, SourceType::ProjectInclude),
+ IsIdPaths(2, FilePathIds{31, 41}, SourceType::ProjectInclude),
+ IsIdPaths(1, FilePathIds{1, 2}, SourceType::SystemInclude),
+ IsIdPaths(2, FilePathIds{11, 21}, SourceType::SystemInclude))));
+
+ manager.update({projectPartContainer1, projectPartContainer2});
+}
+
} // namespace
diff --git a/tests/unit/unittest/projectpartsstorage-test.cpp b/tests/unit/unittest/projectpartsstorage-test.cpp
index ba1b6f7063..b67cd5a37c 100644
--- a/tests/unit/unittest/projectpartsstorage-test.cpp
+++ b/tests/unit/unittest/projectpartsstorage-test.cpp
@@ -29,11 +29,13 @@
#include <builddependenciesstorage.h>
#include <projectpartsstorage.h>
+#include <projectpartstoragestructs.h>
#include <refactoringdatabaseinitializer.h>
#include <sqlitedatabase.h>
#include <sqlitereadstatement.h>
#include <sqlitewritestatement.h>
#include <symbolstorage.h>
+
namespace {
using ClangBackEnd::FilePathId;
@@ -104,8 +106,10 @@ protected:
MockSqliteWriteStatement &insertProjectPartsSourcesStatement = storage.insertProjectPartsSourcesStatement;
MockSqliteReadStatement &fetchProjectPartsHeadersByIdStatement = storage.fetchProjectPartsHeadersByIdStatement;
MockSqliteReadStatement &fetchProjectPartsSourcesByIdStatement = storage.fetchProjectPartsSourcesByIdStatement;
- MockSqliteReadStatement &fetchProjectPrecompiledHeaderPathStatement = storage.fetchProjectPrecompiledHeaderPathStatement;
+ MockSqliteReadStatement &fetchProjectPrecompiledHeaderPathStatement = storage.fetchProjectPrecompiledHeaderBuildTimeStatement;
+ MockSqliteReadStatement &fetchProjectPrecompiledHeaderBuildTimeStatement = storage.fetchProjectPrecompiledHeaderBuildTimeStatement;
MockSqliteWriteStatement &resetDependentIndexingTimeStampsStatement = storage.resetDependentIndexingTimeStampsStatement;
+ MockSqliteReadStatement &fetchAllProjectPartNamesAndIdsStatement = storage.fetchAllProjectPartNamesAndIdsStatement;
IncludeSearchPaths systemIncludeSearchPaths{{"/includes", 1, IncludeSearchPathType::BuiltIn},
{"/other/includes", 2, IncludeSearchPathType::System}};
IncludeSearchPaths projectIncludeSearchPaths{{"/project/includes", 1, IncludeSearchPathType::User},
@@ -123,6 +127,7 @@ protected:
Utils::Language::Cxx,
Utils::LanguageVersion::CXX11,
Utils::LanguageExtension::None};
+ ClangBackEnd::Internal::ProjectPartNameIds projectPartNameIds{{"projectPartName", 2}};
};
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
@@ -138,6 +143,17 @@ TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
storage.fetchProjectPartId("test");
}
+TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartNameUnguarded)
+{
+ InSequence s;
+
+ EXPECT_CALL(fetchProjectPartIdStatement,
+ valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")));
+ EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test")));
+
+ storage.fetchProjectPartIdUnguarded("test");
+}
+
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPart)
{
InSequence s;
@@ -152,6 +168,18 @@ TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPart)
storage.fetchProjectPartId("test");
}
+TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPartUnguarded)
+{
+ InSequence s;
+
+ EXPECT_CALL(fetchProjectPartIdStatement,
+ valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
+ .WillOnce(Return(Utils::optional<ProjectPartId>{20}));
+ EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test"))).Times(0);
+
+ storage.fetchProjectPartIdUnguarded("test");
+}
+
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithBusyDatabaset)
{
InSequence s;
@@ -183,6 +211,18 @@ TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartName)
ASSERT_THAT(id.projectPathId, 21);
}
+TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartNameUnguarded)
+{
+ ON_CALL(fetchProjectPartIdStatement,
+ valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
+ .WillByDefault(Return(Utils::optional<ProjectPartId>{}));
+ ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(21));
+
+ auto id = storage.fetchProjectPartIdUnguarded("test");
+
+ ASSERT_THAT(id.projectPathId, 21);
+}
+
TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartNameAndIsBusy)
{
InSequence s;
@@ -210,6 +250,17 @@ TEST_F(ProjectPartsStorage, FetchProjectIdWithExistingProjectPartName)
ASSERT_THAT(id.projectPathId, 20);
}
+TEST_F(ProjectPartsStorage, FetchProjectIdWithExistingProjectPartNameUnguarded)
+{
+ ON_CALL(fetchProjectPartIdStatement,
+ valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
+ .WillByDefault(Return(Utils::optional<ProjectPartId>{20}));
+
+ auto id = storage.fetchProjectPartIdUnguarded("test");
+
+ ASSERT_THAT(id.projectPathId, 20);
+}
+
TEST_F(ProjectPartsStorage, FetchProjectPartName)
{
InSequence s;
@@ -257,11 +308,11 @@ TEST_F(ProjectPartsStorage, FetchProjectPartsByIds)
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(1)));
EXPECT_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(1024, Eq(1)));
EXPECT_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(1024, Eq(1)));
- EXPECT_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)));
+ EXPECT_CALL(fetchProjectPrecompiledHeaderBuildTimeStatement, valueReturnInt64(Eq(1)));
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(2)));
EXPECT_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(1024, Eq(2)));
EXPECT_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(1024, Eq(2)));
- EXPECT_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(2)));
+ EXPECT_CALL(fetchProjectPrecompiledHeaderBuildTimeStatement, valueReturnInt64(Eq(2)));
EXPECT_CALL(mockDatabase, commit());
storage.fetchProjectParts({1, 2});
@@ -284,34 +335,34 @@ TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsIsBusy)
storage.fetchProjectParts({1, 2});
}
-TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledNullOptional)
+TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsPreCompiledHeaderWasGeneratedNullOptional)
{
- ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)))
- .WillByDefault(Return(Utils::optional<Utils::SmallString>{}));
+ ON_CALL(fetchProjectPrecompiledHeaderBuildTimeStatement, valueReturnInt64(Eq(1)))
+ .WillByDefault(Return(Utils::optional<long long>{}));
auto projectParts = storage.fetchProjectParts({1});
- ASSERT_FALSE(projectParts.front().hasPrecompiledHeader);
+ ASSERT_FALSE(projectParts.front().preCompiledHeaderWasGenerated);
}
-TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledEmptyString)
+TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsPreCompiledHeaderWasGeneratedZero)
{
- ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)))
- .WillByDefault(Return(Utils::optional<Utils::SmallString>{""}));
+ ON_CALL(fetchProjectPrecompiledHeaderBuildTimeStatement, valueReturnInt64(Eq(1)))
+ .WillByDefault(Return(Utils::optional<long long>{0}));
auto projectParts = storage.fetchProjectParts({1});
- ASSERT_FALSE(projectParts.front().hasPrecompiledHeader);
+ ASSERT_FALSE(projectParts.front().preCompiledHeaderWasGenerated);
}
-TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledStringWithContent)
+TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsPreCompiledHeaderWasGeneratedSomeNumber)
{
- ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)))
- .WillByDefault(Return(Utils::optional<Utils::SmallString>{"/some/path"}));
+ ON_CALL(fetchProjectPrecompiledHeaderBuildTimeStatement, valueReturnInt64(Eq(1)))
+ .WillByDefault(Return(Utils::optional<long long>{23}));
auto projectParts = storage.fetchProjectParts({1});
- ASSERT_TRUE(projectParts.front().hasPrecompiledHeader);
+ ASSERT_TRUE(projectParts.front().preCompiledHeaderWasGenerated);
}
TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasMissingId)
@@ -392,8 +443,28 @@ TEST_F(ProjectPartsStorage, UpdateProjectPartsIsBusy)
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdCallsValueInStatement)
{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
.WillRepeatedly(Return(artefact));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchProjectPartArtefact(FilePathId{1});
+}
+
+TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdCallsValueInStatementIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
+ .WillOnce(Throw(Sqlite::StatementIsBusy{""}));
+ EXPECT_CALL(mockDatabase, rollback());
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
+ .WillRepeatedly(Return(artefact));
+ EXPECT_CALL(mockDatabase, commit());
storage.fetchProjectPartArtefact(FilePathId{1});
}
@@ -410,8 +481,12 @@ TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdReturnArtefact)
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactByProjectPartIdCallsValueInStatement)
{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(getProjectPartArtefactsByProjectPartId, valueReturnProjectPartArtefact(74))
.WillRepeatedly(Return(artefact));
+ EXPECT_CALL(mockDatabase, commit());
storage.fetchProjectPartArtefact(ProjectPartId{74});
}
@@ -426,6 +501,22 @@ TEST_F(ProjectPartsStorage, FetchProjectPartArtefactByProjectPartIdReturnArtefac
ASSERT_THAT(result, Eq(artefact));
}
+TEST_F(ProjectPartsStorage, FetchProjectPartArtefactByProjectPartIdReturnArtefactIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(getProjectPartArtefactsByProjectPartId, valueReturnProjectPartArtefact(74))
+ .WillOnce(Throw(Sqlite::StatementIsBusy{""}));
+ EXPECT_CALL(mockDatabase, rollback());
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(getProjectPartArtefactsByProjectPartId, valueReturnProjectPartArtefact(74))
+ .WillRepeatedly(Return(artefact));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchProjectPartArtefact(ProjectPartId{74});
+}
+
TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStamps)
{
InSequence s;
@@ -455,6 +546,34 @@ TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStampsIsBusy)
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
}
+TEST_F(ProjectPartsStorage, FetchAllProjectPartNamesAndIdsCalls)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(fetchAllProjectPartNamesAndIdsStatement, valuesReturnProjectPartNameIds(_))
+ .WillRepeatedly(Return(projectPartNameIds));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchAllProjectPartNamesAndIds();
+}
+
+TEST_F(ProjectPartsStorage, FetchAllProjectPartNamesAndIdsCallsIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(fetchAllProjectPartNamesAndIdsStatement, valuesReturnProjectPartNameIds(_))
+ .WillOnce(Throw(Sqlite::StatementIsBusy{""}));
+ EXPECT_CALL(mockDatabase, rollback());
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(fetchAllProjectPartNamesAndIdsStatement, valuesReturnProjectPartNameIds(_))
+ .WillRepeatedly(Return(projectPartNameIds));
+ EXPECT_CALL(mockDatabase, commit());
+
+ storage.fetchAllProjectPartNamesAndIds();
+}
+
class ProjectPartsStorageSlow : public testing::Test, public Data
{
using Storage = ClangBackEnd::ProjectPartsStorage<Sqlite::Database>;
@@ -490,6 +609,15 @@ TEST_F(ProjectPartsStorageSlow, FetchProjectPartId)
ASSERT_THAT(first, Eq(second));
}
+TEST_F(ProjectPartsStorageSlow, FetchProjectPartIdUnguarded)
+{
+ auto first = storage.fetchProjectPartId("test");
+
+ auto second = storage.fetchProjectPartIdUnguarded("test");
+
+ ASSERT_THAT(first, Eq(second));
+}
+
TEST_F(ProjectPartsStorageSlow, FetchProjectParts)
{
projectPart1.projectPartId = storage.fetchProjectPartId("project1");
@@ -511,16 +639,28 @@ TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps)
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
ASSERT_THAT(buildDependenciesStorage.fetchIndexingTimeStamps(),
- ElementsAre(SourceTimeStamp{1, 0},
- SourceTimeStamp{2, 0},
+ ElementsAre(SourceTimeStamp{1, 34},
+ SourceTimeStamp{2, 34},
SourceTimeStamp{3, 0},
SourceTimeStamp{4, 0},
- SourceTimeStamp{5, 0},
- SourceTimeStamp{6, 0},
+ SourceTimeStamp{5, 34},
+ SourceTimeStamp{6, 34},
SourceTimeStamp{7, 0},
SourceTimeStamp{8, 0},
SourceTimeStamp{9, 34},
SourceTimeStamp{10, 34}));
}
+TEST_F(ProjectPartsStorageSlow, FetchAllProjectPartNamesAndIdsy)
+{
+ using ClangBackEnd::Internal::ProjectPartNameId;
+ auto id = storage.fetchProjectPartId("projectPartName");
+ auto id2 = storage.fetchProjectPartId("projectPartName2");
+
+ auto values = storage.fetchAllProjectPartNamesAndIds();
+
+ ASSERT_THAT(values,
+ UnorderedElementsAre(ProjectPartNameId{"projectPartName", id},
+ ProjectPartNameId{"projectPartName2", id2}));
+}
} // namespace
diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp
index ea1c14dc35..52e68b308c 100644
--- a/tests/unit/unittest/projectupdater-test.cpp
+++ b/tests/unit/unittest/projectupdater-test.cpp
@@ -25,6 +25,7 @@
#include "googletest.h"
+#include "mockfilepathcaching.h"
#include "mockpchmanagerclient.h"
#include "mockpchmanagernotifier.h"
#include "mockpchmanagerserver.h"
@@ -35,6 +36,8 @@
#include <pchmanagerprojectupdater.h>
+#include <clangindexingprojectsettings.h>
+#include <clangindexingsettingsmanager.h>
#include <filepathcaching.h>
#include <pchmanagerclient.h>
#include <precompiledheaderstorage.h>
@@ -52,6 +55,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/algorithm.h>
+#include <utils/namevalueitem.h>
namespace {
@@ -62,10 +66,11 @@ using testing::NiceMock;
using testing::AnyNumber;
using ClangBackEnd::CompilerMacro;
+using ClangBackEnd::FilePath;
using ClangBackEnd::IncludeSearchPath;
using ClangBackEnd::IncludeSearchPathType;
-using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::ProjectPartContainer;
+using ClangBackEnd::V2::FileContainer;
using CppTools::CompilerOptionsBuilder;
using ProjectExplorer::HeaderPath;
@@ -94,7 +99,7 @@ protected:
projectPart.files.push_back(source2ProjectFile);
projectPart.files.push_back(nonActiveProjectFile);
projectPart.displayName = "projectb";
- projectPart.projectMacros = {{"FOO", "2"}, {"BAR", "1"}};
+ projectPart.projectMacros = {{"FOO", "2"}, {"BAR", "1"}, {"POO", "3"}};
projectPartId = projectPartsStorage.fetchProjectPartId(Utils::SmallString{projectPart.id()});
projectPart2.project = &project;
@@ -138,6 +143,9 @@ protected:
Utils::Language::Cxx,
Utils::LanguageVersion::LatestCxx,
Utils::LanguageExtension::None};
+
+ auto settings = settingsManager.settings(&project);
+ settings->saveMacros({{"POO", "3", Utils::NameValueItem::Unset}});
}
protected:
@@ -151,7 +159,11 @@ protected:
mockDependencyCreationProgressManager};
MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient};
NiceMock<MockPchManagerServer> mockPchManagerServer;
- ClangPchManager::ProjectUpdater updater{mockPchManagerServer, filePathCache, projectPartsStorage};
+ ClangPchManager::ClangIndexingSettingsManager settingsManager;
+ ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
+ filePathCache,
+ projectPartsStorage,
+ settingsManager};
ClangBackEnd::ProjectPartId projectPartId;
ClangBackEnd::ProjectPartId projectPartId2;
Utils::PathStringVector headerPaths = {"/path/to/header1.h", "/path/to/header2.h"};
@@ -171,9 +183,18 @@ protected:
CppTools::ProjectPart nonBuildingProjectPart;
ProjectPartContainer expectedContainer;
ProjectPartContainer expectedContainer2;
- FileContainer generatedFile{{"/path/to", "header1.h"}, "content", {}};
- FileContainer generatedFile2{{"/path/to2", "header1.h"}, "content", {}};
- FileContainer generatedFile3{{"/path/to", "header2.h"}, "content", {}};
+ FileContainer generatedFile{{"/path/to", "header1.h"},
+ filePathCache.filePathId(FilePath{"/path/to", "header1.h"}),
+ "content",
+ {}};
+ FileContainer generatedFile2{{"/path/to2", "header1.h"},
+ filePathCache.filePathId(FilePath{"/path/to2", "header1.h"}),
+ "content",
+ {}};
+ FileContainer generatedFile3{{"/path/to", "header2.h"},
+ filePathCache.filePathId(FilePath{"/path/to", "header2.h"}),
+ "content",
+ {}};
};
TEST_F(ProjectUpdater, CallUpdateProjectParts)
@@ -243,10 +264,12 @@ TEST_F(ProjectUpdater, CallRemoveProjectParts)
TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater)
{
+ ClangPchManager::ClangIndexingSettingsManager settingManager;
ClangPchManager::PchManagerProjectUpdater pchUpdater{mockPchManagerServer,
pchManagerClient,
filePathCache,
- projectPartsStorage};
+ projectPartsStorage,
+ settingManager};
ClangBackEnd::RemoveProjectPartsMessage message{{projectPartId, projectPartId2}};
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId));
@@ -258,6 +281,7 @@ TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater)
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
{
updater.setExcludedPaths({"/path/to/header1.h"});
+ updater.fetchProjectPartIds({&projectPart});
auto container = updater.toProjectPartContainer(&projectPart);
@@ -266,30 +290,36 @@ TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainersHaveSameSizeLikeProjectParts)
{
+ updater.fetchProjectPartIds({&projectPart, &nonBuildingProjectPart});
+
auto containers = updater.toProjectPartContainers(
{&projectPart, &projectPart, &nonBuildingProjectPart});
ASSERT_THAT(containers, SizeIs(2));
}
-TEST_F(ProjectUpdater, CallStorageInsideTransaction)
+TEST_F(ProjectUpdater, ProjectPartIdsPrefetchingInsideTransaction)
{
InSequence s;
CppTools::ProjectPart projectPart;
projectPart.project = &project;
projectPart.displayName = "project";
Utils::SmallString projectPartName = projectPart.id();
- MockSqliteTransactionBackend mockSqliteTransactionBackend;
- MockProjectPartsStorage mockProjectPartsStorage;
+ NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend;
+ NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
ON_CALL(mockProjectPartsStorage, transactionBackend())
.WillByDefault(ReturnRef(mockSqliteTransactionBackend));
+ ClangPchManager::ClangIndexingSettingsManager settingsManager;
ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
filePathCache,
- mockProjectPartsStorage};
+ mockProjectPartsStorage,
+ settingsManager};
- EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartId(Eq(projectPartName)));
+ EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
+ EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartIdUnguarded(Eq(projectPartName))).WillOnce(Return(1));
+ EXPECT_CALL(mockSqliteTransactionBackend, commit());
- updater.toProjectPartContainers({&projectPart});
+ updater.fetchProjectPartIds({&projectPart});
}
TEST_F(ProjectUpdater, CreateSortedExcludedPaths)
@@ -303,7 +333,7 @@ TEST_F(ProjectUpdater, CreateSortedExcludedPaths)
TEST_F(ProjectUpdater, CreateSortedCompilerMacros)
{
- auto paths = updater.createCompilerMacros({{"DEFINE", "1"}, {"FOO", "2"}, {"BAR", "1"}});
+ auto paths = updater.createCompilerMacros({{"DEFINE", "1"}, {"FOO", "2"}, {"BAR", "1"}}, {});
ASSERT_THAT(paths, ElementsAre(CompilerMacro{"BAR", "1", 1},
CompilerMacro{"FOO", "2", 2},
@@ -312,12 +342,28 @@ TEST_F(ProjectUpdater, CreateSortedCompilerMacros)
TEST_F(ProjectUpdater, FilterCompilerMacros)
{
- auto paths = updater.createCompilerMacros(
- {{"DEFINE", "1"}, {"QT_TESTCASE_BUILDDIR", "2"}, {"BAR", "1"}});
+ auto paths = updater.createCompilerMacros({{"DEFINE", "1"},
+ {"QT_TESTCASE_BUILDDIR", "2"},
+ {"BAR", "1"}},
+ {});
ASSERT_THAT(paths, ElementsAre(CompilerMacro{"BAR", "1", 1}, CompilerMacro{"DEFINE", "1", 3}));
}
+TEST_F(ProjectUpdater, FilterSettingsMacros)
+{
+ auto paths = updater.createCompilerMacros({{"YI", "1"}, {"SAN", "3"}, {"SE", "4"}, {"WU", "5"}},
+ {{"SE", "44", Utils::NameValueItem::Unset},
+ {"ER", "2", Utils::NameValueItem::SetEnabled},
+ {"WU", "5", Utils::NameValueItem::Unset}});
+
+ ASSERT_THAT(paths,
+ ElementsAre(CompilerMacro{"ER", "2", 3},
+ CompilerMacro{"SE", "4", 3},
+ CompilerMacro{"YI", "1", 1},
+ CompilerMacro{"SAN", "3", 2}));
+}
+
TEST_F(ProjectUpdater, CreateSortedIncludeSearchPaths)
{
CppTools::ProjectPart projectPart;
@@ -440,6 +486,56 @@ TEST_F(ProjectUpdater, FetchProjectPartName)
ASSERT_THAT(projectPartName, Eq(QString{" projectb"}));
}
-// test for update many time and get the same id
+TEST_F(ProjectUpdater, AddProjectFilesToFilePathCache)
+{
+ NiceMock<MockFilePathCaching> mockFilePathCaching;
+ ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
+ mockFilePathCaching,
+ projectPartsStorage,
+ settingsManager};
+
+ EXPECT_CALL(mockFilePathCaching,
+ addFilePaths(UnorderedElementsAre(Eq(headerPaths[0]),
+ Eq(headerPaths[1]),
+ Eq(sourcePaths[0]),
+ Eq(sourcePaths[1]))));
+
+ updater.updateProjectParts({&projectPart}, {});
+}
+
+TEST_F(ProjectUpdater, FillProjectPartIdCacheAtCreation)
+{
+ NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
+
+ EXPECT_CALL(mockProjectPartsStorage, fetchAllProjectPartNamesAndIds());
+
+ ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
+ filePathCache,
+ mockProjectPartsStorage,
+ settingsManager};
+}
+
+TEST_F(ProjectUpdater, DontFetchProjectPartIdFromDatabaseIfItIsInCache)
+{
+ projectPart.files.clear();
+ NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend;
+ NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
+ ON_CALL(mockProjectPartsStorage, transactionBackend())
+ .WillByDefault(ReturnRef(mockSqliteTransactionBackend));
+ ON_CALL(mockProjectPartsStorage, fetchAllProjectPartNamesAndIds())
+ .WillByDefault(Return(
+ ClangBackEnd::Internal::ProjectPartNameIds{{Utils::PathString(projectPart.id()), 55}}));
+ ClangPchManager::ProjectUpdater updater{mockPchManagerServer,
+ filePathCache,
+ mockProjectPartsStorage,
+ settingsManager};
+
+ EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()).Times(0);
+ EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartId(_)).Times(0);
+ EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartIdUnguarded(_)).Times(0);
+ EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
+
+ updater.updateProjectParts({&projectPart}, {});
+}
} // namespace
diff --git a/tests/unit/unittest/readexporteddiagnostics-test.cpp b/tests/unit/unittest/readexporteddiagnostics-test.cpp
new file mode 100644
index 0000000000..368c868233
--- /dev/null
+++ b/tests/unit/unittest/readexporteddiagnostics-test.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <clangtools/clangtoolslogfilereader.h>
+
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+
+#define TESTDATA TESTDATA_DIR "/clangtools/"
+
+using namespace ClangTools::Internal;
+using Debugger::DiagnosticLocation;
+
+namespace {
+
+class ReadExportedDiagnostics : public ::testing::Test
+{
+protected:
+ void SetUp() override
+ {
+ ASSERT_TRUE(temporaryDir.isValid());
+ }
+
+ // Replace FILE_PATH with a real absolute file path in the *.yaml files.
+ QString createFile(const QString &yamlFilePath, const QString &filePathToInject)
+ {
+ QTC_ASSERT(QDir::isAbsolutePath(filePathToInject), return QString());
+ const QString newFileName = temporaryDir.filePath(QFileInfo(yamlFilePath).fileName());
+
+ Utils::FileReader reader;
+ if (QTC_GUARD(reader.fetch(yamlFilePath, QIODevice::ReadOnly | QIODevice::Text))) {
+ QByteArray contents = reader.data();
+ contents.replace("FILE_PATH", filePathToInject.toLocal8Bit());
+
+ Utils::FileSaver fileSaver(newFileName, QIODevice::WriteOnly | QIODevice::Text);
+ QTC_CHECK(fileSaver.write(contents));
+ QTC_CHECK(fileSaver.finalize());
+ }
+
+ return newFileName;
+ }
+
+protected:
+ QString errorMessage;
+ Utils::TemporaryDirectory temporaryDir{"clangtools-tests-XXXXXX"};
+};
+
+TEST_F(ReadExportedDiagnostics, NotExistingFile)
+{
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString("notExistingFile.yaml"),
+ {},
+ &errorMessage);
+
+ ASSERT_THAT(diags, IsEmpty());
+ ASSERT_FALSE(errorMessage.isEmpty());
+}
+
+TEST_F(ReadExportedDiagnostics, EmptyFile)
+{
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(TESTDATA "empty.yaml"),
+ {},
+ &errorMessage);
+
+ ASSERT_THAT(diags, IsEmpty());
+ ASSERT_TRUE(errorMessage.isEmpty());
+}
+
+TEST_F(ReadExportedDiagnostics, UnexpectedFileContents)
+{
+ const QString sourceFile = TESTDATA "tidy.modernize-use-nullptr.cpp";
+
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(sourceFile),
+ {},
+ &errorMessage);
+
+ ASSERT_FALSE(errorMessage.isEmpty());
+ ASSERT_THAT(diags, IsEmpty());
+}
+
+TEST_F(ReadExportedDiagnostics, Tidy)
+{
+ const QString sourceFile = TESTDATA "tidy.modernize-use-nullptr.cpp";
+ const QString exportedFile = createFile(TESTDATA "tidy.modernize-use-nullptr.yaml", sourceFile);
+ Diagnostic expectedDiag;
+ expectedDiag.location = {sourceFile, 2, 25};
+ expectedDiag.description = "use nullptr [modernize-use-nullptr]";
+ expectedDiag.type = "warning";
+ expectedDiag.hasFixits = true;
+ expectedDiag.explainingSteps = {ExplainingStep{"nullptr",
+ expectedDiag.location,
+ {expectedDiag.location, {sourceFile, 2, 26}},
+ true}};
+
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(exportedFile),
+ {},
+ &errorMessage);
+
+ ASSERT_TRUE(errorMessage.isEmpty());
+ ASSERT_THAT(diags, ElementsAre(expectedDiag));
+}
+
+TEST_F(ReadExportedDiagnostics, AcceptDiagsFromFilePaths_None)
+{
+ const QString sourceFile = TESTDATA "tidy.modernize-use-nullptr.cpp";
+ const QString exportedFile = createFile(TESTDATA "tidy.modernize-use-nullptr.yaml", sourceFile);
+ const auto acceptNone = [](const Utils::FilePath &) { return false; };
+
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(exportedFile),
+ acceptNone,
+ &errorMessage);
+
+ ASSERT_TRUE(errorMessage.isEmpty());
+ ASSERT_THAT(diags, IsEmpty());
+}
+
+// Diagnostics from clang passed through via clang-tidy
+TEST_F(ReadExportedDiagnostics, Tidy_Clang)
+{
+ const QString sourceFile = TESTDATA "clang.unused-parameter.cpp";
+ const QString exportedFile = createFile(TESTDATA "clang.unused-parameter.yaml", sourceFile);
+ Diagnostic expectedDiag;
+ expectedDiag.location = {sourceFile, 4, 12};
+ expectedDiag.description = "unused parameter 'g' [clang-diagnostic-unused-parameter]";
+ expectedDiag.type = "warning";
+ expectedDiag.hasFixits = false;
+
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(exportedFile),
+ {},
+ &errorMessage);
+
+ ASSERT_TRUE(errorMessage.isEmpty());
+ ASSERT_THAT(diags, ElementsAre(expectedDiag));
+}
+
+// Diagnostics from clang (static) analyzer passed through via clang-tidy
+TEST_F(ReadExportedDiagnostics, Tidy_ClangAnalyzer)
+{
+ const QString sourceFile = TESTDATA "clang-analyzer.dividezero.cpp";
+ const QString exportedFile = createFile(TESTDATA "clang-analyzer.dividezero.yaml", sourceFile);
+ Diagnostic expectedDiag;
+ expectedDiag.location = {sourceFile, 4, 15};
+ expectedDiag.description = "Division by zero [clang-analyzer-core.DivideZero]";
+ expectedDiag.type = "warning";
+ expectedDiag.hasFixits = false;
+ expectedDiag.explainingSteps = {
+ ExplainingStep{"Assuming 'z' is equal to 0",
+ {sourceFile, 3, 7},
+ {},
+ false,
+ },
+ ExplainingStep{"Taking true branch",
+ {sourceFile, 3, 3},
+ {},
+ false,
+ },
+ ExplainingStep{"Division by zero",
+ {sourceFile, 4, 15},
+ {},
+ false,
+ },
+ };
+
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(exportedFile),
+ {},
+ &errorMessage);
+
+ ASSERT_TRUE(errorMessage.isEmpty());
+ ASSERT_THAT(diags, ElementsAre(expectedDiag));
+}
+
+TEST_F(ReadExportedDiagnostics, Clazy)
+{
+ const QString sourceFile = TESTDATA "clazy.qgetenv.cpp";
+ const QString exportedFile = createFile(TESTDATA "clazy.qgetenv.yaml", sourceFile);
+ Diagnostic expectedDiag;
+ expectedDiag.location = {sourceFile, 7, 5};
+ expectedDiag.description = "qgetenv().isEmpty() allocates. Use qEnvironmentVariableIsEmpty() instead [clazy-qgetenv]";
+ expectedDiag.type = "warning";
+ expectedDiag.hasFixits = true;
+ expectedDiag.explainingSteps = {
+ ExplainingStep{"qEnvironmentVariableIsEmpty",
+ expectedDiag.location,
+ {expectedDiag.location, {sourceFile, 7, 12}},
+ true
+ },
+ ExplainingStep{")",
+ {sourceFile, 7, 18},
+ {{sourceFile, 7, 18}, {sourceFile, 7, 29}},
+ true},
+ };
+
+ Diagnostics diags = readExportedDiagnostics(Utils::FilePath::fromString(exportedFile),
+ {},
+ &errorMessage);
+
+ ASSERT_TRUE(errorMessage.isEmpty());
+ ASSERT_THAT(diags, ElementsAre(expectedDiag));
+}
+
+class ByteOffsetInUtf8TextToLineColumn : public ::testing::Test
+{
+protected:
+ const char *empty = "";
+ const char *asciiWord = "FOO";
+ const char *asciiMultiLine = "FOO\nBAR";
+ const char *asciiMultiLine_dos = "FOO\r\nBAR";
+ const char *asciiEmptyMultiLine = "\n\n";
+ // U+00FC - 2 code units in UTF8, 1 in UTF16 - LATIN SMALL LETTER U WITH DIAERESIS
+ // U+4E8C - 3 code units in UTF8, 1 in UTF16 - CJK UNIFIED IDEOGRAPH-4E8C
+ // U+10302 - 4 code units in UTF8, 2 in UTF16 - OLD ITALIC LETTER KE
+ const char *nonAsciiMultiLine = "\xc3\xbc" "\n"
+ "\xe4\xba\x8c" "\n"
+ "\xf0\x90\x8c\x82" "X";
+
+ // Convenience
+ const char *text = nullptr;
+};
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, InvalidText)
+{
+ ASSERT_FALSE(byteOffsetInUtf8TextToLineColumn(nullptr, 0));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, InvalidOffset_EmptyInput)
+{
+ ASSERT_FALSE(byteOffsetInUtf8TextToLineColumn(empty, 0));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, InvalidOffset_Before)
+{
+ ASSERT_FALSE(byteOffsetInUtf8TextToLineColumn(asciiWord, -1));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, InvalidOffset_After)
+{
+ ASSERT_FALSE(byteOffsetInUtf8TextToLineColumn(asciiWord, 3));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, InvalidOffset_NotFirstByteOfMultiByte)
+{
+ ASSERT_FALSE(byteOffsetInUtf8TextToLineColumn(nonAsciiMultiLine, 1));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, StartOfFirstLine)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(asciiWord, 0);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(1));
+ ASSERT_THAT(info->column, Eq(1));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, EndOfFirstLine)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(asciiWord, 2);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(1));
+ ASSERT_THAT(info->column, Eq(3));
+}
+
+// The invocation
+//
+// clang-tidy "-checks=-*,readability-braces-around-statements" /path/to/file
+//
+// for the code
+//
+// void f(bool b)
+// {
+// if (b)
+// f(b);
+// }
+//
+// emits
+//
+// 3:11: warning: statement should be inside braces [readability-braces-around-statements]
+//
+// The new line in the if-line is considered as column 11, which is normally not visible in the
+// editor.
+TEST_F(ByteOffsetInUtf8TextToLineColumn, OffsetPointingToLineSeparator_unix)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(asciiMultiLine, 3);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(1));
+ ASSERT_THAT(info->column, Eq(4));
+}
+
+// For a file with dos style line endings ("\r\n"), clang-tidy points to '\r'.
+TEST_F(ByteOffsetInUtf8TextToLineColumn, OffsetPointingToLineSeparator_dos)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(asciiMultiLine_dos, 3);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(1));
+ ASSERT_THAT(info->column, Eq(4));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, StartOfSecondLine)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(asciiMultiLine, 4);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(2));
+ ASSERT_THAT(info->column, Eq(1));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, MultiByteCodePoint1)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(nonAsciiMultiLine, 3);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(2));
+ ASSERT_THAT(info->column, Eq(1));
+}
+
+TEST_F(ByteOffsetInUtf8TextToLineColumn, MultiByteCodePoint2)
+{
+ auto info = byteOffsetInUtf8TextToLineColumn(nonAsciiMultiLine, 11);
+
+ ASSERT_TRUE(info);
+ ASSERT_THAT(info->line, Eq(3));
+ ASSERT_THAT(info->column, Eq(2));
+}
+
+} // namespace
+
+#undef TESTDATA
diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
index 8b6237bfad..344eb08f03 100644
--- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
@@ -129,8 +129,8 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesAndDiagnosticsForQue
{
RequestSourceRangesForQueryMessage message{
"functionDecl()",
- {{{TESTDATA_DIR, "query_simplefunction.cpp"}, "void f();", {"cc"}, 1}},
- {{{TESTDATA_DIR, "query_simplefunction.h"}, "void f();", {}, 1}}};
+ {{{TESTDATA_DIR, "query_simplefunction.cpp"}, 1, "void f();", {"cc"}, 1}},
+ {{{TESTDATA_DIR, "query_simplefunction.h"}, 2, "void f();", {}, 1}}};
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
@@ -143,12 +143,13 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesForQueryMessage)
RequestSourceRangesForQueryMessage message{
"functionDecl()",
{{{TESTDATA_DIR, "query_simplefunction.cpp"},
+ 1,
"void f();",
{
"cc",
},
1}},
- {{{TESTDATA_DIR, "query_simplefunction.h"}, "void f();", {}, 1}}};
+ {{{TESTDATA_DIR, "query_simplefunction.h"}, 2, "void f();", {}, 1}}};
EXPECT_CALL(mockRefactoringServer, requestSourceRangesForQueryMessage(message));
@@ -182,7 +183,7 @@ TEST_F(RefactoringClientServerInProcess, SendUpdateProjectPartsMessage)
TEST_F(RefactoringClientServerInProcess, SendUpdateGeneratedFilesMessage)
{
- FileContainer fileContainer{{"/path/to/", "file"}, "content", {}};
+ FileContainer fileContainer{{"/path/to/", "file"}, 1, "content", {}};
UpdateGeneratedFilesMessage message{{fileContainer}};
EXPECT_CALL(mockRefactoringServer, updateGeneratedFiles(message));
diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
index 3af0fc8cfe..7af00158df 100644
--- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
+++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
@@ -60,7 +60,9 @@ TEST_F(RefactoringDatabaseInitializer, AddLocationsTable)
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER, locationKind INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_locations_sourceId_line_column ON locations(sourceId, line, column)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON locations(sourceId, locationKind)")));
-
+ EXPECT_CALL(mockDatabase,
+ execute(Eq(
+ "CREATE INDEX IF NOT EXISTS index_locations_symbolId ON locations(symbolId)")));
initializer.createLocationsTable();
}
@@ -221,6 +223,9 @@ TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor)
execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON "
"locations(sourceId, locationKind)")));
EXPECT_CALL(mockDatabase,
+ execute(Eq(
+ "CREATE INDEX IF NOT EXISTS index_locations_symbolId ON locations(symbolId)")));
+ EXPECT_CALL(mockDatabase,
execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, "
"directoryId INTEGER, sourceName TEXT)")));
EXPECT_CALL(mockDatabase,
diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp
index 280a240942..0648cca8e0 100644
--- a/tests/unit/unittest/refactoringengine-test.cpp
+++ b/tests/unit/unittest/refactoringengine-test.cpp
@@ -65,13 +65,15 @@ protected:
commandLine = Utils::SmallStringVector(
optionsBuilder.build(projectFile.kind, CppTools::UsePrecompiledHeaders::No));
commandLine.push_back(qStringFilePath);
+ ON_CALL(mockFilePathCaching, filePathId(Eq(clangBackEndFilePath))).WillByDefault(Return(12));
+ cursor.setPosition(11);
}
protected:
NiceMock<MockFilePathCaching> mockFilePathCaching;
MockRefactoringServer mockRefactoringServer;
MockRefactoringClient mockRefactoringClient;
- MockSymbolQuery mockSymbolQuery;
+ NiceMock<MockSymbolQuery> mockSymbolQuery;
ClangRefactoring::RefactoringEngine engine{mockRefactoringServer,
mockRefactoringClient,
mockFilePathCaching,
@@ -85,27 +87,96 @@ protected:
SmallStringVector commandLine;
ProjectExplorer::Project project;
CppTools::ProjectPart::Ptr projectPart;
+ CppTools::Usages usages{{"/path1", 1, 3}, {"/path2", 4, 5}};
CppTools::ProjectFile projectFile{qStringFilePath, CppTools::ProjectFile::CXXSource};
};
-TEST_F(RefactoringEngine, ExpectSourceUsagesAtInFindUsages)
+TEST_F(RefactoringEngine, FindUsages)
{
- cursor.setPosition(11);
+ ON_CALL(mockSymbolQuery, sourceUsagesAt(Eq(12), 2, 5)).WillByDefault(Return(usages));
+ NiceMock<MockFunction<void(const CppTools::Usages &)>> mockCallback;
- EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, 2, 5));
+ EXPECT_CALL(mockCallback, Call(usages));
- engine.findUsages(CppTools::CursorInEditor{cursor, filePath},
- [](const CppTools::Usages &) {});
+ engine.findUsages(CppTools::CursorInEditor{cursor, filePath}, mockCallback.AsStdFunction());
}
-TEST_F(RefactoringEngine, ExpectSourceUsagesAtInGlobalRename)
+TEST_F(RefactoringEngine, CallFindUsages)
{
- cursor.setPosition(11);
+ EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(Eq(12), 2, 5));
- EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, 2, 5));
+ engine.findUsages(CppTools::CursorInEditor{cursor, filePath}, [](const CppTools::Usages &) {});
+}
+
+TEST_F(RefactoringEngine, FindUsagesWithInvalidCursor)
+{
+ EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, _, _)).Times(0);
+
+ engine.findUsages(CppTools::CursorInEditor{{}, filePath}, [](const CppTools::Usages &) {});
+}
+
+TEST_F(RefactoringEngine, CallSourceUsagesInInGlobalRename)
+{
+ EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(Eq(12), 2, 5));
engine.globalRename(CppTools::CursorInEditor{cursor, filePath},
- [](const CppTools::Usages &) {}, QString());
+ [](const CppTools::Usages &) {},
+ {});
+}
+
+TEST_F(RefactoringEngine, CallSourceUsagesInInGlobalRenameWithInvalidCursor)
+{
+ EXPECT_CALL(mockSymbolQuery, sourceUsagesAt(_, _, _)).Times(0);
+
+ engine.globalRename(CppTools::CursorInEditor{{}, filePath}, [](const CppTools::Usages &) {}, {});
+}
+
+TEST_F(RefactoringEngine, CallDeclarationsAtInInGlobalFollowSymbol)
+{
+
+ EXPECT_CALL(mockSymbolQuery, declarationsAt(Eq(12), 2, 5));
+
+ engine.globalFollowSymbol(
+ CppTools::CursorInEditor{cursor, filePath}, [](const Utils::Link &) {}, {}, {}, {}, {});
+}
+
+TEST_F(RefactoringEngine, CallDeclarationsAtInInGlobalFollowSymbolWithInvalidCursor)
+{
+ EXPECT_CALL(mockSymbolQuery, declarationsAt(_, _, _)).Times(0);
+
+ engine.globalFollowSymbol(
+ CppTools::CursorInEditor{{}, filePath}, [](const Utils::Link &) {}, {}, {}, {}, {});
+}
+
+TEST_F(RefactoringEngine, InGlobalFollowSymbol)
+{
+ using Utils::Link;
+ NiceMock<MockFunction<void(const Link &)>> mockCallback;
+ ON_CALL(mockSymbolQuery, declarationsAt(Eq(12), 2, 5)).WillByDefault(Return(usages));
+
+ EXPECT_CALL(mockCallback,
+ Call(AllOf(Field(&Link::targetFileName, Eq("/path1")),
+ Field(&Link::targetLine, Eq(1)),
+ Field(&Link::targetColumn, Eq(2)))));
+
+ engine.globalFollowSymbol(
+ CppTools::CursorInEditor{cursor, filePath}, mockCallback.AsStdFunction(), {}, {}, {}, {});
+}
+
+TEST_F(RefactoringEngine, InGlobalFollowSymbolSkipCurrentFile)
+{
+ using Utils::Link;
+ NiceMock<MockFunction<void(const Link &)>> mockCallback;
+ CppTools::Usages usages{{clangBackEndFilePath, 1, 3}, {"/path2", 4, 5}};
+ ON_CALL(mockSymbolQuery, declarationsAt(Eq(12), 2, 5)).WillByDefault(Return(usages));
+
+ EXPECT_CALL(mockCallback,
+ Call(AllOf(Field(&Link::targetFileName, Eq("/path2")),
+ Field(&Link::targetLine, Eq(4)),
+ Field(&Link::targetColumn, Eq(4)))));
+
+ engine.globalFollowSymbol(
+ CppTools::CursorInEditor{cursor, filePath}, mockCallback.AsStdFunction(), {}, {}, {}, {});
}
TEST_F(RefactoringEngine, EngineIsNotUsableForUnusableServer)
diff --git a/tests/unit/unittest/refactoringprojectupdater-test.cpp b/tests/unit/unittest/refactoringprojectupdater-test.cpp
index 6913d1a16f..8b16adc619 100644
--- a/tests/unit/unittest/refactoringprojectupdater-test.cpp
+++ b/tests/unit/unittest/refactoringprojectupdater-test.cpp
@@ -32,10 +32,11 @@
#include <sqlitedatabase.h>
+#include <clangindexingsettingsmanager.h>
+#include <clangrefactoringservermessages.h>
#include <filepathcaching.h>
#include <precompiledheadersupdatedmessage.h>
#include <refactoringdatabaseinitializer.h>
-#include <clangrefactoringservermessages.h>
#include <pchmanagerclient.h>
@@ -63,6 +64,10 @@ MATCHER_P(IsProjectPartContainer,
class RefactoringProjectUpdater : public testing::Test
{
protected:
+ RefactoringProjectUpdater()
+ {
+ ON_CALL(mockProjectPartsStorage, transactionBackend()).WillByDefault(ReturnRef(database));
+ }
ProjectPart::Ptr createProjectPart(const char *name)
{
ProjectPart::Ptr projectPart{new ProjectPart};
@@ -84,11 +89,13 @@ protected:
mockDependencyCreationProgressManager};
MockCppModelManager mockCppModelManager;
ProjectExplorer::Project project;
+ ClangPchManager::ClangIndexingSettingsManager settingsManager;
ClangRefactoring::RefactoringProjectUpdater updater{mockRefactoringServer,
pchManagerClient,
mockCppModelManager,
filePathCache,
- mockProjectPartsStorage};
+ mockProjectPartsStorage,
+ settingsManager};
Utils::SmallString projectPartId;
};
@@ -112,8 +119,6 @@ TEST_F(RefactoringProjectUpdater, UpdateProjectPart)
.WillRepeatedly(Return(QString(" project1")));
EXPECT_CALL(mockCppModelManager, projectPartForId(Eq(QString(" project1"))))
.WillRepeatedly(Return(createProjectPart("project1")));
- EXPECT_CALL(mockProjectPartsStorage, fetchProjectPartId(Eq(" project1")))
- .WillOnce(Return(ClangBackEnd::ProjectPartId{3}));
EXPECT_CALL(mockRefactoringServer,
updateProjectParts(Field(&UpdateProjectPartsMessage::projectsParts,
ElementsAre(IsProjectPartContainer(3)))));
diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp
index 74363de35f..2cc3f26efd 100644
--- a/tests/unit/unittest/refactoringserver-test.cpp
+++ b/tests/unit/unittest/refactoringserver-test.cpp
@@ -26,6 +26,7 @@
#include "googletest.h"
#include "filesystem-utilities.h"
+#include "mockfilepathcaching.h"
#include "mockrefactoringclient.h"
#include "mocksymbolindexing.h"
#include "sourcerangecontainer-matcher.h"
@@ -98,7 +99,11 @@ protected:
ClangBackEnd::GeneratedFiles generatedFiles;
ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing, filePathCache, generatedFiles};
Utils::SmallString sourceContent{"void f()\n {}"};
- FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"}, sourceContent.clone(), {"cc"}};
+ ClangBackEnd::FilePath filePath{TESTDATA_DIR, "query_simplefunction.cpp"};
+ FileContainer source{filePath.clone(),
+ filePathCache.filePathId(filePath),
+ sourceContent.clone(),
+ {"cc"}};
QTemporaryFile temporaryFile{Utils::TemporaryDirectory::masterDirectoryPath()
+ "/clangQuery-XXXXXX.cpp"};
int processingSlotCount = 2;
@@ -126,9 +131,13 @@ TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUns
{
Utils::SmallString unsavedContent{"void f();"};
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.cpp"}),
"#include \"query_simplefunction.h\"",
{"cc"}};
- FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"}, unsavedContent.clone(), {}};
+ FileContainer unsaved{{TESTDATA_DIR, "query_simplefunction.h"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
+ unsavedContent.clone(),
+ {}};
RequestSourceRangesForQueryMessage message{"functionDecl()", {source.clone()}, {unsaved.clone()}};
EXPECT_CALL(mockRefactoringClient,
@@ -240,6 +249,8 @@ TEST_F(RefactoringServerSlowTest, ForValidRequestSourceRangesAndDiagnosticsGetSo
{
RequestSourceRangesAndDiagnosticsForQueryMessage message("functionDecl()",
{FilePath(temporaryFile.fileName()),
+ filePathCache.filePathId(FilePath(
+ temporaryFile.fileName())),
"void f() {}",
{"cc"}});
@@ -259,6 +270,8 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet
{
RequestSourceRangesAndDiagnosticsForQueryMessage message("func()",
{FilePath(temporaryFile.fileName()),
+ filePathCache.filePathId(FilePath(
+ temporaryFile.fileName())),
"void f() {}",
{"cc"}});
@@ -277,6 +290,7 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet
TEST_F(RefactoringServer, UpdateGeneratedFilesSetMemberWhichIsUsedForSymbolIndexing)
{
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
"void f();",
{}}};
@@ -288,6 +302,7 @@ TEST_F(RefactoringServer, UpdateGeneratedFilesSetMemberWhichIsUsedForSymbolIndex
TEST_F(RefactoringServer, RemoveGeneratedFilesSetMemberWhichIsUsedForSymbolIndexing)
{
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
+ filePathCache.filePathId(FilePath{TESTDATA_DIR, "query_simplefunction.h"}),
"void f();",
{}}};
refactoringServer.updateGeneratedFiles(Utils::clone(unsaved));
@@ -297,8 +312,12 @@ TEST_F(RefactoringServer, RemoveGeneratedFilesSetMemberWhichIsUsedForSymbolIndex
ASSERT_THAT(generatedFiles.fileContainers(), IsEmpty());
}
-TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectParts)
+TEST_F(RefactoringServer, UpdateProjectPartsCalls)
{
+ NiceMock<MockFilePathCaching> mockFilePathCaching;
+ ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing,
+ mockFilePathCaching,
+ generatedFiles};
ProjectPartContainers projectParts{
{{1,
{"-I", TESTDATA_DIR},
@@ -313,8 +332,8 @@ TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectPart
Utils::LanguageVersion::C11,
Utils::LanguageExtension::All}}};
- EXPECT_CALL(mockSymbolIndexing,
- updateProjectParts(projectParts));
+ EXPECT_CALL(mockFilePathCaching, populateIfEmpty());
+ EXPECT_CALL(mockSymbolIndexing, updateProjectParts(projectParts));
refactoringServer.updateProjectParts({Utils::clone(projectParts), {}});
}
diff --git a/tests/unit/unittest/skippedsourceranges-test.cpp b/tests/unit/unittest/skippedsourceranges-test.cpp
index fd95dc4779..c91f726437 100644
--- a/tests/unit/unittest/skippedsourceranges-test.cpp
+++ b/tests/unit/unittest/skippedsourceranges-test.cpp
@@ -71,9 +71,9 @@ MATCHER_P4(IsSourceLocation, filePath, line, column, offset,
)
{
if (!arg.filePath().endsWith(filePath)
- || arg.line() != uint(line)
- || arg.column() != uint(column)
- || arg.offset() != uint(offset)) {
+ || arg.line() != line
+ || arg.column() != column
+ || arg.offset() != offset) {
return false;
}
diff --git a/tests/unit/unittest/sourcerange-test.cpp b/tests/unit/unittest/sourcerange-test.cpp
index 1b2b44a8f9..26c7a5a422 100644
--- a/tests/unit/unittest/sourcerange-test.cpp
+++ b/tests/unit/unittest/sourcerange-test.cpp
@@ -125,17 +125,17 @@ TEST_F(SourceRange, Size)
TEST_F(SourceRange, DISABLED_ON_WINDOWS(Start))
{
ASSERT_THAT(sourceRange.start(), IsSourceLocation(Utf8StringLiteral("diagnostic_source_range.cpp"),
- 8u,
- 5u,
- 43u));
+ 8,
+ 5,
+ 43));
}
TEST_F(SourceRange, DISABLED_ON_WINDOWS(End))
{
ASSERT_THAT(sourceRange.end(), IsSourceLocation(Utf8StringLiteral("diagnostic_source_range.cpp"),
- 8u,
- 6u,
- 44u));
+ 8,
+ 6,
+ 44));
}
TEST_F(SourceRange, Create)
diff --git a/tests/unit/unittest/stringcache-test.cpp b/tests/unit/unittest/stringcache-test.cpp
index 102d851042..8eecd92c44 100644
--- a/tests/unit/unittest/stringcache-test.cpp
+++ b/tests/unit/unittest/stringcache-test.cpp
@@ -25,8 +25,9 @@
#include "googletest.h"
-#include "mockmutex.h"
#include "mockfilepathstorage.h"
+#include "mockmutex.h"
+#include "mocksqlitedatabase.h"
#include <stringcache.h>
@@ -44,29 +45,51 @@ using ClangBackEnd::findInSorted;
using StorageIdFunction = std::function<int(Utils::SmallStringView)>;
using StorageStringFunction = std::function<Utils::PathString(int)>;
-using Cache = ClangBackEnd::StringCache<Utils::PathString,
- Utils::SmallStringView,
- int,
- NiceMock<MockMutex>,
- decltype(&Utils::reverseCompare),
- Utils::reverseCompare>;
-using CacheEntries = Cache::CacheEntries;
-
+using CacheWithMockLocking = ClangBackEnd::StringCache<Utils::PathString,
+ Utils::SmallStringView,
+ int,
+ NiceMock<MockMutex>,
+ decltype(&Utils::reverseCompare),
+ Utils::reverseCompare>;
+
+using CacheWithoutLocking = ClangBackEnd::StringCache<Utils::PathString,
+ Utils::SmallStringView,
+ int,
+ NiceMock<MockMutexNonLocking>,
+ decltype(&Utils::reverseCompare),
+ Utils::reverseCompare>;
+
+template<typename Cache>
class StringCache : public testing::Test
{
protected:
- void SetUp();
+ void SetUp()
+ {
+ std::sort(filePaths.begin(), filePaths.end(), [](auto &f, auto &l) {
+ return compare(f, l) < 0;
+ });
+ std::sort(reverseFilePaths.begin(), reverseFilePaths.end(), [](auto &f, auto &l) {
+ return reverseCompare(f, l) < 0;
+ });
+
+ ON_CALL(this->mockStorage, fetchDirectoryId(Eq("foo"))).WillByDefault(Return(42));
+ ON_CALL(this->mockStorage, fetchDirectoryId(Eq("bar"))).WillByDefault(Return(43));
+ ON_CALL(this->mockStorage, fetchDirectoryId(Eq("poo"))).WillByDefault(Return(44));
+ ON_CALL(this->mockStorage, fetchDirectoryId(Eq("taa"))).WillByDefault(Return(45));
+ ON_CALL(this->mockStorage, fetchDirectoryPath(41)).WillByDefault(Return(Utils::PathString("bar")));
+ }
protected:
- NiceMock<MockFilePathStorage> mockStorage;
- StorageIdFunction mockStorageFetchDirectyId = [&] (Utils::SmallStringView string) {
+ NiceMock<MockSqliteDatabase> mockDatabase;
+ NiceMock<MockFilePathStorage> mockStorage{mockDatabase};
+ StorageIdFunction mockStorageFetchDirectyId = [&](Utils::SmallStringView string) {
return mockStorage.fetchDirectoryId(string);
};
- StorageStringFunction mockStorageFetchDirectyPath = [&] (int id) {
+ StorageStringFunction mockStorageFetchDirectyPath = [&](int id) {
return mockStorage.fetchDirectoryPath(id);
};
Cache cache;
- NiceMock<MockMutex> &mockMutex = cache.mutex();
+ typename Cache::MutexType &mockMutex = cache.mutex();
Utils::PathString filePath1{"/file/pathOne"};
Utils::PathString filePath2{"/file/pathTwo"};
Utils::PathString filePath3{"/file/pathThree"};
@@ -84,431 +107,523 @@ protected:
filePath5};
};
-TEST_F(StringCache, AddFilePath)
+using CacheTypes = ::testing::Types<CacheWithMockLocking, CacheWithoutLocking>;
+TYPED_TEST_SUITE(StringCache, CacheTypes);
+
+TYPED_TEST(StringCache, AddFilePath)
{
- auto id = cache.stringId(filePath1);
+ auto id = this->cache.stringId(this->filePath1);
ASSERT_THAT(id, 0);
}
-TEST_F(StringCache, AddSecondFilePath)
+TYPED_TEST(StringCache, AddSecondFilePath)
{
- cache.stringId(filePath1);
+ this->cache.stringId(this->filePath1);
- auto id = cache.stringId(filePath2);
+ auto id = this->cache.stringId(this->filePath2);
ASSERT_THAT(id, 1);
}
-TEST_F(StringCache, AddDuplicateFilePath)
+TYPED_TEST(StringCache, AddDuplicateFilePath)
{
- cache.stringId(filePath1);
+ this->cache.stringId(this->filePath1);
- auto id = cache.stringId(filePath1);
+ auto id = this->cache.stringId(this->filePath1);
ASSERT_THAT(id, 0);
}
-TEST_F(StringCache, AddDuplicateFilePathBetweenOtherEntries)
+TYPED_TEST(StringCache, AddDuplicateFilePathBetweenOtherEntries)
{
- cache.stringId(filePath1);
- cache.stringId(filePath2);
- cache.stringId(filePath3);
- cache.stringId(filePath4);
+ this->cache.stringId(this->filePath1);
+ this->cache.stringId(this->filePath2);
+ this->cache.stringId(this->filePath3);
+ this->cache.stringId(this->filePath4);
- auto id = cache.stringId(filePath3);
+ auto id = this->cache.stringId(this->filePath3);
ASSERT_THAT(id, 2);
}
-TEST_F(StringCache, ThrowForGettingPathForNoEntry)
+TYPED_TEST(StringCache, ThrowForGettingPathForNoEntry)
{
- EXPECT_ANY_THROW(cache.string(0));
+ EXPECT_ANY_THROW(this->cache.string(0));
}
-TEST_F(StringCache, GetFilePathForIdWithOneEntry)
+TYPED_TEST(StringCache, GetFilePathForIdWithOneEntry)
{
- cache.stringId(filePath1);
+ this->cache.stringId(this->filePath1);
- auto filePath = cache.string(0);
+ auto filePath = this->cache.string(0);
- ASSERT_THAT(filePath, filePath1);
+ ASSERT_THAT(filePath, this->filePath1);
}
-TEST_F(StringCache, GetFilePathForIdWithSomeEntries)
+TYPED_TEST(StringCache, GetFilePathForIdWithSomeEntries)
{
- cache.stringId(filePath1);
- cache.stringId(filePath2);
- cache.stringId(filePath3);
- cache.stringId(filePath4);
+ this->cache.stringId(this->filePath1);
+ this->cache.stringId(this->filePath2);
+ this->cache.stringId(this->filePath3);
+ this->cache.stringId(this->filePath4);
- auto filePath = cache.string(2);
+ auto filePath = this->cache.string(2);
- ASSERT_THAT(filePath, filePath3);
+ ASSERT_THAT(filePath, this->filePath3);
}
-TEST_F(StringCache, GetAllFilePaths)
+TYPED_TEST(StringCache, GetAllFilePaths)
{
- cache.stringId(filePath1);
- cache.stringId(filePath2);
- cache.stringId(filePath3);
- cache.stringId(filePath4);
+ this->cache.stringId(this->filePath1);
+ this->cache.stringId(this->filePath2);
+ this->cache.stringId(this->filePath3);
+ this->cache.stringId(this->filePath4);
- const auto &filePaths = cache.strings({0, 1, 2, 3});
+ auto filePaths = this->cache.strings({0, 1, 2, 3});
- ASSERT_THAT(filePaths, ElementsAre(filePath1, filePath2, filePath3, filePath4));
+ ASSERT_THAT(filePaths,
+ ElementsAre(this->filePath1, this->filePath2, this->filePath3, this->filePath4));
}
-TEST_F(StringCache, AddFilePaths)
+TYPED_TEST(StringCache, AddFilePaths)
{
- auto ids = cache.stringIds({filePath1, filePath2, filePath3, filePath4});
+ auto ids = this->cache.stringIds(
+ {this->filePath1, this->filePath2, this->filePath3, this->filePath4});
ASSERT_THAT(ids, ElementsAre(0, 1, 2, 3));
}
-TEST_F(StringCache, IsEmpty)
+TYPED_TEST(StringCache, AddFilePathsWithStorageFunction)
{
- auto isEmpty = cache.isEmpty();
+ auto ids = this->cache.stringIds({"foo", "taa", "poo", "bar"}, this->mockStorageFetchDirectyId);
- ASSERT_TRUE(isEmpty);
+ ASSERT_THAT(ids, UnorderedElementsAre(42, 43, 44, 45));
}
-TEST_F(StringCache, IsNotEmpty)
+TYPED_TEST(StringCache, IsEmpty)
{
- cache.stringId(filePath1);
-
- auto isEmpty = cache.isEmpty();
+ auto isEmpty = this->cache.isEmpty();
- ASSERT_FALSE(isEmpty);
+ ASSERT_TRUE(isEmpty);
}
-TEST_F(StringCache, PopulateWithEmptyVector)
+TYPED_TEST(StringCache, IsNotEmpty)
{
- CacheEntries entries;
+ this->cache.stringId(this->filePath1);
- cache.uncheckedPopulate(std::move(entries));
+ auto isEmpty = this->cache.isEmpty();
- ASSERT_TRUE(cache.isEmpty());
+ ASSERT_FALSE(isEmpty);
}
-TEST_F(StringCache, IsNotEmptyAfterPopulateWithSomeEntries)
+TYPED_TEST(StringCache, PopulateWithEmptyVector)
{
- CacheEntries entries{{filePath1.clone(), 0},
- {filePath2.clone(), 1},
- {filePath3.clone(), 2},
- {filePath4.clone(), 3}};
+ typename TypeParam::CacheEntries entries;
- cache.uncheckedPopulate(std::move(entries));
+ this->cache.uncheckedPopulate(std::move(entries));
- ASSERT_TRUE(!cache.isEmpty());
+ ASSERT_TRUE(this->cache.isEmpty());
}
-TEST_F(StringCache, GetEntryAfterPopulateWithSomeEntries)
+TYPED_TEST(StringCache, IsNotEmptyAfterPopulateWithSomeEntries)
{
- CacheEntries entries{{filePath1.clone(), 0},
- {filePath2.clone(), 1},
- {filePath3.clone(), 2},
- {filePath4.clone(), 3}};
- cache.uncheckedPopulate(std::move(entries));
+ typename TypeParam::CacheEntries entries{{this->filePath1.clone(), 0},
+ {this->filePath2.clone(), 3},
+ {this->filePath3.clone(), 2},
+ {this->filePath4.clone(), 5}};
- auto string = cache.string(2);
+ this->cache.uncheckedPopulate(std::move(entries));
- ASSERT_THAT(string, filePath3);
+ ASSERT_TRUE(!this->cache.isEmpty());
}
-TEST_F(StringCache, EntriesHaveUniqueIds)
+TYPED_TEST(StringCache, GetEntryAfterPopulateWithSomeEntries)
{
- CacheEntries entries{{filePath1.clone(), 0},
- {filePath2.clone(), 1},
- {filePath3.clone(), 2},
- {filePath4.clone(), 2}};
+ typename TypeParam::CacheEntries entries{{this->filePath1.clone(), 0},
+ {this->filePath2.clone(), 1},
+ {this->filePath3.clone(), 7},
+ {this->filePath4.clone(), 3}};
+ this->cache.uncheckedPopulate(std::move(entries));
- ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException);
+ auto string = this->cache.string(7);
+
+ ASSERT_THAT(string, this->filePath3);
}
-TEST_F(StringCache, IdsAreHigherLowerEntriesSize)
+TYPED_TEST(StringCache, EntriesHaveUniqueIds)
{
- CacheEntries entries{{filePath1.clone(), 0},
- {filePath2.clone(), 1},
- {filePath3.clone(), 4},
- {filePath4.clone(), 3}};
+ typename TypeParam::CacheEntries entries{{this->filePath1.clone(), 0},
+ {this->filePath2.clone(), 1},
+ {this->filePath3.clone(), 2},
+ {this->filePath4.clone(), 2}};
- ASSERT_THROW(cache.populate(std::move(entries)), std::out_of_range);
+ ASSERT_THROW(this->cache.populate(std::move(entries)), StringCacheException);
}
-TEST_F(StringCache, MultipleEntries)
+TYPED_TEST(StringCache, MultipleEntries)
{
- CacheEntries entries{{filePath1.clone(), 0},
- {filePath1.clone(), 1},
- {filePath3.clone(), 2},
- {filePath4.clone(), 3}};
+ typename TypeParam::CacheEntries entries{{this->filePath1.clone(), 0},
+ {this->filePath1.clone(), 1},
+ {this->filePath3.clone(), 2},
+ {this->filePath4.clone(), 3}};
- ASSERT_THROW(cache.populate(std::move(entries)), StringCacheException);
+ ASSERT_THROW(this->cache.populate(std::move(entries)), StringCacheException);
}
-TEST_F(StringCache, DontFindInSorted)
+TYPED_TEST(StringCache, DontFindInSorted)
{
- auto found = findInSorted(filePaths.cbegin(), filePaths.cend(), "/file/pathFoo", compare);
+ auto found = findInSorted(this->filePaths.cbegin(), this->filePaths.cend(), "/file/pathFoo", compare);
ASSERT_FALSE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedOne)
+TYPED_TEST(StringCache, FindInSortedOne)
{
- auto found = findInSorted(filePaths.cbegin(), filePaths.cend(), "/file/pathOne", compare);
+ auto found = findInSorted(this->filePaths.cbegin(), this->filePaths.cend(), "/file/pathOne", compare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedTwo)
+TYPED_TEST(StringCache, FindInSortedTwo)
{
- auto found = findInSorted(filePaths.cbegin(), filePaths.cend(), "/file/pathTwo", compare);
+ auto found = findInSorted(this->filePaths.cbegin(), this->filePaths.cend(), "/file/pathTwo", compare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedTree)
+TYPED_TEST(StringCache, FindInSortedTree)
{
- auto found = findInSorted(filePaths.cbegin(), filePaths.cend(), "/file/pathThree", compare);
+ auto found = findInSorted(this->filePaths.cbegin(),
+ this->filePaths.cend(),
+ "/file/pathThree",
+ compare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedFour)
+TYPED_TEST(StringCache, FindInSortedFour)
{
- auto found = findInSorted(filePaths.cbegin(), filePaths.cend(), "/file/pathFour", compare);
+ auto found = findInSorted(this->filePaths.cbegin(), this->filePaths.cend(), "/file/pathFour", compare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedFife)
+TYPED_TEST(StringCache, FindInSortedFife)
{
- auto found = findInSorted(filePaths.cbegin(), filePaths.cend(), "/file/pathFife", compare);
+ auto found = findInSorted(this->filePaths.cbegin(), this->filePaths.cend(), "/file/pathFife", compare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, DontFindInSortedReverse)
+TYPED_TEST(StringCache, DontFindInSortedReverse)
{
- auto found = findInSorted(reverseFilePaths.cbegin(), reverseFilePaths.cend(), "/file/pathFoo", reverseCompare);
+ auto found = findInSorted(this->reverseFilePaths.cbegin(),
+ this->reverseFilePaths.cend(),
+ "/file/pathFoo",
+ reverseCompare);
ASSERT_FALSE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedOneReverse)
+TYPED_TEST(StringCache, FindInSortedOneReverse)
{
- auto found = findInSorted(reverseFilePaths.cbegin(), reverseFilePaths.cend(), "/file/pathOne", reverseCompare);
+ auto found = findInSorted(this->reverseFilePaths.cbegin(),
+ this->reverseFilePaths.cend(),
+ "/file/pathOne",
+ reverseCompare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedTwoReverse)
+TYPED_TEST(StringCache, FindInSortedTwoReverse)
{
- auto found = findInSorted(reverseFilePaths.cbegin(), reverseFilePaths.cend(), "/file/pathTwo", reverseCompare);
+ auto found = findInSorted(this->reverseFilePaths.cbegin(),
+ this->reverseFilePaths.cend(),
+ "/file/pathTwo",
+ reverseCompare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedTreeReverse)
+TYPED_TEST(StringCache, FindInSortedTreeReverse)
{
- auto found = findInSorted(reverseFilePaths.cbegin(), reverseFilePaths.cend(), "/file/pathThree", reverseCompare);
+ auto found = findInSorted(this->reverseFilePaths.cbegin(),
+ this->reverseFilePaths.cend(),
+ "/file/pathThree",
+ reverseCompare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedFourReverse)
+TYPED_TEST(StringCache, FindInSortedFourReverse)
{
- auto found = findInSorted(reverseFilePaths.cbegin(), reverseFilePaths.cend(), "/file/pathFour", reverseCompare);
+ auto found = findInSorted(this->reverseFilePaths.cbegin(),
+ this->reverseFilePaths.cend(),
+ "/file/pathFour",
+ reverseCompare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, FindInSortedFifeReverse)
+TYPED_TEST(StringCache, FindInSortedFifeReverse)
{
- auto found = findInSorted(reverseFilePaths.cbegin(), reverseFilePaths.cend(), "/file/pathFife", reverseCompare);
+ auto found = findInSorted(this->reverseFilePaths.cbegin(),
+ this->reverseFilePaths.cend(),
+ "/file/pathFife",
+ reverseCompare);
ASSERT_TRUE(found.wasFound);
}
-TEST_F(StringCache, StringIdIsReadAndWriteLockedForUnknownEntry)
+TYPED_TEST(StringCache, StringIdIsReadAndWriteLockedForUnknownEntry)
{
InSequence s;
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
- EXPECT_CALL(mockMutex, lock());
- EXPECT_CALL(mockMutex, unlock());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock());
+ EXPECT_CALL(this->mockMutex, unlock());
- cache.stringId("foo");
+ this->cache.stringId("foo");
}
-TEST_F(StringCache, StringIdWithStorageFunctionIsReadAndWriteLockedForUnknownEntry)
+TYPED_TEST(StringCache, StringIdWithStorageFunctionIsReadAndWriteLockedForUnknownEntry)
{
InSequence s;
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
- EXPECT_CALL(mockMutex, lock());
- EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("foo")));
- EXPECT_CALL(mockMutex, unlock());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock());
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("foo")));
+ EXPECT_CALL(this->mockMutex, unlock());
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
}
-TEST_F(StringCache, StringIdWithStorageFunctionIsReadLockedForKnownEntry)
+TYPED_TEST(StringCache, StringIdWithStorageFunctionIsReadLockedForKnownEntry)
{
InSequence s;
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
- EXPECT_CALL(mockMutex, lock()).Times(0);
- EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("foo"))).Times(0);
- EXPECT_CALL(mockMutex, unlock()).Times(0);
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock()).Times(0);
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("foo"))).Times(0);
+ EXPECT_CALL(this->mockMutex, unlock()).Times(0);
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
}
-TEST_F(StringCache, StringIdIsReadLockedForKnownEntry)
+TYPED_TEST(StringCache, StringIdIsReadLockedForKnownEntry)
{
- cache.stringId("foo");
+ this->cache.stringId("foo");
+
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock()).Times(0);
+ EXPECT_CALL(this->mockMutex, unlock()).Times(0);
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
- EXPECT_CALL(mockMutex, lock()).Times(0);
- EXPECT_CALL(mockMutex, unlock()).Times(0);
+ this->cache.stringId("foo");
+}
+
+TYPED_TEST(StringCache, StringIdsIsLocked)
+{
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
- cache.stringId("foo");
+ this->cache.stringIds({"foo"});
}
-TEST_F(StringCache, StringIdsIsLocked)
+TYPED_TEST(StringCache, StringIdsWithStorageIsLocked)
{
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
- cache.stringIds({"foo"});
+ this->cache.stringIds({"foo"}, this->mockStorageFetchDirectyId);
}
-TEST_F(StringCache, StringIsLocked)
+TYPED_TEST(StringCache, StringIsLocked)
{
- auto id = cache.stringId("foo");
+ auto id = this->cache.stringId("foo");
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
- cache.string(id);
+ this->cache.string(id);
}
-TEST_F(StringCache, StringsIsLocked)
+TYPED_TEST(StringCache, StringsIsLocked)
{
- auto ids = cache.stringIds({"foo", "bar"});
+ auto ids = this->cache.stringIds({"foo", "bar"});
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
- cache.strings(ids);
+ this->cache.strings(ids);
}
-TEST_F(StringCache, StringWithStorageFunctionIsReadAndWriteLockedForUnknownId)
+TYPED_TEST(StringCache, StringWithStorageFunctionIsReadAndWriteLockedForUnknownId)
{
InSequence s;
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
- EXPECT_CALL(mockMutex, lock());
- EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(41)));
- EXPECT_CALL(mockMutex, unlock());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock());
+ EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(41)));
+ EXPECT_CALL(this->mockMutex, unlock());
- cache.string(41, mockStorageFetchDirectyPath);
+ this->cache.string(41, this->mockStorageFetchDirectyPath);
}
-TEST_F(StringCache, StringWithStorageFunctionIsReadLockedForKnownId)
+TYPED_TEST(StringCache, StringWithStorageFunctionIsReadLockedForKnownId)
{
InSequence s;
- cache.string(41, mockStorageFetchDirectyPath);
+ this->cache.string(41, this->mockStorageFetchDirectyPath);
- EXPECT_CALL(mockMutex, lock_shared());
- EXPECT_CALL(mockMutex, unlock_shared());
- EXPECT_CALL(mockMutex, lock()).Times(0);
- EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(41))).Times(0);
- EXPECT_CALL(mockMutex, unlock()).Times(0);
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock()).Times(0);
+ EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(41))).Times(0);
+ EXPECT_CALL(this->mockMutex, unlock()).Times(0);
- cache.string(41, mockStorageFetchDirectyPath);
+ this->cache.string(41, this->mockStorageFetchDirectyPath);
}
-TEST_F(StringCache, StringIdWithStorageFunctionWhichHasNoEntryIsCallingStorageFunction)
+TYPED_TEST(StringCache, StringIdWithStorageFunctionWhichHasNoEntryIsCallingStorageFunction)
{
- EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("foo")));
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("foo")));
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
}
-TEST_F(StringCache, StringIdWithStorageFunctionWhichHasEntryIsNotCallingStorageFunction)
+TYPED_TEST(StringCache, StringIdWithStorageFunctionWhichHasEntryIsNotCallingStorageFunction)
{
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
- EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("foo"))).Times(0);
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("foo"))).Times(0);
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
}
-TEST_F(StringCache, IndexOfStringIdWithStorageFunctionWhichHasEntry)
+TYPED_TEST(StringCache, IndexOfStringIdWithStorageFunctionWhichHasEntry)
{
- cache.stringId("foo", mockStorageFetchDirectyId);
+ this->cache.stringId("foo", this->mockStorageFetchDirectyId);
- auto index = cache.stringId("foo", mockStorageFetchDirectyId);
+ auto index = this->cache.stringId("foo", this->mockStorageFetchDirectyId);
ASSERT_THAT(index, 42);
}
-TEST_F(StringCache, IndexOfStringIdWithStorageFunctionWhichHasNoEntry)
+TYPED_TEST(StringCache, IndexOfStringIdWithStorageFunctionWhichHasNoEntry)
{
- auto index = cache.stringId("foo", mockStorageFetchDirectyId);
+ auto index = this->cache.stringId("foo", this->mockStorageFetchDirectyId);
ASSERT_THAT(index, 42);
}
-TEST_F(StringCache, GetEntryByIndexAfterInsertingByCustomIndex)
+TYPED_TEST(StringCache, GetEntryByIndexAfterInsertingByCustomIndex)
{
- auto index = cache.stringId("foo", mockStorageFetchDirectyId);
+ auto index = this->cache.stringId("foo", this->mockStorageFetchDirectyId);
- auto string = cache.string(index, mockStorageFetchDirectyPath);
+ auto string = this->cache.string(index, this->mockStorageFetchDirectyPath);
ASSERT_THAT(string, Eq("foo"));
}
-TEST_F(StringCache, CallFetchDirectoryPathForLowerIndex)
+TYPED_TEST(StringCache, CallFetchDirectoryPathForLowerIndex)
{
- auto index = cache.stringId("foo", mockStorageFetchDirectyId);
+ auto index = this->cache.stringId("foo", this->mockStorageFetchDirectyId);
- EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(index - 1)));
+ EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(index - 1)));
- cache.string(index - 1, mockStorageFetchDirectyPath);
+ this->cache.string(index - 1, this->mockStorageFetchDirectyPath);
}
-TEST_F(StringCache, CallFetchDirectoryPathForUnknownIndex)
+TYPED_TEST(StringCache, CallFetchDirectoryPathForUnknownIndex)
{
- EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(0)));
+ EXPECT_CALL(this->mockStorage, fetchDirectoryPath(Eq(0)));
- cache.string(0, mockStorageFetchDirectyPath);
+ this->cache.string(0, this->mockStorageFetchDirectyPath);
}
-TEST_F(StringCache, FetchDirectoryPathForUnknownIndex)
+TYPED_TEST(StringCache, FetchDirectoryPathForUnknownIndex)
{
- auto string = cache.string(41, mockStorageFetchDirectyPath);
+ auto string = this->cache.string(41, this->mockStorageFetchDirectyPath);
ASSERT_THAT(string, Eq("bar"));
}
-void StringCache::SetUp()
+TYPED_TEST(StringCache, AddStringCalls)
{
- std::sort(filePaths.begin(), filePaths.end(), [] (auto &f, auto &l) { return compare(f, l) < 0;});
- std::sort(reverseFilePaths.begin(), reverseFilePaths.end(), [] (auto &f, auto &l) { return reverseCompare(f, l) < 0;});
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("foo")));
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("bar")));
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("poo")));
- ON_CALL(mockStorage, fetchDirectoryId(Eq("foo")))
- .WillByDefault(Return(42));
- ON_CALL(mockStorage, fetchDirectoryPath(41))
- .WillByDefault(Return(Utils::PathString("bar")));
+ this->cache.addStrings({"foo", "bar", "poo"}, this->mockStorageFetchDirectyId);
}
+
+TYPED_TEST(StringCache, AddStringCallsOnlyForNewStrings)
+{
+ this->cache.addStrings({"foo", "poo"}, this->mockStorageFetchDirectyId);
+
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("taa")));
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("bar")));
+
+ this->cache.addStrings({"foo", "bar", "poo", "taa"}, this->mockStorageFetchDirectyId);
+}
+
+TYPED_TEST(StringCache, GetStringIdAfterAddingStrings)
+{
+ this->cache.addStrings({"foo", "bar", "poo", "taa"}, this->mockStorageFetchDirectyId);
+
+ ASSERT_THAT(this->cache.string(this->cache.stringId("taa")), Eq("taa"));
}
+TYPED_TEST(StringCache, GetStringAfterAddingStrings)
+{
+ this->cache.addStrings({"foo", "bar", "poo", "taa"}, this->mockStorageFetchDirectyId);
+
+ ASSERT_THAT(this->cache.string(this->cache.stringId("taa")), Eq("taa"));
+}
+
+TYPED_TEST(StringCache, GetStringIdAfterAddingStringsMultipleTimes)
+{
+ this->cache.addStrings({"foo", "taa"}, this->mockStorageFetchDirectyId);
+
+ this->cache.addStrings({"foo", "bar", "poo", "taa"}, this->mockStorageFetchDirectyId);
+
+ ASSERT_THAT(this->cache.string(this->cache.stringId("taa")), Eq("taa"));
+}
+
+TYPED_TEST(StringCache, GetStringIdAfterAddingTheSameStringsMultipleTimes)
+{
+ this->cache.addStrings({"foo", "taa", "poo", "taa", "bar", "taa"},
+ this->mockStorageFetchDirectyId);
+
+ ASSERT_THAT(this->cache.string(this->cache.stringId("taa")), Eq("taa"));
+}
+
+TYPED_TEST(StringCache, AddingEmptyStrings)
+{
+ this->cache.addStrings({}, this->mockStorageFetchDirectyId);
+}
+
+TYPED_TEST(StringCache, FetchStringIdsFromStorageCalls)
+{
+ InSequence s;
+
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock());
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("foo")));
+ EXPECT_CALL(this->mockMutex, unlock());
+ EXPECT_CALL(this->mockMutex, lock_shared());
+ EXPECT_CALL(this->mockMutex, unlock_shared());
+ EXPECT_CALL(this->mockMutex, lock());
+ EXPECT_CALL(this->mockStorage, fetchDirectoryId(Eq("bar")));
+ EXPECT_CALL(this->mockMutex, unlock());
+
+ this->cache.stringIds({"foo", "bar"}, this->mockStorageFetchDirectyId);
+}
+} // namespace
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index 86d0072c90..25c7056f02 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -111,7 +111,6 @@ protected:
ON_CALL(mockCollector, sourceLocations()).WillByDefault(ReturnRef(sourceLocations));
ON_CALL(mockCollector, sourceFiles()).WillByDefault(ReturnRef(sourceFileIds));
ON_CALL(mockCollector, usedMacros()).WillByDefault(ReturnRef(usedMacros));
- ON_CALL(mockCollector, fileStatuses()).WillByDefault(ReturnRef(fileStatus));
ON_CALL(mockCollector, sourceDependencies()).WillByDefault(ReturnRef(sourceDependencies));
ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(A<FilePathId>()))
.WillByDefault(Return(artefact));
@@ -204,6 +203,7 @@ protected:
Utils::LanguageVersion::CXX14,
Utils::LanguageExtension::None};
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
+ filePathId(TESTDATA_DIR "/query_simplefunction.h"),
"void f();",
{}}};
SymbolEntries symbolEntries{{1, {"function", "function", SymbolKind::Function}}};
@@ -871,8 +871,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsFetchIncludedIndexingTimeStamps)
InSequence s;
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
- EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
- EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(_));
+ EXPECT_CALL(mockBuildDependenciesStorage,
+ insertOrUpdateIndexingTimeStampsWithoutTransaction(_, _));
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
@@ -886,8 +886,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsIsBusyInStoringData)
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin())
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
- EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
- EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(_));
+ EXPECT_CALL(mockBuildDependenciesStorage,
+ insertOrUpdateIndexingTimeStampsWithoutTransaction(_, _));
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
diff --git a/tests/unit/unittest/symbolquery-test.cpp b/tests/unit/unittest/symbolquery-test.cpp
index a2aeb41d08..8a7fad4272 100644
--- a/tests/unit/unittest/symbolquery-test.cpp
+++ b/tests/unit/unittest/symbolquery-test.cpp
@@ -61,12 +61,11 @@ protected:
MockSqliteReadStatement &selectSymbolsForKindAndStartsWith2 = mockStatementFactory.selectSymbolsForKindAndStartsWith2;
MockSqliteReadStatement &selectSymbolsForKindAndStartsWith3 = mockStatementFactory.selectSymbolsForKindAndStartsWith3;
MockSqliteReadStatement &selectLocationOfSymbol = mockStatementFactory.selectLocationOfSymbol;
- SourceLocations locations{{1, 1, 1},
- {1, 2, 3},
- {2, 1, 1},
- {2, 3, 1},
- {4, 1, 1},
- {4, 1, 3}};
+ MockSqliteReadStatement &selectSourceUsagesOrderedForSymbolLocation = mockStatementFactory
+ .selectSourceUsagesOrderedForSymbolLocation;
+ MockSqliteReadStatement &selectSourceUsagesByLocationKindForSymbolLocation
+ = mockStatementFactory.selectSourceUsagesByLocationKindForSymbolLocation;
+ SourceLocations locations{{1, 1, 1}, {1, 2, 3}, {2, 1, 1}, {2, 3, 1}, {4, 1, 1}, {4, 1, 3}};
MockQuery query{mockStatementFactory};
};
@@ -78,8 +77,9 @@ protected:
database.execute("INSERT INTO sources VALUES (1, 1, \"filename.h\")");
database.execute("INSERT INTO sources VALUES (2, 1, \"filename.cpp\")");
database.execute("INSERT INTO directories VALUES (1, \"/path/to\")");
- database.execute("INSERT INTO locations VALUES (1, 2, 3, 1, 1)");
- database.execute("INSERT INTO locations VALUES (1, 4, 6, 2, 3)");
+ database.execute("INSERT INTO locations VALUES (1, 2, 3, 1, 2)");
+ database.execute("INSERT INTO locations VALUES (1, 4, 6, 2, 1)");
+ database.execute("INSERT INTO locations VALUES (1, 20, 36, 2, 3)");
database.execute("INSERT INTO symbols VALUES (1, \"functionusr\", \"Function\", 3, \"void function(int)\")");
database.execute("INSERT INTO symbols VALUES (2, \"classusr\", \"Class\", 2, \"class Class final\")");
database.execute("INSERT INTO symbols VALUES (3, \"enumusr\", \"Enum\", 1, \"enum Enum : char\")");
@@ -105,7 +105,8 @@ TEST_F(SymbolQuerySlowTest, LocationsAt)
ASSERT_THAT(locations,
UnorderedElementsAre(SourceLocation(1, 2, 3),
- SourceLocation(2, 4, 6)));
+ SourceLocation(2, 4, 6),
+ SourceLocation(2, 20, 36)));
}
TEST_F(SymbolQuery, SourceUsagesAtCallsValues)
@@ -121,7 +122,8 @@ TEST_F(SymbolQuerySlowTest, SourceUsagesAt)
ASSERT_THAT(usages,
UnorderedElementsAre(CppTools::Usage("/path/to/filename.h", 2, 3),
- CppTools::Usage("/path/to/filename.cpp", 4, 6)));
+ CppTools::Usage("/path/to/filename.cpp", 4, 6),
+ CppTools::Usage("/path/to/filename.cpp", 20, 36)));
}
TEST_F(SymbolQuery, SymbolsCallsValuesWithOneKindParameter)
@@ -193,4 +195,39 @@ TEST_F(SymbolQuerySlowTest, LocationForSymbolId)
ASSERT_THAT(location.value(), Eq(SourceLocation(2, {4, 6})));
}
+TEST_F(SymbolQuery, SourceUsagesAtByLocationKindCallsValues)
+{
+ EXPECT_CALL(selectSourceUsagesByLocationKindForSymbolLocation,
+ valuesReturnSourceUsages(
+ _, 42, 14, 7, static_cast<int>(ClangBackEnd::SourceLocationKind::Definition)));
+
+ query.sourceUsagesAtByLocationKind(42, 14, 7, ClangBackEnd::SourceLocationKind::Definition);
+}
+
+TEST_F(SymbolQuerySlowTest, SourceUsagesAtByLocationKind)
+{
+ auto usages = query.sourceUsagesAtByLocationKind(2,
+ 4,
+ 6,
+ ClangBackEnd::SourceLocationKind::Definition);
+
+ ASSERT_THAT(usages, ElementsAre(CppTools::Usage("/path/to/filename.cpp", 4, 6)));
+}
+
+TEST_F(SymbolQuery, DeclarationsAtCallsValues)
+{
+ EXPECT_CALL(selectSourceUsagesOrderedForSymbolLocation, valuesReturnSourceUsages(_, 42, 14, 7));
+
+ query.declarationsAt(42, 14, 7);
+}
+
+TEST_F(SymbolQuerySlowTest, DeclarationsAt)
+{
+ auto usages = query.declarationsAt(2, 4, 6);
+
+ ASSERT_THAT(usages,
+ ElementsAre(CppTools::Usage("/path/to/filename.cpp", 4, 6),
+ CppTools::Usage("/path/to/filename.h", 2, 3)));
}
+
+} // namespace
diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp
index a766b70fa4..5954f8a9f5 100644
--- a/tests/unit/unittest/symbolscollector-test.cpp
+++ b/tests/unit/unittest/symbolscollector-test.cpp
@@ -146,7 +146,7 @@ protected:
static std::time_t lastModified(Utils::SmallStringView filePath)
{
- return QFileInfo(QString(filePath)).lastModified().toTime_t();
+ return QFileInfo(QString(filePath)).lastModified().toSecsSinceEpoch();
}
ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const
@@ -177,7 +177,7 @@ protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
FilePathCaching filePathCache{database};
- ClangBackEnd::SymbolsCollector collector{database};
+ ClangBackEnd::SymbolsCollector collector{filePathCache};
};
TEST_F(SymbolsCollector, CollectSymbolName)
@@ -264,8 +264,10 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation)
TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile))
{
- FileContainers unsaved{
- {{TESTDATA_DIR, "symbolscollector/generated_file.h"}, "void function();", {}}};
+ FileContainers unsaved{{{TESTDATA_DIR, "symbolscollector/generated_file.h"},
+ filePathId({TESTDATA_DIR, "symbolscollector/generated_file.h"}),
+ "void function();",
+ {}}};
collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/unsaved.cpp"), {"cc"});
collector.setUnsavedFiles(std::move(unsaved));
@@ -295,16 +297,6 @@ TEST_F(SymbolsCollector, ClearSourceLocations)
ASSERT_THAT(collector.sourceLocations(), IsEmpty());
}
-TEST_F(SymbolsCollector, ClearFileStatus)
-{
- collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"});
- collector.collectSymbols();
-
- collector.clear();
-
- ASSERT_THAT(collector.fileStatuses(), IsEmpty());
-}
-
TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared)
{
collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"});
@@ -315,16 +307,6 @@ TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared)
ASSERT_THAT(collector.symbols(), IsEmpty());
}
-TEST_F(SymbolsCollector, DontCollectFileStatusAfterFilesAreCleared)
-{
- collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"});
-
- collector.clear();
- collector.collectSymbols();
-
- ASSERT_THAT(collector.fileStatuses(), IsEmpty());
-}
-
TEST_F(SymbolsCollector, CollectMacroDefinitionSourceLocation)
{
auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h");
@@ -457,19 +439,6 @@ TEST_F(SymbolsCollector, DISABLED_CollectMacroCompilerArgumentSymbols)
Contains(AllOf(HasSymbolName("COMPILER_ARGUMENT"), HasSymbolKind(SymbolKind::Macro))));
}
-TEST_F(SymbolsCollector, CollectFileStatuses)
-{
- auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/main.cpp");
- collector.setFile(fileId, {"cc"});
-
- collector.collectSymbols();
-
- ASSERT_THAT(collector.fileStatuses(),
- ElementsAre(fileStatus(TESTDATA_DIR "/symbolscollector/main.cpp"),
- fileStatus(TESTDATA_DIR "/symbolscollector/header1.h"),
- fileStatus(TESTDATA_DIR "/symbolscollector/header2.h")));
-}
-
TEST_F(SymbolsCollector, IsClassSymbol)
{
collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/symbolkind.cpp"), {"cc"});
@@ -679,4 +648,44 @@ TEST_F(SymbolsCollector, ClearInputFilesAfterCollectingSymbols)
ASSERT_TRUE(collector.isClean());
}
+
+TEST_F(SymbolsCollector, ClassDeclarations)
+{
+ collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"), {"cc"});
+
+ collector.collectSymbols();
+
+ ASSERT_THAT(
+ collector.sourceLocations(),
+ AllOf(Contains(IsSourceLocationEntry(symbolId("Class"),
+ filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"),
+ 1,
+ 7,
+ SourceLocationKind::Definition)),
+ Contains(IsSourceLocationEntry(symbolId("bar"),
+ filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"),
+ 8,
+ 8,
+ SourceLocationKind::Definition)),
+ Contains(IsSourceLocationEntry(symbolId("foo"),
+ filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"),
+ 11,
+ 13,
+ SourceLocationKind::Definition)),
+ Contains(IsSourceLocationEntry(symbolId("foo"),
+ filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"),
+ 6,
+ 8,
+ SourceLocationKind::Declaration)),
+ Contains(IsSourceLocationEntry(symbolId("Class"),
+ filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"),
+ 11,
+ 6,
+ SourceLocationKind::DeclarationReference)),
+ Contains(IsSourceLocationEntry(symbolId("bar"),
+ filePathId(TESTDATA_DIR "/symbolscollector/class.cpp"),
+ 13,
+ 5,
+ SourceLocationKind::DeclarationReference))));
+}
} // namespace
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index bcd1bae2b0..c72d767ee0 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -48,7 +48,7 @@ QMAKE_SUBSTITUTES += cpptoolsjson
DEFINES += CPPTOOLS_JSON=\"R\\\"xxx($${cpptoolsjson.output})xxx\\\"\"
SOURCES += \
- directorypathcompressor-test.cpp \
+ clangindexingsettingsmanager-test.cpp \
clangpathwatcher-test.cpp \
clangqueryexamplehighlightmarker-test.cpp \
clangqueryhighlightmarker-test.cpp \
@@ -57,6 +57,7 @@ SOURCES += \
cppprojectfilecategorizer-test.cpp \
cppprojectinfogenerator-test.cpp \
cppprojectpartchooser-test.cpp \
+ directorypathcompressor-test.cpp \
fakeprocess.cpp \
filepath-test.cpp \
filepathview-test.cpp \
@@ -69,6 +70,7 @@ SOURCES += \
pchmanagerclientserverinprocess-test.cpp \
pchmanagerclient-test.cpp \
pchmanagerserver-test.cpp \
+ preprocessormacrocollector-test.cpp \
processevents-utilities.cpp \
projectpartsmanager-test.cpp \
projectpartsstorage-test.cpp \
@@ -118,7 +120,8 @@ SOURCES += \
commandlinebuilder-test.cpp \
headerpathfilter-test.cpp \
toolchainargumentscache-test.cpp \
- modifiedtimechecker-test.cpp
+ modifiedtimechecker-test.cpp \
+ readexporteddiagnostics-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
diff --git a/tests/unit/unittest/usedmacrocollector-test.cpp b/tests/unit/unittest/usedmacrocollector-test.cpp
index 31aa4fab38..191662db6b 100644
--- a/tests/unit/unittest/usedmacrocollector-test.cpp
+++ b/tests/unit/unittest/usedmacrocollector-test.cpp
@@ -63,7 +63,7 @@ protected:
static std::time_t lastModified(Utils::SmallStringView filePath)
{
- return QFileInfo(QString(filePath)).lastModified().toTime_t();
+ return QFileInfo(QString(filePath)).lastModified().toSecsSinceEpoch();
}
ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const